]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
added offline wrapper for HLT TPC CA tracker (Sergey)
authorrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 2 Jul 2008 12:06:02 +0000 (12:06 +0000)
committerrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 2 Jul 2008 12:06:02 +0000 (12:06 +0000)
38 files changed:
HLT/TPCLib/tracking-ca/AliHLT3DTrackParam.h
HLT/TPCLib/tracking-ca/AliHLTTPCCACell.cxx
HLT/TPCLib/tracking-ca/AliHLTTPCCACell.h
HLT/TPCLib/tracking-ca/AliHLTTPCCADisplay.cxx
HLT/TPCLib/tracking-ca/AliHLTTPCCADisplay.h
HLT/TPCLib/tracking-ca/AliHLTTPCCAEndPoint.cxx [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCAEndPoint.h [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCAGBHit.cxx [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCAGBHit.h [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCAGBTrack.cxx [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCAGBTrack.h [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCAGBTracker.cxx [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCAGBTracker.h [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCAGrid.cxx [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCAGrid.h [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCAHit.cxx
HLT/TPCLib/tracking-ca/AliHLTTPCCAHit.h
HLT/TPCLib/tracking-ca/AliHLTTPCCAMCTrack.cxx [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCAMCTrack.h [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCAOutTrack.cxx
HLT/TPCLib/tracking-ca/AliHLTTPCCAOutTrack.h
HLT/TPCLib/tracking-ca/AliHLTTPCCAParam.cxx
HLT/TPCLib/tracking-ca/AliHLTTPCCAParam.h
HLT/TPCLib/tracking-ca/AliHLTTPCCAPerformance.cxx [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCAPerformance.h [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCARow.cxx
HLT/TPCLib/tracking-ca/AliHLTTPCCARow.h
HLT/TPCLib/tracking-ca/AliHLTTPCCATrack.cxx
HLT/TPCLib/tracking-ca/AliHLTTPCCATrack.h
HLT/TPCLib/tracking-ca/AliHLTTPCCATrackParam.cxx [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCATrackParam.h [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCATracker.cxx
HLT/TPCLib/tracking-ca/AliHLTTPCCATracker.h
HLT/TPCLib/tracking-ca/AliHLTTPCCATrackerComponent.cxx
HLT/TPCLib/tracking-ca/AliHLTTPCCATrackerComponent.h
HLT/TPCLib/tracking-ca/AliTPCtrackerCA.cxx [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliTPCtrackerCA.h [new file with mode: 0644]
HLT/libAliHLTTPC.pkg

index e818440f7a54263ae5d1dda5126cdb11a3da2baa..4af2626a6f4e602aa8f4a062fb285c3edf1b4529 100644 (file)
 #define ALIHLT3DTRACKPARAM_H
 
 #include "Rtypes.h"
+#include "TObject.h"
 
 /**
  * @class AliHLT3DTrackParam
  */
-class AliHLT3DTrackParam{
+class AliHLT3DTrackParam :public TObject
+{
  public:
 
   //*
@@ -119,7 +121,7 @@ class AliHLT3DTrackParam{
   Int_t    fNDF;      // Number of Degrees of Freedom
   Int_t    fSignQ;    // Charge
 
-  ClassDef(AliHLT3DTrackParam, 0);
+  ClassDef(AliHLT3DTrackParam, 1);
 
 };
 
index 92dadeea02e71a439eba37a352ea9d730f792d06..2beebe37abf802fab791ae2b4074351dfce4f46a 100644 (file)
@@ -1,26 +1,27 @@
 // @(#) $Id$
-//*************************************************************************
-// This file is property of and copyright by the ALICE HLT Project        * 
-// ALICE Experiment at CERN, All rights reserved.                         *
-//                                                                        *
-// Primary Authors: Jochen Thaeder <thaeder@kip.uni-heidelberg.de>        *
-//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>              *
-//                  for The ALICE HLT Project.                            *
-//                                                                        *
-// Permission to use, copy, modify and distribute this software and its   *
-// documentation strictly for non-commercial purposes is hereby granted   *
-// without fee, provided that the above copyright notice appears in all   *
-// copies and that both the copyright notice and this permission notice   *
-// appear in the supporting documentation. The authors make no claims     *
-// about the suitability of this software for any purpose. It is          *
-// provided "as is" without express or implied warranty.                  *
-//*************************************************************************
+//***************************************************************************
+// This file is property of and copyright by the ALICE HLT Project          
+// ALICE Experiment at CERN, All rights reserved.                           *
+//                                                                          *
+// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
+//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
+//                  for The ALICE HLT Project.                              *
+//                                                                          *
+// Permission to use, copy, modify and distribute this software and its     *
+// documentation strictly for non-commercial purposes is hereby granted     *
+// without fee, provided that the above copyright notice appears in all     *
+// copies and that both the copyright notice and this permission notice     *
+// appear in the supporting documentation. The authors make no claims       *
+// about the suitability of this software for any purpose. It is            *
+// provided "as is" without express or implied warranty.                    *
+//***************************************************************************
 
 #include "AliHLTTPCCACell.h"
 
 
-ClassImp(AliHLTTPCCACell)
+  //ClassImp(AliHLTTPCCACell)
 
 void AliHLTTPCCACell::Dummy()
 {
+  //* do nothing
 }
index c5c0103ae05395ada6a30802cdf99ca3ec7641fe..0f5bfe6f6906b638752786448eb401f095939eb1 100644 (file)
@@ -5,13 +5,6 @@
 //* ALICE Experiment at CERN, All rights reserved.                         *
 //* See cxx source for full Copyright notice                               *
 
-//*                                                                        *
-//* The AliHLTTPCCACell class describes the "Cell" object ---              *
-//* the set of neghbouring clusters in the same TPC row.                   *
-//* The cells are used as the minimal data units                           *
-//* by the Cellular Automaton tracking algorithm.                          *
-//*                                                                        *
-
 #ifndef ALIHLTTPCCACELL_H
 #define ALIHLTTPCCACELL_H
 
@@ -31,35 +24,41 @@ class AliHLTTPCCACell
 {
  public:
 
-  AliHLTTPCCACell(): fFirstHitRef(0),fNHits(0),fY(0),fZ(0),fErrY(0),fErrZ(0),fIDown(0),fIUp(0),fIUsed(0){}
+  //AliHLTTPCCACell(): fY(0),fZ(0),fErrY(0),fErrZ(0),fFirstHitRef(0),fNHits(0),fLink(0),fTrackID(0){}
 
-  virtual ~AliHLTTPCCACell(){}
+  //virtual ~AliHLTTPCCACell(){}
 
   Float_t &Y(){ return fY; }
   Float_t &Z(){ return fZ; }
   Float_t &ErrY(){ return fErrY; } 
   Float_t &ErrZ(){ return fErrZ; }
+  Float_t &ZMin(){ return fZMin; }
+  Float_t &ZMax(){ return fZMax; }
   
   Int_t &FirstHitRef(){ return fFirstHitRef; }
   Int_t &NHits()      { return fNHits; }
-  Int_t &IDown()      { return fIDown; }
-  Int_t &IUp()        { return fIUp; }
-  Int_t &IUsed()      { return fIUsed; }
+
+  Int_t &Link()       { return fLink; }
+  Int_t &Status()     { return fStatus; }
+  Int_t &TrackID()    { return fTrackID; }
  
  protected:
 
-  Int_t fFirstHitRef;   // index of the first cell hit in the cell->hit reference array
-  Int_t fNHits;         // number of hits in the cell
-  Float_t fY, fZ;       // Y and Z coordinates
-  Float_t fErrY, fErrZ; // cell errors in Y and Z
-  Int_t fIDown, fIUp;   // indices of 2 neighboring cells in up & down directions
-  Int_t fIUsed;         // if it is used by a reconstructed track
+  Float_t fY, fZ, fZMin,fZMax;       //* Y and Z coordinates
+  Float_t fErrY, fErrZ; //* cell errors in Y and Z
+
+  Int_t fFirstHitRef;   //* index of the first cell hit in the cell->hit reference array
+  Int_t fNHits;         //* number of hits in the cell
+
+  Int_t fLink;          //* link to the next cell on the track
+  Int_t fStatus;        //* status flag
+  Int_t fTrackID;       //* index of track
 
  private:
 
   void Dummy(); // to make rulechecker happy by having something in .cxx file
 
-  ClassDef(AliHLTTPCCACell,1);
+  //ClassDef(AliHLTTPCCACell,1);
 };
 
 
index 4f994471d59fd9fcbb1273c797d8306c300f7a5a..5bd8ce4ba07c9f3911fa57025bc92687e634868f 100644 (file)
@@ -1,30 +1,33 @@
-// @(#) $Id$
-//*************************************************************************
-// This file is property of and copyright by the ALICE HLT Project        * 
-// ALICE Experiment at CERN, All rights reserved.                         *
-//                                                                        *
-// Primary Authors: Jochen Thaeder <thaeder@kip.uni-heidelberg.de>        *
-//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>              *
-//                  for The ALICE HLT Project.                            *
-//                                                                        *
-// Permission to use, copy, modify and distribute this software and its   *
-// documentation strictly for non-commercial purposes is hereby granted   *
-// without fee, provided that the above copyright notice appears in all   *
-// copies and that both the copyright notice and this permission notice   *
-// appear in the supporting documentation. The authors make no claims     *
-// about the suitability of this software for any purpose. It is          *
-// provided "as is" without express or implied warranty.                  *
-//*************************************************************************
+// $Id$
+//***************************************************************************
+// This file is property of and copyright by the ALICE HLT Project          
+// ALICE Experiment at CERN, All rights reserved.                           *
+//                                                                          *
+// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
+//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
+//                  for The ALICE HLT Project.                              *
+//                                                                          *
+// Permission to use, copy, modify and distribute this software and its     *
+// documentation strictly for non-commercial purposes is hereby granted     *
+// without fee, provided that the above copyright notice appears in all     *
+// copies and that both the copyright notice and this permission notice     *
+// appear in the supporting documentation. The authors make no claims       *
+// about the suitability of this software for any purpose. It is            *
+// provided "as is" without express or implied warranty.                    *
+//***************************************************************************
 
 #include "AliHLTTPCCADisplay.h"
 
 #include "AliHLTTPCCATracker.h"
-  //#include "TString.h"
+#include "AliHLTTPCCAEndPoint.h"
+#include "AliHLTTPCCARow.h"
+#include "AliHLTTPCCATrack.h"
+
+//#include "TString.h"
 #include "Riostream.h"
 #include "TMath.h"
 #include "TStyle.h"
 #include "TCanvas.h"
-#include <algorithm>
 
 ClassImp(AliHLTTPCCADisplay)
 
@@ -35,17 +38,18 @@ AliHLTTPCCADisplay &AliHLTTPCCADisplay::Instance()
   return gAliHLTTPCCADisplay; 
 }
 
-AliHLTTPCCADisplay::AliHLTTPCCADisplay() : fYX(0), fZX(0), fAsk(1), fSectorView(1), fSector(0), 
-                                          fCos(1), fSin(0), fZMin(-250), fZMax(250),
+AliHLTTPCCADisplay::AliHLTTPCCADisplay() : TObject(), fYX(0), fZX(0), fAsk(1), fSliceView(1), fSlice(0), 
+                                          fCos(1), fSin(0), fZMin(-250), fZMax(250),fSliceCos(1), fSliceSin(0),
                                           fRInnerMin(83.65), fRInnerMax(133.3), fROuterMin(133.5), fROuterMax(247.7),
                                           fTPCZMin(-250.), fTPCZMax(250), fArc(), fLine(), fPLine(), fMarker(), fBox(), fCrown(), fLatex()
 {
   // constructor
-}
+} 
+
 
 AliHLTTPCCADisplay::AliHLTTPCCADisplay( const AliHLTTPCCADisplay& ) 
-  : fYX(0), fZX(0), fAsk(1), fSectorView(1), fSector(0), 
-    fCos(1), fSin(0), fZMin(-250), fZMax(250),
+  : TObject(), fYX(0), fZX(0), fAsk(1), fSliceView(1), fSlice(0), 
+    fCos(1), fSin(0), fZMin(-250), fZMax(250),fSliceCos(1), fSliceSin(0),
     fRInnerMin(83.65), fRInnerMax(133.3), fROuterMin(133.5), fROuterMax(247.7),
     fTPCZMin(-250.), fTPCZMax(250), fArc(), fLine(), fPLine(), fMarker(), fBox(), fCrown(), fLatex()
 {
@@ -73,7 +77,7 @@ void AliHLTTPCCADisplay::Init()
   gStyle->SetCanvasColor(0);
   fYX = new TCanvas ("YX", "YX window", -1, 0, 600, 600);
   fZX = new TCanvas ("ZX", "ZX window", -610, 0, 590, 600);  
-  fMarker = TMarker(0.0, 0.0, 6);
+  fMarker = TMarker(0.0, 0.0, 20);//6);
 }
 
 void AliHLTTPCCADisplay::Update()
@@ -84,7 +88,7 @@ void AliHLTTPCCADisplay::Update()
   fZX->Update();
 }
 
-void AliHLTTPCCADisplay::Clear()
+void AliHLTTPCCADisplay::ClearView()
 {
   // clear windows
   fYX->Clear();
@@ -107,44 +111,79 @@ void AliHLTTPCCADisplay::Ask()
 }
 
 
-void AliHLTTPCCADisplay::SetSectorView()
+void AliHLTTPCCADisplay::SetSliceView()
 {
-  // switch to sector view
-  fSectorView = 1;
+  // switch to slice view
+  fSliceView = 1;
 }
 
 void AliHLTTPCCADisplay::SetTPCView()
 {
   // switch to full TPC view
-  fSectorView = 0;
+  fSliceView = 0;
   fCos = 1;
   fSin = 0;
   fZMin = fTPCZMin;
   fZMax = fTPCZMax;
 }
 
-void AliHLTTPCCADisplay::SetCurrentSector( AliHLTTPCCATracker *sec )
+void AliHLTTPCCADisplay::SetCurrentSlice( AliHLTTPCCATracker *slice )
 {
-  // set reference to the current CA tracker, and read the current sector geometry
-  fSector = sec;
-  if( fSectorView ){
-    fCos = sec->Param().SinAlpha();
-    fSin = - sec->Param().CosAlpha();
-    fZMin = sec->Param().ZMin();
-    fZMax = sec->Param().ZMax();
-    Clear();
-    Double_t r0 = .5*(sec->Param().RMax()+sec->Param().RMin());
-    Double_t dr = .5*(sec->Param().RMax()-sec->Param().RMin());
+  // set reference to the current CA tracker, and read the current slice geometry
+  fSlice = slice;
+  SetSliceTransform( slice );
+  if( fSliceView ){
+    fCos = slice->Param().SinAlpha();
+    fSin = slice->Param().CosAlpha();
+    fZMin = slice->Param().ZMin();
+    fZMax = slice->Param().ZMax();
+    ClearView();
+    Double_t r0 = .5*(slice->Param().RMax()+slice->Param().RMin());
+    Double_t dr = .5*(slice->Param().RMax()-slice->Param().RMin());
     Double_t cx = 0;
-    Double_t cy = r0;
+    Double_t cy = r0;    
+    fYX->Range(cx-dr, cy-dr*1.05, cx+dr, cy+dr);
+    Double_t cz = .5*(slice->Param().ZMax()+slice->Param().ZMin());
+    Double_t dz = .5*(slice->Param().ZMax()-slice->Param().ZMin())*1.2;
+    fZX->Range(cz-dz, cy-dr*1.05, cz+dz, cy+dr);//+dr);
+
+    //fYX->Range(cx-dr/3, cy-dr/3, cx+dr, cy+dr);
+    //fZX->Range(cz-dz/3, cy-dr/3, cz+dz, cy+dr);//+dr);
+    //fYX->Range(cx-dr/3, cy-dr/2*1.3, cx+dr/3, cy-dr/2*1.1);//+dr);
+    //fZX->Range(cz-dz*0.65, cy-dr/2*1.3, cz+dz*0-dz*0.55, cy-dr/2*1.1);//+dr);
+   }
+}
 
-    fYX->Range(cx-dr, cy-dr, cx+dr, cy+dr);
-    Double_t cz = .5*(sec->Param().ZMax()+sec->Param().ZMin());
-    Double_t dz = .5*(sec->Param().ZMax()-sec->Param().ZMin())*1.2;
-    fZX->Range(cz-dz, cy-dr, cz+dz, cy+dr);
-  }
+void AliHLTTPCCADisplay::Set2Slices( AliHLTTPCCATracker *slice )
+{
+  //* Set view for two neighbouring slices
+
+  fSlice = slice;
+  fSliceView = 0;
+  fCos = TMath::Cos(TMath::Pi()/2 - (slice->Param().Alpha()+10./180.*TMath::Pi()));
+  fSin = TMath::Sin(TMath::Pi()/2 - (slice->Param().Alpha()+10./180.*TMath::Pi()));
+  fZMin = slice->Param().ZMin();
+  fZMax = slice->Param().ZMax();
+  ClearView();
+  Double_t r0 = .5*(slice->Param().RMax()+slice->Param().RMin());
+  Double_t dr = .5*(slice->Param().RMax()-slice->Param().RMin());
+  Double_t cx = 0;
+  Double_t cy = r0;    
+  fYX->Range(cx-1.3*dr, cy-1.1*dr, cx+1.3*dr, cy+1.1*dr);
+  fYX->cd();
+  Int_t islice = slice->Param().ISlice();
+  Int_t jslice = slice->Param().ISlice()+1;
+  if( islice==17 ) jslice = 0;
+  else if( islice==35 ) jslice = 18;
+  fLatex.DrawLatex(cx-1.3*dr+1.3*dr*.05,cy-dr+dr*.05, Form("YX, Slices %2i/%2i",islice,jslice));
+  Double_t cz = .5*(slice->Param().ZMax()+slice->Param().ZMin());
+  Double_t dz = .5*(slice->Param().ZMax()-slice->Param().ZMin())*1.2;
+  fZX->Range(cz-dz, cy-1.1*dr, cz+dz, cy+1.1*dr);//+dr);
+  fZX->cd();  
+  fLatex.DrawLatex(cz-dz+dz*.05,cy-dr+dr*.05, Form("ZX, Slices %2i/%2i",islice,jslice));
 }
 
+
 Int_t AliHLTTPCCADisplay::GetColor( Double_t z ) const 
 {
   // Get color with respect to Z coordinate
@@ -165,13 +204,24 @@ void AliHLTTPCCADisplay::Global2View( Double_t x, Double_t y, Double_t *xv, Doub
   *yv = y*fCos - x*fSin;
 }
 
-void AliHLTTPCCADisplay::Sec2View( Double_t x, Double_t y, Double_t *xv, Double_t *yv ) const
+void AliHLTTPCCADisplay::SetSliceTransform( Double_t alpha )
+{
+  fSliceCos = TMath::Cos( alpha );
+  fSliceSin = TMath::Sin( alpha );
+} 
+
+void AliHLTTPCCADisplay::SetSliceTransform( AliHLTTPCCATracker *slice )
+{
+  SetSliceTransform(slice->Param().Alpha());
+}
+
+void AliHLTTPCCADisplay::Slice2View( Double_t x, Double_t y, Double_t *xv, Double_t *yv ) const
 {
-  // convert coordinates sector->view
-  Double_t xg = x*fSector->Param().CosAlpha() - y*fSector->Param().SinAlpha();
-  Double_t yg = y*fSector->Param().CosAlpha() + x*fSector->Param().SinAlpha();
-  *xv = xg*fCos + yg*fSin;
-  *yv = yg*fCos - xg*fSin;
+  // convert coordinates slice->view
+  Double_t xg = x*fSliceCos - y*fSliceSin;
+  Double_t yg = y*fSliceCos + x*fSliceSin;
+  *xv = xg*fCos - yg*fSin;
+  *yv = yg*fCos + xg*fSin;
 }
 
 
@@ -184,11 +234,11 @@ void AliHLTTPCCADisplay::DrawTPC()
     fArc.SetLineColor(kBlack);
     fArc.SetFillStyle(0);
     fYX->cd();    
-    for( Int_t iSec=0; iSec<18; iSec++){
+    for( Int_t iSlice=0; iSlice<18; iSlice++){
       fCrown.SetLineColor(kBlack);
       fCrown.SetFillStyle(0);
-      fCrown.DrawCrown(0,0,fRInnerMin, fRInnerMax, 360./18.*iSec, 360./18.*(iSec+1) );
-      fCrown.DrawCrown(0,0,fROuterMin, fROuterMax, 360./18.*iSec, 360./18.*(iSec+1) );
+      fCrown.DrawCrown(0,0,fRInnerMin, fRInnerMax, 360./18.*iSlice, 360./18.*(iSlice+1) );
+      fCrown.DrawCrown(0,0,fROuterMin, fROuterMax, 360./18.*iSlice, 360./18.*(iSlice+1) );
     }
   }
   fZX->cd();
@@ -196,98 +246,164 @@ void AliHLTTPCCADisplay::DrawTPC()
   fZX->Clear();
 }
 
-void AliHLTTPCCADisplay::DrawSector( AliHLTTPCCATracker *sec )
+void AliHLTTPCCADisplay::DrawSlice( AliHLTTPCCATracker *slice )
 {     
-  // draw current the TPC sector
+  // draw current the TPC slice
   fYX->cd();
-  Double_t r0 = .5*(sec->Param().RMax()+sec->Param().RMin());
-  Double_t dr = .5*(sec->Param().RMax()-sec->Param().RMin());
-  Double_t cx = r0*sec->Param().CosAlpha();
-  Double_t cy = r0*sec->Param().SinAlpha();
+  Double_t r0 = .5*(slice->Param().RMax()+slice->Param().RMin());
+  Double_t dr = .5*(slice->Param().RMax()-slice->Param().RMin());
+  Double_t cx = r0*slice->Param().CosAlpha();
+  Double_t cy = r0*slice->Param().SinAlpha();
   Double_t raddeg = 180./3.1415;
-  Double_t a0 = raddeg*.5*(sec->Param().AngleMax() + sec->Param().AngleMin());
-  Double_t da = raddeg*.5*(sec->Param().AngleMax() - sec->Param().AngleMin());
-  if( fSectorView ){
+  Double_t a0 = raddeg*.5*(slice->Param().AngleMax() + slice->Param().AngleMin());
+  Double_t da = raddeg*.5*(slice->Param().AngleMax() - slice->Param().AngleMin());
+  if( fSliceView ){
     cx = 0; cy = r0;
     a0 = 90.;
-    fLatex.DrawLatex(cx-dr+dr*.05,cy-dr+dr*.05, Form("Sec.%2i",sec->Param().ISec()));
+    fLatex.DrawLatex(cx-dr+dr*.05,cy-dr+dr*.05, Form("YX, Slice %2i",slice->Param().ISlice()));
+  } else {
+    a0+= raddeg*TMath::ATan2(fSin, fCos );
   }
   fArc.SetLineColor(kBlack);
   fArc.SetFillStyle(0);     
   fCrown.SetLineColor(kBlack);
   fCrown.SetFillStyle(0);
     
-  fCrown.DrawCrown(0,0, sec->Param().RMin(),sec->Param().RMax(), a0-da, a0+da );
+  fCrown.DrawCrown(0,0, slice->Param().RMin(),slice->Param().RMax(), a0-da, a0+da );
 
   fLine.SetLineColor(kBlack);
  
   fZX->cd();
 
-  Double_t cz = .5*(sec->Param().ZMax()+sec->Param().ZMin());
-  Double_t dz = .5*(sec->Param().ZMax()-sec->Param().ZMin())*1.2;
+  Double_t cz = .5*(slice->Param().ZMax()+slice->Param().ZMin());
+  Double_t dz = .5*(slice->Param().ZMax()-slice->Param().ZMin())*1.2;
   //fLine.DrawLine(cz+dz, cy-dr, cz+dz, cy+dr ); 
-  if( fSectorView ) fLatex.DrawLatex(cz-dz+dz*.05,cy-dr+dr*.05, Form("Sec.%2i",sec->Param().ISec()));
+  if( fSliceView ) fLatex.DrawLatex(cz-dz+dz*.05,cy-dr+dr*.05, Form("ZX, Slice %2i",slice->Param().ISlice()));
 }
 
 
 void AliHLTTPCCADisplay::DrawHit( Int_t iRow, Int_t iHit, Int_t color )
 {
   // draw hit
-  if( !fSector ) return;
-  AliHLTTPCCARow &row = fSector->Rows()[iRow];
+  if( !fSlice ) return;
+  AliHLTTPCCARow &row = fSlice->Rows()[iRow];
   AliHLTTPCCAHit *h = &(row.Hits()[iHit]);
   if( color<0 ) color = GetColor( h->Z() );
 
-  //Double_t dgy = 3.*TMath::Abs(h->ErrY()*fSector->Param().CosAlpha() - fSector->Param().ErrX()*fSector->Param().SinAlpha() );
-  //Double_t dx = fSector->Param().ErrX()*TMath::Sqrt(12.)/2.;
-  //Double_t dy = h->ErrY()*3.;
-  //Double_t dz = h->ErrZ()*3.;
+  //Double_t dgy = 3.5*TMath::Abs(h->ErrY()*fSlice->Param().CosAlpha() - fSlice->Param().ErrX()*fSlice->Param().SinAlpha() );
+  Double_t dx = 0.1;//fSlice->Param().ErrX()*TMath::Sqrt(12.)/2.;
+  Double_t dy = h->ErrY()*3.5;
+  //Double_t dz = h->ErrZ()*3.5;
+  fMarker.SetMarkerSize(.3);
   fMarker.SetMarkerColor(color);
   fArc.SetLineColor(color);
   fArc.SetFillStyle(0);
-  Double_t vx, vy;
-  Sec2View( row.X(), h->Y(), &vx, &vy );
+  Double_t vx, vy, dvx, dvy;
+  Slice2View( row.X(), h->Y(), &vx, &vy );
+  Slice2View( dx, dy, &dvx, &dvy );
   
   fYX->cd();
-  //if( fSectorView ) fArc.DrawEllipse( vx, vy, dx, dy, 0,360, 90);
-  //else  fArc.DrawEllipse( vx, vy, dx, dy, 0,360, fSector->Param().Alpha()*180./3.1415);
+  //if( fSliceView ) fArc.DrawEllipse( vx, vy, dvx, dvy, 0,360, 0);
+  //else  fArc.DrawEllipse( vx, vy, dx, dy, 0,360, fSlice->Param().Alpha()*180./3.1415);
   fMarker.DrawMarker(vx, vy);
   fZX->cd();
-  //if( fSectorView ) fArc.DrawEllipse( h->Z(), vy, dz, dx, 0,360, 90 );
-  //else fArc.DrawEllipse( h->Z(), vy, dz, dgy, 0,360, fSector->Param().Alpha()*180./3.1415);
+  //if( fSliceView ) fArc.DrawEllipse( h->Z(), vy, dz, dvy, 0,360, 0 );
+  //else fArc.DrawEllipse( h->Z(), vy, dz, dgy, 0,360, fSlice->Param().Alpha()*180./3.1415);
   fMarker.DrawMarker(h->Z(), vy); 
 }
 
 void AliHLTTPCCADisplay::DrawCell( Int_t iRow, AliHLTTPCCACell &cell, Int_t width, Int_t color )
 {
   // draw cell
-  AliHLTTPCCARow &row = fSector->Rows()[iRow];
-  Double_t vx, vy, vdx, vdy;
-  Sec2View(row.X(), cell.Y(), &vx, &vy);
-  Sec2View(0, cell.ErrY()*3, &vdx, &vdy);
+  AliHLTTPCCARow &row = fSlice->Rows()[iRow];
+  Double_t vx, vy, vdx, vdy, vz = cell.Z(), vdz = cell.ErrZ()*3.5;
+  Slice2View(row.X(), cell.Y(), &vx, &vy);
+  Slice2View(0.2, cell.ErrY()*3.5, &vdx, &vdy);
   if( color<0 ) color = GetColor(cell.Z());
   fLine.SetLineColor(color);
   fLine.SetLineWidth(width);
+  fArc.SetLineColor(color);
+  fArc.SetFillStyle(0);
   fYX->cd();
-  fLine.DrawLine(vx-vdx,vy-vdy, vx+vdx, vy+vdy );
+  //fLine.DrawLine(vx-vdx,vy-vdy, vx+vdx, vy+vdy );
+  fArc.DrawEllipse(vx, vy, vdx, vdy, 0,360, 0);
   fZX->cd();
-  fLine.DrawLine(cell.Z()-3*cell.ErrZ(),vy-vdy, cell.Z()+3*cell.ErrZ(), vy+vdy ); 
+  //fLine.DrawLine(cell.Z()-3*cell.ErrZ(),vy-vdy, cell.Z()+3*cell.ErrZ(), vy+vdy ); 
+  fArc.DrawEllipse(vz, vy, vdz, vdy, 0,360, 0);
   fLine.SetLineWidth(1);
 }
 
 void  AliHLTTPCCADisplay::DrawCell( Int_t iRow, Int_t iCell, Int_t width, Int_t color )
 {
   // draw cell
-  AliHLTTPCCARow &row = fSector->Rows()[iRow];
+  AliHLTTPCCARow &row = fSlice->Rows()[iRow];
   DrawCell( iRow, row.Cells()[iCell], width, color );
 }
  
+
+void AliHLTTPCCADisplay::DrawEndPoint( Int_t ID, Float_t R, Int_t width, Int_t color)
+{
+  // draw endpoint
+  if( !fSlice ) return;
+  AliHLTTPCCARow &row = fSlice->ID2Row(ID);
+  AliHLTTPCCAEndPoint &p = fSlice->ID2Point(ID);
+  AliHLTTPCCACell &c = fSlice->ID2Cell(p.CellID());
+  if( color<0 ) color = GetColor( c.Z() );
+
+  fArc.SetLineColor(color);
+  fArc.SetFillStyle(0);
+  fArc.SetLineWidth(width);
+
+  Double_t vx, vy;
+  Slice2View( row.X(), c.Y(), &vx, &vy );  
+  fYX->cd();
+  fArc.DrawEllipse( vx, vy, R, R, 0,360, 90);  
+  fZX->cd();
+  fArc.DrawEllipse( c.Z(), vy, R, R, 0,360, 90);  
+  fArc.SetLineWidth(1);
+
+}
+void AliHLTTPCCADisplay::ConnectEndPoints( Int_t iID, Int_t jID, Float_t R, Int_t width, Int_t color )
+{
+   // connect endpoints
+  if( !fSlice ) return;
+  AliHLTTPCCARow &irow = fSlice->ID2Row(iID);
+  AliHLTTPCCAEndPoint &ip = fSlice->ID2Point(iID);
+  AliHLTTPCCACell &ic = fSlice->ID2Cell(ip.CellID());
+  AliHLTTPCCARow &jrow = fSlice->ID2Row(jID);
+  AliHLTTPCCAEndPoint &jp = fSlice->ID2Point(jID);
+  AliHLTTPCCACell &jc = fSlice->ID2Cell(jp.CellID());
+  if( color<0 ) color = GetColor( ic.Z() );
+  
+  fArc.SetLineColor(color);
+  fArc.SetFillStyle(0);
+  fArc.SetLineWidth(width);
+  fLine.SetLineWidth(width);
+  fLine.SetLineColor(color);
+  Double_t ivx, ivy;
+  Slice2View( irow.X(), ic.Y(), &ivx, &ivy );  
+  Double_t jvx, jvy;
+  Slice2View( jrow.X(), jc.Y(), &jvx, &jvy );  
+
+  fYX->cd();
+  fArc.DrawEllipse( ivx, ivy, R, R, 0,360, 90);  
+  fArc.DrawEllipse( jvx, jvy, R, R, 0,360, 90);  
+  fLine.DrawLine(ivx, ivy,jvx, jvy);
+  fZX->cd();
+  fArc.DrawEllipse( ic.Z(), ivy, R, R, 0,360, 90);  
+  fArc.DrawEllipse( jc.Z(), jvy, R, R, 0,360, 90);  
+  fLine.DrawLine(ic.Z(), ivy, jc.Z(), jvy);
+  fArc.SetLineWidth(1);
+  fLine.SetLineWidth(1);
+}
+
 void AliHLTTPCCADisplay::ConnectCells( Int_t iRow1, AliHLTTPCCACell &cell1, 
                                       Int_t iRow2, AliHLTTPCCACell &cell2, Int_t color )
 {
   // connect two cells on display, kind of row is drawing
-  AliHLTTPCCARow &row1 = fSector->Rows()[iRow1];
-  AliHLTTPCCARow &row2 = fSector->Rows()[iRow2];
+  AliHLTTPCCARow &row1 = fSlice->Rows()[iRow1];
+  AliHLTTPCCARow &row2 = fSlice->Rows()[iRow2];
 
   AliHLTTPCCAHit &h11 = row1.GetCellHit(cell1,0);
   AliHLTTPCCAHit &h12 = row1.GetCellHit(cell1,cell1.NHits()-1);
@@ -309,10 +425,10 @@ void AliHLTTPCCADisplay::ConnectCells( Int_t iRow1, AliHLTTPCCACell &cell1,
 
   Double_t vx11, vx12, vy11, vy12, vx21, vx22, vy21, vy22;
 
-  Sec2View(x11,y11, &vx11, &vy11 );
-  Sec2View(x12,y12, &vx12, &vy12 );
-  Sec2View(x21,y21, &vx21, &vy21 );
-  Sec2View(x22,y22, &vx22, &vy22 );
+  Slice2View(x11,y11, &vx11, &vy11 );
+  Slice2View(x12,y12, &vx12, &vy12 );
+  Slice2View(x21,y21, &vx21, &vy21 );
+  Slice2View(x22,y22, &vx22, &vy22 );
 
   Double_t lx[] = { vx11, vx12, vx22, vx21, vx11 };
   Double_t ly[] = { vy11, vy12, vy22, vy21, vy11 };
@@ -333,112 +449,132 @@ void AliHLTTPCCADisplay::ConnectCells( Int_t iRow1, AliHLTTPCCACell &cell1,
 }
 
 
-void AliHLTTPCCADisplay::DrawTrack( AliHLTTPCCATrack &track, Int_t color )
+
+
+void AliHLTTPCCADisplay::DrawTrack1( AliHLTTPCCATrack &track, Int_t color, Bool_t DrawCells )
 {
   // draw track
 
   if( track.NCells()<2 ) return;
   int width = 3;
-  Double_t b = -5;    
 
   AliHLTTPCCADisplayTmpCell *vCells = new AliHLTTPCCADisplayTmpCell[track.NCells()];
+  AliHLTTPCCATrackParam &t = fSlice->ID2Point(track.PointID()[0]).Param();
 
-  AliHLTTPCCATrackPar t = track.Param();
-  for( Int_t iCell=0; iCell<track.NCells(); iCell++ ){
-    AliHLTTPCCACell &c = fSector->GetTrackCell(track,iCell);
-    AliHLTTPCCARow &row = fSector->GetTrackCellRow(track,iCell);
-    Double_t xyz[3] = {row.X(), c.Y(), c.Z()};
-    if( iCell==0 ) t.TransportBz(-5, xyz);    
-    vCells[iCell].Index() = iCell;
-    vCells[iCell].S() = t.GetDsToPointBz(-5.,xyz);
-  }
-  sort(vCells, vCells + track.NCells(), AliHLTTPCCADisplayTmpCell::CompareCellDS );
-  t.Normalize();
-  const Double_t kCLight = 0.000299792458;
-  Double_t bc = b*kCLight;
-  Double_t pt = sqrt(t.Par()[3]*t.Par()[3] +t.Par()[4]*t.Par()[4] );
-  //Double_t p = sqrt(pt*pt +t.Par()[5]*t.Par()[5] );
-  Double_t q = t.Par()[6];
-
-  //for( Int_t iCell=0; iCell<track.fNCells-1; iCell++ )
-  {    
-    AliHLTTPCCACell &c1 = fSector->GetTrackCell(track,vCells[0].Index());
-    AliHLTTPCCACell &c2 = fSector->GetTrackCell(track,vCells[track.NCells()-1].Index());
-    AliHLTTPCCARow &row1 = fSector->GetTrackCellRow(track,vCells[0].Index());
-    AliHLTTPCCARow &row2 = fSector->GetTrackCellRow(track,vCells[track.NCells()-1].Index());
-    Double_t x1, y1, z1, x2, y2, z2;
-    {
-      Double_t xyz[3] = {row1.X(), c1.Y(), c1.Z()};
-      t.TransportBz(-5, xyz);
-      x1 = t.Par()[0]; y1 = t.Par()[1]; z1 = t.Par()[2];
-    }
-    {
-      Double_t xyz[3] = {row2.X(), c2.Y(), c2.Z()};
-      t.TransportBz(-5, xyz);
-      x2 = t.Par()[0]; y2 = t.Par()[1]; z2 = t.Par()[2];
+  Int_t iID = track.FirstCellID();
+  {
+    Int_t iCell=0;
+    while( iID>=0 ){
+      AliHLTTPCCACell *c = &(fSlice->ID2Cell( iID )); 
+      AliHLTTPCCARow &row = fSlice->ID2Row(iID);
+      vCells[iCell].ID() = iID;    
+      vCells[iCell].S() = t.GetS( row.X(), c->Y() );
+      vCells[iCell].Z() = c->Z();
+      iCell++;
+      iID = c->Link(); 
     }
+  }
+  sort(vCells, vCells + track.NCells(), AliHLTTPCCADisplayTmpCell::CompareCellZ );
+  
+  {
+    AliHLTTPCCACell &c1 = fSlice->ID2Cell(vCells[0].ID());
+    AliHLTTPCCACell &c2 = fSlice->ID2Cell(vCells[track.NCells()-1].ID());
+    if( color<0 ) color = GetColor( (c1.Z()+c2.Z())/2. );
+  }
+  
+  fMarker.SetMarkerColor(color);//kBlue);
+  fMarker.SetMarkerSize(1.);
+  /*
+  for( Int_t i=0; i<3; i++){    
+    AliHLTTPCCACell &c1 = fSlice->ID2Cell(track.CellID()[i]);    
+    AliHLTTPCCARow &row1 = fSlice->ID2Row(track.CellID()[i]);
+    Double_t vx1, vy1;
+    Slice2View(row1.X(), c1.Y(), &vx1, &vy1 ); 
+    fYX->cd();
+    fMarker.DrawMarker(vx1,vy1);
+    fZX->cd();
+    fMarker.DrawMarker(c1.Z(),vy1);
+  }
+  */
+  DrawTrackletPoint( fSlice->ID2Point(track.PointID()[0]).Param(), kBlack);//color );
+  DrawTrackletPoint( fSlice->ID2Point(track.PointID()[1]).Param(), kBlack);//color );
 
-    if( color<0 ) color = GetColor( (z1+z2)/2. );
+  for( Int_t iCell=0; iCell<track.NCells()-1; iCell++ )
+  {
+    AliHLTTPCCACell &c1 = fSlice->ID2Cell(vCells[iCell].ID());
+    AliHLTTPCCACell &c2 = fSlice->ID2Cell(vCells[iCell+1].ID());
+    AliHLTTPCCARow &row1 = fSlice->ID2Row(vCells[iCell].ID());
+    AliHLTTPCCARow &row2 = fSlice->ID2Row(vCells[iCell+1].ID());
+    Float_t x1, y1, z1, x2, y2, z2;    
+    t.GetDCAPoint( row1.X(), c1.Y(), c1.Z(), x1, y1, z1 );
+    t.GetDCAPoint( row2.X(), c2.Y(), c2.Z(), x2, y2, z2 );
+
+    //if( color<0 ) color = GetColor( (z1+z2)/2. );
     Double_t vx1, vy1, vx2, vy2;
-    Sec2View(x1, y1, &vx1, &vy1 );
-    Sec2View(x2, y2, &vx2, &vy2 );
+    Slice2View(x1, y1, &vx1, &vy1 );
+    Slice2View(x2, y2, &vx2, &vy2 );
     
     fLine.SetLineColor( color );
     fLine.SetLineWidth( width );
     
-    if( TMath::Abs(q)>.1 ){
-      Double_t qq = pt/q;
-      
-      Double_t xc = t.Par()[0] + qq*t.Par()[4]/pt/bc;
-      Double_t yc = t.Par()[1] - qq*t.Par()[3]/pt/bc;
-      Double_t r = TMath::Abs(qq)/TMath::Abs(bc);
-       
-      Double_t vx, vy;
-      Sec2View( xc, yc, &vx, &vy );
-      
-      Double_t a1 = TMath::ATan2(vy1-vy, vx1-vx)/TMath::Pi()*180.;
-      Double_t a2 = TMath::ATan2(vy2-vy, vx2-vx)/TMath::Pi()*180.;
-      Double_t da= a2-a1;      
-      if( da>=180 ) da=360-da;
-      if( da<=-180 ) da=360-da;
-      a1 = a2-da;
+    Double_t x0 = t.GetX();
+    Double_t y0 = t.GetY();
+    Double_t sinPhi = t.GetSinPhi();
+    Double_t k = t.GetKappa();
+    Double_t ex = t.GetCosPhi();
+    Double_t ey = sinPhi;
+    if( TMath::Abs(k)>1.e-4 ){
+
       fArc.SetFillStyle(0);
       fArc.SetLineColor(color);    
       fArc.SetLineWidth(width);        
       
       fYX->cd();
+
+      Double_t r = 1/TMath::Abs(k);
+      Double_t xc = x0 -ey*(1/k);
+      Double_t yc = y0 +ex*(1/k);
+     
+      Double_t vx, vy;
+      Slice2View( xc, yc, &vx, &vy );
       
+      Double_t a1 = TMath::ATan2(vy1-vy, vx1-vx)/TMath::Pi()*180.;
+      Double_t a2 = TMath::ATan2(vy2-vy, vx2-vx)/TMath::Pi()*180.;
+      if( a1<0 ) a1+=360;
+      if( a2<0 ) a2+=360;
+      if( a2<a1 ) a2+=360;
+      Double_t da = TMath::Abs(a2-a1);
+      if( da>360 ) da-= 360;
+      if( da>180 ){
+       da = a1;
+       a1 = a2;
+       a2 = da;
+       if( a2<a1 ) a2+=360;    
+      }
       fArc.DrawArc(vx,vy,r, a1,a2,"only");
-    } else {
+      //fArc.DrawArc(vx,vy,r, 0,360,"only");
+   } else {
       fYX->cd();
       fLine.DrawLine(vx1,vy1, vx2, vy2 );
     }
-    
   }
 
   for( Int_t iCell=0; iCell<track.NCells()-1; iCell++ ){
-    
-    AliHLTTPCCACell &c1 = fSector->GetTrackCell(track,vCells[iCell].Index());
-    AliHLTTPCCACell &c2 = fSector->GetTrackCell(track,vCells[iCell+1].Index());
-    AliHLTTPCCARow &row1 = fSector->GetTrackCellRow(track,vCells[iCell].Index());
-    AliHLTTPCCARow &row2 = fSector->GetTrackCellRow(track,vCells[iCell+1].Index());
-    ConnectCells( fSector->GetTrackCellIRow(track,vCells[iCell].Index()),c1,
-                 fSector->GetTrackCellIRow(track,vCells[iCell+1].Index()),c2, color );
-    Double_t x1, y1, z1, x2, y2, z2;
-    {
-      Double_t xyz[3] = {row1.X(), c1.Y(), c1.Z()};
-      t.TransportBz(-5, xyz);
-      x1 = t.Par()[0]; y1 = t.Par()[1]; z1 = t.Par()[2];
-    }
-    {
-      Double_t xyz[3] = {row2.X(), c2.Y(), c2.Z()};
-      t.TransportBz(-5, xyz);
-      x2 = t.Par()[0]; y2 = t.Par()[1]; z2 = t.Par()[2];
-    }
-   
+    AliHLTTPCCACell &c1 = fSlice->ID2Cell(vCells[iCell].ID());
+    AliHLTTPCCACell &c2 = fSlice->ID2Cell(vCells[iCell+1].ID());
+    AliHLTTPCCARow &row1 = fSlice->ID2Row(vCells[iCell].ID());
+    AliHLTTPCCARow &row2 = fSlice->ID2Row(vCells[iCell+1].ID());
+
+    if( DrawCells ) ConnectCells( fSlice->ID2IRow(vCells[iCell].ID()),c1,
+                                 fSlice->ID2IRow(vCells[iCell+1].ID()),c2, color );
+    Float_t x1, y1, z1, x2, y2, z2;
+    t.GetDCAPoint( row1.X(), c1.Y(), c1.Z(), x1, y1, z1 );
+    t.GetDCAPoint( row2.X(), c2.Y(), c2.Z(), x2, y2, z2 );
+
     Double_t vx1, vy1, vx2, vy2;
-    Sec2View(x1, y1, &vx1, &vy1 );
-    Sec2View(x2, y2, &vx2, &vy2 );
+    Slice2View(x1, y1, &vx1, &vy1 );
+    Slice2View(x2, y2, &vx2, &vy2 );
     
     fLine.SetLineColor(color);
     fLine.SetLineWidth(width);    
@@ -450,3 +586,42 @@ void AliHLTTPCCADisplay::DrawTrack( AliHLTTPCCATrack &track, Int_t color )
   delete[] vCells;
 }
 
+void AliHLTTPCCADisplay::DrawTrackletPoint( AliHLTTPCCATrackParam &t, Int_t color )
+{
+  // draw tracklet point
+
+  Double_t x = t.GetX();
+  Double_t y = t.GetY();
+  Double_t sinPhi = t.GetSinPhi();
+  Double_t z = t.GetZ();
+  Double_t dzds = t.GetDzDs();
+  Double_t ex = t.GetCosPhi();
+  Double_t ey = sinPhi;
+
+  int width = 3;
+
+  if( color<0 ) color = GetColor( t.GetZ() );
+    
+  fMarker.SetMarkerColor(color);
+  fMarker.SetMarkerSize(.5);
+  fLine.SetLineWidth(width);  
+  fLine.SetLineColor(color);
+
+  Double_t vx, vy, vex, vey, vdx, vdy;
+  Double_t dz = TMath::Sqrt(t.GetErr2Z());
+  Slice2View( x, y, &vx, &vy ); 
+  Slice2View( ex, ey, &vex, &vey ); 
+  Slice2View( 0, TMath::Sqrt(t.GetErr2Y())*3.5, &vdx, &vdy);
+  Double_t d = TMath::Sqrt(vex*vex+vey*vey);
+  vex/=d;
+  vey/=d;
+  fYX->cd();
+  fMarker.DrawMarker(vx,vy);
+  fLine.DrawLine(vx,vy,vx+vex*4, vy+vey*4);
+  fLine.DrawLine(vx-vdx,vy-vdy, vx+vdx, vy+vdy );
+  fZX->cd();
+  fMarker.DrawMarker(z,vy);
+  fLine.DrawLine(z,vy,z+dzds*4, vy+vey*4);
+  fLine.DrawLine(z-3.5*dz,vy-vdy, z+3.5*dz, vy+vdy ); 
+  fLine.SetLineWidth(1);
+}
index eb23307dcf900625c915203c830f6e8527e7ed9d..e2c9b589a7b0d416b634e48f78503f7e4c85f47a 100644 (file)
@@ -16,8 +16,9 @@
 class AliHLTTPCCATracker;
 class AliHLTTPCCACell;
 class AliHLTTPCCATrack;
-
+class AliHLTTPCCATrackParam;
 class TCanvas;
+#include "TObject.h"
 #include "TArc.h"
 #include "TLine.h"
 #include "TPolyLine.h"
@@ -30,7 +31,7 @@ class TCanvas;
 /**
  * @class AliHLTTPCCADisplay
  */
-class AliHLTTPCCADisplay
+class AliHLTTPCCADisplay:public TObject
 {
  public:
 
@@ -44,34 +45,45 @@ class AliHLTTPCCADisplay
 
   void Init();
   void Update();
-  void Clear();
+  void ClearView();
   void Ask();
-  void SetSectorView();
+  void SetSliceView();
   void SetTPCView();
-  void SetCurrentSector( AliHLTTPCCATracker *sec ); 
+  void SetCurrentSlice( AliHLTTPCCATracker *slice ); 
+  void Set2Slices( AliHLTTPCCATracker *slice );
 
   Int_t GetColor( Double_t z ) const ;
   void Global2View( Double_t x, Double_t y, Double_t *xv, Double_t *yv ) const ;
-  void Sec2View( Double_t x, Double_t y, Double_t *xv, Double_t *yv ) const ;
+  void Slice2View( Double_t x, Double_t y, Double_t *xv, Double_t *yv ) const ;
 
   void DrawTPC();
-  void DrawSector( AliHLTTPCCATracker *sec ); 
+  void DrawSlice( AliHLTTPCCATracker *slice ); 
 
   void DrawHit( Int_t iRow,Int_t iHit, Int_t color=-1 );
   void DrawCell( Int_t iRow, AliHLTTPCCACell &cell, Int_t width=1, Int_t color=-1 );
   void DrawCell( Int_t iRow, Int_t iCell, Int_t width=1, Int_t color=-1 );
 
+  void DrawEndPoint( Int_t ID, Float_t R, Int_t width=1, Int_t color=-1 );
+  void ConnectEndPoints( Int_t iID, Int_t jID, Float_t R, Int_t width=1, Int_t color=-1 );
+
   void ConnectCells( Int_t iRow1, AliHLTTPCCACell &cell1, Int_t iRow2, AliHLTTPCCACell &cell2, Int_t color=-1 );
 
-  void DrawTrack( AliHLTTPCCATrack &track, Int_t color=-1 );
+  void DrawTrack1( AliHLTTPCCATrack &track, Int_t color=-1, Bool_t DrawCells=1 );
+  void DrawTrackletPoint( AliHLTTPCCATrackParam &t, Int_t color=-1 );
+
+  void SetSliceTransform( Double_t alpha );
+
+  void SetSliceTransform( AliHLTTPCCATracker *slice );
+
 
  protected:
 
   TCanvas *fYX, *fZX;               // two views
   Bool_t fAsk;                      // flag to ask for the pressing key
-  Bool_t fSectorView;               // switch between sector/TPC zoomv
-  AliHLTTPCCATracker *fSector;      // current CA tracker, includes sector geometry
+  Bool_t fSliceView;               // switch between slice/TPC zoom
+  AliHLTTPCCATracker *fSlice;      // current CA tracker, includes slice geometry
   Double_t fCos, fSin, fZMin, fZMax;// view parameters
+  Double_t fSliceCos, fSliceSin;        // current slice angle
   Double_t fRInnerMin, fRInnerMax, fROuterMin, fROuterMax,fTPCZMin, fTPCZMax; // view parameters
 
   TArc fArc;       // parameters of drawing objects are copied from this members
@@ -83,18 +95,26 @@ class AliHLTTPCCADisplay
   TLatex fLatex;   //!
 
   class AliHLTTPCCADisplayTmpCell{  
+
   public:
-    Int_t &Index(){ return fIndex; }
+    Int_t &ID(){ return fCellID; }
     Double_t &S(){ return fS; }
+    Double_t &Z(){ return fZ; }
 
     static Bool_t CompareCellDS( const AliHLTTPCCADisplayTmpCell &a, 
                                 const AliHLTTPCCADisplayTmpCell  &b )
     {    
       return (a.fS < b.fS);
     }
+    static Bool_t CompareCellZ( const AliHLTTPCCADisplayTmpCell &a, 
+                                const AliHLTTPCCADisplayTmpCell  &b )
+    {    
+      return (a.fZ < b.fZ);
+    }
   protected:
-    Int_t fIndex; // cell index
-    Double_t fS;  // cell position on the track
+    Int_t fCellID; // cell ID
+    Double_t fS;  // cell position on the XY track curve 
+    Double_t fZ;  // cell Z position
   };
 
 
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCAEndPoint.cxx b/HLT/TPCLib/tracking-ca/AliHLTTPCCAEndPoint.cxx
new file mode 100644 (file)
index 0000000..30532d2
--- /dev/null
@@ -0,0 +1,24 @@
+// $Id$
+//***************************************************************************
+// This file is property of and copyright by the ALICE HLT Project          * 
+// ALICE Experiment at CERN, All rights reserved.                           *
+//                                                                          *
+// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
+//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
+//                  for The ALICE HLT Project.                              *
+//                                                                          *
+// Permission to use, copy, modify and distribute this software and its     *
+// documentation strictly for non-commercial purposes is hereby granted     *
+// without fee, provided that the above copyright notice appears in all     *
+// copies and that both the copyright notice and this permission notice     *
+// appear in the supporting documentation. The authors make no claims       *
+// about the suitability of this software for any purpose. It is            *
+// provided "as is" without express or implied warranty.                    *
+//***************************************************************************
+
+#include "AliHLTTPCCAEndPoint.h"
+
+void AliHLTTPCCAEndPoint::Dummy()
+{
+  //* do nothing
+}
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCAEndPoint.h b/HLT/TPCLib/tracking-ca/AliHLTTPCCAEndPoint.h
new file mode 100644 (file)
index 0000000..7ed1ac6
--- /dev/null
@@ -0,0 +1,48 @@
+//-*- Mode: C++ -*-
+// $Id$
+
+//* This file is property of and copyright by the ALICE HLT Project        * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//* See cxx source for full Copyright notice                               *
+
+//*                                                                        *
+//* The AliHLTTPCCAEndPoint class describes the end point of the track     *
+//* it contains the fitted track parameters at this point                  *
+//* The class is used for the matching of tracks withing one TPC slice     *
+//*                                                                        *
+
+#ifndef ALIHLTTPCCAENDPOINT_H
+#define ALIHLTTPCCAENDPOINT_H
+
+
+#include "Rtypes.h"
+#include "AliHLTTPCCATrackParam.h"
+
+/**
+ * @class AliHLTTPCCAEndPoint
+ */
+class AliHLTTPCCAEndPoint
+{
+ public:
+  
+  AliHLTTPCCAEndPoint() :fCellID(0),fTrackID(0),fLink(0),fParam(){}
+  Int_t &CellID()  { return fCellID; }
+  Int_t &TrackID() { return fTrackID; }
+  Int_t &Link()    { return fLink; }
+
+  AliHLTTPCCATrackParam &Param(){ return fParam; };
+
+ protected:
+
+  Int_t fCellID;                //* index of the cell
+  Int_t fTrackID;               //* index of the track
+  Int_t fLink;                  //* link to the neighbour (if found)
+  AliHLTTPCCATrackParam fParam; //* track parameters at the end point
+
+private:
+  void Dummy(); //* to make rulechecker happy by having something in .cxx file
+
+};
+
+
+#endif
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCAGBHit.cxx b/HLT/TPCLib/tracking-ca/AliHLTTPCCAGBHit.cxx
new file mode 100644 (file)
index 0000000..65d80ca
--- /dev/null
@@ -0,0 +1,31 @@
+// $Id$
+//***************************************************************************
+// This file is property of and copyright by the ALICE HLT Project          * 
+// ALICE Experiment at CERN, All rights reserved.                           *
+//                                                                          *
+// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
+//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
+//                  for The ALICE HLT Project.                              *
+//                                                                          *
+// Permission to use, copy, modify and distribute this software and its     *
+// documentation strictly for non-commercial purposes is hereby granted     *
+// without fee, provided that the above copyright notice appears in all     *
+// copies and that both the copyright notice and this permission notice     *
+// appear in the supporting documentation. The authors make no claims       *
+// about the suitability of this software for any purpose. It is            *
+// provided "as is" without express or implied warranty.                    *
+//***************************************************************************
+
+#include "AliHLTTPCCAGBHit.h"
+
+//ClassImp(AliHLTTPCCAGBHit)
+
+bool AliHLTTPCCAGBHit::Compare(const AliHLTTPCCAGBHit &a, const AliHLTTPCCAGBHit &b)
+{
+  //* Comparison function for sorting hits
+  if( a.fISlice<b.fISlice ) return 1;
+  if( a.fISlice>b.fISlice ) return 0;
+  if( a.fIRow<b.fIRow ) return 1;
+  if( a.fIRow>b.fIRow ) return 0;
+  return (a.fZ < b.fZ);
+}
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCAGBHit.h b/HLT/TPCLib/tracking-ca/AliHLTTPCCAGBHit.h
new file mode 100644 (file)
index 0000000..43f6586
--- /dev/null
@@ -0,0 +1,76 @@
+//-*- Mode: C++ -*-
+// $Id$
+
+//* This file is property of and copyright by the ALICE HLT Project        * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//* See cxx source for full Copyright notice                               *
+
+#ifndef ALIHLTTPCCAGBHIT_H
+#define ALIHLTTPCCAGBHIT_H
+
+#include "Rtypes.h"
+#include "AliHLTTPCCAHit.h"
+
+/**
+ * @class AliHLTTPCCAGBHit
+ *
+ * The AliHLTTPCCAGBHit class is the internal representation
+ * of the TPC clusters for the AliHLTTPCCAGBTracker algorithm.
+ *
+ */
+class AliHLTTPCCAGBHit
+{
+ public:
+  AliHLTTPCCAGBHit()
+    :fX(0),fY(0),fZ(0),fErrX(0),fErrY(0),fErrZ(0),
+    fISlice(0), fIRow(0), fID(0), fIsUsed(0),fSliceHit(){}
+
+  virtual ~AliHLTTPCCAGBHit(){}
+
+  Float_t &X(){ return fX; }
+  Float_t &Y(){ return fY; } 
+  Float_t &Z(){ return fZ; } 
+
+  Float_t &ErrX(){ return fErrX; }
+  Float_t &ErrY(){ return fErrY; }
+  Float_t &ErrZ(){ return fErrZ; }
+
+  Int_t &ISlice(){ return fISlice; }
+  Int_t &IRow(){ return fIRow; }
+  Int_t &ID(){ return fID; }
+  Bool_t &IsUsed(){ return fIsUsed; };
+
+  AliHLTTPCCAHit &SliceHit(){ return fSliceHit; } 
+
+
+  static bool Compare(const AliHLTTPCCAGBHit &a, const AliHLTTPCCAGBHit &b);
+
+  static bool CompareRowDown(const AliHLTTPCCAGBHit &a, const AliHLTTPCCAGBHit &b){
+    return ( a.fIRow>b.fIRow );
+  }
+  static bool ComparePRowDown(const AliHLTTPCCAGBHit *a, const AliHLTTPCCAGBHit *b){
+    return ( a->fIRow>b->fIRow );
+  }
+
+ protected:
+
+  Float_t fX; //* X position
+  Float_t fY; //* Y position
+  Float_t fZ; //* Z position
+
+  Float_t fErrX; //* X position error
+  Float_t fErrY; //* Y position error
+  Float_t fErrZ; //* Z position error
+
+  Int_t fISlice; //* slice number
+  Int_t fIRow;   //* row number
+  Int_t fID;     //* external ID (id of AliTPCcluster) 
+  Bool_t fIsUsed; //* is used by GBTracks
+
+  AliHLTTPCCAHit fSliceHit; //* corresponding slice hit
+
+  //ClassDef(AliHLTTPCCAGBHit,1);
+
+};
+
+#endif
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCAGBTrack.cxx b/HLT/TPCLib/tracking-ca/AliHLTTPCCAGBTrack.cxx
new file mode 100644 (file)
index 0000000..5427df0
--- /dev/null
@@ -0,0 +1,26 @@
+// $Id$
+//***************************************************************************
+// This file is property of and copyright by the ALICE HLT Project          * 
+// ALICE Experiment at CERN, All rights reserved.                           *
+//                                                                          *
+// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
+//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
+//                  for The ALICE HLT Project.                              *
+//                                                                          *
+// Permission to use, copy, modify and distribute this software and its     *
+// documentation strictly for non-commercial purposes is hereby granted     *
+// without fee, provided that the above copyright notice appears in all     *
+// copies and that both the copyright notice and this permission notice     *
+// appear in the supporting documentation. The authors make no claims       *
+// about the suitability of this software for any purpose. It is            *
+// provided "as is" without express or implied warranty.                    *
+//***************************************************************************
+
+#include "AliHLTTPCCAGBTrack.h"
+
+ClassImp(AliHLTTPCCAGBTrack)
+void AliHLTTPCCAGBTrack::Dummy()
+{ 
+  //* do nothing
+}
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCAGBTrack.h b/HLT/TPCLib/tracking-ca/AliHLTTPCCAGBTrack.h
new file mode 100644 (file)
index 0000000..aba0a01
--- /dev/null
@@ -0,0 +1,51 @@
+//-*- Mode: C++ -*-
+// $Id$
+
+//* This file is property of and copyright by the ALICE HLT Project        * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//* See cxx source for full Copyright notice                               *
+
+#ifndef ALIHLTTPCCAGBTRACK_H
+#define ALIHLTTPCCAGBTRACK_H
+
+#include "Rtypes.h"
+
+#include "AliHLTTPCCATrackParam.h"
+
+/**
+ * @class AliHLTTPCCAGBTrack
+ *
+ *
+ */
+class AliHLTTPCCAGBTrack
+{
+ public:
+
+  AliHLTTPCCAGBTrack():fFirstHitRef(0),fNHits(0),fParam(),fAlpha(0){ ; }
+  virtual ~AliHLTTPCCAGBTrack(){ ; }
+
+  Int_t &NHits()               { return fNHits; }
+  Int_t &FirstHitRef()         { return fFirstHitRef; }
+  AliHLTTPCCATrackParam &Param() { return fParam; }
+  Double_t &Alpha()            { return fAlpha; }
+
+  static Bool_t ComparePNClusters( const AliHLTTPCCAGBTrack *a, const AliHLTTPCCAGBTrack *b){
+    return (a->fNHits > b->fNHits);
+  }
+
+ protected:
+  
+  Int_t fFirstHitRef;        // index of the first hit reference in track->hit reference array
+  Int_t fNHits;              // number of track hits
+  AliHLTTPCCATrackParam fParam;// fitted track parameters
+  Double_t fAlpha;             //* Alpha angle of the parametrerisation
+
+ private:
+
+  void Dummy(); // to make rulechecker happy by having something in .cxx file
+
+  ClassDef(AliHLTTPCCAGBTrack,1);
+};
+
+
+#endif
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCAGBTracker.cxx b/HLT/TPCLib/tracking-ca/AliHLTTPCCAGBTracker.cxx
new file mode 100644 (file)
index 0000000..a371623
--- /dev/null
@@ -0,0 +1,771 @@
+// $Id$
+//***************************************************************************
+// This file is property of and copyright by the ALICE HLT Project          * 
+// ALICE Experiment at CERN, All rights reserved.                           *
+//                                                                          *
+// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
+//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
+//                  for The ALICE HLT Project.                              *
+//                                                                          *
+// Permission to use, copy, modify and distribute this software and its     *
+// documentation strictly for non-commercial purposes is hereby granted     *
+// without fee, provided that the above copyright notice appears in all     *
+// copies and that both the copyright notice and this permission notice     *
+// appear in the supporting documentation. The authors make no claims       *
+// about the suitability of this software for any purpose. It is            *
+// provided "as is" without express or implied warranty.                    *
+//***************************************************************************
+
+#include "AliHLTTPCCAGBTracker.h"
+#include "AliHLTTPCCAGBHit.h"
+#include "AliHLTTPCCAOutTrack.h"
+#include "AliHLTTPCCATracker.h"
+#include "AliHLTTPCCAGBTrack.h"
+
+#include "TMath.h"
+#include "TStopwatch.h"
+#include "Riostream.h"
+#include "TROOT.h"
+
+//#define DRAW
+
+#ifdef DRAW
+#include "AliHLTTPCCADisplay.h"
+#include "TApplication.h"
+#endif //DRAW
+
+ClassImp(AliHLTTPCCAGBTracker)
+
+AliHLTTPCCAGBTracker::AliHLTTPCCAGBTracker()
+  : TObject(),
+    fSlices(0), 
+    fNSlices(0), 
+    fHits(0),
+    fNHits(0),
+    fTrackHits(0), 
+    fTracks(0), 
+    fNTracks(0),
+    fSliceTrackInfos(0),
+    fStatNEvents(0)
+{
+  //* constructor
+  fStatTime[0] = 0;
+  fStatTime[1] = 0;
+  fStatTime[2] = 0;
+  fStatTime[3] = 0;
+  fStatTime[4] = 0;
+  fStatTime[5] = 0;
+  fStatTime[6] = 0;
+  fStatTime[7] = 0;
+  fStatTime[8] = 0;
+  fStatTime[9] = 0;
+}
+
+AliHLTTPCCAGBTracker::AliHLTTPCCAGBTracker(const AliHLTTPCCAGBTracker&)
+  : TObject(),
+    fSlices(0), 
+    fNSlices(0), 
+    fHits(0),
+    fNHits(0),
+    fTrackHits(0), 
+    fTracks(0), 
+    fNTracks(0),
+    fSliceTrackInfos(0),
+    fStatNEvents(0)
+{
+  //* dummy
+}
+
+AliHLTTPCCAGBTracker &AliHLTTPCCAGBTracker::operator=(const AliHLTTPCCAGBTracker&)
+{
+  //* dummy
+  return *this;
+}
+
+AliHLTTPCCAGBTracker::~AliHLTTPCCAGBTracker()
+{
+  //* destructor
+  StartEvent();
+  if( fSliceTrackInfos ) delete[] fSliceTrackInfos;
+  fSliceTrackInfos = 0;
+  if( fSlices ) delete[] fSlices;
+  fSlices=0;
+}
+
+void AliHLTTPCCAGBTracker::SetNSlices( Int_t N )
+{
+  //* set N of slices
+  StartEvent();
+  fNSlices = N;
+  if( fSliceTrackInfos ) delete[] fSliceTrackInfos;
+  fSliceTrackInfos = 0;
+  if( fSlices ) delete[] fSlices;
+  fSlices=0;
+  fSlices = new AliHLTTPCCATracker[N];
+  fSliceTrackInfos = new AliHLTTPCCAGBSliceTrackInfo *[N];
+  for( Int_t iSlice=0; iSlice<fNSlices; iSlice++ ){
+    fSliceTrackInfos[iSlice] = 0;
+  }
+}
+
+void AliHLTTPCCAGBTracker::StartEvent()
+{
+  //* clean up track and hit arrays
+
+  if( fSliceTrackInfos ){
+    for( Int_t iSlice=0; iSlice<fNSlices; iSlice++ ){
+      if( fSliceTrackInfos[iSlice] ) delete[] fSliceTrackInfos[iSlice];
+      fSliceTrackInfos[iSlice] = 0;
+    }
+  }
+  if( fTrackHits ) delete[] fTrackHits;
+  fTrackHits = 0;
+  if( fTracks ) delete[] fTracks;
+  fTracks = 0;
+  if( fHits ) delete[] fHits;
+  fHits=0;
+  fNHits = 0;
+  fNTracks = 0;
+  for( int i=0; i<fNSlices; i++) fSlices[i].StartEvent();
+}
+
+
+void AliHLTTPCCAGBTracker::SetNHits( Int_t nHits )
+{
+  //* set the number of hits
+  if( fHits ) delete[] fHits;
+  fHits = 0;
+  fHits = new AliHLTTPCCAGBHit[ nHits ];
+  fNHits = 0;
+}  
+
+void AliHLTTPCCAGBTracker::ReadHit( Double_t x, Double_t y, Double_t z, 
+                                   Double_t errY, Double_t errZ,
+                                   Int_t ID, Int_t iSlice, Int_t iRow )
+{
+  //* read the hit to local array
+  AliHLTTPCCAGBHit &hit = fHits[fNHits];
+  hit.X() = x;
+  hit.Y() = y;
+  hit.Z() = z;  
+  hit.ErrX() = 1.e-4;//fSlices[iSlice].Param().ErrX();
+  hit.ErrY() = errY;
+  hit.ErrZ() = errZ;
+  hit.ID() = ID;
+  hit.ISlice()=iSlice;
+  hit.IRow() = iRow;
+  hit.IsUsed() = 0;
+
+  hit.SliceHit().Y() = y;
+  hit.SliceHit().Z() = z;
+  hit.SliceHit().ErrY() = errY;
+  hit.SliceHit().ErrZ() = errZ;
+  hit.SliceHit().ID() = 0;
+  fNHits++;
+}
+
+void AliHLTTPCCAGBTracker::FindTracks()
+{
+  //* main tracking routine
+
+  fStatNEvents++;
+
+#ifdef DRAW
+  if( fStatNEvents<=1 ){
+    if( !gApplication ){
+      TApplication *myapp = new TApplication("myapp",0,0);
+    }    
+    AliHLTTPCCADisplay::Instance().Init();
+  }
+  AliHLTTPCCADisplay::Instance().SetSliceView();
+  //AliHLTTPCCADisplay::Instance().SetTPCView();
+  //AliHLTTPCCADisplay::Instance().DrawTPC();
+#endif //DRAW
+
+  if( fNHits<=0 ) return;
+  
+  sort(fHits,fHits+fNHits, AliHLTTPCCAGBHit::Compare );
+
+  // Read hits, row by row
+
+  Int_t oldRow = -1;
+  Int_t oldSlice = -1;
+  Int_t nRowHits = 0;
+  Int_t firstRowHit = 0;
+  int nHitsTotal = fNHits;
+  AliHLTTPCCAHit *vHits = new AliHLTTPCCAHit[nHitsTotal]; // CA hit array
+  
+  for( int ih=0; ih<nHitsTotal; ih++){
+    AliHLTTPCCAGBHit &h = fHits[ih];
+    h.SliceHit().ID() = ih;
+    vHits[ih] = h.SliceHit();
+    if( h.IRow() != oldRow || h.ISlice() != oldSlice ){
+      if( oldRow>=0 && oldSlice>=0 ){  
+       fSlices[oldSlice].ReadHitRow( oldRow, vHits+firstRowHit, nRowHits );
+      }
+      oldRow = h.IRow();
+      oldSlice = h.ISlice();
+      firstRowHit = ih;
+      nRowHits = 0;
+    }
+    nRowHits++;    
+  }    
+  if( oldRow>=0 && oldSlice>=0 ){
+    fSlices[oldSlice].ReadHitRow( oldRow, vHits+firstRowHit, nRowHits );
+  }
+  delete[] vHits;
+  
+  //cout<<"Start CA reconstruction"<<endl;
+
+  for( int iSlice=0; iSlice<fNSlices; iSlice++ ){
+    TStopwatch timer;
+    AliHLTTPCCATracker &slice = fSlices[iSlice];
+    slice.Reconstruct();
+    timer.Stop();
+    fStatTime[0] += timer.CpuTime();
+    fStatTime[1]+=slice.Timers()[0];
+    fStatTime[2]+=slice.Timers()[1];
+    fStatTime[3]+=slice.Timers()[2];
+    fStatTime[4]+=slice.Timers()[3];
+    fStatTime[5]+=slice.Timers()[4];
+    fStatTime[6]+=slice.Timers()[5];
+    fStatTime[7]+=slice.Timers()[6];
+#ifdef DRAW
+    //SlicePerformance( iSlice );
+    //if( slice.NTracks()>0 ) AliHLTTPCCADisplay::Instance().Ask();
+#endif 
+  }
+  //cout<<"End CA reconstruction"<<endl;
+  
+  for( Int_t iSlice=0; iSlice<fNSlices; iSlice++ ){
+    AliHLTTPCCATracker &iS = fSlices[iSlice];
+    if( fSliceTrackInfos[iSlice] ) delete[] fSliceTrackInfos[iSlice];
+    fSliceTrackInfos[iSlice]=0;
+    int iNTracks = iS.NOutTracks();
+    fSliceTrackInfos[iSlice] = new AliHLTTPCCAGBSliceTrackInfo[iNTracks];
+    for( Int_t itr=0; itr<iNTracks; itr++ ){
+      fSliceTrackInfos[iSlice][itr].fPrevNeighbour = -1;
+      fSliceTrackInfos[iSlice][itr].fNextNeighbour = -1; 
+      fSliceTrackInfos[iSlice][itr].fUsed = 0;
+    }
+  }
+  
+  //cout<<"Start CA merging"<<endl;
+  TStopwatch timerMerge;
+  Merging();
+  timerMerge.Stop();
+  fStatTime[8]+=timerMerge.CpuTime();
+  //cout<<"End CA merging"<<endl;
+
+#ifdef DRAW
+  AliHLTTPCCADisplay::Instance().Ask();
+#endif //DRAW
+}
+
+void AliHLTTPCCAGBTracker::Merging()
+{
+  //* track merging between slices
+
+  Double_t dalpha = fSlices[1].Param().Alpha() - fSlices[0].Param().Alpha();
+  Int_t maxNSliceTracks = 0;
+  for( Int_t iSlice=0; iSlice<fNSlices; iSlice++ ){
+    AliHLTTPCCATracker &iS = fSlices[iSlice];
+    if( maxNSliceTracks < iS.NOutTracks() ) maxNSliceTracks = iS.NOutTracks();
+  }
+
+  //* arrays for rotated track parameters
+
+  AliHLTTPCCATrackParam *iTrParams[2], *jTrParams[2];
+  Bool_t *iOK[2], *jOK[2];
+  for( int i=0; i<2; i++ ){
+    iTrParams[i] = new AliHLTTPCCATrackParam[maxNSliceTracks];
+    jTrParams[i] = new AliHLTTPCCATrackParam[maxNSliceTracks];
+    iOK[i] = new Bool_t [maxNSliceTracks];
+    jOK[i] = new Bool_t [maxNSliceTracks];
+  }
+  
+  for( Int_t iSlice=0; iSlice<fNSlices; iSlice++ ){
+    AliHLTTPCCATracker &iS = fSlices[iSlice];
+    Int_t jSlice = iSlice+1;
+    if( iSlice==fNSlices/2-1 ) jSlice = 0;
+    else if( iSlice==fNSlices-1 ) jSlice = fNSlices/2;
+    AliHLTTPCCATracker &jS = fSlices[jSlice];    
+    int iNTracks = iS.NOutTracks();
+    int jNTracks = jS.NOutTracks();
+    if( iNTracks<=0 || jNTracks<=0 ) continue;
+    
+    //* prepare slice tracks for merging
+    
+    for (Int_t itr=0; itr<iNTracks; itr++) {      
+      iOK[0][itr] = 0;
+      iOK[1][itr] = 0;
+      if( iS.OutTracks()[itr].NHits()<30 ) continue;
+      AliHLTTPCCATrackParam &iT1 = iTrParams[0][itr];
+      AliHLTTPCCATrackParam &iT2 = iTrParams[1][itr];
+      iT1 = iS.OutTracks()[itr].StartPoint();
+      iT2 = iS.OutTracks()[itr].EndPoint();
+      iOK[0][itr] = iT1.Rotate( dalpha/2 - TMath::Pi()/2 );
+      iOK[1][itr] = iT2.Rotate( dalpha/2 - TMath::Pi()/2 );
+
+      if( iOK[0][itr] ){
+       iOK[0][itr] = iT1.TransportToX( 0 );
+       if( iS.Param().RMin() > iT1.Y() || iS.Param().RMax() < iT1.Y() ) iOK[0][itr]=0;
+      }
+      if( iOK[1][itr] ){
+       iOK[1][itr] = iT2.TransportToX( 0 );
+       if( iS.Param().RMin() > iT2.Y() || iS.Param().RMax() < iT2.Y() ) iOK[1][itr]=0;
+      }
+    }
+
+    for (Int_t jtr=0; jtr<jNTracks; jtr++) {      
+      jOK[0][jtr] = 0;
+      jOK[1][jtr] = 0;
+      if( jS.OutTracks()[jtr].NHits()<30 ) continue;
+      AliHLTTPCCATrackParam &jT1 = jTrParams[0][jtr];
+      AliHLTTPCCATrackParam &jT2 = jTrParams[1][jtr];
+      jT1 = jS.OutTracks()[jtr].StartPoint();
+      jT2 = jS.OutTracks()[jtr].EndPoint();
+      jOK[0][jtr] = jT1.Rotate( -dalpha/2 - TMath::Pi()/2 );
+      jOK[1][jtr] = jT2.Rotate( -dalpha/2 - TMath::Pi()/2 );
+      if( jOK[0][jtr] ){
+       jOK[0][jtr] = jT1.TransportToX( 0 );
+       if( jS.Param().RMin() > jT1.Y() || jS.Param().RMax() < jT1.Y() ) jOK[0][jtr]=0;
+      }
+      if( jOK[1][jtr] ){
+       jOK[1][jtr] = jT2.TransportToX( 0 );
+       if( jS.Param().RMin() > jT2.Y() || jS.Param().RMax() < jT2.Y() ) jOK[1][jtr]=0;
+      }
+    }
+
+    //* start merging
+
+    for (Int_t itr=0; itr<iNTracks; itr++) {      
+      if( !iOK[0][itr] && !iOK[1][itr] ) continue;
+      Int_t jBest = -1;
+      Int_t lBest = 0;
+      for (Int_t jtr=0; jtr<jNTracks; jtr++) {
+       if( jS.OutTracks()[jtr].NHits() < lBest ) continue;     
+       if( !jOK[0][jtr] && !jOK[1][jtr] ) continue;
+       for( Int_t ip=0; ip<2 && (jBest!=jtr) ; ip++ ){
+         if( !iOK[ip][itr] ) continue;
+         for( Int_t jp=0; jp<2 && (jBest!=jtr) ; jp++ ){
+           if( !jOK[jp][jtr] ) continue;         
+           AliHLTTPCCATrackParam &iT = iTrParams[ip][itr];
+           AliHLTTPCCATrackParam &jT = jTrParams[jp][jtr];
+           // check for neighbouring   
+           {
+             Float_t factor2 = 3.5*3.5;
+             float d = jT.GetY() - iT.GetY();
+             float s2 = jT.GetErr2Y() + iT.GetErr2Y();
+             if( d*d>factor2*s2 ){
+               continue;
+             }
+             d = jT.GetZ() - iT.GetZ();
+             s2 = jT.GetErr2Z() + iT.GetErr2Z();
+             if( d*d>factor2*s2 ){         
+               continue;
+             }
+             Bool_t ok = 1;
+             { // phi, kappa, DsDz signs are the same 
+               d = jT.GetSinPhi() - iT.GetSinPhi();
+               s2 = jT.GetErr2SinPhi() + iT.GetErr2SinPhi();
+               if( d*d>factor2*s2 ) ok = 0;
+               d = jT.GetKappa() - iT.GetKappa(); 
+               s2 = jT.GetErr2Kappa() + iT.GetErr2Kappa();
+               if( d*d>factor2*s2 ) ok = 0;
+               d = jT.GetDzDs() - iT.GetDzDs();
+               s2 = jT.GetErr2DzDs() + iT.GetErr2DzDs();
+               if( d*d>factor2*s2 ) ok = 0;
+             }
+             if( !ok ){ // phi, kappa, DsDz signs are the different
+               d = jT.GetSinPhi() + iT.GetSinPhi();
+               s2 = jT.GetErr2SinPhi() + iT.GetErr2SinPhi();
+               if( d*d>factor2*s2 ) continue;
+               d = jT.GetKappa() + iT.GetKappa(); 
+               s2 = jT.GetErr2Kappa() + iT.GetErr2Kappa();
+               if( d*d>factor2*s2 ) continue;
+               d = jT.GetDzDs() + iT.GetDzDs();
+               s2 = jT.GetErr2DzDs() + iT.GetErr2DzDs();
+               if( d*d>factor2*s2 ) continue;
+             }
+             // tracks can be matched
+
+             lBest = jS.OutTracks()[jtr].NHits();
+             jBest = jtr;
+           }
+         }
+       }
+      }
+      if( jBest>=0 ){
+       Int_t oldi = fSliceTrackInfos[jSlice][jBest].fPrevNeighbour;
+       if( oldi >= 0 ){
+         if( iS.OutTracks()[ oldi ].NHits() < iS.OutTracks()[ itr ].NHits() ){
+           fSliceTrackInfos[jSlice][jBest].fPrevNeighbour = -1;
+           fSliceTrackInfos[iSlice][oldi].fNextNeighbour = -1;
+         } else continue;
+       }
+       
+       fSliceTrackInfos[iSlice][itr].fNextNeighbour = jBest;
+       fSliceTrackInfos[jSlice][jBest].fPrevNeighbour = itr;   
+      }    
+    }
+  }
+
+  for( Int_t i=0; i<2; i++){
+    if( iTrParams[i] ) delete[] iTrParams[i];
+    if( jTrParams[i] ) delete[] jTrParams[i];
+    if( iOK[i] ) delete[] iOK[i];
+    if( jOK[i] ) delete[] jOK[i];
+  }
+
+  Int_t nTracksTot = 0;
+  for( Int_t iSlice = 0; iSlice<fNSlices; iSlice++ ){    
+    AliHLTTPCCATracker &slice = fSlices[iSlice];
+    nTracksTot+= slice.NOutTracks();
+  }
+  
+  if( fTrackHits ) delete[] fTrackHits;
+  fTrackHits = 0;
+  if(fTracks ) delete[] fTracks;
+  fTracks = 0;
+  fTrackHits = new Int_t [fNHits*10];
+  fTracks = new AliHLTTPCCAGBTrack[nTracksTot];
+  fNTracks = 0;
+
+  Int_t nTrackHits = 0;
+
+  for( Int_t iSlice = 0; iSlice<fNSlices; iSlice++ ){
+    
+    AliHLTTPCCATracker &slice = fSlices[iSlice];
+    for( Int_t itr=0; itr<slice.NOutTracks(); itr++ ){
+      if( fSliceTrackInfos[iSlice][itr].fUsed ) continue;
+      fSliceTrackInfos[iSlice][itr].fUsed = 1;
+      AliHLTTPCCAOutTrack &tCA = slice.OutTracks()[itr];
+      AliHLTTPCCAGBTrack &t = fTracks[fNTracks];
+      t.Param() = tCA.StartPoint();
+      t.NHits() = 0;
+      t.FirstHitRef() = nTrackHits;
+      t.Alpha() = slice.Param().Alpha();
+            
+      Int_t ihit = 0;
+      Int_t jSlice = iSlice;
+      Int_t jtr = itr;
+      for( int jhit=0; jhit<tCA.NHits(); jhit++){
+       int index = slice.OutTrackHits()[tCA.FirstHitRef()+jhit];
+       fTrackHits[nTrackHits+ihit] = index;
+       ihit++;     
+      }
+      while( fSliceTrackInfos[jSlice][jtr].fNextNeighbour >=0 ){
+       jtr = fSliceTrackInfos[jSlice][jtr].fNextNeighbour;
+       if( jSlice==fNSlices/2-1 ) jSlice = 0;
+       else if( jSlice==fNSlices-1 ) jSlice = fNSlices/2;
+       else jSlice = jSlice + 1;
+       if( fSliceTrackInfos[jSlice][jtr].fUsed ) break;
+       fSliceTrackInfos[jSlice][jtr].fUsed = 1;
+       AliHLTTPCCAOutTrack &jTr = fSlices[jSlice].OutTracks()[jtr];
+       for( int jhit=0; jhit<jTr.NHits(); jhit++){
+         int index = fSlices[jSlice].OutTrackHits()[jTr.FirstHitRef()+jhit];     
+         fTrackHits[nTrackHits+ihit] = index;
+         ihit++;
+       }
+      }
+      t.NHits() = ihit;
+      if( t.NHits()<50 ) continue;
+      Int_t nHitsOld = t.NHits();
+
+      // refit 
+      {
+       if( t.NHits()<10 ) continue;
+
+
+       AliHLTTPCCAGBHit* *vhits = new AliHLTTPCCAGBHit*[nHitsOld];
+       
+       for( Int_t ih=0; ih<nHitsOld; ih++ ){
+         vhits[ih] = &(fHits[fTrackHits[t.FirstHitRef() + ih]]);
+       }       
+       
+       sort(vhits, vhits+nHitsOld, AliHLTTPCCAGBHit::ComparePRowDown );
+
+       AliHLTTPCCATrackParam t0;
+       
+       {         
+         AliHLTTPCCAGBHit &h0 = *(vhits[0]);
+         AliHLTTPCCAGBHit &h1 = *(vhits[nHitsOld/2]);
+         AliHLTTPCCAGBHit &h2 = *(vhits[nHitsOld-1]);
+         if( h0.IRow()==h1.IRow() || h0.IRow()==h2.IRow() || h1.IRow()==h2.IRow() ) continue;
+         Double_t x1,y1,z1, x2, y2, z2, x3, y3, z3;
+         fSlices[h0.ISlice()].Param().Slice2Global(h0.X(), h0.Y(), h0.Z(), &x1,&y1,&z1);
+         fSlices[h1.ISlice()].Param().Slice2Global(h1.X(), h1.Y(), h1.Z(), &x2,&y2,&z2);
+         fSlices[h2.ISlice()].Param().Slice2Global(h2.X(), h2.Y(), h2.Z(), &x3,&y3,&z3);
+         fSlices[h0.ISlice()].Param().Global2Slice(x1, y1, z1, &x1,&y1,&z1);
+         fSlices[h0.ISlice()].Param().Global2Slice(x2, y2, z2, &x2,&y2,&z2);
+         fSlices[h0.ISlice()].Param().Global2Slice(x3, y3, z3, &x3,&y3,&z3);
+         Float_t sp0[5] = {x1, y1, z1, .5, .5 };       
+         Float_t sp1[5] = {x2, y2, z2, .5, .5 };
+         Float_t sp2[5] = {x3, y3, z3, .5, .5 };
+         t0.ConstructXYZ3(sp0,sp1,sp2,1., 0);
+       }             
+
+       Int_t currslice = vhits[0]->ISlice();
+       Int_t currrow = fSlices[currslice].Param().NRows()-1;
+       Double_t currd2 = 1.e10;
+       AliHLTTPCCAGBHit *currhit = 0;
+
+       for( Int_t ih=0; ih<nHitsOld; ih++ ){
+         Double_t y0 = t0.GetY();
+         Double_t z0 = t0.GetZ();      
+         AliHLTTPCCAGBHit &h = *(vhits[ih]);
+         //cout<<"hit,slice,row="<<ih<<" "<<h.slice<<" "<<h.row<<endl;
+         if( h.ISlice() == currslice && h.IRow() == currrow ){
+           //* select the best hit in the row
+           Double_t dy = h.Y() - y0;
+           Double_t dz = h.Z() - z0;
+           Double_t d2 = dy*dy + dz*dz;
+           if( d2<currd2 ){
+             currhit = &h;
+             currd2 = d2;
+           }
+           continue;
+         }else{
+           if( currhit != 0 ){ 
+             //* update track  
+             t0.Filter(currhit->Y(), currhit->Z(), currhit->ErrY(), currhit->ErrZ());
+             currhit = 0;
+           }
+           if( h.ISlice() != currslice ){
+             //* Rotate to the new slice
+             currhit = 0;
+             if( !t0.Rotate( -fSlices[currslice].Param().Alpha() +fSlices[h.ISlice()].Param().Alpha() ) ) break;       
+             currslice = h.ISlice();
+             //currrow = 300;
+             currd2 = 1.e10;
+           }
+           //* search for missed hits in rows
+           {
+             Double_t factor2 = 3.5*3.5;
+             AliHLTTPCCATracker &cslice = fSlices[currslice];        
+             for( Int_t srow=currrow-1; srow>h.IRow(); srow--){
+               AliHLTTPCCARow &row = cslice.Rows()[srow];
+               if( !t0.TransportToX( row.X() ) ) continue;
+               Int_t bestsh = -1;
+               Double_t ds = 1.e10;
+               for( Int_t ish=0; ish<row.NHits(); ish++ ){
+                 AliHLTTPCCAHit &sh = row.Hits()[ish];
+                 Double_t dy = sh.Y() - t0.GetY();
+                 Double_t dz = sh.Z() - t0.GetZ();
+                 Double_t dds = dy*dy+dz*dz;
+                 if( dds<ds ){
+                   ds = dds;
+                   bestsh = ish;
+                 }
+               }
+               if( bestsh<0 ) continue;
+               AliHLTTPCCAHit &sh = row.Hits()[bestsh];
+               Double_t dy = sh.Y() - t0.GetY();
+               Double_t dz = sh.Z() - t0.GetZ();
+               Double_t s2z = /*t0.GetErr2Z() + */ sh.ErrZ()*sh.ErrZ();
+               if( dz*dz>factor2*s2z ) continue;               
+               Double_t s2y = /*t0.GetErr2Y() + */ sh.ErrY()*sh.ErrY();
+               if( dy*dy>factor2*s2y ) continue;
+               //* update track          
+               t0.Filter(sh.Y(), sh.Z(), sh.ErrY()/.33, sh.ErrZ()/.33);
+               fTrackHits[nTrackHits+t.NHits()] = sh.ID();
+               t.NHits()++;
+             }
+           }
+           //* transport to the new row
+           currrow = h.IRow();  
+           Bool_t ok = t0.TransportToX( h.X() );       
+           if( ok ){
+             currrow = h.IRow();
+             Double_t dy = h.Y() - t0.GetY();
+             Double_t dz = h.Z() - t0.GetZ();
+             currd2 = dy*dy + dz*dz;
+             currhit = &h;
+           }
+         }
+       }
+       if( currhit != 0 ){ // update track
+         
+         t0.Filter(currhit->Y(), currhit->Z(), currhit->ErrY(), currhit->ErrZ());
+       }
+       
+       //* search for missed hits in rows
+       {
+         Double_t factor2 = 3.5*3.5;
+         for( Int_t srow=currrow-1; srow>=0; srow--){
+           AliHLTTPCCATracker *cslice = &(fSlices[currslice]);
+           AliHLTTPCCARow *row = &(cslice->Rows()[srow]);
+           if( !t0.TransportToX( row->X() ) ) continue;
+           if( t0.GetY() > row->MaxY() ){ //next slice
+             Int_t j = currslice+1;
+             if( currslice==fNSlices/2-1 ) j = 0;
+             else if( currslice==fNSlices-1 ) j = fNSlices/2;
+             //* Rotate to the new slice
+             if( !t0.Rotate( -fSlices[currslice].Param().Alpha() +fSlices[j].Param().Alpha() ) ) break;
+             currslice = j;
+             cslice = &(fSlices[currslice]);
+             row = &(cslice->Rows()[srow]);
+             if( !t0.TransportToX( row->X() ) ) continue;              
+           }else if( t0.GetY() < -row->MaxY() ){ //prev slice
+             Int_t j = currslice-1;
+             if( currslice==0 ) j = fNSlices/2-1;
+             else if( currslice==fNSlices/2 ) j = fNSlices-1;
+             //* Rotate to the new slice
+             if( !t0.Rotate( -fSlices[currslice].Param().Alpha() +fSlices[j].Param().Alpha() ) ) break;
+             currslice = j;
+             cslice = &(fSlices[currslice]);
+             row = &(cslice->Rows()[srow]);
+             if( !t0.TransportToX( row->X() ) ) continue;              
+           }
+           Int_t bestsh = -1;
+           Double_t ds = 1.e10;
+           for( Int_t ish=0; ish<row->NHits(); ish++ ){
+             AliHLTTPCCAHit &sh = row->Hits()[ish];
+             Double_t dy = sh.Y() - t0.GetY();
+             Double_t dz = sh.Z() - t0.GetZ();
+             Double_t dds = dy*dy+dz*dz;
+             if( dds<ds ){
+               ds = dds;
+               bestsh = ish;
+             }
+           }
+           if( bestsh<0 ) continue;
+           AliHLTTPCCAHit &sh = row->Hits()[bestsh];
+           Double_t dy = sh.Y() - t0.GetY();
+           Double_t dz = sh.Z() - t0.GetZ();
+           Double_t s2z = /*t0.GetErr2Z() + */ sh.ErrZ()*sh.ErrZ();
+           if( dz*dz>factor2*s2z ) continue;           
+           Double_t s2y = /*t0.GetErr2Y() + */ sh.ErrY()*sh.ErrY();
+           if( dy*dy>factor2*s2y ) continue;
+           //* update track      
+           t0.Filter(sh.Y(), sh.Z(), sh.ErrY()/.33, sh.ErrZ()/.33);
+           fTrackHits[nTrackHits+t.NHits()] = sh.ID();
+           t.NHits()++;
+         }     
+       }
+       if( vhits ) delete[] vhits;
+
+       //* search for missed hits in rows
+       {
+         Double_t factor2 = 3.5*3.5;   
+         AliHLTTPCCAGBHit &h0 = fHits[fTrackHits[t.FirstHitRef()]];
+         
+         Bool_t ok = t0.Rotate( -fSlices[currslice].Param().Alpha() +fSlices[h0.ISlice()].Param().Alpha() );
+         
+         currslice = h0.ISlice();
+         currrow = h0.IRow();
+         
+         for( Int_t srow=currrow+1; srow<fSlices[0].Param().NRows()&&ok; srow++){
+           AliHLTTPCCATracker *cslice = &(fSlices[currslice]);
+           AliHLTTPCCARow *row = &(cslice->Rows()[srow]);
+           if( !t0.TransportToX( row->X() ) ) continue;
+           if( t0.GetY() > row->MaxY() ){ //next slice
+             Int_t j = currslice+1;
+             if( currslice==fNSlices/2-1 ) j = 0;
+             else if( currslice==fNSlices-1 ) j = fNSlices/2;
+             //* Rotate to the new slice
+             if( !t0.Rotate( -fSlices[currslice].Param().Alpha() +fSlices[j].Param().Alpha() ) ) break;
+             currslice = j;
+             cslice = &(fSlices[currslice]);
+             row = &(cslice->Rows()[srow]);
+             if( !t0.TransportToX( row->X() ) ) continue;              
+           }else if( t0.GetY() < -row->MaxY() ){ //prev slice
+             Int_t j = currslice-1;
+             if( currslice==0 ) j = fNSlices/2-1;
+             else if( currslice==fNSlices/2 ) j = fNSlices-1;
+             //* Rotate to the new slice
+             if( !t0.Rotate( -fSlices[currslice].Param().Alpha() +fSlices[j].Param().Alpha() ) ) break;
+             currslice = j;
+             cslice = &(fSlices[currslice]);
+             row = &(cslice->Rows()[srow]);
+             if( !t0.TransportToX( row->X() ) ) continue;              
+           }
+           Int_t bestsh = -1;
+           Double_t ds = 1.e10;
+           for( Int_t ish=0; ish<row->NHits(); ish++ ){
+             AliHLTTPCCAHit &sh = row->Hits()[ish];
+             Double_t dy = sh.Y() - t0.GetY();
+             Double_t dz = sh.Z() - t0.GetZ();
+             Double_t dds = dy*dy+dz*dz;
+             if( dds<ds ){
+               ds = dds;
+               bestsh = ish;
+             }
+           }
+           if( bestsh<0 ) continue;
+           AliHLTTPCCAHit &sh = row->Hits()[bestsh];
+           Double_t dy = sh.Y() - t0.GetY();
+           Double_t dz = sh.Z() - t0.GetZ();
+           Double_t s2z = /*t0.GetErr2Z() + */ sh.ErrZ()*sh.ErrZ();
+           if( dz*dz>factor2*s2z ) continue;           
+           Double_t s2y = /*t0.GetErr2Y() + */ sh.ErrY()*sh.ErrY();
+           if( dy*dy>factor2*s2y ) continue;
+           //* update track      
+           t0.Filter(sh.Y(), sh.Z(), sh.ErrY()/.33, sh.ErrZ()/.33);
+           fTrackHits[nTrackHits+t.NHits()] = sh.ID();
+           t.NHits()++;
+         }     
+       }
+       
+       Bool_t ok=1;
+       {
+         for( int i=0; i<15; i++ ) ok = ok && finite(t0.Cov()[i]);
+         for( int i=0; i<5; i++ ) ok = ok && finite(t0.Par()[i]);
+         ok = ok && (t0.GetX()>50);
+       }
+       if(!ok) continue;
+       if( TMath::Abs(t0.Kappa())<1.e-8 ) t0.Kappa() = 1.e-8;
+       if( nHitsOld != t.NHits() ){
+         //cout<<"N matched hits = "<<(t.NHits() - nHitsOld )<<" / "<<nHitsOld<<endl;
+       }
+
+       t.Param() = t0;
+       t.Alpha() = fSlices[currslice].Param().Alpha();
+       if( t.NHits()<50 ) continue;
+       nTrackHits+= t.NHits();
+       fNTracks++;      
+      }
+    }
+  }
+  
+  //* selection  
+
+  {
+    AliHLTTPCCAGBTrack *vtracks = new AliHLTTPCCAGBTrack [fNTracks];
+    Int_t *vhits = new Int_t [fNHits];
+    AliHLTTPCCAGBTrack **vptracks = new AliHLTTPCCAGBTrack* [fNTracks];
+
+    for( Int_t itr=0; itr<fNTracks; itr++ ){
+      vptracks[itr] = &(fTracks[itr]);
+    }
+    Int_t nTracks = 0;
+    Int_t nHits = 0;
+    sort(vptracks, vptracks+fNTracks, AliHLTTPCCAGBTrack::ComparePNClusters );
+    for( Int_t itr=0; itr<fNTracks; itr++ ){
+      AliHLTTPCCAGBTrack &t = *(vptracks[itr]);
+      AliHLTTPCCAGBTrack &to = vtracks[nTracks];
+      to=*(vptracks[itr]);
+      to.FirstHitRef() = nHits;
+      to.NHits() = 0;
+      for( Int_t ih=0; ih<t.NHits(); ih++ ){
+       Int_t jh = fTrackHits[t.FirstHitRef()+ih];
+       AliHLTTPCCAGBHit &h = fHits[jh];
+       if( h.IsUsed() ) continue;
+       vhits[to.FirstHitRef() + to.NHits()] = jh;
+       to.NHits()++;
+       h.IsUsed() = 1;
+      }
+      if( to.NHits()<50 ) continue;
+      nHits+=to.NHits();
+      nTracks++;
+    }
+    fNTracks = nTracks;
+    if( fTrackHits ) delete[] fTrackHits;
+    if( fTracks ) delete[] fTracks;
+    fTrackHits = vhits;
+    fTracks = vtracks;
+    delete[] vptracks;
+  }
+
+}
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCAGBTracker.h b/HLT/TPCLib/tracking-ca/AliHLTTPCCAGBTracker.h
new file mode 100644 (file)
index 0000000..a653fb7
--- /dev/null
@@ -0,0 +1,89 @@
+//-*- Mode: C++ -*-
+// $Id$
+
+//* This file is property of and copyright by the ALICE HLT Project        * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//* See cxx source for full Copyright notice                               *
+
+#ifndef ALIHLTTPCCAGBTRACKER_H
+#define ALIHLTTPCCAGBTRACKER_H
+
+#include "TObject.h"
+
+class AliHLTTPCCATracker;
+class AliHLTTPCCAGBTrack;
+class AliHLTTPCCAGBHit;
+class TParticle;
+class TProfile;
+
+
+/**
+ * @class AliHLTTPCCAGBTracker
+ * 
+ * Global Cellular Automaton-based HLT tracker for TPC detector
+ * The class reconstructs tracks in the whole TPC
+ * It calls the AliHLTTPCCATracker slice tracker and constructs 
+ * the global TPC tracks by merging the slice tracks 
+ *
+ * The tracker is designed stand-alone. 
+ * It will be integrated to the HLT framework via AliHLTTPCCAGBTrackerComponent interface,
+ * and to off-line framework via TPC/AliTPCtrackerCA class
+ * The class is under construction.
+ *
+ */
+class AliHLTTPCCAGBTracker:public TObject
+{
+
+public:
+
+  AliHLTTPCCAGBTracker();
+  AliHLTTPCCAGBTracker(const AliHLTTPCCAGBTracker&);
+  AliHLTTPCCAGBTracker &operator=(const AliHLTTPCCAGBTracker&);
+
+  virtual ~AliHLTTPCCAGBTracker();
+
+  void StartEvent();
+  void SetNSlices( Int_t N );
+  void SetNHits( Int_t nHits );
+
+  void ReadHit( Double_t x, Double_t y, Double_t z, 
+               Double_t ErrY, Double_t ErrZ, Int_t ID, 
+               Int_t iSlice, Int_t iRow );
+
+  void FindTracks();
+  void Merging();
+  AliHLTTPCCATracker *Slices(){ return fSlices; }
+  AliHLTTPCCAGBHit *Hits(){ return fHits; }
+  Int_t NHits() const { return fNHits; }
+  Int_t NSlices() const { return fNSlices; }
+  Double_t StatTime( Int_t iTimer ) const { return fStatTime[iTimer]; }
+  Int_t StatNEvents() const { return fStatNEvents; }
+  Int_t NTracks() const { return fNTracks; }
+  AliHLTTPCCAGBTrack *Tracks(){ return fTracks; }
+  Int_t *TrackHits() {return fTrackHits; }
+
+protected:
+
+  AliHLTTPCCATracker *fSlices; //* array of slice trackers
+  Int_t fNSlices;              //* N slices
+  AliHLTTPCCAGBHit *fHits;     //* hit array
+  Int_t fNHits;                //* N hits in event
+  Int_t *fTrackHits;           //* track->hits reference array
+  AliHLTTPCCAGBTrack *fTracks; //* array of tracks
+  Int_t fNTracks;              //* N tracks
+
+  struct AliHLTTPCCAGBSliceTrackInfo{
+    Int_t fPrevNeighbour; //* neighbour in the previous slide
+    Int_t fNextNeighbour; //* neighbour in the next slide
+    Bool_t fUsed;         //* is the slice track used by global tracks
+  };
+
+  AliHLTTPCCAGBSliceTrackInfo **fSliceTrackInfos; //* additional information for slice tracks
+
+  Double_t fStatTime[10]; //* time measured
+  Int_t fStatNEvents;    //* n events proceed
+
+  ClassDef(AliHLTTPCCAGBTracker,1) //Base class for conformal mapping tracking
+};
+
+#endif
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCAGrid.cxx b/HLT/TPCLib/tracking-ca/AliHLTTPCCAGrid.cxx
new file mode 100644 (file)
index 0000000..571c85d
--- /dev/null
@@ -0,0 +1,67 @@
+// $Id$
+//***************************************************************************
+// This file is property of and copyright by the ALICE HLT Project          * 
+// ALICE Experiment at CERN, All rights reserved.                           *
+//                                                                          *
+// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
+//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
+//                  for The ALICE HLT Project.                              *
+//                                                                          *
+// Permission to use, copy, modify and distribute this software and its     *
+// documentation strictly for non-commercial purposes is hereby granted     *
+// without fee, provided that the above copyright notice appears in all     *
+// copies and that both the copyright notice and this permission notice     *
+// appear in the supporting documentation. The authors make no claims       *
+// about the suitability of this software for any purpose. It is            *
+// provided "as is" without express or implied warranty.                    *
+//***************************************************************************
+
+#include "AliHLTTPCCAGrid.h"
+#include "TMath.h"
+
+AliHLTTPCCAGrid::AliHLTTPCCAGrid(const AliHLTTPCCAGrid&)
+  :fGrid(0),fNy(0),fNz(0),fN(0),
+   fYMin(0),fYMax(0),fZMin(0),fZMax(0),fStepYInv(0),fStepZInv(0)
+{
+  //* dummy
+}
+
+AliHLTTPCCAGrid& AliHLTTPCCAGrid::operator=(const AliHLTTPCCAGrid&)
+{
+  //* dummy
+  return *this;
+}
+
+void AliHLTTPCCAGrid::Create( Float_t yMin, Float_t yMax, Float_t zMin, Float_t zMax, Int_t n )
+{
+  //* Create the grid
+  
+  fYMin = TMath::Min(yMin,yMax);
+  fYMax = TMath::Max(yMin,yMax);
+  fZMin = TMath::Min(zMin,zMax);
+  fZMax = TMath::Max(zMin,zMax);
+  fNy = fNz = (Int_t) TMath::Sqrt( (Float_t) n );
+  fNy = TMath::Max(fNy,1);
+  fNz = TMath::Max(fNz,1);
+  fN = fNy*fNz;
+  if( fGrid ) delete[] fGrid;
+  fGrid = new void*[fN];
+  for( Int_t i=0; i<fN; i++ ) fGrid[i] = 0;
+  fStepYInv = (fYMax - fYMin);
+  fStepZInv = (fZMax - fZMin);
+  fStepYInv =  ( fStepYInv>1.e-4 ) ?(fNy-1)/fStepYInv :0;
+  fStepZInv =  ( fStepZInv>1.e-4 ) ?(fNz-1)/fStepZInv :0;
+}
+
+void **AliHLTTPCCAGrid::Get( Float_t Y, Float_t Z ) const
+{
+  //* get the bin pointer
+
+  Int_t yBin = (Int_t) ( (Y-fYMin)*fStepYInv );
+  Int_t zBin = (Int_t) ( (Z-fZMin)*fStepZInv );
+  if( yBin<0 ) yBin = 0;
+  else if( yBin>=fNy ) yBin = fNy - 1;
+  if( zBin<0 ) zBin = 0;
+  else if( zBin>=fNz ) zBin = fNz - 1;
+  return fGrid + zBin*fNy + yBin;
+}
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCAGrid.h b/HLT/TPCLib/tracking-ca/AliHLTTPCCAGrid.h
new file mode 100644 (file)
index 0000000..7e3ec80
--- /dev/null
@@ -0,0 +1,71 @@
+//-*- Mode: C++ -*-
+// $Id$
+
+//* This file is property of and copyright by the ALICE HLT Project        * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//* See cxx source for full Copyright notice                               *
+
+#ifndef ALIHLTTPCCAGRID_H
+#define ALIHLTTPCCAGRID_H
+
+#include "Rtypes.h"
+
+/**
+ * @class AliHLTTPCCAGrid
+ *
+ * 2-dimensional grid of pointers.
+ * pointers to (y,z)-like objects are assigned to the corresponding grig bin
+ * used by AliHLTTPCCATracker to speed-up the hit operations
+ * grid axis are named Z,Y to be similar to TPC row coordinates.
+ */
+class AliHLTTPCCAGrid
+{
+ public:
+  AliHLTTPCCAGrid():fGrid(0),fNy(0),fNz(0),fN(0),
+    fYMin(0),fYMax(0),fZMin(0),fZMax(0),fStepYInv(0),fStepZInv(0){}
+
+  AliHLTTPCCAGrid(const AliHLTTPCCAGrid&);
+  AliHLTTPCCAGrid &operator=(const AliHLTTPCCAGrid&);
+
+  virtual ~AliHLTTPCCAGrid(){ 
+    if( fGrid ) delete[] fGrid; 
+  }
+
+  void Create( Float_t yMin, Float_t yMax, Float_t zMin, Float_t zMax, Int_t n );
+
+  void **Get( Float_t Y, Float_t Z ) const;
+
+  void **GetNoCheck( Float_t Y, Float_t Z ) const {
+    Int_t yBin = (Int_t) ( (Y-fYMin)*fStepYInv );
+    Int_t zBin = (Int_t) ( (Z-fZMin)*fStepZInv );
+    return fGrid + zBin*fNy + yBin;
+  }
+
+  Int_t N() const { return fN; }
+  Int_t Ny() const { return fNy; }
+  Int_t Nz() const { return fNz; }
+  Float_t YMin() const { return fYMin; }
+  Float_t YMax() const { return fYMax; }
+  Float_t ZMin() const { return fZMin; }
+  Float_t ZMax() const { return fZMax; }
+  Float_t StepYInv() const { return fStepYInv; }
+  Float_t StepZInv() const { return fStepZInv; }
+  void **Grid(){ return fGrid; }
+
+ protected:
+
+  void **fGrid;      //* the grid as 1-d array
+  Int_t fNy;         //* N bins in Y
+  Int_t fNz;         //* N bins in Z
+  Int_t fN;          //* total N bins
+  Float_t fYMin;     //* minimal Y value
+  Float_t fYMax;     //* maximal Y value
+  Float_t fZMin;     //* minimal Z value
+  Float_t fZMax;     //* maximal Z value
+  Float_t fStepYInv; //* inverse bin size in Y
+  Float_t fStepZInv; //* inverse bin size in Z
+  
+};
+
+
+#endif
index 6e7c90e6bc96abb0bae324ba7ebcb1e8958b9124..3ca286c23cb384f902979e190cd0a190043eeb7b 100644 (file)
@@ -1,27 +1,25 @@
 // @(#) $Id$
-//*************************************************************************
-// This file is property of and copyright by the ALICE HLT Project        * 
-// ALICE Experiment at CERN, All rights reserved.                         *
-//                                                                        *
-// Primary Authors: Jochen Thaeder <thaeder@kip.uni-heidelberg.de>        *
-//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>              *
-//                  for The ALICE HLT Project.                            *
-//                                                                        *
-// Permission to use, copy, modify and distribute this software and its   *
-// documentation strictly for non-commercial purposes is hereby granted   *
-// without fee, provided that the above copyright notice appears in all   *
-// copies and that both the copyright notice and this permission notice   *
-// appear in the supporting documentation. The authors make no claims     *
-// about the suitability of this software for any purpose. It is          *
-// provided "as is" without express or implied warranty.                  *
-//*************************************************************************
+//***************************************************************************
+// This file is property of and copyright by the ALICE HLT Project          
+// ALICE Experiment at CERN, All rights reserved.                           *
+//                                                                          *
+// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
+//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
+//                  for The ALICE HLT Project.                              *
+//                                                                          *
+// Permission to use, copy, modify and distribute this software and its     *
+// documentation strictly for non-commercial purposes is hereby granted     *
+// without fee, provided that the above copyright notice appears in all     *
+// copies and that both the copyright notice and this permission notice     *
+// appear in the supporting documentation. The authors make no claims       *
+// about the suitability of this software for any purpose. It is            *
+// provided "as is" without express or implied warranty.                    *
+//***************************************************************************
 
 #include "AliHLTTPCCAHit.h"
 
 
-ClassImp(AliHLTTPCCAHit)
-
 void AliHLTTPCCAHit::Dummy()
 {
-  // do nothing
+  //* do nothing
 }
index 4b4a0990fa73438ab9e8f1cc2543af7c3ca27d35..f414bea564bdb1250e1ad111a152d97162d8c5e5 100644 (file)
@@ -23,15 +23,15 @@ class AliHLTTPCCAHit
   AliHLTTPCCAHit(): fY(0),fZ(0),fErrY(0),fErrZ(0),fID(0){;}
   virtual ~AliHLTTPCCAHit(){}
 
-  Float_t &Y(){ return fY; }
-  Float_t &Z(){ return fZ; }
+  Float_t &Y()   { return fY;    }
+  Float_t &Z()   { return fZ;    }
   Float_t &ErrY(){ return fErrY; } 
   Float_t &ErrZ(){ return fErrZ; }
   
   Int_t &ID(){ return fID; }
  
-  void Set( Int_t HitID, Double_t HitY, Double_t HitZ
-           Double_t HitErrY, Double_t HitErrZ  );
+  void Set( Int_t id, Float_t y, Float_t z
+           Float_t errY, Float_t errZ  );
 
  protected:
 
@@ -42,21 +42,20 @@ class AliHLTTPCCAHit
  private:
 
   void Dummy(); // to make rulechecker happy by having something in .cxx file
-
-  ClassDef(AliHLTTPCCAHit,1);
+  
 };
 
 
 
-inline void AliHLTTPCCAHit::Set( Int_t HitID, Double_t HitY, Double_t HitZ
-                                Double_t HitErrY, Double_t HitErrZ  )
+inline void AliHLTTPCCAHit::Set( Int_t id, Float_t y, Float_t z
+                                Float_t errY, Float_t errZ  )
 {
   //* set parameters
-  fID = HitID;
-  fY = HitY;
-  fZ = HitZ;
-  fErrY = HitErrY;
-  fErrZ = HitErrZ;
+  fID = id;
+  fY = y;
+  fZ = z;
+  fErrY = errY;
+  fErrZ = errZ;
 }
 
 
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCAMCTrack.cxx b/HLT/TPCLib/tracking-ca/AliHLTTPCCAMCTrack.cxx
new file mode 100644 (file)
index 0000000..311330a
--- /dev/null
@@ -0,0 +1,60 @@
+// $Id$
+//***************************************************************************
+// This file is property of and copyright by the ALICE HLT Project          * 
+// ALICE Experiment at CERN, All rights reserved.                           *
+//                                                                          *
+// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
+//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
+//                  for The ALICE HLT Project.                              *
+//                                                                          *
+// Permission to use, copy, modify and distribute this software and its     *
+// documentation strictly for non-commercial purposes is hereby granted     *
+// without fee, provided that the above copyright notice appears in all     *
+// copies and that both the copyright notice and this permission notice     *
+// appear in the supporting documentation. The authors make no claims       *
+// about the suitability of this software for any purpose. It is            *
+// provided "as is" without express or implied warranty.                    *
+//***************************************************************************
+
+#include "AliHLTTPCCAMCTrack.h"
+#include "TParticle.h"
+#include "TDatabasePDG.h"
+#include "TMath.h"
+
+
+AliHLTTPCCAMCTrack::AliHLTTPCCAMCTrack()
+  : fP(0), fPt(0), fNHits(0), fNReconstructed(0), fSet(0), fNTurns(0)
+{
+  //* Default constructor
+}
+
+
+AliHLTTPCCAMCTrack::AliHLTTPCCAMCTrack( const TParticle *part )
+  : fP(0), fPt(0), fNHits(0), fNReconstructed(0), fSet(0), fNTurns(0)
+{
+  //* Constructor from TParticle
+
+  for( Int_t i=0; i<7; i++ ) fPar[i] = 0;
+  fP = 0;
+  fPt = 0;
+
+  if( !part ) return;
+  TLorentzVector mom, vtx;
+  part->ProductionVertex(vtx);
+  part->Momentum(mom);
+  fPar[0] = part->Vx();
+  fPar[1] = part->Vy();
+  fPar[2] = part->Vz();
+  fP = part->P();
+  fPt = part->Pt();
+  Double_t pi = ( fP >1.e-4 ) ?1./fP :0;
+  fPar[3] = part->Px()*pi;
+  fPar[4] = part->Py()*pi;
+  fPar[5] = part->Pz()*pi;
+  fPar[6] = 0;
+  Int_t pdg  = part->GetPdgCode();       
+  if ( TMath::Abs(pdg) < 100000 ){
+    TParticlePDG *pPDG = TDatabasePDG::Instance()->GetParticle(pdg);
+    if( pPDG ) fPar[6] = pPDG->Charge()/3.0*pi;
+  }
+}
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCAMCTrack.h b/HLT/TPCLib/tracking-ca/AliHLTTPCCAMCTrack.h
new file mode 100644 (file)
index 0000000..20398f3
--- /dev/null
@@ -0,0 +1,46 @@
+//-*- Mode: C++ -*-
+// $Id$
+
+//* This file is property of and copyright by the ALICE HLT Project        * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//* See cxx source for full Copyright notice                               *
+
+#ifndef ALIHLTTPCCAMCTRACK_H
+#define ALIHLTTPCCAMCTRACK_H
+
+#include "Rtypes.h"
+
+class TParticle;
+
+
+/**
+ * @class AliHLTTPCCAMCTrack
+ * store MC track information for AliHLTTPCCAPerformance
+ */
+class AliHLTTPCCAMCTrack
+{
+ public:
+
+  AliHLTTPCCAMCTrack();
+  AliHLTTPCCAMCTrack( const TParticle *part );
+
+  Double_t *Par()           { return fPar; }
+  Double_t &P()             { return fP; }
+  Double_t &Pt()            { return fPt; }
+  Int_t    &NHits()         { return fNHits;}
+  Int_t    &NReconstructed(){ return fNReconstructed; }
+  Int_t    &Set()           { return fSet; }
+  Int_t    &NTurns()        { return fNTurns; }
+
+ protected:
+
+  Double_t fPar[7];         //* x,y,z,ex,ey,ez,q/p
+  Double_t fP, fPt;         //* momentum and transverse momentum
+  Int_t    fNHits;          //* N TPC clusters
+  Int_t    fNReconstructed; //* how many times is reconstructed
+  Int_t    fSet;            //* set of tracks 0-OutSet, 1-ExtraSet, 2-RefSet 
+  Int_t    fNTurns;         //* N of turns in the current sector
+
+};
+
+#endif
index 2c2168c2c7b5e566e8aaa1bf21bc43cd39b36000..e0b3c800dffa477e0af684be078c1e28134c92bb 100644 (file)
@@ -1,20 +1,20 @@
 // @(#) $Id$
-//*************************************************************************
-// This file is property of and copyright by the ALICE HLT Project        * 
-// ALICE Experiment at CERN, All rights reserved.                         *
-//                                                                        *
-// Primary Authors: Jochen Thaeder <thaeder@kip.uni-heidelberg.de>        *
-//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>              *
-//                  for The ALICE HLT Project.                            *
-//                                                                        *
-// Permission to use, copy, modify and distribute this software and its   *
-// documentation strictly for non-commercial purposes is hereby granted   *
-// without fee, provided that the above copyright notice appears in all   *
-// copies and that both the copyright notice and this permission notice   *
-// appear in the supporting documentation. The authors make no claims     *
-// about the suitability of this software for any purpose. It is          *
-// provided "as is" without express or implied warranty.                  *
-//*************************************************************************
+//***************************************************************************
+// This file is property of and copyright by the ALICE HLT Project          
+// ALICE Experiment at CERN, All rights reserved.                           *
+//                                                                          *
+// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
+//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
+//                  for The ALICE HLT Project.                              *
+//                                                                          *
+// Permission to use, copy, modify and distribute this software and its     *
+// documentation strictly for non-commercial purposes is hereby granted     *
+// without fee, provided that the above copyright notice appears in all     *
+// copies and that both the copyright notice and this permission notice     *
+// appear in the supporting documentation. The authors make no claims       *
+// about the suitability of this software for any purpose. It is            *
+// provided "as is" without express or implied warranty.                    *
+//***************************************************************************
 
 #include "AliHLTTPCCAOutTrack.h"
 
@@ -23,4 +23,5 @@ ClassImp(AliHLTTPCCAOutTrack)
 
 void AliHLTTPCCAOutTrack::Dummy()
 {
+  //* do nothing
 }
index 924c90af3a86167178fa63f5e53aa2a197b6bb45..a816cab94197960020231cebe018370018378363 100644 (file)
@@ -9,7 +9,7 @@
 #define ALIHLTTPCCAOUTTRACK_H
 
 #include "Rtypes.h"
-#include "AliHLTTPCCATrackPar.h"
+#include "AliHLTTPCCATrackParam.h"
 
 /**
  * @class AliHLTTPCCAOutTrack
@@ -24,18 +24,23 @@ class AliHLTTPCCAOutTrack
 {
  public:
 
-  AliHLTTPCCAOutTrack():fFirstHitRef(0),fNHits(0),fParam(){}
+  AliHLTTPCCAOutTrack():fFirstHitRef(0),fNHits(0),fStartPoint(),fEndPoint(),fOrigTrackID(0){}
   virtual ~AliHLTTPCCAOutTrack(){}
 
   Int_t &NHits()               { return fNHits; }
   Int_t &FirstHitRef()         { return fFirstHitRef; }
-  AliHLTTPCCATrackPar &Param() { return fParam; }
+
+  AliHLTTPCCATrackParam &StartPoint() { return fStartPoint; }
+  AliHLTTPCCATrackParam &EndPoint()   { return fEndPoint; }
+  Int_t &OrigTrackID()                { return fOrigTrackID; }
 
  protected:
   
-  Int_t fFirstHitRef;        // index of the first hit reference in track->hit reference array
-  Int_t fNHits;              // number of track hits
-  AliHLTTPCCATrackPar fParam;// fitted track parameters
+  Int_t fFirstHitRef;   //* index of the first hit reference in track->hit reference array
+  Int_t fNHits;         //* number of track hits
+  AliHLTTPCCATrackParam fStartPoint; //* fitted track parameters at the start point
+  AliHLTTPCCATrackParam fEndPoint;   //* fitted track parameters at the start point
+  Int_t fOrigTrackID;                //* index of the original slice track
 
  private:
 
index 05f0095ec9c27b1a102b640193a4411b247e4b20..e7c1c0218e33766647271d617a251baa7e347b0a 100644 (file)
@@ -1,61 +1,63 @@
 // @(#) $Id$
-//*************************************************************************
-// This file is property of and copyright by the ALICE HLT Project        * 
-// ALICE Experiment at CERN, All rights reserved.                         *
-//                                                                        *
-// Primary Authors: Jochen Thaeder <thaeder@kip.uni-heidelberg.de>        *
-//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>              *
-//                  for The ALICE HLT Project.                            *
-//                                                                        *
-// Permission to use, copy, modify and distribute this software and its   *
-// documentation strictly for non-commercial purposes is hereby granted   *
-// without fee, provided that the above copyright notice appears in all   *
-// copies and that both the copyright notice and this permission notice   *
-// appear in the supporting documentation. The authors make no claims     *
-// about the suitability of this software for any purpose. It is          *
-// provided "as is" without express or implied warranty.                  *
-//*************************************************************************
+//***************************************************************************
+// This file is property of and copyright by the ALICE HLT Project          
+// ALICE Experiment at CERN, All rights reserved.                           *
+//                                                                          *
+// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
+//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
+//                  for The ALICE HLT Project.                              *
+//                                                                          *
+// Permission to use, copy, modify and distribute this software and its     *
+// documentation strictly for non-commercial purposes is hereby granted     *
+// without fee, provided that the above copyright notice appears in all     *
+// copies and that both the copyright notice and this permission notice     *
+// appear in the supporting documentation. The authors make no claims       *
+// about the suitability of this software for any purpose. It is            *
+// provided "as is" without express or implied warranty.                    *
+//***************************************************************************
 
 #include "AliHLTTPCCAParam.h"
 #include "TMath.h"
 
 
 ClassImp(AliHLTTPCCAParam)
-
+  
 AliHLTTPCCAParam::AliHLTTPCCAParam()
-  : fISec(0),fNRows(63),fAlpha(0.174533), fDAlpha(0.349066),
+  : fISlice(0),fNRows(63),fAlpha(0.174533), fDAlpha(0.349066),
     fCosAlpha(0), fSinAlpha(0), fAngleMin(0), fAngleMax(0), fRMin(83.65), fRMax(133.3),
-    fZMin(0.0529937), fZMax(249.778), fErrZ(0.228808), fErrX(0), fErrY(0),fPadPitch(0.4),fBz(-5.), 
-    fCellConnectionFactor(3), fTrackConnectionFactor(5), fTrackChiCut(6), fTrackChi2Cut(0), fMaxTrackMatchDRow(4),
-    fYErrorCorrection(0.33), fZErrorCorrection(0.45)
+    fZMin(0.0529937), fZMax(249.778), fErrX(0), fErrY(0), fErrZ(0.228808),fPadPitch(0.4),fBz(-5.), 
+    fYErrorCorrection(0.33), fZErrorCorrection(0.45),
+    fCellConnectionAngleXY(35./180.*TMath::Pi()), 
+    fCellConnectionAngleXZ(35./180.*TMath::Pi()),
+    fMaxTrackMatchDRow(4), fTrackConnectionFactor(3.5), fTrackChiCut(3.5), fTrackChi2Cut(10)
 {
   Update();
 }
 
-void AliHLTTPCCAParam::Initialize( Int_t ParISec
-                                  Int_t ParNRows, Double_t ParRowX[],
-                                  Double_t ParAlpha, Double_t ParDAlpha,
-                                  Double_t ParRMin, Double_t ParRMax,
-                                  Double_t ParZMin, Double_t ParZMax,
-                                  Double_t ParPadPitch, Double_t ParZSigma,
-                                  Double_t ParBz
+void AliHLTTPCCAParam::Initialize( Int_t iSlice
+                                  Int_t nRows, Double_t rowX[],
+                                  Double_t alpha, Double_t dAlpha,
+                                  Double_t rMin, Double_t rMax,
+                                  Double_t zMin, Double_t zMax,
+                                  Double_t padPitch, Double_t zSigma,
+                                  Double_t bz
                                   )
 {
   // initialization 
-  fISec = ParISec;
-  fAlpha = ParAlpha;
-  fDAlpha = ParDAlpha;
-  fRMin = ParRMin;
-  fRMax = ParRMax;
-  fZMin = ParZMin;
-  fZMax = ParZMax;
-  fPadPitch = ParPadPitch;
+  fISlice = iSlice;
+  fAlpha = alpha;
+  fDAlpha = dAlpha;
+  fRMin = rMin;
+  fRMax = rMax;
+  fZMin = zMin;
+  fZMax = zMax;
+  fPadPitch = padPitch;
   fErrY = 1.; // not in use
-  fErrZ = ParZSigma;
-  fBz = ParBz;
-  fNRows = ParNRows;
-  for( Int_t irow=0; irow<ParNRows; irow++ ){
-    fRowX[irow] = ParRowX[irow];
+  fErrZ = zSigma;
+  fBz = bz;
+  fNRows = nRows;
+  for( Int_t irow=0; irow<nRows; irow++ ){
+    fRowX[irow] = rowX[irow];
   }
 
   Update();
@@ -72,7 +74,7 @@ void AliHLTTPCCAParam::Update()
   fTrackChi2Cut = fTrackChiCut * fTrackChiCut;
 }
 
-void AliHLTTPCCAParam::Sec2Global(   Double_t x, Double_t y,  Double_t z, 
+void AliHLTTPCCAParam::Slice2Global( Double_t x, Double_t y,  Double_t z, 
                                     Double_t *X, Double_t *Y,  Double_t *Z ) const
 {  
   // conversion of coorinates sector->global
@@ -81,8 +83,8 @@ void AliHLTTPCCAParam::Sec2Global(   Double_t x, Double_t y,  Double_t z,
   *Z = z;
 }
  
-void AliHLTTPCCAParam::Global2Sec( Double_t X, Double_t Y,  Double_t Z, 
-                                  Double_t *x, Double_t *y,  Double_t *z ) const
+void AliHLTTPCCAParam::Global2Slice( Double_t X, Double_t Y,  Double_t Z, 
+                                    Double_t *x, Double_t *y,  Double_t *z ) const
 {
   // conversion of coorinates global->sector
   *x = X*fCosAlpha + Y*fSinAlpha;
index 8bc599c54e74c16043f81f9d0019e182797f9b1e..c2e92a0c9cf06deed04bd4e3743b834147f52f86 100644 (file)
@@ -12,7 +12,7 @@
 
 /**
  * @class ALIHLTTPCCAParam
- * parameters of the CATracker, including geometry information
+ * parameters of the AliHLTTPCCATracker, including geometry information
  * and some reconstructon constants.
  *
  * The class is under construction.
@@ -25,20 +25,19 @@ class AliHLTTPCCAParam
   AliHLTTPCCAParam();
   virtual ~AliHLTTPCCAParam(){;}
 
-  void Initialize( Int_t ParISec, Int_t ParNRows, Double_t ParRowX[],
-                  Double_t ParAlpha, Double_t ParDAlpha,
-                  Double_t ParRMin, Double_t ParRMax, 
-                  Double_t ParZMin, Double_t ParZMax,
-                  Double_t ParPadPitch, Double_t ParZSigma, Double_t ParBz );
+  void Initialize( Int_t iSlice, Int_t nRows, Double_t rowX[],
+                  Double_t alpha, Double_t dAlpha,
+                  Double_t rMin, Double_t rMax, Double_t zMin, Double_t zMax,
+                  Double_t padPitch, Double_t zSigma, Double_t bz );
   void Update();
-
-  void Sec2Global( Double_t x, Double_t y,  Double_t z, 
-                  Double_t *X, Double_t *Y,  Double_t *Z ) const;
-  void Global2Sec( Double_t x, Double_t y,  Double_t z, 
-                  Double_t *X, Double_t *Y,  Double_t *Z ) const;
-  Int_t &ISec(){ return fISec;}
+  
+  void Slice2Global( Double_t x, Double_t y,  Double_t z, 
+                    Double_t *X, Double_t *Y,  Double_t *Z ) const;
+  void Global2Slice( Double_t x, Double_t y,  Double_t z, 
+                    Double_t *X, Double_t *Y,  Double_t *Z ) const;
+  Int_t &ISlice(){ return fISlice;}
   Int_t &NRows(){ return fNRows;}
-
+  
   Double_t &RowX( Int_t iRow ){ return fRowX[iRow]; }
   
   Double_t &Alpha(){ return fAlpha;}
@@ -56,34 +55,38 @@ class AliHLTTPCCAParam
   Double_t &ErrY(){ return fErrY;}
   Double_t &Bz(){ return fBz;}
 
-  Double_t &CellConnectionFactor(){ return fCellConnectionFactor; }
   Double_t &TrackConnectionFactor(){ return fTrackConnectionFactor; }
   Double_t &TrackChiCut() { return fTrackChiCut; }
   Double_t &TrackChi2Cut(){ return fTrackChi2Cut; }
   Int_t    &MaxTrackMatchDRow(){ return fMaxTrackMatchDRow; }
   Double_t &YErrorCorrection(){ return fYErrorCorrection; }
   Double_t &ZErrorCorrection(){ return fZErrorCorrection; }
+  Double_t &CellConnectionAngleXY(){ return fCellConnectionAngleXY; }
+  Double_t &CellConnectionAngleXZ(){ return fCellConnectionAngleXZ; }
 
  protected:
 
-  Int_t fISec; // sector number
+  Int_t fISlice; // slice number
   Int_t fNRows; // number of rows
-  Double_t fAlpha, fDAlpha; // sector angle and angular size
-  Double_t fCosAlpha, fSinAlpha;// sign and cosine of the sector angle
+
+  Double_t fAlpha, fDAlpha; // slice angle and angular size
+  Double_t fCosAlpha, fSinAlpha;// sign and cosine of the slice angle
   Double_t fAngleMin, fAngleMax; // minimal and maximal angle
-  Double_t fRMin, fRMax;// sector R range
-  Double_t fZMin, fZMax;// sector Z range
-  Double_t fErrZ, fErrX, fErrY;// default cluster errors
+  Double_t fRMin, fRMax;// slice R range
+  Double_t fZMin, fZMax;// slice Z range
+  Double_t fErrX, fErrY, fErrZ;// default cluster errors
   Double_t fPadPitch; // pad pitch 
   Double_t fBz;       // magnetic field value (only constant field can be used)
 
-  Double_t fCellConnectionFactor; // allowed distance in Chi^2/3.5 for neighbouring cells
+  Double_t fYErrorCorrection;// correction factor for Y error of input clusters
+  Double_t fZErrorCorrection;// correction factor for Z error of input clusters
+
+  Double_t fCellConnectionAngleXY; // max phi angle between connected cells
+  Double_t fCellConnectionAngleXZ; // max psi angle between connected cells
+  Int_t    fMaxTrackMatchDRow;// maximal jump in TPC row for connecting track segments
   Double_t fTrackConnectionFactor; // allowed distance in Chi^2/3.5 for neighbouring tracks
   Double_t fTrackChiCut; // cut for track Sqrt(Chi2/NDF);
   Double_t fTrackChi2Cut;// cut for track Chi^2/NDF
-  Int_t    fMaxTrackMatchDRow;// maximal jump in TPC row for connecting track segments
-  Double_t fYErrorCorrection;// correction factor for Y error of input clusters
-  Double_t fZErrorCorrection;// correction factor for Z error of input clusters
 
   Double_t fRowX[200];// X-coordinate of rows
 
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCAPerformance.cxx b/HLT/TPCLib/tracking-ca/AliHLTTPCCAPerformance.cxx
new file mode 100644 (file)
index 0000000..b2d66ef
--- /dev/null
@@ -0,0 +1,551 @@
+// $Id$
+//***************************************************************************
+// This file is property of and copyright by the ALICE HLT Project          * 
+// ALICE Experiment at CERN, All rights reserved.                           *
+//                                                                          *
+// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
+//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
+//                  for The ALICE HLT Project.                              *
+//                                                                          *
+// Permission to use, copy, modify and distribute this software and its     *
+// documentation strictly for non-commercial purposes is hereby granted     *
+// without fee, provided that the above copyright notice appears in all     *
+// copies and that both the copyright notice and this permission notice     *
+// appear in the supporting documentation. The authors make no claims       *
+// about the suitability of this software for any purpose. It is            *
+// provided "as is" without express or implied warranty.                    *
+//***************************************************************************
+
+#include "AliHLTTPCCAPerformance.h"
+#include "AliHLTTPCCAGBHit.h"
+#include "AliHLTTPCCAMCTrack.h"
+#include "AliHLTTPCCAOutTrack.h"
+#include "AliHLTTPCCAGBTracker.h"
+#include "AliHLTTPCCATracker.h"
+
+#include "TMath.h"
+#include "TROOT.h"
+#include "Riostream.h"
+#include "TFile.h"
+#include "TH1.h"
+#include "TProfile.h"
+
+
+ClassImp(AliHLTTPCCAPerformance)
+
+
+
+AliHLTTPCCAPerformance::AliHLTTPCCAPerformance()
+  : TObject(),
+    fTracker(0),
+    fHitLabels(0), 
+    fNHits(0),
+    fMCTracks(0),
+    fNMCTracks(0),
+    fStatNEvents(0),
+    fStatNRecTot(0),
+    fStatNRecOut(0),
+    fStatNGhost(0),
+    fStatNMCAll(0),
+    fStatNRecAll(0),
+    fStatNClonesAll(0),
+    fStatNMCRef(0),
+    fStatNRecRef(0),
+    fStatNClonesRef(0),
+    fHistoDir(0),
+    fhHitErrY(0),
+    fhHitErrZ(0),
+    fhHitResX(0),
+    fhHitResY(0),
+    fhHitResZ(0),
+    fhHitPullX(0),
+    fhHitPullY(0),
+    fhHitPullZ(0),
+    fhCellPurity(0),
+    fhCellNHits(0),
+    fhCellPurityVsN(0), 
+    fhCellPurityVsPt(0),
+    fhEffVsP(0)
+{
+  //* constructor
+}
+
+
+AliHLTTPCCAPerformance::AliHLTTPCCAPerformance(const AliHLTTPCCAPerformance&)
+  : TObject(),
+    fTracker(0),
+    fHitLabels(0), 
+    fNHits(0),
+    fMCTracks(0),
+    fNMCTracks(0),
+    fStatNEvents(0),
+    fStatNRecTot(0),
+    fStatNRecOut(0),
+    fStatNGhost(0),
+    fStatNMCAll(0),
+    fStatNRecAll(0),
+    fStatNClonesAll(0),
+    fStatNMCRef(0),
+    fStatNRecRef(0),
+    fStatNClonesRef(0),
+    fHistoDir(0),
+    fhHitErrY(0),
+    fhHitErrZ(0),
+    fhHitResX(0),
+    fhHitResY(0),
+    fhHitResZ(0),
+    fhHitPullX(0),
+    fhHitPullY(0),
+    fhHitPullZ(0),
+    fhCellPurity(0),
+    fhCellNHits(0),
+    fhCellPurityVsN(0), 
+    fhCellPurityVsPt(0),
+    fhEffVsP(0)
+{
+  //* dummy
+}
+
+AliHLTTPCCAPerformance &AliHLTTPCCAPerformance::operator=(const AliHLTTPCCAPerformance&)
+{
+  //* dummy
+  return *this;
+}
+
+AliHLTTPCCAPerformance::~AliHLTTPCCAPerformance()
+{
+  //* destructor
+  StartEvent();
+}
+
+void AliHLTTPCCAPerformance::SetTracker( AliHLTTPCCAGBTracker *Tracker )
+{
+  //* set pointer to HLT CA Global tracker
+  fTracker = Tracker;
+}
+
+void AliHLTTPCCAPerformance::StartEvent()
+{
+  //* clean up arrays
+  if( !fHistoDir )  CreateHistos();
+  if( fHitLabels ) delete[] fHitLabels;
+  fHitLabels = 0;
+  fNHits = 0;
+  if( fMCTracks ) delete[] fMCTracks;
+  fMCTracks = 0;
+  fNMCTracks = 0;
+}
+
+void AliHLTTPCCAPerformance::SetNHits( Int_t NHits )
+{
+  //* set number of hits
+  if( fHitLabels ) delete[] fHitLabels;
+  fHitLabels = 0;
+  fHitLabels = new AliHLTTPCCAHitLabel[ NHits ];
+  fNHits = NHits;
+}  
+
+void AliHLTTPCCAPerformance::SetNMCTracks( Int_t NMCTracks )
+{
+  //* set number of MC tracks
+  if( fMCTracks ) delete[] fMCTracks;
+  fMCTracks = 0;
+  fMCTracks = new AliHLTTPCCAMCTrack[ NMCTracks ];
+  fNMCTracks = NMCTracks;
+}  
+
+void AliHLTTPCCAPerformance::ReadHitLabel( Int_t HitID, 
+                                          Int_t lab0, Int_t lab1, Int_t lab2 )
+{
+  //* read the hit labels
+  AliHLTTPCCAHitLabel hit;
+  hit.fLab[0] = lab0;
+  hit.fLab[1] = lab1;
+  hit.fLab[2] = lab2;
+  fHitLabels[HitID] = hit;
+}
+
+void AliHLTTPCCAPerformance::ReadMCTrack( Int_t index, const TParticle *part )
+{
+  //* read mc track to local array
+  fMCTracks[index] = AliHLTTPCCAMCTrack(part);
+}
+
+void AliHLTTPCCAPerformance::CreateHistos()
+{
+  //* create performance histogramms
+  TDirectory *curdir = gDirectory;
+  fHistoDir = gROOT->mkdir("HLTTPCCATrackerPerformance");
+  fHistoDir->cd();
+  gDirectory->mkdir("Fit");
+  gDirectory->cd("Fit");  
+  /*
+  fhResY = new TH1D("resY", "Y resoltion [cm]", 100, -5., 5.);
+  fhResZ = new TH1D("resZ", "Z resoltion [cm]", 100, -5., 5.);
+  fhResTy = new TH1D("resTy", "Ty resoltion ", 100, -1., 1.);
+  fhResTz = new TH1D("resTz", "Tz resoltion ", 100, -1., 1.);
+  fhResP = new TH1D("resP", "P resoltion ", 100, -10., 10.);
+  fhPullY = new TH1D("pullY", "Y pull", 100, -10., 10.);
+  fhPullZ = new TH1D("pullZ", "Z pull", 100, -10., 10.);
+  fhPullTy = new TH1D("pullTy", "Ty pull", 100, -10., 10.);
+  fhPullTz = new TH1D("pullTz", "Tz pull", 100, -10., 10.);
+  fhPullQp = new TH1D("pullQp", "Qp pull", 100, -10., 10.);
+  */
+  gDirectory->cd("..");  
+
+  fhEffVsP = new TProfile("EffVsP", "Eff vs P", 100, 0., 5.);
+
+  fhHitResX = new TH1D("resHitX", "X cluster resoltion [cm]", 100, -2., 2.);
+  fhHitResY = new TH1D("resHitY", "Y cluster resoltion [cm]", 100, -2., 2.);
+  fhHitResZ = new TH1D("resHitZ", "Z cluster resoltion [cm]", 100, -2., 2.);
+  fhHitPullX = new TH1D("pullHitX", "X cluster pull", 100, -10., 10.);
+  fhHitPullY = new TH1D("pullHitY", "Y cluster pull", 100, -10., 10.);
+  fhHitPullZ = new TH1D("pullHitZ", "Z cluster pull", 100, -10., 10.);
+
+
+  fhHitErrY = new TH1D("HitErrY", "Y cluster error [cm]", 100, 0., 1.);
+  fhHitErrZ = new TH1D("HitErrZ", "Z cluster error [cm]", 100, 0., 1.);
+
+  fhCellPurity = new TH1D("CellPurity", "Cell Purity", 100, -0.1, 1.1);
+  fhCellNHits = new TH1D("CellNHits", "Cell NHits", 40, 0., 40.);
+  fhCellPurityVsN = new TProfile("CellPurityVsN", "Cell purity Vs N hits", 40, 2., 42.);
+  fhCellPurityVsPt = new TProfile("CellPurityVsPt", "Cell purity Vs Pt", 100, 0., 5.);
+
+  curdir->cd();  
+}
+
+void AliHLTTPCCAPerformance::WriteDir2Current( TObject *obj )
+{
+  //* recursive function to copy the directory 'obj' to the current one
+  if( !obj->IsFolder() ) obj->Write();
+  else{
+    TDirectory *cur = gDirectory;
+    TDirectory *sub = cur->mkdir(obj->GetName());
+    sub->cd();
+    TList *listSub = ((TDirectory*)obj)->GetList();
+    TIter it(listSub);
+    while( TObject *obj1=it() ) WriteDir2Current(obj1);
+    cur->cd();
+  }
+}
+
+void AliHLTTPCCAPerformance::WriteHistos()
+{
+  //* write histograms to the file
+  TDirectory *curr = gDirectory;
+  // Open output file and write histograms
+  TFile* outfile = new TFile("HLTTPCCATrackerPerformance.root","RECREATE");
+  outfile->cd();
+  WriteDir2Current(fHistoDir);
+  outfile->Close();
+  curr->cd();
+}
+
+
+void AliHLTTPCCAPerformance::SlicePerformance( Int_t iSlice, Bool_t PrintFlag )
+{ 
+  //* calculate slice tracker performance
+  if( !fTracker ) return;
+
+  int nRecTot = 0, nGhost=0, nRecOut=0;
+  int nMCAll = 0, nRecAll=0, nClonesAll=0;
+  int nMCRef = 0, nRecRef=0, nClonesRef=0;
+  AliHLTTPCCATracker &slice = fTracker->Slices()[iSlice];
+
+  int firstSliceHit = 0;
+  for( ; firstSliceHit<fTracker->NHits(); firstSliceHit++){
+    if( fTracker->Hits()[firstSliceHit].ISlice()==iSlice ) break;
+  }
+  int endSliceHit = firstSliceHit;
+
+  for( ; endSliceHit<fTracker->NHits(); endSliceHit++){
+    if( fTracker->Hits()[endSliceHit].ISlice()!=iSlice ) break;
+  }
+
+  { // Cell construction performance
+    
+    for( Int_t iRow=0; iRow<slice.Param().NRows(); iRow++ ){
+      AliHLTTPCCARow &row = slice.Rows()[iRow];      
+      for (Int_t ic = 0; ic<row.NCells(); ic++){
+       AliHLTTPCCACell &c  = row.Cells()[ic];
+       Int_t *lb = new Int_t[c.NHits()*3];
+       Int_t nla = 0;
+       //cout<<11<<" "<<c.NHits()<<endl;
+       for( Int_t j=0; j<c.NHits(); j++){
+         AliHLTTPCCAHit &h = row.GetCellHit(c,j);
+         //cout<<"hit ID="<<h.ID()<<" of"<<fTracker->NHits()<<endl;
+         //cout<<"gb hit ID="<<fTracker->Hits()[h.ID()].ID()<<endl;
+         AliHLTTPCCAHitLabel &l = fHitLabels[fTracker->Hits()[h.ID()].ID()];
+         if( l.fLab[0]>=0 ) lb[nla++]= l.fLab[0];
+         if( l.fLab[1]>=0 ) lb[nla++]= l.fLab[1];
+         if( l.fLab[2]>=0 ) lb[nla++]= l.fLab[2];
+       }
+       //cout<<12<<endl;
+       sort( lb, lb+nla );
+       int labmax = -1, labcur=-1, lmax = 0, lcurr=0;  
+       for( int i=0; i<nla; i++ ){
+         if( lb[i]!=labcur ){
+           if( labcur>=0 && lmax<lcurr ){
+             lmax = lcurr;
+             labmax = labcur;
+           }
+           labcur = lb[i];
+           lcurr = 0;
+         }
+         lcurr++;
+       }
+       if( labcur>=0 && lmax<lcurr ){
+         lmax = lcurr;
+         labmax = labcur;
+       }
+
+       int label = labmax;
+       lmax = 0;
+       for( Int_t j=0; j<c.NHits(); j++){
+         AliHLTTPCCAHit &h = row.GetCellHit(c,j);
+         AliHLTTPCCAHitLabel &l = fHitLabels[fTracker->Hits()[h.ID()].ID()];
+         if( l.fLab[0]==label || l.fLab[1]==label || l.fLab[2]==label ) lmax++;
+       }
+
+       nla = c.NHits();
+       if( nla>0 && label>=0 ){
+         double purity = double(lmax)/double(nla);
+         fhCellPurity->Fill(purity);
+         fhCellPurityVsN->Fill(c.NHits(),purity);
+         fhCellPurityVsPt->Fill(fMCTracks[label].Pt(),purity);
+       }
+       fhCellNHits->Fill(c.NHits());
+       if(lb) delete[] lb;
+      }
+    }
+  }
+
+  // Select reconstructable MC tracks
+
+  {
+    for (Int_t imc=0; imc<fNMCTracks; imc++) fMCTracks[imc].NHits() = 0;
+          
+    for( int ih=firstSliceHit; ih<endSliceHit; ih++){
+      AliHLTTPCCAHitLabel &l = fHitLabels[fTracker->Hits()[ih].ID()];
+      if( l.fLab[0]>=0 ) fMCTracks[l.fLab[0]].NHits()++;
+      if( l.fLab[1]>=0 ) fMCTracks[l.fLab[1]].NHits()++;
+      if( l.fLab[2]>=0 ) fMCTracks[l.fLab[2]].NHits()++;
+    }
+    
+    for (Int_t imc=0; imc<fNMCTracks; imc++) {         
+      AliHLTTPCCAMCTrack &mc = fMCTracks[imc];
+      mc.Set() = 0;
+      mc.NReconstructed() = 0;
+      mc.NTurns() = 1;
+      if( mc.NHits() >=  10 && mc.P()>=.05 ){
+       mc.Set() = 1;
+       nMCAll++;
+       if( mc.P()>=1. ){
+         mc.Set() = 2;
+         nMCRef++;
+       }
+      }
+    }
+  }
+
+  int traN = slice.NOutTracks();
+  Int_t *traLabels = new Int_t[traN];
+  Double_t *traPurity = new Double_t[traN];
+  {
+    for (Int_t itr=0; itr<traN; itr++) {
+      traLabels[itr]=-1;
+      traPurity[itr]= 0;
+      AliHLTTPCCAOutTrack &tCA = slice.OutTracks()[itr];
+      int nhits = tCA.NHits();
+      int *lb = new Int_t[nhits*3];
+      int nla=0;
+      for( int ihit=0; ihit<nhits; ihit++){
+       int index = slice.OutTrackHits()[tCA.FirstHitRef()+ihit];
+       AliHLTTPCCAHitLabel &l = fHitLabels[fTracker->Hits()[index].ID()];
+       if(l.fLab[0]>=0 ) lb[nla++]= l.fLab[0];
+       if(l.fLab[1]>=0 ) lb[nla++]= l.fLab[1];
+       if(l.fLab[2]>=0 ) lb[nla++]= l.fLab[2];
+      }
+      sort( lb, lb+nla );
+      int labmax = -1, labcur=-1, lmax = 0, lcurr=0;
+      for( int i=0; i<nla; i++ ){
+       if( lb[i]!=labcur ){
+         if( labcur>=0 && lmax<lcurr ){
+           lmax = lcurr;
+           labmax = labcur;
+         }
+         labcur = lb[i];
+         lcurr = 0;
+       }
+       lcurr++;
+      }
+      if( labcur>=0 && lmax<lcurr ){
+       lmax = lcurr;
+       labmax = labcur;
+      }
+      lmax = 0;
+      for( int ihit=0; ihit<nhits; ihit++){
+       int index = slice.OutTrackHits()[tCA.FirstHitRef()+ihit];
+       AliHLTTPCCAHitLabel &l = fHitLabels[fTracker->Hits()[index].ID()];
+       if( l.fLab[0] == labmax || l.fLab[1] == labmax || l.fLab[2] == labmax 
+           ) lmax++;
+      }
+      traLabels[itr] = labmax;
+      traPurity[itr] = ( (nhits>0) ?double(lmax)/double(nhits) :0 );
+      if( lb ) delete[] lb;
+    }
+  }
+
+  nRecTot+= traN;
+  for(int itr=0; itr<traN; itr++){      
+    if( traPurity[itr]<.7 || traLabels[itr]<0 || traLabels[itr]>=fNMCTracks){
+      nGhost++;
+      continue;
+    }
+
+    AliHLTTPCCAMCTrack &mc = fMCTracks[traLabels[itr]];        
+    mc.NReconstructed()++;
+    if( mc.Set()== 0 ) nRecOut++;
+    else{
+      if( mc.NReconstructed()==1 ) nRecAll++;
+      else if(mc.NReconstructed() > mc.NTurns() ) nClonesAll++;
+      if( mc.Set()==2 ){
+       if( mc.NReconstructed()==1 ) nRecRef++;
+       else if(mc.NReconstructed() > mc.NTurns() ) nClonesRef++;
+      }
+    }      
+  }
+
+  for (Int_t ipart=0; ipart<fNMCTracks; ipart++) {             
+    AliHLTTPCCAMCTrack &mc = fMCTracks[ipart];
+    if( mc.Set()>0 ) fhEffVsP->Fill(mc.P(), ( mc.NReconstructed()>0 ?1 :0));
+  }  
+
+
+  if( traLabels ) delete[] traLabels;
+  if( traPurity ) delete[] traPurity;
+
+  fStatNRecTot += nRecTot;
+  fStatNRecOut += nRecOut;
+  fStatNGhost  += nGhost;
+  fStatNMCAll  += nMCAll;
+  fStatNRecAll  += nRecAll;
+  fStatNClonesAll  += nClonesAll;
+  fStatNMCRef  += nMCRef;
+  fStatNRecRef  += nRecRef;
+  fStatNClonesRef  += nClonesRef;
+
+  if( nMCAll ==0 ) return;
+
+  if( PrintFlag ){
+    cout<<"Performance for slice "<<iSlice<<" : "<<endl;
+    cout<<" N tracks : "
+       <<nMCAll<<" mc all, "
+       <<nMCRef<<" mc ref, "
+       <<nRecTot<<" rec total, "
+       <<nRecAll<<" rec all, "
+       <<nClonesAll<<" clones all, "
+       <<nRecRef<<" rec ref, "
+       <<nClonesRef<<" clones ref, "
+       <<nRecOut<<" out, "
+       <<nGhost<<" ghost"<<endl;
+  
+    Int_t nRecExtr = nRecAll - nRecRef;
+    Int_t nMCExtr = nMCAll - nMCRef;
+    Int_t nClonesExtr = nClonesAll - nClonesRef;
+  
+    Double_t dRecTot = (nRecTot>0 ) ? nRecTot :1;
+    Double_t dMCAll = (nMCAll>0 ) ? nMCAll :1;
+    Double_t dMCRef = (nMCRef>0 ) ? nMCRef :1;
+    Double_t dMCExtr = (nMCExtr>0 ) ? nMCExtr :1;
+    Double_t dRecAll = (nRecAll+nClonesAll>0 ) ? nRecAll+nClonesAll :1;
+    Double_t dRecRef = (nRecRef+nClonesRef>0 ) ? nRecRef+nClonesRef :1;
+    Double_t dRecExtr = (nRecExtr+nClonesExtr>0 ) ? nRecExtr+nClonesExtr :1;
+    
+    cout<<" EffRef = ";
+    if( nMCRef>0 ) cout<<nRecRef/dMCRef; else cout<<"_";
+    cout<<", CloneRef = ";
+    if( nRecRef >0 ) cout << nClonesRef/dRecRef; else cout<<"_";
+    cout<<endl;
+    cout<<" EffExtra = ";
+    if( nMCExtr>0 ) cout << nRecExtr/dMCExtr; else cout<<"_";
+    cout <<", CloneExtra = ";
+    if( nRecExtr>0 ) cout << nClonesExtr/dRecExtr; else cout<<"_";
+    cout<<endl;
+    cout<<" EffAll = ";
+    if( nMCAll>0 ) cout<<nRecAll/dMCAll; else cout<<"_";
+    cout <<", CloneAll = ";
+    if( nRecAll>0 ) cout << nClonesAll/dRecAll; else cout<<"_";
+    cout <<endl;
+    cout<<" Out = ";
+    if( nRecTot>0 ) cout <<nRecOut/dRecTot; else cout<<"_";
+    cout <<", Ghost = ";
+    if( nRecTot>0 ) cout<<nGhost/dRecTot; else cout<<"_";
+    cout<<endl;
+  }
+}
+
+
+void AliHLTTPCCAPerformance::Performance()
+{ 
+  // main routine for performance calculation  
+  fStatNEvents++;
+  for( int islice=0; islice<fTracker->NSlices(); islice++){
+    SlicePerformance(islice,0);
+  }
+  
+  // distribution of cluster errors
+
+  {    
+    Int_t nHits = fTracker->NHits();
+    for( Int_t ih=0; ih<nHits; ih++ ){
+      AliHLTTPCCAGBHit &hit = fTracker->Hits()[ih];
+      fhHitErrY->Fill(hit.ErrY());
+      fhHitErrZ->Fill(hit.ErrZ());
+    }
+  }
+  
+  cout<<" N tracks : "
+      <<fStatNMCAll/fStatNEvents<<" mc all, "
+      <<fStatNMCRef/fStatNEvents<<" mc ref, "
+      <<fStatNRecTot/fStatNEvents<<" rec total, "
+      <<fStatNRecAll/fStatNEvents<<" rec all, "
+      <<fStatNClonesAll/fStatNEvents<<" clones all, "
+      <<fStatNRecRef/fStatNEvents<<" rec ref, "
+      <<fStatNClonesRef/fStatNEvents<<" clones ref, "
+      <<fStatNRecOut/fStatNEvents<<" out, "
+      <<fStatNGhost/fStatNEvents<<" ghost"<<endl;
+  
+  Int_t nRecExtr = fStatNRecAll - fStatNRecRef;
+  Int_t nMCExtr = fStatNMCAll - fStatNMCRef;
+  Int_t nClonesExtr = fStatNClonesAll - fStatNClonesRef;
+  
+  Double_t dRecTot = (fStatNRecTot>0 ) ? fStatNRecTot :1;
+  Double_t dMCAll = (fStatNMCAll>0 ) ? fStatNMCAll :1;
+  Double_t dMCRef = (fStatNMCRef>0 ) ? fStatNMCRef :1;
+  Double_t dMCExtr = (nMCExtr>0 ) ? nMCExtr :1;
+  Double_t dRecAll = (fStatNRecAll+fStatNClonesAll>0 ) ? fStatNRecAll+fStatNClonesAll :1;
+  Double_t dRecRef = (fStatNRecRef+fStatNClonesRef>0 ) ? fStatNRecRef+fStatNClonesRef :1;
+  Double_t dRecExtr = (nRecExtr+nClonesExtr>0 ) ? nRecExtr+nClonesExtr :1;
+
+  cout<<" EffRef = "<< fStatNRecRef/dMCRef
+      <<", CloneRef = " << fStatNClonesRef/dRecRef <<endl;
+  cout<<" EffExtra = "<<nRecExtr/dMCExtr
+      <<", CloneExtra = " << nClonesExtr/dRecExtr<<endl;
+  cout<<" EffAll = "<<fStatNRecAll/dMCAll
+      <<", CloneAll = " << fStatNClonesAll/dRecAll<<endl;
+  cout<<" Out = "<<fStatNRecOut/dRecTot
+      <<", Ghost = "<<fStatNGhost/dRecTot<<endl;
+  cout<<" Time = "<<fTracker->StatTime(0)/fTracker->StatNEvents()*1.e3<<" msec/event "<<endl;
+  cout<<" Local timers = "
+      <<fTracker->StatTime(1)/fTracker->StatNEvents()*1.e3<<" "
+      <<fTracker->StatTime(2)/fTracker->StatNEvents()*1.e3<<" "
+      <<fTracker->StatTime(3)/fTracker->StatNEvents()*1.e3<<" "
+      <<fTracker->StatTime(4)/fTracker->StatNEvents()*1.e3<<" "
+      <<fTracker->StatTime(5)/fTracker->StatNEvents()*1.e3<<"["
+      <<fTracker->StatTime(6)/fTracker->StatNEvents()*1.e3<<"/"
+      <<fTracker->StatTime(7)/fTracker->StatNEvents()*1.e3<<"], merge:"
+      <<fTracker->StatTime(8)/fTracker->StatNEvents()*1.e3
+      <<" msec/event "<<endl;
+  WriteHistos();
+}
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCAPerformance.h b/HLT/TPCLib/tracking-ca/AliHLTTPCCAPerformance.h
new file mode 100644 (file)
index 0000000..38982bd
--- /dev/null
@@ -0,0 +1,100 @@
+//-*- Mode: C++ -*-
+// $Id$
+
+//* This file is property of and copyright by the ALICE HLT Project        * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//* See cxx source for full Copyright notice                               *
+
+#ifndef ALIHLTTPCCAPERFORMANCE_H
+#define ALIHLTTPCCAPERFORMANCE_H
+
+
+#include "TObject.h"
+
+class TParticle;
+class AliHLTTPCCAMCTrack;
+class AliHLTTPCCAGBTracker;
+class TDirectory;
+class TH1D;
+class TProfile;
+
+/**
+ * @class AliHLTTPCCAPerformance
+ * 
+ * Does performance evaluation of the HLT Cellular Automaton-based tracker
+ * It checks performance for AliHLTTPCCATracker slice tracker 
+ * and for AliHLTTPCCAGBTracker global tracker
+ *
+ */
+class AliHLTTPCCAPerformance:public TObject
+{
+
+ public:
+
+  AliHLTTPCCAPerformance();
+  AliHLTTPCCAPerformance(const AliHLTTPCCAPerformance&);
+  AliHLTTPCCAPerformance &operator=(const AliHLTTPCCAPerformance&);
+
+  virtual ~AliHLTTPCCAPerformance();
+
+  void SetTracker( AliHLTTPCCAGBTracker *Tracker );
+  void StartEvent();
+  void SetNHits( Int_t NHits );
+  void SetNMCTracks( Int_t NMCTracks );
+  void ReadHitLabel( Int_t HitID, 
+                    Int_t lab0, Int_t lab1, Int_t lab2 );
+  void ReadMCTrack( Int_t index, const TParticle *part );
+
+  void CreateHistos();
+  void WriteHistos();
+  void SlicePerformance( Int_t iSlice, Bool_t PrintFlag  );
+  void Performance();
+
+protected:
+
+  AliHLTTPCCAGBTracker *fTracker; //* pointer to the tracker
+  
+  struct AliHLTTPCCAHitLabel{
+    Int_t fLab[3]; //* array of 3 MC labels
+  };
+  AliHLTTPCCAHitLabel *fHitLabels; //* array of hit MC labels
+  Int_t fNHits; //* number of hits
+  AliHLTTPCCAMCTrack *fMCTracks; //* array of Mc tracks
+  Int_t fNMCTracks; //* number of MC tracks
+  Int_t fStatNEvents; //* n of events proceed
+  Int_t fStatNRecTot; //* total n of reconstructed tracks 
+  Int_t fStatNRecOut; //* n of reconstructed tracks in Out set
+  Int_t fStatNGhost;//* n of reconstructed tracks in Ghost set
+  Int_t fStatNMCAll;//* n of MC tracks 
+  Int_t fStatNRecAll; //* n of reconstructed tracks in All set
+  Int_t fStatNClonesAll;//* total n of reconstructed tracks in Clone set
+  Int_t fStatNMCRef; //* n of MC reference tracks 
+  Int_t fStatNRecRef; //* n of reconstructed tracks in Ref set
+  Int_t fStatNClonesRef; //* n of reconstructed clones in Ref set
+
+  TDirectory *fHistoDir; //* ROOT directory with histogramms
+
+  TH1D 
+  *fhHitErrY, //* hit error in Y
+    *fhHitErrZ,//* hit error in Z
+    *fhHitResX,//* hit resolution X
+    *fhHitResY,//* hit resolution Y
+    *fhHitResZ,//* hit resolution Z
+    *fhHitPullX,//* hit  pull X
+    *fhHitPullY,//* hit  pull Y
+    *fhHitPullZ,//* hit  pull Z
+    *fhCellPurity,//* cell purity
+    *fhCellNHits//* cell n hits
+    ;
+
+    TProfile 
+  *fhCellPurityVsN, //* cell purity vs N hits
+  *fhCellPurityVsPt,//* cell purity vs MC Pt
+  *fhEffVsP; //* reconstruction efficiency vs P plot
+
+  static void WriteDir2Current( TObject *obj );
+  
+  ClassDef(AliHLTTPCCAPerformance,1) 
+};
+
+#endif
index e53de231e15bb514e02ef3105eb934226ecf8107..1a0370d7a5a0f9b0f417151b6e78813613451453 100644 (file)
@@ -1,55 +1,56 @@
 // @(#) $Id$
-//*************************************************************************
-// This file is property of and copyright by the ALICE HLT Project        * 
-// ALICE Experiment at CERN, All rights reserved.                         *
-//                                                                        *
-// Primary Authors: Jochen Thaeder <thaeder@kip.uni-heidelberg.de>        *
-//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>              *
-//                  for The ALICE HLT Project.                            *
-//                                                                        *
-// Permission to use, copy, modify and distribute this software and its   *
-// documentation strictly for non-commercial purposes is hereby granted   *
-// without fee, provided that the above copyright notice appears in all   *
-// copies and that both the copyright notice and this permission notice   *
-// appear in the supporting documentation. The authors make no claims     *
-// about the suitability of this software for any purpose. It is          *
-// provided "as is" without express or implied warranty.                  *
-//*************************************************************************
+//***************************************************************************
+// This file is property of and copyright by the ALICE HLT Project          
+// ALICE Experiment at CERN, All rights reserved.                           *
+//                                                                          *
+// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
+//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
+//                  for The ALICE HLT Project.                              *
+//                                                                          *
+// Permission to use, copy, modify and distribute this software and its     *
+// documentation strictly for non-commercial purposes is hereby granted     *
+// without fee, provided that the above copyright notice appears in all     *
+// copies and that both the copyright notice and this permission notice     *
+// appear in the supporting documentation. The authors make no claims       *
+// about the suitability of this software for any purpose. It is            *
+// provided "as is" without express or implied warranty.                    *
+//***************************************************************************
 
 #include "AliHLTTPCCARow.h"
 
-
 ClassImp(AliHLTTPCCARow)
 
-AliHLTTPCCARow::AliHLTTPCCARow() :fHits(0),fCells(0),fCellHitPointers(0),fNHits(0),fNCells(0),fX(0)
+  AliHLTTPCCARow::AliHLTTPCCARow() :fHits(0),fCells(0),fCellHitPointers(0),fEndPoints(0),fNHits(0),fNCells(0),fNEndPoints(0),fX(0),fMaxY(0),fDeltaY(0),fDeltaZ(0)
 {
-  // constructor
+  //* constructor
 }
 
 AliHLTTPCCARow::AliHLTTPCCARow( const AliHLTTPCCARow &)
-  :fHits(0),fCells(0),fCellHitPointers(0),fNHits(0),fNCells(0),fX(0)
+  :fHits(0),fCells(0),fCellHitPointers(0),fEndPoints(0),fNHits(0),fNCells(0),fNEndPoints(0),fX(0),fMaxY(0),fDeltaY(0),fDeltaZ(0)
 {
-  // dummy
+  //* dummy
 }
 
 AliHLTTPCCARow &AliHLTTPCCARow::operator=( const AliHLTTPCCARow &)
 {
-  // dummy
+  //* dummy
   fHits = 0;
   fCells = 0;
   fCellHitPointers = 0;
+  fEndPoints = 0;
   fNHits = 0;
   fNCells = 0;
+  fNEndPoints = 0;
   return *this;
 }
 
 void AliHLTTPCCARow::Clear()
 {
-  // clear memory
-  delete[] fHits;
-  delete[] fCells;
+  //* clear memory
+  if(fHits) delete[] fHits;
   fHits = 0;
   fCells = 0;
   fCellHitPointers = 0;    
-  fNHits = fNCells = 0;
+  fEndPoints = 0;
+  fNHits = fNCells = fNEndPoints = 0;
 }
index 15069f11679b4c94af6a067057aa120853df4b91..87bd09da17fd0403359b1ae37453b589ffe5b35e 100644 (file)
@@ -8,11 +8,11 @@
 #ifndef ALIHLTTPCCAROW_H
 #define ALIHLTTPCCAROW_H
 
-
 #include "Rtypes.h"
 
 #include "AliHLTTPCCAHit.h"
 #include "AliHLTTPCCACell.h"
+#include "AliHLTTPCCAEndPoint.h"
 
 /**
  * @class ALIHLTTPCCARow
@@ -34,10 +34,15 @@ class AliHLTTPCCARow
   AliHLTTPCCAHit  *&Hits() { return fHits; }
   AliHLTTPCCACell *&Cells(){ return fCells;}
   Int_t  *&CellHitPointers() { return fCellHitPointers; }
-  
+  AliHLTTPCCAEndPoint *&EndPoints(){ return fEndPoints;}
   Int_t &NHits()  { return fNHits; }
   Int_t &NCells() { return fNCells; }
+  Int_t &NEndPoints() { return fNEndPoints; }
   Float_t &X() { return fX; }
+  Float_t &MaxY() { return fMaxY; }
+  Float_t &DeltaY() { return fDeltaY; }
+  Float_t &DeltaZ() { return fDeltaZ; }
 
   AliHLTTPCCAHit  &GetCellHit( AliHLTTPCCACell &c, Int_t i ){ 
     //* get hit number i of the cell c
@@ -46,13 +51,26 @@ class AliHLTTPCCARow
 
   void Clear();
 
- private:
+  static Bool_t CompareCellZMax( AliHLTTPCCACell&c, Double_t ZMax )
+  {
+    return (c.ZMax()<ZMax);
+  }
+  static Bool_t CompareEndPointZ( AliHLTTPCCAEndPoint &p, Double_t Z )
+  {
+    return (p.Param().GetZ()<Z);
+  }
+
+private:
 
   AliHLTTPCCAHit *fHits;   // hit array
   AliHLTTPCCACell *fCells; // cell array
   Int_t *fCellHitPointers; // pointers cell->hits
-  Int_t fNHits, fNCells;   // number of hits and cells
+  AliHLTTPCCAEndPoint *fEndPoints; // array of track end points
+  Int_t fNHits, fNCells, fNEndPoints;   // number of hits and cells
   Float_t fX;              // X coordinate of the row
+  Float_t fMaxY;           // maximal Y coordinate of the row
+  Float_t fDeltaY;         // allowed Y deviation to the next row
+  Float_t fDeltaZ;         // allowed Z deviation to the next row
 
   ClassDef(AliHLTTPCCARow,1);
 };
index 988c83c6705b31ed95e54d73b5c77a1ede13aefe..78ba817d5e83e39cea520b88f650f047c1f115fd 100644 (file)
@@ -1,25 +1,25 @@
 // @(#) $Id$
-//*************************************************************************
-// This file is property of and copyright by the ALICE HLT Project        * 
-// ALICE Experiment at CERN, All rights reserved.                         *
-//                                                                        *
-// Primary Authors: Jochen Thaeder <thaeder@kip.uni-heidelberg.de>        *
-//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>              *
-//                  for The ALICE HLT Project.                            *
-//                                                                        *
-// Permission to use, copy, modify and distribute this software and its   *
-// documentation strictly for non-commercial purposes is hereby granted   *
-// without fee, provided that the above copyright notice appears in all   *
-// copies and that both the copyright notice and this permission notice   *
-// appear in the supporting documentation. The authors make no claims     *
-// about the suitability of this software for any purpose. It is          *
-// provided "as is" without express or implied warranty.                  *
-//*************************************************************************
+//***************************************************************************
+// This file is property of and copyright by the ALICE HLT Project          
+// ALICE Experiment at CERN, All rights reserved.                           *
+//                                                                          *
+// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
+//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
+//                  for The ALICE HLT Project.                              *
+//                                                                          *
+// Permission to use, copy, modify and distribute this software and its     *
+// documentation strictly for non-commercial purposes is hereby granted     *
+// without fee, provided that the above copyright notice appears in all     *
+// copies and that both the copyright notice and this permission notice     *
+// appear in the supporting documentation. The authors make no claims       *
+// about the suitability of this software for any purpose. It is            *
+// provided "as is" without express or implied warranty.                    *
+//***************************************************************************
 
 #include "AliHLTTPCCATrack.h"
 
 
-ClassImp(AliHLTTPCCATrack)
+//ClassImp(AliHLTTPCCATrack)
 
 void AliHLTTPCCATrack::Dummy()
 {
index 86a2b05d86ad468d3794e36f042b9dd300d38622..1bfb49cca9d582f6da56a50b6c92cbb93e3cda42 100644 (file)
@@ -8,41 +8,39 @@
 #ifndef ALIHLTTPCCATRACK_H
 #define ALIHLTTPCCATRACK_H
 
-#include "AliHLTTPCCATrackPar.h"
+#include "Rtypes.h"
 
 /**
  * @class ALIHLTTPCCAtrack
  *
  * The class describes the [partially] reconstructed TPC track [candidate].
  * The class is dedicated for internal use by the AliHLTTPCCATracker algorithm.
- *
+ * The track parameters at both ends are stored separately in the AliHLTTPCCAEndPoint class
  */
 class AliHLTTPCCATrack
 {
  public:
-  AliHLTTPCCATrack():fUsed(0),fNCells(0),fIFirstCell(0),fParam(){}
+  AliHLTTPCCATrack():fAlive(0),fFirstCellID(0),fNCells(0){}
   virtual ~AliHLTTPCCATrack(){}
 
-  static bool CompareSize(const AliHLTTPCCATrack &t1, const AliHLTTPCCATrack &t2 ){
-    return t2.fNCells<t1.fNCells;
-  }
-
-  Bool_t &Used()              { return fUsed; }
+  Bool_t &Alive()              { return fAlive; }
   Int_t  &NCells()            { return fNCells; }
-  Int_t &IFirstCell()         { return fIFirstCell; }
-  AliHLTTPCCATrackPar &Param(){ return fParam; }
+  Int_t  *CellID()            { return fCellID; }
+  Int_t  &FirstCellID()        { return fFirstCellID; }
+  Int_t  *PointID()            { return fPointID; }
 
  private:
 
-  Bool_t fUsed;       // flag for mark tracks used by the track merger
-  Int_t  fNCells;     // number of track cells
-  Int_t  fIFirstCell; // index of first cell reference in track->cell reference array
+  Bool_t fAlive;       // flag for mark tracks used by the track merger
+  Int_t  fFirstCellID; // index of the first track cell in the track->cell pointer array
+  Int_t  fNCells;      // number of track cells
+  Int_t  fCellID[3];   // ID of first,middle,last cell
+  Int_t  fPointID[2];  // ID of the track endpoints
   
-  AliHLTTPCCATrackPar fParam; // fitted track parameters
-
+ private:
   void Dummy(); // to make rulechecker happy by having something in .cxx file
 
-  ClassDef(AliHLTTPCCATrack,1);
+  //ClassDef(AliHLTTPCCATrack,1);
 };
 
 #endif
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCATrackParam.cxx b/HLT/TPCLib/tracking-ca/AliHLTTPCCATrackParam.cxx
new file mode 100644 (file)
index 0000000..950b419
--- /dev/null
@@ -0,0 +1,521 @@
+// $Id$
+//***************************************************************************
+// This file is property of and copyright by the ALICE HLT Project          * 
+// ALICE Experiment at CERN, All rights reserved.                           *
+//                                                                          *
+// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
+//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
+//                  for The ALICE HLT Project.                              *
+//                                                                          *
+// Permission to use, copy, modify and distribute this software and its     *
+// documentation strictly for non-commercial purposes is hereby granted     *
+// without fee, provided that the above copyright notice appears in all     *
+// copies and that both the copyright notice and this permission notice     *
+// appear in the supporting documentation. The authors make no claims       *
+// about the suitability of this software for any purpose. It is            *
+// provided "as is" without express or implied warranty.                    *
+//***************************************************************************
+
+#include "AliHLTTPCCATrackParam.h"
+#include "TMath.h"
+#include "AliExternalTrackParam.h"
+
+//ClassImp(AliHLTTPCCATrackParam)
+
+//
+// Circle in XY:
+// 
+// R  = 1/TMath::Abs(Kappa);
+// Xc = X - sin(Phi)/Kappa;
+// Yc = Y + cos(Phi)/Kappa;
+//
+
+
+
+void AliHLTTPCCATrackParam::ConstructXY3( const Float_t x[3], const Float_t y[3], 
+                                         const Float_t sigmaY2[3], Float_t CosPhi0 )
+{
+  //* Construct the track in XY plane by 3 points
+
+  Float_t x0 = x[0];
+  Float_t y0 = y[0];
+  Float_t x1 = x[1] - x0;
+  Float_t y1 = y[1] - y0;
+  Float_t x2 = x[2] - x0;
+  Float_t y2 = y[2] - y0;
+  
+  Float_t a1 = x1*x1 + y1*y1;
+  Float_t a2 = x2*x2 + y2*y2;
+  Float_t a = 2*(x1*y2 - y1*x2);
+  Float_t lx =  a1*y2 - a2*y1;
+  Float_t ly = -a1*x2 + a2*x1;
+  Float_t l = TMath::Sqrt(lx*lx + ly*ly);
+  Float_t li = 1./l;
+  Float_t li2 = li*li;
+  Float_t li3 = li2*li;
+  Float_t cosPhi = ly*li;
+
+  Float_t sinPhi = -lx*li;
+  Float_t kappa = a/l;
+
+  Float_t dlx = a2 - a1;     //  D lx / D y0
+  Float_t dly = -a;          //  D ly / D y0
+  Float_t dA  = 2*(x2 - x1); // D a  / D y0
+  Float_t dl = (lx*dlx + ly*dly)*li;
+  
+  // D sinPhi,kappa / D y0
+
+  Float_t d0[2] = { -(dlx*ly-lx*dly)*ly*li3, (dA*l-a*dl)*li2 };
+
+  // D sinPhi,kappa / D y1 
+
+  dlx = -a2 + 2*y1*y2;
+  dly = -2*x2*y1;
+  dA  = -2*x2;
+  dl = (lx*dlx + ly*dly)*li;
+
+  Float_t d1[2] = { -(dlx*ly-lx*dly)*ly*li3, (dA*l-a*dl)*li2 };
+
+  // D sinPhi,kappa / D y2
+
+  dlx = a1 - 2*y1*y2;
+  dly = -2*x1*y2;
+  dA  = 2*x1;
+  dl = (lx*dlx + ly*dly)*li;
+
+  Float_t d2[2] = { -(dlx*ly-lx*dly)*ly*li3, (dA*l-a*dl)*li2 };
+   
+  if( CosPhi0*cosPhi <0 ){
+    cosPhi = -cosPhi;
+    sinPhi = -sinPhi;
+    kappa = -kappa;   
+    d0[0] = -d0[0];
+    d0[1] = -d0[1];
+    d1[0] = -d1[0];
+    d1[1] = -d1[1];
+    d2[0] = -d2[0];
+    d2[1] = -d2[1];
+  }
+  
+  X() = x0;  
+  Y() = y0;
+  SinPhi() = sinPhi;
+  Kappa() = kappa;
+  CosPhi() = cosPhi;
+
+  Float_t s0 = sigmaY2[0];
+  Float_t s1 = sigmaY2[1];
+  Float_t s2 = sigmaY2[2];
+  
+  fC[0] = s0;
+  fC[1] = 0;
+  fC[2] = 0;
+
+  fC[3] = d0[0]*s0;
+  fC[4] = 0;
+  fC[5] = d0[0]*d0[0]*s0 + d1[0]*d1[0]*s1 + d2[0]*d2[0]*s2;
+
+  fC[6] = 0;
+  fC[7] = 0;
+  fC[8] = 0;
+  fC[9] = 0;
+
+  fC[10] = d0[1]*s0;
+  fC[11] = 0;
+  fC[12] = d0[0]*d0[1]*s0 + d1[0]*d1[1]*s1 + d2[0]*d2[1]*s2;
+  fC[13] = 0;
+  fC[14] = d0[1]*d0[1]*s0 + d1[1]*d1[1]*s1 + d2[1]*d2[1]*s2;
+}
+
+
+Float_t  AliHLTTPCCATrackParam::GetS( Float_t x, Float_t y ) const
+{
+  //* Get XY path length to the given point
+
+  Float_t k  = GetKappa();
+  Float_t ex = GetCosPhi();
+  Float_t ey = GetSinPhi();
+  x-= GetX();
+  y-= GetY();
+  Float_t dS = x*ex + y*ey;
+  if( TMath::Abs(k)>1.e-4 ) dS = TMath::ATan2( k*dS, 1+k*(x*ey-y*ex) )/k;
+  return dS;
+}
+
+void  AliHLTTPCCATrackParam::GetDCAPoint( Float_t x, Float_t y, Float_t z,
+                                          Float_t &xp, Float_t &yp, Float_t &zp ) const
+{
+  //* Get the track point closest to the (x,y,z)
+
+  Float_t x0 = GetX();
+  Float_t y0 = GetY();
+  Float_t k  = GetKappa();
+  Float_t ex = GetCosPhi();
+  Float_t ey = GetSinPhi();
+  Float_t dx = x - x0;
+  Float_t dy = y - y0; 
+  Float_t ax = dx*k+ey;
+  Float_t ay = dy*k-ex;
+  Float_t a = sqrt( ax*ax+ay*ay );
+  xp = x0 + (dx - ey*( (dx*dx+dy*dy)*k - 2*(-dx*ey+dy*ex) )/(a+1) )/a;
+  yp = y0 + (dy + ex*( (dx*dx+dy*dy)*k - 2*(-dx*ey+dy*ex) )/(a+1) )/a;
+  Float_t s = GetS(x,y);
+  zp = GetZ() + GetDzDs()*s;
+  if( TMath::Abs(k)>1.e-2 ){
+    Float_t dZ = TMath::Abs( GetDzDs()*TMath::TwoPi()/k );
+    if( dZ>.1 ){
+      zp+= TMath::Nint((z-zp)/dZ)*dZ;    
+    }
+  }
+}
+
+void AliHLTTPCCATrackParam::ConstructXYZ3( const Float_t p0[5], const Float_t p1[5], 
+                                          const Float_t p2[5], 
+                                          Float_t CosPhi0, Float_t t0[] )
+{      
+  //* Construct the track in XYZ by 3 points
+
+  Float_t px[3]   = { p0[0], p1[0], p2[0] };
+  Float_t py[3]   = { p0[1], p1[1], p2[1] };
+  Float_t pz[3]   = { p0[2], p1[2], p2[2] };
+  Float_t ps2y[3] = { p0[3]*p0[3], p1[3]*p1[3], p2[3]*p2[3] };
+  Float_t ps2z[3] = { p0[4]*p0[4], p1[4]*p1[4], p2[4]*p2[4] };
+
+  Float_t kold = t0 ?t0[4] :0;
+  ConstructXY3( px, py, ps2y, CosPhi0 );
+
+  Float_t pS[3] = { GetS(px[0],py[0]), GetS(px[1],py[1]), GetS(px[2],py[2]) };
+  Float_t k = Kappa();
+  if( TMath::Abs(k)>1.e-2 ){    
+    Float_t dS = TMath::Abs( TMath::TwoPi()/k );
+    pS[1]+= TMath::Nint( (pS[0]-pS[1])/dS )*dS; // not more than half turn
+    pS[2]+= TMath::Nint( (pS[1]-pS[2])/dS )*dS;
+    if( t0 ){
+      Float_t dZ = TMath::Abs(t0[3]*dS);
+      if( TMath::Abs(dZ)>1. ){
+       Float_t dsDz = 1./t0[3];
+       if( kold*k<0 ) dsDz = -dsDz;
+       Float_t s0 = (pz[0]-t0[1])*dsDz;
+       Float_t s1 = (pz[1]-t0[1])*dsDz;
+       Float_t s2 = (pz[2]-t0[1])*dsDz;        
+       pS[0]+= TMath::Nint( (s0-pS[0])/dS )*dS ;
+       pS[1]+= TMath::Nint( (s1-pS[1])/dS )*dS ;
+       pS[2]+= TMath::Nint( (s2-pS[2])/dS )*dS ;       
+      }
+    }
+  }
+
+  Float_t s = pS[0] + pS[1] + pS[2];
+  Float_t z = pz[0] + pz[1] + pz[2];
+  Float_t sz = pS[0]*pz[0] + pS[1]*pz[1] + pS[2]*pz[2];
+  Float_t ss = pS[0]*pS[0] + pS[1]*pS[1] + pS[2]*pS[2];
+  
+  Float_t a = 3*ss-s*s;
+  Z() = (z*ss-sz*s)/a; // z0
+  DzDs() = (3*sz-z*s)/a; // t = dz/ds
+    
+  Float_t dz0[3] = {ss - pS[0]*s,ss - pS[1]*s,ss - pS[2]*s };
+  Float_t dt [3] = {3*pS[0] - s, 3*pS[1] - s, 3*pS[2] - s };
+
+  fC[2] = (dz0[0]*dz0[0]*ps2z[0] + dz0[1]*dz0[1]*ps2z[1] + dz0[2]*dz0[2]*ps2z[2])/a/a;
+  fC[7]= (dz0[0]*dt [0]*ps2z[0] + dz0[1]*dt [1]*ps2z[1] + dz0[2]*dt [2]*ps2z[2])/a/a;  
+  fC[9]= (dt [0]*dt [0]*ps2z[0] + dt [1]*dt [1]*ps2z[1] + dt [2]*dt [2]*ps2z[2])/a/a;  
+}
+
+
+Bool_t  AliHLTTPCCATrackParam::TransportToX( Float_t x )
+{
+  //* Transport the track parameters to X=x 
+
+  Bool_t ret = 1;
+
+  Float_t x0  = X();
+  //Float_t y0  = Y();
+  Float_t k   = Kappa();
+  Float_t ex = CosPhi();
+  Float_t ey = SinPhi();
+  Float_t dx = x - x0;
+
+  Float_t ey1 = k*dx + ey;
+  Float_t ex1;
+  if( TMath::Abs(ey1)>1 ){ // no intersection -> check the border    
+    ey1 = ( ey1>0 ) ?1 :-1;
+    ex1 = 0;
+    dx = ( TMath::Abs(k)>1.e-4) ? ( (ey1-ey)/k ) :0;
+    
+    Float_t ddx = TMath::Abs(x0+dx - x)*k*k;
+    Float_t hx[] = {0, -k, 1+ey };
+    Float_t sx2 = hx[1]*hx[1]*fC[ 3] + hx[2]*hx[2]*fC[ 5];
+    if( ddx*ddx>3.5*3.5*sx2 ) ret = 0; // x not withing the error
+    ret = 0; // any case
+    return ret;
+  }else{
+    ex1 = TMath::Sqrt(1 - ey1*ey1);
+    if( ex<0 ) ex1 = -ex1;  
+  }
+  
+  Float_t dx2 = dx*dx;
+  CosPhi() = ex1;
+  Float_t ss = ey+ey1;
+  Float_t cc = ex+ex1;  
+  Float_t tg = 0;
+  if( TMath::Abs(cc)>1.e-4 ) tg = ss/cc; // tan((phi1+phi)/2)
+  else ret = 0; 
+  Float_t dy = dx*tg;
+  Float_t dl = dx*TMath::Sqrt(1+tg*tg);
+
+  if( cc<0 ) dl = -dl;
+  Float_t dSin = dl*k/2;
+  if( dSin > 1 ) dSin = 1;
+  if( dSin <-1 ) dSin = -1;
+  Float_t dS = ( TMath::Abs(k)>1.e-4)  ? (2*TMath::ASin(dSin)/k) :dl;
+  Float_t dz = dS*DzDs();
+
+  Float_t cci = 0, exi = 0, ex1i = 0;
+  if( TMath::Abs(cc)>1.e-4 ) cci = 1./cc;
+  else ret = 0;
+  if( TMath::Abs(ex)>1.e-4 ) exi = 1./ex;
+  else ret = 0;
+  if( TMath::Abs(ex1)>1.e-4 ) ex1i = 1./ex1;
+  else ret = 0;
+
+  if( !ret ) return ret;
+  X() += dx;
+  fP[0]+= dy;
+  fP[1]+= dz;
+  fP[2] = ey1;
+  fP[3] = fP[3];
+  fP[4] = fP[4];
+
+  Float_t h2 = dx*(1+ ex*ex1 + ey*ey1 )*cci*exi*ex1i;
+  Float_t h4 = dx2*(cc + ss*ey1*ex1i )*cci*cci;
+
+  Float_t c00 = fC[0];
+  Float_t c10 = fC[1];
+  Float_t c11 = fC[2];
+  Float_t c20 = fC[3];
+  Float_t c21 = fC[4];
+  Float_t c22 = fC[5];
+  Float_t c30 = fC[6];
+  Float_t c31 = fC[7];
+  Float_t c32 = fC[8];
+  Float_t c33 = fC[9];
+  Float_t c40 = fC[10];
+  Float_t c41 = fC[11];
+  Float_t c42 = fC[12];
+  Float_t c43 = fC[13];
+  Float_t c44 = fC[14];
+
+  //Float_t H0[5] = { 1,0, h2,  0, h4 };
+  //Float_t H1[5] = { 0, 1, 0, dS,  0 };
+  //Float_t H2[5] = { 0, 0, 1,  0, dx };
+  //Float_t H3[5] = { 0, 0, 0,  1,  0 };
+  //Float_t H4[5] = { 0, 0, 0,  0,  1 };
+
+
+  fC[0]=( c00  + h2*h2*c22 + h4*h4*c44 
+         + 2*( h2*c20 + h4*c40 + h2*h4*c42 )  ); 
+
+  fC[1]= c10 + h2*c21 + h4*c41 + dS*(c30 + h2*c32 + h4*c43);
+  fC[2]= c11 + 2*dS*c31 + dS*dS*c33;
+
+  fC[3]= c20 + h2*c22 + h4*c42 + dx*( c40 + h2*c42 + h4*c44);
+  fC[4]= c21 + dS*c32 + dx*(c41 + dS*c43);
+  fC[5]= c22 +2*dx*c42 + dx2*c44;
+
+  fC[6]= c30 + h2*c32 + h4*c43;
+  fC[7]= c31 + dS*c33;
+  fC[8]= c32 + dx*c43;
+  fC[9]= c33;
+
+  fC[10]= c40 + h2*c42 + h4*c44;
+  fC[11]= c41 + dS*c43;
+  fC[12]= c42 + dx*c44;
+  fC[13]= c43;
+  fC[14]= c44;
+
+  return ret;
+}
+
+
+
+Bool_t AliHLTTPCCATrackParam::Rotate( Float_t alpha )
+{
+  //* Rotate the coordinate system in XY on the angle alpha
+
+  Bool_t ret = 1;
+
+  Float_t cA = TMath::Cos( alpha );
+  Float_t sA = TMath::Sin( alpha );
+  Float_t x = X(), y= Y(), sP= SinPhi(), cP= CosPhi();
+
+  X()      =   x*cA +  y*sA;
+  Y()      =  -x*sA +  y*cA;
+  CosPhi() =  cP*cA + sP*sA;
+  SinPhi() = -cP*sA + sP*cA;
+
+  Float_t j0 = 0, j2 = 0;
+    
+  if( TMath::Abs(CosPhi())>1.e-4 ) j0 = cP/CosPhi(); else ret = 0;
+  if( TMath::Abs(cP)>1.e-4 ) j2 = CosPhi()/cP; else ret = 0;
+
+  //Float_t J[5][5] = { { j0, 0, 0,  0,  0 }, // Y
+  //                      {  0, 1, 0,  0,  0 }, // Z
+  //                      {  0, 0, j2, 0,  0 }, // SinPhi
+  //                     {  0, 0, 0,  1,  0 }, // DzDs
+  //                     {  0, 0, 0,  0,  1 } }; // Kappa
+
+  fC[0]*= j0*j0;
+  fC[1]*= j0;
+  //fC[3]*= j0;
+  fC[6]*= j0;
+  fC[10]*= j0;
+
+  //fC[3]*= j2;
+  fC[4]*= j2;
+  fC[5]*= j2*j2; 
+  fC[8]*= j2;
+  fC[12]*= j2;
+  return ret;
+}
+
+
+void AliHLTTPCCATrackParam::GetExtParam( AliExternalTrackParam &T, Double_t alpha, Double_t Bz ) const
+{
+  //* Convert to AliExternalTrackParam parameterisation, 
+  //* the angle alpha is the global angle of the local X axis 
+
+  Double_t par[5], cov[15];
+  for( Int_t i=0; i<5; i++ ) par[i] = fP[i];
+  for( Int_t i=0; i<15; i++ ) cov[i] = fC[i];
+
+  if(par[2]>.999 ) par[2]=.999;
+  if(par[2]<-.999 ) par[2]=-.999;
+
+  const Double_t kCLight = 0.000299792458;  
+  Double_t c = 1./(Bz*kCLight);
+  { // kappa => 1/pt
+    par[4] *= c;
+    cov[10]*= c;
+    cov[11]*= c;
+    cov[12]*= c;
+    cov[13]*= c;
+    cov[14]*= c*c;
+  }
+  if( GetCosPhi()<0 ){ // change direction
+    par[2] = -par[2]; // sin phi
+    par[3] = -par[3]; // DzDs
+    par[4] = -par[4]; // kappa
+    cov[3] = -cov[3];
+    cov[4] = -cov[4];
+    cov[6] = -cov[6];
+    cov[7] = -cov[7];
+    cov[10] = -cov[10];
+    cov[11] = -cov[11];
+  }
+  T.Set(GetX(),alpha,par,cov);
+}
+
+void AliHLTTPCCATrackParam::SetExtParam( const AliExternalTrackParam &T, Double_t Bz )
+{
+  //* Convert from AliExternalTrackParam parameterisation
+  
+  for( Int_t i=0; i<5; i++ ) fP[i] = T.GetParameter()[i];
+  for( Int_t i=0; i<15; i++ ) fC[i] = T.GetCovariance()[i];
+  X() = T.GetX();
+  if(SinPhi()>.999 ) SinPhi()=.999;
+  if(SinPhi()<-.999 ) SinPhi()=-.999;
+  CosPhi() = TMath::Sqrt(1.-SinPhi()*SinPhi());
+  const Double_t kCLight = 0.000299792458;  
+  Double_t c = Bz*kCLight;
+  { // 1/pt -> kappa 
+    fP[4] *= c;
+    fC[10]*= c;
+    fC[11]*= c;
+    fC[12]*= c;
+    fC[13]*= c;
+    fC[14]*= c*c;
+  }
+}
+
+
+void AliHLTTPCCATrackParam::Filter( Float_t y, Float_t z, Float_t erry, Float_t errz )
+{
+  //* Add the y,z measurement with the Kalman filter 
+
+  Float_t 
+    c00 = fC[ 0],
+    c10 = fC[ 1], c11 = fC[ 2],
+    c20 = fC[ 3], c21 = fC[ 4],
+    c30 = fC[ 6], c31 = fC[ 7],
+    c40 = fC[10], c41 = fC[11];
+  
+  Float_t
+    z0 = y-fP[0],
+    z1 = z-fP[1];
+
+  Float_t v[3] = {erry*erry, 0, errz*errz};
+
+  Float_t mS[3] = { c00+v[0], c10+v[1], c11+v[2] };
+
+  Float_t mSi[3];
+  Float_t det = (mS[0]*mS[2] - mS[1]*mS[1]);
+
+  if( TMath::Abs(det)<1.e-8 ) return;
+  det = 1./det;
+  mSi[0] = mS[2]*det;
+  mSi[1] = -mS[1]*det;
+  mSi[2] = mS[0]*det;
+  fNDF  += 2;
+  fChi2 += ( +(mSi[0]*z0 + mSi[1]*z1 )*z0
+            +(mSi[1]*z0 + mSi[2]*z1 )*z1 );
+
+  // K = CHtS
+  
+  Float_t k00, k01 , k10, k11, k20, k21, k30, k31, k40, k41;
+    
+  k00 = c00*mSi[0] + c10*mSi[1]; k01 = c00*mSi[1] + c10*mSi[2];
+  k10 = c10*mSi[0] + c11*mSi[1]; k11 = c10*mSi[1] + c11*mSi[2];
+  k20 = c20*mSi[0] + c21*mSi[1]; k21 = c20*mSi[1] + c21*mSi[2];
+  k30 = c30*mSi[0] + c31*mSi[1]; k31 = c30*mSi[1] + c31*mSi[2] ;
+  k40 = c40*mSi[0] + c41*mSi[1]; k41 = c40*mSi[1] + c41*mSi[2] ;
+
+  Float_t sinPhi = fP[2] + k20*z0  + k21*z1  ;
+  if( TMath::Abs(sinPhi)>=0.99 ) return;
+
+  fP[ 0]+= k00*z0  + k01*z1 ;
+  fP[ 1]+= k10*z0  + k11*z1  ;
+  fP[ 2]+= k20*z0  + k21*z1  ;
+  fP[ 3]+= k30*z0  + k31*z1  ;
+  fP[ 4]+= k40*z0  + k41*z1  ;
+
+    
+  fC[ 0]-= k00*c00 + k01*c10 ;
+  
+  fC[ 1]-= k10*c00 + k11*c10 ;
+  fC[ 2]-= k10*c10 + k11*c11 ;
+
+  fC[ 3]-= k20*c00 + k21*c10 ;
+  fC[ 4]-= k20*c10 + k21*c11 ;
+  fC[ 5]-= k20*c20 + k21*c21 ;
+
+  fC[ 6]-= k30*c00 + k31*c10 ;
+  fC[ 7]-= k30*c10 + k31*c11 ;
+  fC[ 8]-= k30*c20 + k31*c21 ;
+  fC[ 9]-= k30*c30 + k31*c31 ;
+
+  fC[10]-= k40*c00 + k41*c10 ;
+  fC[11]-= k40*c10 + k41*c11 ;
+  fC[12]-= k40*c20 + k41*c21 ;
+  fC[13]-= k40*c30 + k41*c31 ;
+  fC[14]-= k40*c40 + k41*c41 ;
+    
+  if( CosPhi()>=0 ){
+    CosPhi() = TMath::Sqrt(1-SinPhi()*SinPhi());
+  }else{
+    CosPhi() = -TMath::Sqrt(1-SinPhi()*SinPhi());
+  }   
+    
+}
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCATrackParam.h b/HLT/TPCLib/tracking-ca/AliHLTTPCCATrackParam.h
new file mode 100644 (file)
index 0000000..a59f946
--- /dev/null
@@ -0,0 +1,96 @@
+//-*- Mode: C++ -*-
+// $Id$
+
+//* This file is property of and copyright by the ALICE HLT Project           * 
+//* ALICE Experiment at CERN, All rights reserved.                            *
+//* See cxx source for full Copyright notice                                  *
+
+
+#ifndef ALIHLTTPCCATRACKPARAM_H
+#define ALIHLTTPCCATRACKPARAM_H
+
+#include "Rtypes.h"
+
+/**
+ * @class AliHLTTPCCATrackParam
+ *
+ * AliHLTTPCCATrackParam class describes the track parametrisation
+ * which is used by the AliHLTTPCCATracker slice tracker.
+ *
+ */
+class AliExternalTrackParam;
+
+class AliHLTTPCCATrackParam
+{
+ public:
+
+  AliHLTTPCCATrackParam(): fX(0),fCosPhi(1),fChi2(0), fNDF(0){}
+  //virtual ~AliHLTTPCCATrackParam(){}
+
+  Float_t &X()     { return fX;    }
+  Float_t &Y()     { return fP[0]; }
+  Float_t &Z()     { return fP[1]; }
+  Float_t &SinPhi(){ return fP[2]; }
+  Float_t &DzDs()  { return fP[3]; }
+  Float_t &Kappa() { return fP[4]; }
+  Float_t &CosPhi(){ return fCosPhi; }
+  Float_t &Chi2()  { return fChi2; }
+  Int_t   &NDF()   { return fNDF; }
+
+  Float_t &Err2Y()      { return fC[0]; }
+  Float_t &Err2Z()      { return fC[2]; }
+  Float_t &Err2SinPhi() { return fC[5]; }
+  Float_t &Err2DzDs()   { return fC[9]; }
+  Float_t &Err2Kappa()  { return fC[14]; }
+
+  Float_t GetX()      const { return fX; }
+  Float_t GetY()      const { return fP[0]; }
+  Float_t GetZ()      const { return fP[1]; }
+  Float_t GetSinPhi() const { return fP[2]; }
+  Float_t GetDzDs()   const { return fP[3]; }
+  Float_t GetKappa()  const { return fP[4]; }
+  Float_t GetCosPhi() const { return fCosPhi; }
+  Float_t GetChi2()   const { return fChi2; }
+  Int_t   GetNDF()    const { return fNDF; }
+
+  Float_t GetErr2Y()      const { return fC[0]; }
+  Float_t GetErr2Z()      const { return fC[2]; }
+  Float_t GetErr2SinPhi() const { return fC[5]; }
+  Float_t GetErr2DzDs()   const { return fC[9]; }
+  Float_t GetErr2Kappa()  const { return fC[14]; }
+
+  Float_t *Par(){ return fP; }
+  Float_t *Cov(){ return fC; }
+
+  void ConstructXY3( const Float_t x[3], const Float_t y[3], const Float_t sigmaY2[3], Float_t CosPhi0 );
+
+  void ConstructXYZ3( const Float_t p0[5], const Float_t p1[5], const Float_t p2[5], 
+                     Float_t CosPhi0, Float_t t0[]=0 );
+
+  Float_t GetS( Float_t x, Float_t y ) const;
+
+  void GetDCAPoint( Float_t x, Float_t y, Float_t z,
+                   Float_t &px, Float_t &py, Float_t &pz ) const;
+  
+  Bool_t TransportToX( Float_t X );
+  Bool_t Rotate( Float_t alpha );
+
+  void GetExtParam( AliExternalTrackParam &T, Double_t alpha, Double_t Bz ) const;
+  void SetExtParam( const AliExternalTrackParam &T, Double_t Bz );
+  void Filter( Float_t y, Float_t z, Float_t erry, Float_t errz );
+
+ private:
+
+  Float_t fX;      // x position
+  Float_t fCosPhi; // cosPhi
+  Float_t fP[5];   // 'active' track parameters: Y, Z, SinPhi, DzDs, Kappa
+  Float_t fC[15];  // the covariance matrix for Y,Z,SinPhi,..
+  Float_t fChi2;   // the chi^2 value
+  Int_t   fNDF;    // the Number of Degrees of Freedom
+
+  //ClassDef(AliHLTTPCCATrackParam, 0);
+
+};
+
+
+#endif
index 7e32f92a10c241914266d656cf3d96ee5a6ef44b..acc467682ef9456d4e789878bd7c3ffe134a30cf 100644 (file)
@@ -1,44 +1,48 @@
 // @(#) $Id$
-//*************************************************************************
-// This file is property of and copyright by the ALICE HLT Project        * 
-// ALICE Experiment at CERN, All rights reserved.                         *
-//                                                                        *
-// Primary Authors: Jochen Thaeder <thaeder@kip.uni-heidelberg.de>        *
-//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>              *
-//                  for The ALICE HLT Project.                            *
-//                                                                        *
-// Permission to use, copy, modify and distribute this software and its   *
-// documentation strictly for non-commercial purposes is hereby granted   *
-// without fee, provided that the above copyright notice appears in all   *
-// copies and that both the copyright notice and this permission notice   *
-// appear in the supporting documentation. The authors make no claims     *
-// about the suitability of this software for any purpose. It is          *
-// provided "as is" without express or implied warranty.                  *
-//*************************************************************************
+//***************************************************************************
+// This file is property of and copyright by the ALICE HLT Project          
+// ALICE Experiment at CERN, All rights reserved.                           *
+//                                                                          *
+// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
+//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
+//                  for The ALICE HLT Project.                              *
+//                                                                          *
+// Permission to use, copy, modify and distribute this software and its     *
+// documentation strictly for non-commercial purposes is hereby granted     *
+// without fee, provided that the above copyright notice appears in all     *
+// copies and that both the copyright notice and this permission notice     *
+// appear in the supporting documentation. The authors make no claims       *
+// about the suitability of this software for any purpose. It is            *
+// provided "as is" without express or implied warranty.                    *
+//***************************************************************************
 
 #include "AliHLTTPCCATracker.h"
 
 #include "AliHLTTPCCAHit.h"
 #include "AliHLTTPCCACell.h"
+#include "AliHLTTPCCAEndPoint.h"
 #include "AliHLTTPCCAOutTrack.h"
+#include "AliHLTTPCCAGrid.h"
+#include "AliHLTTPCCARow.h"
+#include "AliHLTTPCCATrack.h"
 
 #include "TMath.h"
-//#include "Riostream.h"
-#include <vector>
-#include <algorithm>
+#include "Riostream.h"
+//#include <algo.h>
 #include "TStopwatch.h"
+
 //#define DRAW
 
 #ifdef DRAW
-#include "AliHLTTPCCADisplay.h"
-#include "TApplication.h"
+  #include "AliHLTTPCCADisplay.h"
+  #include "TApplication.h"
 #endif //DRAW
 
 ClassImp(AliHLTTPCCATracker)
 
 
 AliHLTTPCCATracker::AliHLTTPCCATracker()
-  :fParam(),fRows(0),fOutTrackHits(0),fNOutTrackHits(0),fOutTracks(0),fNOutTracks(0),fTrackCells(0),fNHitsTotal(0),fTracks(0),fNTracks(0),fCellHitPointers(0)
+  :fParam(),fRows(0),fOutTrackHits(0),fNOutTrackHits(0),fOutTracks(0),fNOutTracks(0),fNHitsTotal(0),fTracks(0),fNTracks(0),fCellHitPointers(0),fCells(0),fEndPoints(0)
 {
   // constructor
   fRows = new AliHLTTPCCARow[fParam.NRows()];
@@ -46,7 +50,7 @@ AliHLTTPCCATracker::AliHLTTPCCATracker()
 }
 
 AliHLTTPCCATracker::AliHLTTPCCATracker( const AliHLTTPCCATracker& )
-  :fParam(),fRows(0),fOutTrackHits(0),fNOutTrackHits(0),fOutTracks(0),fNOutTracks(0),fTrackCells(0),fNHitsTotal(0),fTracks(0),fNTracks(0),fCellHitPointers(0)
+  :fParam(),fRows(0),fOutTrackHits(0),fNOutTrackHits(0),fOutTracks(0),fNOutTracks(0),fNHitsTotal(0),fTracks(0),fNTracks(0),fCellHitPointers(0),fCells(0),fEndPoints(0)
 {
   // dummy
 }
@@ -58,7 +62,6 @@ AliHLTTPCCATracker &AliHLTTPCCATracker::operator=( const AliHLTTPCCATracker& )
   fOutTrackHits=0;
   fOutTracks=0;
   fNOutTracks=0;
-  fTrackCells=0;
   return *this;
 }
 
@@ -79,8 +82,15 @@ void AliHLTTPCCATracker::Initialize( AliHLTTPCCAParam &param )
   fParam = param;
   fParam.Update();
   fRows = new AliHLTTPCCARow[fParam.NRows()];
+  Float_t xStep = 1;
+  Float_t deltaY = TMath::Tan(fParam.CellConnectionAngleXY());
+  Float_t deltaZ = TMath::Tan(fParam.CellConnectionAngleXZ());
   for( Int_t irow=0; irow<fParam.NRows(); irow++ ){
-    fRows[irow].X() = fParam.RowX(irow);
+    fRows[irow].X() = fParam.RowX(irow);        
+    if( irow < fParam.NRows()-1 ) xStep = fParam.RowX(irow+1) - fParam.RowX(irow);
+    fRows[irow].DeltaY() = xStep*deltaY;
+    fRows[irow].DeltaZ() = xStep*deltaZ;
+    fRows[irow].MaxY() = TMath::Tan( fParam.DAlpha()/2.)*fRows[irow].X();
   }
   StartEvent();
 }
@@ -88,15 +98,19 @@ void AliHLTTPCCATracker::Initialize( AliHLTTPCCAParam &param )
 void AliHLTTPCCATracker::StartEvent()
 {
   // start new event and fresh the memory  
-  delete[] fTracks;
-  delete[] fTrackCells;
-  delete[] fOutTrackHits;
-  delete[] fOutTracks;
-  delete[] fCellHitPointers;
+
+  if( fTracks ) delete[] fTracks;
+  if( fOutTrackHits ) delete[] fOutTrackHits;
+  if( fOutTracks ) delete[] fOutTracks;
+  if( fCellHitPointers ) delete[] fCellHitPointers;
+  if( fCells ) delete[] fCells;
+  if( fEndPoints ) delete[] fEndPoints;
   fTracks = 0;
-  fTrackCells = 0;
   fOutTrackHits = 0;
   fOutTracks = 0;
+  fCellHitPointers = 0;
+  fCells = 0;
+  fEndPoints = 0;
   fNTracks = 0;
   fNOutTrackHits = 0;
   fNOutTracks = 0;
@@ -123,456 +137,916 @@ void AliHLTTPCCATracker::ReadHitRow( Int_t iRow, AliHLTTPCCAHit *Row, Int_t NHit
 
 void AliHLTTPCCATracker::Reconstruct()
 {
-  // reconstruction of event
+  //* reconstruction of event
+
+#ifdef DRAW
+  if( !gApplication ){
+    TApplication *myapp = new TApplication("myapp",0,0);
+  }
+  //AliHLTTPCCADisplay::Instance().Init();
+  
+  AliHLTTPCCADisplay::Instance().SetCurrentSector( this );
+  AliHLTTPCCADisplay::Instance().SetSectorView();
+  AliHLTTPCCADisplay::Instance().DrawSector( this );  
+  for( Int_t iRow=0; iRow<fParam.NRows(); iRow++ )
+    for (Int_t i = 0; i<fRows[iRow].NHits(); i++) 
+      AliHLTTPCCADisplay::Instance().DrawHit( iRow, i );
+  AliHLTTPCCADisplay::Instance().Ask();
+#endif
+
+  //if( fParam.ISec()!=8 ) return;
+  //if( fParam.ISec()!=8 ) return;
+  //if( fParam.ISec()!=33 ) return;
+  //if( fParam.ISec()!=2 ) return;
   fTimers[0] = 0;
   fTimers[1] = 0;
   fTimers[2] = 0;
   fTimers[3] = 0;
+  fTimers[4] = 0;
+  fTimers[5] = 0;
+  fTimers[6] = 0;
+  if( fNHitsTotal < 1 ) return;
+
   //cout<<"Find Cells..."<<endl;
   FindCells();
+  //cout<<"Merge Cells..."<<endl;
+  MergeCells();
   //cout<<"Find Tracks..."<<endl;
-   FindTracks();
-   //cout<<"Find Tracks OK"<<endl;
+  FindTracks();
+  //cout<<"Find Tracks OK"<<endl;
  }
 
 
 void AliHLTTPCCATracker::FindCells()
 {
-  // cell finder - neighbouring hits are grouped to cells
+  //* cell finder - neighbouring hits are grouped to cells
 
   TStopwatch timer;
-  Bool_t *vUsed = new Bool_t [fNHitsTotal];
+
   fCellHitPointers = new Int_t [fNHitsTotal];
-  AliHLTTPCCACell *vCells = new AliHLTTPCCACell[fNHitsTotal]; 
+  fCells = new AliHLTTPCCACell[fNHitsTotal]; 
+  fEndPoints = new AliHLTTPCCAEndPoint[fNHitsTotal]; 
+  struct THitCont{
+    Float_t Ymin, Ymax, Zmin, Zmax;
+    Int_t binYmin, binYmax, binZmin, binZmax;
+    Bool_t used;
+    AliHLTTPCCAHit *h;
+    THitCont *next;
+  };
+  THitCont *hitCont = new THitCont[fNHitsTotal];    
 
   Int_t lastCellHitPointer = 0;
+  Int_t lastCell = 0;
+
   for( Int_t irow=0; irow<fParam.NRows(); irow++ ){
     AliHLTTPCCARow &row=fRows[irow];
     Int_t nHits = row.NHits();
+    //cout<<"row = "<<irow<<", x="<<row.X()<<endl;
     if( nHits<1 ) continue;
+    //cout<<nHits*sizeof(AliHLTTPCCAHit)/1024.<<endl;
+
+    Float_t deltaY = row.DeltaY();
+    Float_t deltaZ = row.DeltaZ();
+
+    Float_t yMin = 1.e20, zMin = 1.e20, yMax = -1.e20, zMax = -1.e20;
+    for (Int_t ih = 0; ih<nHits; ih++){    
+      AliHLTTPCCAHit &h  = row.Hits()[ih];    
+      if( yMin> h.Y() ) yMin = h.Y();
+      if( yMax< h.Y() ) yMax = h.Y();
+      if( zMin> h.Z() ) zMin = h.Z();
+      if( zMax< h.Z() ) zMax = h.Z();
+    }
+    AliHLTTPCCAGrid grid;
+    grid.Create( yMin, yMax, zMin, zMax, nHits );
+    //cout<<"row "<<irow<<", delta = "<<delta<<" :\n"<<endl;
+    for (Int_t ih = 0; ih<nHits; ih++){    
+      AliHLTTPCCAHit &h  = row.Hits()[ih];
+      THitCont &cont = hitCont[ih];
+      THitCont *&bin = * ((THitCont **) grid.GetNoCheck(h.Y(),h.Z()));
+      cont.h = &h;
+      cont.used = 0;
+      Float_t y = h.Y();
+      //cout<<"ih = "<<ih<<", y= "<<y<<endl;
+      Float_t dY = 3.5*h.ErrY() + deltaY;
+      cont.Ymin = y-dY;
+      cont.Ymax = y+dY;
+      Float_t z = h.Z();
+      Float_t dZ = 3.5*h.ErrZ() + deltaZ;
+      cont.Zmin = z-dZ;
+      cont.Zmax = z+dZ;
+      cont.binYmin = (Int_t ) ( (cont.Ymin-dY-grid.YMin())*grid.StepYInv() );
+      cont.binYmax = (Int_t ) ( (cont.Ymax+dY-grid.YMin())*grid.StepYInv() );
+      cont.binZmin = (Int_t ) ( (cont.Zmin-dZ-grid.ZMin())*grid.StepZInv() );
+      cont.binZmax = (Int_t ) ( (cont.Zmax+dZ-grid.ZMin())*grid.StepZInv() );
+      if( cont.binYmin<0 ) cont.binYmin = 0;
+      if( cont.binYmin>=grid.Ny() ) cont.binYmin = grid.Ny()-1;
+      if( cont.binYmax<0 ) cont.binYmax = 0;
+      if( cont.binYmax>=grid.Ny() ) cont.binYmax = grid.Ny()-1;
+      if( cont.binZmin<0 ) cont.binZmin = 0;
+      if( cont.binZmin>=grid.Nz() ) cont.binZmin = grid.Nz()-1;
+      if( cont.binZmax<0 ) cont.binZmax = 0;
+      if( cont.binZmax>=grid.Nz() ) cont.binZmax = grid.Nz()-1;
+      cont.next = bin;
+      bin = &cont;
+    }        
+
     row.CellHitPointers() = fCellHitPointers + lastCellHitPointer;
+    row.Cells() = fCells + lastCell;
     Int_t nPointers = 0;
     Int_t nCells = 0;
 
-    for (Int_t ih = 0; ih<nHits; ih++) vUsed[ih] = 0;
-    
+    //Int_t statMaxBins = 0;
+    //Int_t statMaxHits = 0;
     for (Int_t ih = 0; ih<nHits; ih++){    
-      if( vUsed[ih] ) continue;
+      THitCont &cont = hitCont[ih];
+      if( cont.used ) continue;
       // cell start
-      AliHLTTPCCACell &cell = vCells[nCells++];
+      AliHLTTPCCACell &cell = row.Cells()[nCells++];
       cell.FirstHitRef() = nPointers;
       cell.NHits() = 1;
-      cell.IDown() = -1;
-      cell.IUp() = -1;
-      cell.IUsed() = 0;
+      cell.Link() = -1;
+      cell.Status() = 0;
+      cell.TrackID() = -1;
       row.CellHitPointers()[nPointers++] = ih;
-      vUsed[ih] = 1;
-      Int_t jLast = ih;
-      while( jLast<nHits-1 ){
-       AliHLTTPCCAHit &h  = row.Hits()[jLast];    
-       Double_t d2min = 1.e10;
-       Int_t jBest = -1;
-       for (Int_t j = jLast+1; j<nHits; j++){    
-         if( vUsed[j] ) continue;
-         AliHLTTPCCAHit &h1  = row.Hits()[j];
-         Double_t dy = TMath::Abs(h.Y() - h1.Y() );
-         if( dy>(h.ErrY()+h1.ErrY())*3.5*2 ) break;
-         Double_t dz = TMath::Abs(h.Z() - h1.Z() );
-         if( dz>(h.ErrZ()+h1.ErrZ())*3.5*2 ) continue;
-         Double_t d2 = dz*dz+dy*dy;
-         if( d2<d2min ){
-           d2min = d2;
-           jBest = j;
+      cont.used = 1;      
+
+#ifdef DRAW
+      //AliHLTTPCCADisplay::Instance().DrawHit( irow, ih, kRed );
+#endif
+  // cell finder - neighbouring hits are grouped to cells
+
+      
+      Float_t ymin = cont.Ymin;
+      Float_t ymax = cont.Ymax;
+      Float_t zmin = cont.Zmin;
+      Float_t zmax = cont.Zmax;
+      Int_t binYmin = cont.binYmin;
+      Int_t binYmax = cont.binYmax;
+      Int_t binZmin = cont.binZmin;
+      Int_t binZmax = cont.binZmax;
+
+      Bool_t repeat = 1;
+      while( repeat ){
+       repeat = 0;
+       THitCont ** startY = (THitCont **) grid.Grid() + binZmin*grid.Ny();
+       //Float_t Ymax1 = Ymax;
+       //Float_t Ymin1 = Ymin;
+       //Float_t Zmax1 = Zmax;
+       //Float_t Zmin1 = Zmin;
+       Int_t binYmax1 = binYmax;
+       Int_t binYmin1 = binYmin;
+       Int_t binZmax1 = binZmax;
+       Int_t binZmin1 = binZmin;
+#ifdef DRAW
+       //cell.Y() = .5*(Ymin+Ymax);
+       //cell.Z() = .5*(Zmin+Zmax);
+       //cell.ErrY() = .5*( Ymax - Ymin )/3.5;
+       //cell.ErrZ() = .5*( Zmax - Zmin )/3.5;
+       //cell.YMin() = Ymin;
+       //cell.YMax() = Ymax;
+       //AliHLTTPCCADisplay::Instance().DrawCell( irow, nCells-1, 1,kRed );
+       //AliHLTTPCCADisplay::Instance().Ask();
+#endif
+       for( Int_t iGridZ=binZmin1; iGridZ<=binZmax1; iGridZ++, startY += grid.Ny() ){
+         for( Int_t iGridY=binYmin1; iGridY<=binYmax1; iGridY++ ){
+           for( THitCont *bin = *(startY + iGridY); bin; bin=bin->next ){
+             Int_t jh = bin->h-row.Hits();
+             THitCont &cont1 = hitCont[jh];
+             if( cont1.used ) continue;              
+             //cout<<"["<<Ymin<<","<<Ymax<<"]: ["<<cont1.Ymin<<","<<cont1.Ymax<<"]"<<endl;
+             if( cont1.Ymax < ymin ) continue; 
+             if( cont1.Ymin > ymax ) continue;
+             if( cont1.Zmax < zmin ) break;// in the grid cell hit Y is decreasing
+             if( cont1.Zmin > zmax ) continue;
+               
+             if( cont1.Ymin < ymin ){ ymin = cont1.Ymin; repeat = 1; }
+             if( cont1.Ymax > ymax ){ ymax = cont1.Ymax; repeat = 1; }
+             if( cont1.Zmin < zmin ){ zmin = cont1.Zmin; repeat = 1; }
+             if( cont1.Zmax > zmax ){ zmax = cont1.Zmax; repeat = 1; }
+             if( cont1.binYmin < binYmin ){ binYmin = cont1.binYmin; repeat = 1; }
+             if( cont1.binYmax > binYmax ){ binYmax = cont1.binYmax; repeat = 1; }
+             if( cont1.binZmin < binZmin ){ binZmin = cont1.binZmin; repeat = 1; }
+             if( cont1.binZmax > binZmax ){ binZmax = cont1.binZmax; repeat = 1; }
+               
+             row.CellHitPointers()[nPointers++] = jh;
+             cell.NHits()++;
+             cont1.used = 1;       
+#ifdef DRAW
+             //AliHLTTPCCADisplay::Instance().DrawHit( irow, jh, kRed );
+             //AliHLTTPCCADisplay::Instance().Ask();  
+#endif
+           }
          }
        }
-       if( jBest<0 ) break;
-       row.CellHitPointers()[nPointers++] = jBest;
-       cell.NHits()++;
-       vUsed[jBest] = 1;     
-       jLast = jBest;
       }
-
-      AliHLTTPCCAHit &h = row.GetCellHit(cell,0);
-      AliHLTTPCCAHit &h1= row.GetCellHit(cell,cell.NHits()-1);
-    
-      cell.Y() = .5*(h.Y() + h1.Y());
-      cell.Z() = .5*(h.Z() + h1.Z());
-      cell.ErrY() = .5*(TMath::Abs(h.Y() - h1.Y())/3 + h.ErrY() + h1.ErrY());
-      cell.ErrZ() = .5*(TMath::Abs(h.Z() - h1.Z())/3 + h.ErrZ() + h1.ErrZ());
+      
+      cell.Y() = .5*(ymin+ymax);
+      cell.Z() = .5*(zmin+zmax);
+      cell.ErrY() = .5*( ymax - ymin - 2*deltaY)/3.5;
+      cell.ErrZ() = .5*( zmax - zmin -2*deltaZ)/3.5;
+      cell.ZMin() = zmin;
+      cell.ZMax() = zmax;
+#ifdef DRAW
+      //AliHLTTPCCADisplay::Instance().DrawCell( irow, nCells-1 );
+      //AliHLTTPCCADisplay::Instance().Ask();  
+#endif
     }
+    //cout<<statMaxBins<<"/"<<grid.N()<<" "<<statMaxHits<<"/"<<nHits<<endl;
+
     
-    row.Cells() = new AliHLTTPCCACell[nCells];
     row.NCells() = nCells;
     lastCellHitPointer += nPointers;
-    for( Int_t i=0; i<nCells; i++ ) row.Cells()[i]=vCells[i];  
+    lastCell += nCells;
   }
-  delete[] vUsed;
-  delete[] vCells;
+  delete[] hitCont;
   timer.Stop();
   fTimers[0] = timer.CpuTime();
 }
 
 
-void AliHLTTPCCATracker::FindTracks()
+void AliHLTTPCCATracker::MergeCells()
 {
-  // the Cellular Automaton track finder
+  // First step: 
+  //  for each Cell find one neighbour in the next row (irow+1)
+  //  when there are no neighbours, look to the rows (irow+2),(irow+3)
+  //
+  // Initial state: 
+  //  cell.Link  =-1
+  //  cell.Link1  =-1
+  //  cell.Track      =-1
+  //
+  // Intermediate state: same as final
+  //
+  // Final state:
+  //  cell.Link = Neighbour ID, if there is a neighbour 
+  //             = -1, if no neighbours found
+  //             = -2, if there was more than one neighbour
+  //  cell.Link1 = ID of the cell which has this Cell as a forward neighbour
+  //             = -1 there are no backward neighbours
+  //             = -2 there are more than one neighbour
+  //  cell.Track = -1
+  //
+
+  TStopwatch timer1;
+
+  Int_t nStartCells = 0;
+  for( Int_t iRow1=0; iRow1<fParam.NRows(); iRow1++ ){
+    AliHLTTPCCARow &row1 = fRows[iRow1];
+      
+    Float_t deltaY = row1.DeltaY();
+    Float_t deltaZ = row1.DeltaZ();
+
+    Int_t lastRow2 = iRow1+3;
+    if( lastRow2>=fParam.NRows() ) lastRow2 = fParam.NRows()-1;
+
+    for (Int_t i1 = 0; i1<row1.NCells(); i1++){
+      AliHLTTPCCACell &c1  = row1.Cells()[i1];
+      //cout<<"row, cell= "<<iRow1<<" "<<i1<<" "<<c1.Y()<<" "<<c1.ErrY()<<" "<<c1.Z()<<" "<<c1.ErrZ()<<endl;
+      //Float_t sy1 = c1.ErrY()*c1.ErrY();
+      Float_t yMin = c1.Y() - 3.5*c1.ErrY() - deltaY;
+      Float_t yMax = c1.Y() + 3.5*c1.ErrY() + deltaY;
+      Float_t zMin = c1.Z() - 3.5*c1.ErrZ() - deltaZ;
+      Float_t zMax = c1.Z() + 3.5*c1.ErrZ() + deltaZ;
+      //Float_t sz1 = c1.ErrZ()*c1.ErrZ();
+      if( c1.Status()<=0 ) nStartCells++;
+
+      // looking for neighbour for the Cell c1
+      Bool_t found = 0;
+      for( Int_t iRow2=iRow1+1; iRow2<=lastRow2&&(!found); iRow2++ ){
+       AliHLTTPCCARow &row2 = fRows[iRow2];
+       AliHLTTPCCACell *cc2 = lower_bound(row2.Cells(),row2.Cells()+row2.NCells(),zMin,AliHLTTPCCARow::CompareCellZMax);
+       for (Int_t i2 = (cc2 - row2.Cells()); i2<row2.NCells(); i2++){
+         //cout<<"   candidat = "<<iRow2<<" "<<i2<<endl;
+         
+         AliHLTTPCCACell &c2  = row2.Cells()[i2];
+         Float_t y2Min = c2.Y() - 3.5*c2.ErrY();
+         Float_t y2Max = c2.Y() + 3.5*c2.ErrY();
+         Float_t z2Min = c2.Z() - 3.5*c2.ErrZ();
+         Float_t z2Max = c2.Z() + 3.5*c2.ErrZ();
+
+         if( y2Min > yMax ) continue;
+         if( y2Max < yMin ) continue;
+         if( z2Min > zMax ) break;
+         if( z2Max < zMin ) continue;
+
+         // c1 & c2 are neighbours
+
+         found = 1;
+         
+         if( c1.Link() ==-1 && c2.Status()==0 ){ 
+           // one-to-one connection - OK
+           c1.Link() = IRowICell2ID(iRow2,i2);
+           c2.Status() = 1;
+         }else{
+           // multi-connection - break all links
+           if( c1.Link()>=0 ) ID2Cell(c1.Link()).Status() = -1;            
+           c1.Link()  = -2;
+           c2.Status() = -1;
+         }
+       }
+      }//row2
+    }
+  }//row1
+
+  timer1.Stop();
+  fTimers[1] = timer1.CpuTime();
   
-  if( fNHitsTotal < 1 ) return;
+  // Second step: create tracks 
+  //  for each sequence of neighbouring Cells create Track object
+  //
+  // Final state:
+  //  cell.Track     = TrackNumber for first and last track cell
+  //                 = -1 for other cells
+  //  cell.Link     = Neighbour ID, if there is a neighbour 
+  //                 = -1, if no neighbour (last cell on the track )
+  //  cell.Link1     = backward neighbour ID, if there is a neighbour 
+  //                 = -1 for first and last track cells
+  
+  TStopwatch timer2;
+  
+  fTracks = new AliHLTTPCCATrack[nStartCells];
+  fNTracks = 0;
+
+  for( Int_t iRow=0; iRow<fParam.NRows(); iRow++ ){
+    AliHLTTPCCARow &row = fRows[iRow];
+    for( Int_t iCell = 0; iCell<row.NCells(); iCell++){ 
+      AliHLTTPCCACell &c  = row.Cells()[iCell];
+      if( c.Status()>0 ) continue; // not a starting cell
+
+      Int_t firstID = IRowICell2ID( iRow, iCell );
+      Int_t midID = firstID;
+      Int_t lastID = firstID;
+
+      AliHLTTPCCATrack &track = fTracks[fNTracks];
+      track.Alive() = 1;
+      track.NCells() = 1;
+      AliHLTTPCCACell *last = &c;
+      while( last->Link() >=0 ){
+       Int_t nextID = last->Link();
+       AliHLTTPCCACell *next = & ID2Cell(nextID);
+       if(next->Status()!=1 ){
+         last->Link() = -1;
+         break;
+       }       
+       track.NCells()++;
+       last = next;
+       lastID = nextID;
+      }
+      Int_t nCells05 = (track.NCells()-1)/2;
+      for( Int_t i=0; i<nCells05; i++ ) midID = ID2Cell(midID).Link();
+      //cout<<fNTracks<<", NCells="<<track.NCells()<<" "<<nCells05<<"id="<<firstID<<" "<<midID<<" "<<lastID<<endl;
+      c.TrackID() = fNTracks;
+      last->TrackID() = fNTracks;
+      track.FirstCellID() = firstID;
+      track.CellID()[0] = firstID;
+      track.CellID()[1] = midID;
+      track.CellID()[2] = lastID;
+      track.PointID()[0] = -1;
+      track.PointID()[1] = -1;
+      //cout<<"Track N "<<fNTracks<<", NCells="<<track.NCells()<<endl;
+
+      fNTracks++;
+    }
+  }
+  if( fNTracks != nStartCells ){
+    //cout<<"fNTracks="<<fNTracks<<", NStrartCells="<<nStartCells<<endl;
+    //exit(0);
+    return;
+  }
+
+  // create endpoints 
+
+  Int_t nEndPointsTotal = 0;
+  for( Int_t iRow=0; iRow<fParam.NRows(); iRow++ ){
+    AliHLTTPCCARow &row = fRows[iRow];
+    row.EndPoints()= fEndPoints + nEndPointsTotal;
+    row.NEndPoints()=0;
+    for( Int_t iCell = 0; iCell<row.NCells(); iCell++){ 
+      AliHLTTPCCACell &c  = row.Cells()[iCell];
+      if( c.TrackID()< 0 ) continue; // not an endpoint
+      AliHLTTPCCAEndPoint &p = row.EndPoints()[row.NEndPoints()];
+      p.CellID() = IRowICell2ID(iRow,iCell);
+      p.TrackID() = c.TrackID();
+      p.Link() = -1;
+      AliHLTTPCCATrack &track = fTracks[c.TrackID()];
+      if( c.Link()>=0 ){
+       track.PointID()[0] = IRowICell2ID(iRow,row.NEndPoints());
+      }else{
+       track.PointID()[1] = IRowICell2ID(iRow,row.NEndPoints());
+       if( track.PointID()[0]<0 )track.PointID()[0] = track.PointID()[1];
+      }
+      row.NEndPoints()++;
+    }
+    nEndPointsTotal += row.NEndPoints();
+  }
+  timer2.Stop();
+  fTimers[2] = timer2.CpuTime();
+}
+
+void AliHLTTPCCATracker::FindTracks()
+{
+  // the Cellular Automaton track finder  
+  TStopwatch timer3;
+  //cout<<"combine & fit tracks"<<endl;
+  for( Int_t itr=0; itr<fNTracks; itr++ ){
+    AliHLTTPCCATrack &iTrack = fTracks[itr];
+    //if( iTrack.NCells()<3 ) continue;
+    //cout<<" fit track "<<itr<<", NCells="<<iTrack.NCells()<<endl;    
+    ID2Point(iTrack.PointID()[0]).Param().CosPhi() = -1;//[2] = -TMath::Pi();
+    ID2Point(iTrack.PointID()[1]).Param().CosPhi() = 1;//[2] = 0;   
+    FitTrack( iTrack );
+    //if( iTrack.Param().Chi2() > fParam.TrackChi2Cut()*iTrack.Param().NDF() ){
+      //iTrack.Alive() = 0;
+    //}
+  }
+  timer3.Stop();
+  fTimers[3] = timer3.CpuTime();
 
 #ifdef DRAW
   if( !gApplication ){
     TApplication *myapp = new TApplication("myapp",0,0);
   }    
   //AliHLTTPCCADisplay::Instance().Init();
+  
   AliHLTTPCCADisplay::Instance().SetCurrentSector( this );
   AliHLTTPCCADisplay::Instance().DrawSector( this );
+  cout<<"draw hits..."<<endl;
   for( Int_t iRow=0; iRow<fParam.NRows(); iRow++ )
     for (Int_t i = 0; i<fRows[iRow].NHits(); i++) 
       AliHLTTPCCADisplay::Instance().DrawHit( iRow, i );
-  cout<<"hits"<<endl;
   AliHLTTPCCADisplay::Instance().Ask();
-  AliHLTTPCCADisplay::Instance().Clear();
-  AliHLTTPCCADisplay::Instance().DrawSector( this );
+  //AliHLTTPCCADisplay::Instance().Clear();
+  //AliHLTTPCCADisplay::Instance().DrawSector( this );
+  cout<<"draw cells..."<<endl;
   for( Int_t iRow=0; iRow<fParam.NRows(); iRow++ )
     for (Int_t i = 0; i<fRows[iRow].NCells(); i++) 
       AliHLTTPCCADisplay::Instance().DrawCell( iRow, i );
-  cout<<"cells"<<endl;
   AliHLTTPCCADisplay::Instance().Ask();  
-  Int_t nConnectedCells = 0;
-#endif 
 
-  std::vector<AliHLTTPCCATrack> vTracks; 
-  std::vector<Int_t> vTrackCells; 
-  fTrackCells = new Int_t[2*fNHitsTotal];
+  Int_t nConnectedCells = 0;
 
-  TStopwatch timer1;
-  Double_t factor2 = 3.5*fParam.CellConnectionFactor()*3.5*fParam.CellConnectionFactor();
+  cout<<"draw merged cells..."<<endl;
 
-  for( Int_t iRow1=0; iRow1<fParam.NRows()-1; iRow1++ ){
-    AliHLTTPCCARow &row1 = fRows[iRow1];
-    Int_t lastRow2 = iRow1+3;
-    if( lastRow2>=fParam.NRows() ) lastRow2 = fParam.NRows()-1;    
-    for( Int_t iRow2=iRow1+1; iRow2<=lastRow2; iRow2++ ){
-      AliHLTTPCCARow &row2 = fRows[iRow2];
-      for (Int_t i1 = 0; i1<row1.NCells(); i1++){
-       AliHLTTPCCACell *c1  = &(row1.Cells()[i1]);
-       if( c1->IUp()>=0 ) continue;
-       Double_t sy1 = c1->ErrY()*c1->ErrY();
-       Double_t sz1 = c1->ErrZ()*c1->ErrZ();
-       for (Int_t i2 = 0; i2<row2.NCells(); i2++){
-         AliHLTTPCCACell *c2  = &(row2.Cells()[i2]);
-         Double_t sy2 = c2->ErrY()*c2->ErrY();
-         Double_t dy = c1->Y()-c2->Y();
-         if( dy*dy>factor2*(sy1+sy2) ){
-           if( dy>0 ) continue;
-           else break;
-         }
-         Double_t sz2 = c2->ErrZ()*c2->ErrZ();
-         Double_t dz = c1->Z()-c2->Z();
-         if( dz*dz>factor2*(sz1+sz2) ) continue;
-         if( c1->IUp() ==-1 ) c1->IUp() = (i2<<8)+iRow2;
-         else c1->IUp() = -2;
-         if( c2->IDown() ==-1 ) c2->IDown() = (i1<<8)+iRow1;
-         else c2->IDown() = -2;
-       }
+  for( Int_t iRow=0; iRow<fParam.NRows(); iRow++ )
+    for (Int_t i = 0; i<fRows[iRow].NCells(); i++) 
+      {
+       AliHLTTPCCACell &c = fRows[iRow].Cells()[i];
+       Int_t id = c.Link();
+       if( id<0 ) continue;    
+       AliHLTTPCCADisplay::Instance().ConnectCells( iRow,c,ID2IRow(id),ID2Cell(id) );
+       nConnectedCells++;
       }
-    }
+  if( nConnectedCells>0 ){
+    AliHLTTPCCADisplay::Instance().Ask();  
   }
 
-  timer1.Stop();
-  fTimers[1] = timer1.CpuTime();
-
-  TStopwatch timer2;
+  
+  AliHLTTPCCADisplay::Instance().Clear();
+  AliHLTTPCCADisplay::Instance().DrawSector( this );
+  for( Int_t iRow=0; iRow<fParam.NRows(); iRow++ )
+    for (Int_t i = 0; i<fRows[iRow].NCells(); i++) 
+      AliHLTTPCCADisplay::Instance().DrawCell( iRow, i );  
 
-  Int_t nOutTrackHits = 0;
-  Int_t nTrackCells = 0;
-  for( Int_t iRow1=0; iRow1<fParam.NRows(); iRow1++ ){
-    AliHLTTPCCARow &row1 = fRows[iRow1];    
-    for (Int_t i1 = 0; i1<row1.NCells(); i1++){ 
-      AliHLTTPCCACell *c1  = &(row1.Cells()[i1]);
-      //if( c1->IDown()==-2 || c1->IUp()==-2 ) continue;
-      if( c1->IUsed()>0 ) continue;
-      c1->IUsed() = 1;
-      AliHLTTPCCATrack track;
-      track.Used() = 0;
-      track.NCells() = 1;
-      track.IFirstCell() = nTrackCells;
-      fTrackCells[nTrackCells++] = (i1<<8)+iRow1;
-      AliHLTTPCCACell *last = c1;
-      Int_t lastRow = iRow1;
-      while( last->IUp() >=0 ){
-       Int_t iRow2 = last->IUp()%256;
-       AliHLTTPCCARow &row2 = fRows[iRow2];
-       AliHLTTPCCACell *next = &(row2.Cells()[last->IUp()>>8]);
-       if( next->IDown()==-2 || next->IUp()==-2 ) break;
-#ifdef DRAW
-       AliHLTTPCCADisplay::Instance().ConnectCells( lastRow,*last,iRow2,*next );
-       nConnectedCells++;
+  cout<<"draw initial tracks"<<endl;
+  
+  for( Int_t itr=0; itr<fNTracks; itr++ ){
+    //if( itr!=58 ) continue;
+    AliHLTTPCCATrack &iTrack = fTracks[itr];
+    if( iTrack.NCells()<3 ) continue;
+    if( !iTrack.Alive() ) continue;    
+    AliHLTTPCCADisplay::Instance().DrawTrack1( iTrack );
+  }
+  //if( fNTracks>0 ) 
+  AliHLTTPCCADisplay::Instance().Ask();
 #endif 
-       next->IUsed() = 1;      
-       fTrackCells[nTrackCells++] = last->IUp();
-       track.NCells()++;
-       last = next;
-       lastRow = iRow2;
-      } 
-      vTracks.push_back(track);
+
+  TStopwatch timer4;
+
+  Bool_t doMerging=1;
+  
+  Float_t factor2 = fParam.TrackConnectionFactor()*fParam.TrackConnectionFactor();
+  Int_t *refEndPoints = new Int_t[fNHitsTotal];
+  Int_t nRefEndPoints = 0;
+  for( Int_t iRow=0; iRow<fParam.NRows(); iRow++ ){
+    AliHLTTPCCARow &irow = fRows[iRow];
+    for (Int_t iPoint = 0; iPoint<irow.NEndPoints(); iPoint++){ 
+      refEndPoints[nRefEndPoints++] = IRowICell2ID(iRow,iPoint);
     }
   }
+  bool first = 1;
+  while( doMerging ){
 
-  timer2.Stop();
-  fTimers[2] = timer2.CpuTime();
-  
-  Int_t nTracks = vTracks.size();
-  std::sort( vTracks.begin(), vTracks.end(), AliHLTTPCCATrack::CompareSize);
+    //cout<<"do merging"<<endl;
+    
+    doMerging = 0;
 
-#ifdef DRAW
-  if( nConnectedCells>0 ) AliHLTTPCCADisplay::Instance().Ask();  
-#endif 
+    // find nejghbouring tracks
+    TStopwatch timer5;
+    //cout<<"nRefEndPoints = "<<nRefEndPoints<<endl;
 
-  
-  fTracks = new AliHLTTPCCATrack[nTracks];
-  fNTracks = 0;
-  vTrackCells.clear();
-  Int_t *vMatchedTracks = new Int_t[nTracks];
+    for( Int_t iRef=0; iRef<nRefEndPoints; iRef++ ){
+      Int_t iRow = ID2IRow(refEndPoints[iRef]);
+      AliHLTTPCCARow &irow = fRows[iRow];
+      Int_t iPoint = ID2ICell(refEndPoints[iRef]);      
+      AliHLTTPCCAEndPoint &ip  = irow.EndPoints()[iPoint];
+      if( ip.TrackID()<0 ) continue; // not active endpoint
 
-  //cout<<"nTracks = "<<nTracks<<endl;
-  TStopwatch timer3;
-  
-  for( Int_t itr=0; itr<nTracks; itr++ ){
-    AliHLTTPCCATrack &iTrack = vTracks[itr];
-    if( iTrack.NCells()<3 ) break;
+      AliHLTTPCCATrack &iTrack = fTracks[ip.TrackID()];
+      if( iTrack.NCells()<3 ) continue;
+      
+      Int_t jRowMin = iRow - fParam.MaxTrackMatchDRow();
+      Int_t jRowMax = iRow + fParam.MaxTrackMatchDRow();
+      if( jRowMin<0 ) jRowMin = 0;
+      if( jRowMax>=fParam.NRows() ) jRowMax = fParam.NRows()-1;
+
+      if( ip.Param().CosPhi()>=0 ){ //TMath::Abs([2])<TMath::Pi()/2. ){
+       jRowMin = iRow;
+      }else{
+       jRowMax = iRow;
+      }
 
+      Int_t bestNeighbourN = -1;
+      Float_t bestDist2 = 1.e20;
+      Int_t bestLink = -1;
+      if( ip.Link()>=0 ){ 
+       bestNeighbourN = fTracks[ID2Point(ip.Link()).TrackID()].NCells();
+      }
+      
+      Float_t y0 = ip.Param().GetY();
+      Float_t z0 = ip.Param().GetZ();
+
+ #ifdef DRAW      
+      //AliHLTTPCCADisplay::Instance().DrawTrackletPoint(ip.Param(),kBlue);
+      //AliHLTTPCCADisplay::Instance().Ask();
+#endif
+     
+      for( Int_t jRow = jRowMin; jRow<=jRowMax; jRow++){
+       AliHLTTPCCARow &jrow = fRows[jRow];
+       Float_t dx2 = (irow.X()-jrow.X())*(irow.X()-jrow.X());
+
+       // extrapolate the track to row jRow
+
+       //for( int ii=0; ii<10; ii++){
+       //AliHLTTPCCATrackParam iPar = ip.Param();
+       //iPar.TransportToX( jrow.X());
+       //}
+       AliHLTTPCCATrackParam iPar = ip.Param();
+       Bool_t ok = iPar.TransportToX( jrow.X());
+       if( !ok ) continue;
 #ifdef DRAW
-    FitTrack( iTrack );
-    //AliHLTTPCCADisplay::Instance().Ask();
-    AliHLTTPCCADisplay::Instance().DrawTrack( iTrack );
-    //AliHLTTPCCADisplay::Instance().Ask();
-#endif 
-    if( iTrack.Used() ) continue;    
-    
-   
-    FitTrack( iTrack, 1 );
-    if( iTrack.Param().Chi2() > fParam.TrackChi2Cut()*iTrack.Param().NDF() ) continue;
-
-    Int_t iFirstRow =  GetTrackCellIRow( iTrack, 0);
-    Int_t iLastRow  =  GetTrackCellIRow( iTrack, iTrack.NCells()-1);
-    AliHLTTPCCACell *iFirstCell = &GetTrackCell( iTrack, 0);
-    AliHLTTPCCACell *iLastCell = &GetTrackCell( iTrack, iTrack.NCells()-1);   
-    Bool_t updated = 1;
-    Int_t nMatched = 0;
-    std::vector<Int_t> vMatchedCellsFront;
-    std::vector<Int_t> vMatchedCellsBack;
-    while( updated ){
-      updated = 0;
-      for( Int_t jtr=itr+1; jtr<nTracks; jtr++ ){
-       AliHLTTPCCATrack &jTrack = vTracks[jtr];
-       if( jTrack.Used() ) continue;
-       Int_t jFirstRow =  GetTrackCellIRow( jTrack, 0);
-       Int_t jLastRow =  GetTrackCellIRow( jTrack, jTrack.NCells()-1);
-       AliHLTTPCCACell *jFirstCell = &GetTrackCell( jTrack, 0);
-       AliHLTTPCCACell *jLastCell = &GetTrackCell( jTrack, jTrack.NCells()-1);
-
-       Int_t dFirstRow1 = TMath::Abs(iFirstRow-jLastRow);
-       Int_t dFirstRow2 = TMath::Abs(iFirstRow-jFirstRow);
-       Int_t dLastRow1 = TMath::Abs(iLastRow-jLastRow);
-       Int_t dLastRow2 = TMath::Abs(iLastRow-jFirstRow);
-       if( dFirstRow1 > fParam.MaxTrackMatchDRow() && 
-           dFirstRow2 > fParam.MaxTrackMatchDRow() &&
-           dLastRow1  > fParam.MaxTrackMatchDRow() && 
-           dLastRow2  > fParam.MaxTrackMatchDRow()    ) continue;
-       Int_t iCase=0;
-       AliHLTTPCCACell *iC, *jC;
-       if( dFirstRow1<dFirstRow2 && dFirstRow1<dLastRow1 && dFirstRow1<dLastRow2 ){
-         iCase = 0;
-         iC = iFirstCell;
-         jC = jLastCell;
-       }else if( dFirstRow2<dLastRow1 && dFirstRow2<dLastRow2 ){
-         iCase = 1;
-         iC = iFirstCell;
-         jC = jFirstCell;
-       }else if( dLastRow1<dLastRow2 ){
-         iCase = 2;
-         iC = iLastCell; 
-         jC = jLastCell;
-       }else{
-         iCase = 3;
-         iC = iLastCell; 
-         jC = jFirstCell;
-       }
-       {
-         Double_t dy = TMath::Abs(iC->Y() - jC->Y());
-         Double_t dz = TMath::Abs(iC->Z() - jC->Z());
-         Double_t sy1 = iC->ErrY()*iC->ErrY();
-         Double_t sz1 = iC->ErrZ()*iC->ErrZ();
-         Double_t sy2 = jC->ErrY()*jC->ErrY();
-         Double_t sz2 = jC->ErrZ()*jC->ErrZ();
-         Double_t dist1 = sqrt( (dy*dy)/(sy1+sy2) );
-         Double_t dist2 = sqrt( (dz*dz)/(sz1+sz2) );
-         if( dist1>3.5*fParam.TrackConnectionFactor() ) continue;
-         if( dist2>3.5*fParam.TrackConnectionFactor() ) continue;
-       }
-       AliHLTTPCCATrackPar t = iTrack.Param();
-       //t.Chi2() = 0;
-       //t.NDF() = 0;
-       for( Int_t i=0; i<jTrack.NCells() ; i++){
-         AliHLTTPCCACell &c = GetTrackCell(jTrack,i);  
-         AliHLTTPCCARow &row = GetTrackCellRow(jTrack,i);
-         for( Int_t j=0; j<c.NHits(); j++){
-           AliHLTTPCCAHit &h = row.GetCellHit(c,j);
-           Double_t m[3] = {row.X(), h.Y(), h.Z() };
-           Double_t mV[6] = {fParam.ErrX()*fParam.ErrX(), 0, h.ErrY()*h.ErrY(), 0, 0, h.ErrZ()*h.ErrZ() };
-           Double_t mV1[6];
-           t.TransportBz(fParam.Bz(),m);
-           t.GetConnectionMatrix(fParam.Bz(),m, mV1);
-           t.Filter(m, mV, mV1);
-         }
-       }
-       if( t.Chi2() > fParam.TrackChi2Cut()*t.NDF() ) continue;
-       if( iCase==0 ){
-         iFirstRow = jFirstRow;
-         iFirstCell = jFirstCell;
-         for( Int_t i=jTrack.NCells()-1; i>=0; i-- ){
-           vMatchedCellsBack.push_back(fTrackCells[jTrack.IFirstCell()+i]);
-         }
-       }else if( iCase ==1 ){
-         iFirstRow = jLastRow;
-         iFirstCell = jLastCell;
-         for( Int_t i=0; i<jTrack.NCells(); i++){
-           vMatchedCellsBack.push_back(fTrackCells[jTrack.IFirstCell()+i]);
+       //AliHLTTPCCADisplay::Instance().DrawTrackletPoint(iPar, kBlack);
+       //AliHLTTPCCADisplay::Instance().Ask();
+#endif
+       Float_t zMin = iPar.GetZ() - 3.5*TMath::Sqrt(iPar.GetErr2Z()) - .2*3.5;
+       AliHLTTPCCAEndPoint *jjp = lower_bound(jrow.EndPoints(),jrow.EndPoints()+jrow.NEndPoints(),zMin,AliHLTTPCCARow::CompareEndPointZ);
+       
+       for (Int_t jPoint = jjp-jrow.EndPoints(); jPoint<jrow.NEndPoints(); jPoint++){ 
+
+         AliHLTTPCCAEndPoint &jp  = jrow.EndPoints()[jPoint];
+         
+         if( jp.TrackID()<0 ) continue; // endpoint not active
+         if( jp.TrackID()==ip.TrackID() ) continue; // same track
+         
+         AliHLTTPCCATrack &jTrack = fTracks[jp.TrackID()];
+         
+         if( bestNeighbourN > jTrack.NCells() ){
+           continue; // there is already better neighbour found
          }
-       }else if( iCase == 2 ){
-         iLastRow = jFirstRow;
-         iLastCell = jFirstCell;
-         for( Int_t i=jTrack.NCells()-1; i>=0; i-- ){
-           vMatchedCellsFront.push_back(fTrackCells[jTrack.IFirstCell()+i]);
+         if( jp.Link()>=0 &&
+             fTracks[ID2Point(jp.Link()).TrackID()].NCells()>=iTrack.NCells() ){
+           continue; // jTrack is already linked to a better track or to iTrack
          }
-       }else{
-         iLastRow = jLastRow;
-         iLastCell = jLastCell;
-         for( Int_t i=0; i<jTrack.NCells(); i++){
-           vMatchedCellsFront.push_back(fTrackCells[jTrack.IFirstCell()+i]);
+
+         Float_t dy2, dz2;
+         AliHLTTPCCATrackParam &jPar = jp.Param();
+         
+         // check for neighbouring
+         {
+           float d = jPar.GetY() - iPar.GetY();
+           float s2 = jPar.GetErr2Y() + iPar.GetErr2Y();
+           if( d*d>factor2*s2 ){
+             continue;
+           }
+           d = jPar.GetZ() - iPar.GetZ();
+           s2 = jPar.GetErr2Z() + iPar.GetErr2Z();
+           if( d*d>factor2*s2 ){
+             if( d>0 ) break;
+             continue;
+           }
+           if( iTrack.NCells()>=3 && jTrack.NCells()>=3 ){
+             d = jPar.GetSinPhi() + iPar.GetSinPhi(); //! phi sign is different
+             s2 = jPar.GetErr2SinPhi() + iPar.GetErr2SinPhi();
+             if( d*d>factor2*s2 ) continue;
+             d = jPar.GetKappa() + iPar.GetKappa(); // ! kappa sign iz different
+             s2 = jPar.GetErr2Kappa() + iPar.GetErr2Kappa();
+             if( d*d>factor2*s2 ) continue;
+             d = jPar.GetDzDs() + iPar.GetDzDs(); // ! DzDs sign iz different
+             s2 = jPar.GetErr2DzDs() + iPar.GetErr2DzDs();
+             if( d*d>factor2*s2 ) continue;
+           }
          }
+         
+         Float_t dy = jPar.GetY() - y0;
+         dy2 = dy*dy;
+         Float_t dz = jPar.GetZ() - z0;
+         dz2 = dz*dz;
+         Float_t dist2 = dx2+dy2+dz2;
+
+         if( ( bestNeighbourN == jTrack.NCells() ) && dist2>bestDist2 ) continue;
+         
+         // tracks can be matched
+         
+         bestLink = IRowICell2ID( jRow, jPoint );
+         bestNeighbourN = jTrack.NCells();
+         bestDist2 = dist2;
        }
-       t.Normalize();
-
-       //t.NDF()+= iTrack.Param().NDF();
-       //t.Chi2()+= iTrack.Param().Chi2();
-       iTrack.Param() = t;
-       vMatchedTracks[nMatched++] = jtr;
-       jTrack.Used()=1;
-       updated = 1;
-       break;
       }
-    }// while updated
-
-    if(0){
-      Double_t t0[7];
-      for( Int_t i=0; i<7; i++ ) t0[i] = iTrack.Param().Par()[i];
-      iTrack.Param().Init();
-      for( Int_t i=0; i<7; i++ ) iTrack.Param().Par()[i] = t0[i];
-      for( Int_t i=0; i<iTrack.NCells() ; i++){
-       AliHLTTPCCACell &c = GetTrackCell( iTrack, i);
-       AliHLTTPCCARow &row = GetTrackCellRow( iTrack, i);
-       for( Int_t j=0; j<c.NHits(); j++){
-         AliHLTTPCCAHit &h = row.GetCellHit(c,j);
-         Double_t m[3] = {row.X(), h.Y(), h.Z() };
-         Double_t mV[6] = {0, 0, h.ErrY()*h.ErrY(), 0, 0, h.ErrZ()*h.ErrZ() };
-         Double_t mV1[6];
-         iTrack.Param().TransportBz(fParam.Bz(), m, t0);
-         iTrack.Param().GetConnectionMatrix(fParam.Bz(), m, mV1, t0);
-         iTrack.Param().Filter(m, mV, mV1);
-       }
+               
+      if( bestLink < 0 ) continue; // no neighbours found
+
+      AliHLTTPCCAEndPoint &jp = ID2Point(bestLink);
+      
+      if( ip.Link()>=0 ){ // break existing link of iTrack
+       ID2Point(ip.Link()).Link() = -1;
       }
-      iTrack.Param().Normalize();
-    }
-    //FitTrack(iTrack,5);
-    Int_t nHits = 0;
-    for( Int_t iCell=0; iCell<iTrack.NCells(); iCell++){
-      Int_t ind = fTrackCells[iTrack.IFirstCell()+iCell];
-      AliHLTTPCCARow &row = fRows[ind%256];
-      AliHLTTPCCACell &c = row.Cells()[ind>>8];
-      nHits+=c.NHits();
-    }
-    for( UInt_t i=0; i<vMatchedCellsBack.size(); i++){
-      Int_t ind = vMatchedCellsBack[i];
-      AliHLTTPCCARow &row = fRows[ind%256];
-      AliHLTTPCCACell &c = row.Cells()[ind>>8];
-      nHits+=c.NHits();
-    }
-    for( UInt_t i=0; i<vMatchedCellsFront.size(); i++){
-      Int_t ind = vMatchedCellsFront[i];
-      AliHLTTPCCARow &row = fRows[ind%256];
-      AliHLTTPCCACell &c = row.Cells()[ind>>8];
-      nHits+=c.NHits();
-    }
-    Int_t nCells = iTrack.NCells()+vMatchedCellsBack.size()+vMatchedCellsFront.size();
-    if( nHits<5 || nCells<3){
-      for( Int_t i=0; i<nMatched; i++ ) vTracks[vMatchedTracks[i]].Used()=0;
-      continue;
+      if( jp.Link()>=0 ){ // break existing link of jTrack
+       ID2Point(jp.Link()).Link() = -1;
+      }
+      ip.Link() = bestLink;
+      jp.Link()= IRowICell2ID( iRow, iPoint );
+      
+      //cout<<"create link ("<<jp.Link()<<","<<ip.TrackID()<<")->("<<ip.Link()<<","<<jp.TrackID()<<")"<<endl;
+      
     }
-    iTrack.Used() = 1;
 
-    AliHLTTPCCATrack &mTrack = fTracks[fNTracks++];
-    mTrack = iTrack;
-    mTrack.IFirstCell() = vTrackCells.size();
-    mTrack.NCells() = 0;
+    timer5.Stop();
+    if(first) fTimers[5] += timer5.CpuTime();
 
-    for( Int_t i=vMatchedCellsBack.size()-1; i>=0; i-- ){
-      vTrackCells.push_back(vMatchedCellsBack[i]);
-      mTrack.NCells()++;
-    }
-    for( Int_t i=0; i<iTrack.NCells() ; i++){
-      vTrackCells.push_back(fTrackCells[iTrack.IFirstCell()+i]);
-      mTrack.NCells()++;
+    //cout<<"merge neighbours"<<endl;
+    // merge neighbours
+
+    TStopwatch timer6;
+
+    Int_t nRefEndPointsNew = 0;
+    for( Int_t iRef=0; iRef<nRefEndPoints; iRef++ ){
+
+      Int_t iRow = ID2IRow(refEndPoints[iRef]);
+      Int_t iPoint = ID2ICell(refEndPoints[iRef]);
+      AliHLTTPCCARow &irow = fRows[iRow];
+      AliHLTTPCCAEndPoint &ip  = irow.EndPoints()[iPoint];
+      if( ip.TrackID()<0 ) continue; // not active endpoint 
+      if( ip.Link()<0 ) continue; // no neighbours found
+
+      Int_t ipID = IRowICell2ID(iRow,iPoint);
+      Int_t jpID = ip.Link();
+      AliHLTTPCCAEndPoint &jp  = ID2Point(jpID);
+      
+      if( jp.Link()!=ipID ){
+       //cout<<"broken link: jp.Link()!=iID"<<endl;
+       //exit(0);
+       return;
+      }
+      if( jp.TrackID()<0 ){ 
+       //cout<<"broken link: jp.TrackID()<=0"<<endl;
+       //exit(0);
+       return;
+      }
+      if( jp.TrackID()==ip.TrackID() ){
+       //cout<<"broken link: jp.TrackID()==ip.TrackID()"<<endl;
+       //exit(0);        
+       return;
+      }
+     
+      //cout<<"Merge neighbours ("<<ipID<<","<<ip.TrackID()<<")->("<<jpID<<","<<jp.TrackID()<<")"<<endl;
+
+      AliHLTTPCCATrack &iTrack = fTracks[ip.TrackID()];
+      AliHLTTPCCATrack &jTrack = fTracks[jp.TrackID()];
+
+      // rotate cell link direction for jTrack if necessary
+      
+      Int_t icID = ip.CellID();
+      Int_t jcID = jp.CellID();
+      AliHLTTPCCACell &ic  = ID2Cell(icID);
+      AliHLTTPCCACell &jc  = ID2Cell(jcID);
+      
+      if( ic.Link()<0 && jc.Link()<0 || ic.Link()>=0 && jc.Link()>=0 ){
+
+       Int_t currID =  jTrack.CellID()[0];
+       jTrack.CellID()[0] = jTrack.CellID()[2];
+       jTrack.CellID()[2] = currID;
+
+       Int_t pID =  jTrack.PointID()[0];
+       jTrack.PointID()[0] = jTrack.PointID()[1];
+       jTrack.PointID()[1] = pID;
+
+       currID = jTrack.FirstCellID();
+       Int_t lastID = -1;
+       while( currID>=0 ){
+         AliHLTTPCCACell &c = ID2Cell( currID );
+         Int_t nextID = c.Link();
+         c.Link() = lastID;
+         lastID = currID;
+         currID = nextID;
+       }
+       jTrack.FirstCellID() = lastID;  
+      }
+      //cout<<"track i "<<ip.TrackID()<<", points="<<ipID<<", "<<iTrack.PointID()[0]<<", "<<iTrack.PointID()[1]<<endl;
+      //cout<<"track j "<<jp.TrackID()<<", points="<<jpID<<", "<<jTrack.PointID()[0]<<", "<<jTrack.PointID()[1]<<endl;
+      Int_t itr = ip.TrackID();
+      ip.TrackID() = -1;
+      jp.TrackID() = -1;
+      ip.Link()  = -1;
+      jp.Link()  = -1;
+      jTrack.Alive() = 0;
+      
+      //cout<<"iTrack ID: "<<iTrack.CellID()[0]<<" "<<iTrack.CellID()[1]<<" "<<iTrack.CellID()[2]<<endl;
+      //cout<<"jTrack ID: "<<jTrack.CellID()[0]<<" "<<jTrack.CellID()[1]<<" "<<jTrack.CellID()[2]<<endl;
+      if( ic.Link()<0 ){ //match iTrack->jTrack
+       ic.Link() = jcID;
+       iTrack.PointID()[1] = jTrack.PointID()[1];
+       ID2Point(iTrack.PointID()[1]).TrackID() = itr;
+       if( jTrack.NCells()<3 ){
+         refEndPoints[nRefEndPointsNew++] = iTrack.PointID()[1];
+         doMerging = 1;
+         ID2Point(iTrack.PointID()[1]).Param() = ip.Param();// just to set phi direction
+       }
+       if( iTrack.NCells()<3 ){
+         refEndPoints[nRefEndPointsNew++] = iTrack.PointID()[0];
+         doMerging = 1;
+         ID2Point(iTrack.PointID()[0]).Param() = jp.Param();// just to set phi direction
+       }
+
+       if( TMath::Abs(ID2Cell(jTrack.CellID()[2]).Z()-ID2Cell(iTrack.CellID()[0]).Z())>
+           TMath::Abs(ID2Cell(iTrack.CellID()[2]).Z()-ID2Cell(iTrack.CellID()[0]).Z())  ){
+         iTrack.CellID()[2] = jTrack.CellID()[2];
+       }
+      }else{ //match jTrack->iTrack
+       jc.Link() = icID;
+       iTrack.FirstCellID()=jTrack.FirstCellID();
+       iTrack.PointID()[0] = jTrack.PointID()[0];
+       ID2Point(iTrack.PointID()[0]).TrackID() = itr;
+       if( jTrack.NCells()<3 ){
+         refEndPoints[nRefEndPointsNew++] = iTrack.PointID()[0];
+         doMerging = 1;
+         ID2Point(iTrack.PointID()[0]).Param() = ip.Param(); // just to set phi direction
+       }
+       if( iTrack.NCells()<3 ){
+         refEndPoints[nRefEndPointsNew++] = iTrack.PointID()[1];
+         doMerging = 1;
+         ID2Point(iTrack.PointID()[1]).Param() = jp.Param();// just to set phi direction
+       }
+       if( TMath::Abs(ID2Cell(jTrack.CellID()[0]).Z()-ID2Cell(iTrack.CellID()[2]).Z())>
+           TMath::Abs(ID2Cell(iTrack.CellID()[0]).Z()-ID2Cell(iTrack.CellID()[2]).Z())  ){
+         iTrack.CellID()[0] = jTrack.CellID()[0];
+       }
+      }
+
+      //cout<<"merged ID: "<<iTrack.CellID()[0]<<" "<<iTrack.CellID()[1]<<" "<<iTrack.CellID()[2]<<endl;
+
+      if( jTrack.NCells()>iTrack.NCells() ){
+       iTrack.CellID()[1] = jTrack.CellID()[1];
+      }
+      
+      AliHLTTPCCAEndPoint &p0 = ID2Point(iTrack.PointID()[0]);
+      AliHLTTPCCAEndPoint &p1 = ID2Point(iTrack.PointID()[1]);
+      
+      if( p0.Link() == iTrack.PointID()[1] ){
+       p0.Link() = -1;
+       p1.Link() = -1;
+      }
+      //cout<<" NCells itr/jtr= "<<iTrack.NCells()<<" "<<jTrack.NCells()<<endl;
+      //cout<<" fit merged track "<<itr<<", NCells="<<iTrack.NCells()<<endl;
+      Float_t *t0 = ( jTrack.NCells()>iTrack.NCells() ) ?jp.Param().Par() :ip.Param().Par();            
+      iTrack.NCells()+=jTrack.NCells();      
+      FitTrack(iTrack,t0);
+
+#ifdef DRAW
+      cout<<"merged points..."<<ipID<<"/"<<jpID<<endl;
+      //AliHLTTPCCADisplay::Instance().ConnectCells( iRow,ic,ID2IRow(jcID),jc,kRed );
+      AliHLTTPCCADisplay::Instance().ConnectEndPoints( ipID,jpID,1.,2,kRed );
+      //AliHLTTPCCADisplay::Instance().DrawEndPoint( ipID,1.,2,kRed );
+      //AliHLTTPCCADisplay::Instance().DrawEndPoint( jpID,1.,2,kRed );
+      AliHLTTPCCADisplay::Instance().Ask();
+      cout<<"merged track"<<endl;
+      AliHLTTPCCADisplay::Instance().DrawTrack1(iTrack);
+      AliHLTTPCCADisplay::Instance().Ask();
+#endif
+      /*
+      static int ntr=0;
+      if( ntr++==1 ){
+       doMerging = 0;
+       break;
+      }
+      */
+      //doMerging = 1;    
     }
-    for( UInt_t i=0; i<vMatchedCellsFront.size(); i++){
-      vTrackCells.push_back(vMatchedCellsFront[i]);
-      mTrack.NCells()++;
-    }     
-    nOutTrackHits+= nHits;  
-  }
 
-  timer3.Stop();
-  fTimers[3] = timer3.CpuTime();
+    timer6.Stop();  
+    if(first)fTimers[6] += timer6.CpuTime();
 
-  delete[] vMatchedTracks;
+    nRefEndPoints = nRefEndPointsNew;
+
+    //cout<<"merging ok"<<endl;
+    //first = 0;
+  }// do merging
+  delete[] refEndPoints;
+  timer4.Stop();  
+  fTimers[4] = timer4.CpuTime();
 
-  //fTrackCells = new Int_t[vTrackCells.size()];
-  for( UInt_t i=0; i<vTrackCells.size(); i++ ) fTrackCells[i] = vTrackCells[i];
-  
 #ifdef DRAW
-  if( nTracks>0 ) AliHLTTPCCADisplay::Instance().Ask();
+  if( fNTracks>0 ) AliHLTTPCCADisplay::Instance().Ask();
 #endif 
 
-  //cout<<"n out Tracks = "<<fNTracks<<endl;
 
-  fOutTrackHits = new Int_t[nOutTrackHits];
-  fNOutTrackHits = 0;
-  fNOutTracks = fNTracks;
-  fOutTracks = new AliHLTTPCCAOutTrack[fNOutTracks];
-  for( Int_t itr=0; itr<fNOutTracks; itr++ ){
-    AliHLTTPCCATrack &t = fTracks[itr];
+
+
 #ifdef DRAW
-    AliHLTTPCCADisplay::Instance().DrawTrack( t );
-    //AliHLTTPCCADisplay::Instance().Ask();
-#endif 
-    AliHLTTPCCAOutTrack &tmp = fOutTracks[itr];
-    tmp.FirstHitRef() = fNOutTrackHits;
-    tmp.NHits() = 0;
-    tmp.Param() = t.Param();
-    for( Int_t iCell=0; iCell<t.NCells(); iCell++){
-      AliHLTTPCCACell &cell = GetTrackCell(t,iCell);
-      AliHLTTPCCARow &row = GetTrackCellRow(t,iCell);
-      for( Int_t iHit=0; iHit<cell.NHits(); iHit++ ){
-       AliHLTTPCCAHit &hit = row.GetCellHit(cell,iHit);
-       fOutTrackHits[fNOutTrackHits] = hit.ID();
+  AliHLTTPCCADisplay::Instance().Clear();
+  AliHLTTPCCADisplay::Instance().DrawSector( this );
+  for( Int_t iRow=0; iRow<fParam.NRows(); iRow++ )
+    for (Int_t i = 0; i<fRows[iRow].NCells(); i++) 
+      AliHLTTPCCADisplay::Instance().DrawCell( iRow, i );  
+  
+  cout<<"draw final tracks"<<endl;
+  
+  for( Int_t itr=0; itr<fNTracks; itr++ ){
+    AliHLTTPCCATrack &iTrack = fTracks[itr];
+    //if( itr!=3 ) continue;
+    if( iTrack.NCells()<3 ) continue;
+    if( !iTrack.Alive() ) continue;
+    AliHLTTPCCADisplay::Instance().DrawTrack1( iTrack );
+  }
+  AliHLTTPCCADisplay::Instance().Ask();
+#endif
+
+  // write output
+  //cout<<"write output"<<endl;
+  fOutTrackHits = new Int_t[fNHitsTotal];
+  fOutTracks = new AliHLTTPCCAOutTrack[fNTracks];
+  fNOutTrackHits = 0;
+  fNOutTracks = 0;
+
+  for( Int_t iTr=0; iTr<fNTracks; iTr++){
+    AliHLTTPCCATrack &iTrack = fTracks[iTr];
+    if( !iTrack.Alive() ) continue;
+    if( iTrack.NCells()<3 ) continue;      
+    AliHLTTPCCAOutTrack &out = fOutTracks[fNOutTracks];
+    out.FirstHitRef() = fNOutTrackHits;
+    out.NHits() = 0;
+    out.OrigTrackID() = iTr;
+    {
+      AliHLTTPCCAEndPoint &p0 = ID2Point(iTrack.PointID()[0]); 
+      AliHLTTPCCAEndPoint &p2 = ID2Point(iTrack.PointID()[1]); 
+      out.StartPoint() = p0.Param();
+      out.EndPoint() = p2.Param();
+    }
+    AliHLTTPCCATrackParam t = out.StartPoint();
+    Int_t iID = iTrack.FirstCellID();
+    Int_t fNOutTrackHitsOld = fNOutTrackHits;
+    for( AliHLTTPCCACell *ic = &ID2Cell(iID); ic->Link()>=0; iID = ic->Link(), ic = &ID2Cell(iID) ){
+      //cout<<"itr="<<iTr<<", cell ="<<ID2IRow(iID)<<" "<<ID2ICell(iID)<<endl;
+      AliHLTTPCCARow &row = ID2Row(iID);
+      for( Int_t iHit=0; iHit<ic->NHits(); iHit++ ){
+       AliHLTTPCCAHit &h = row.GetCellHit(*ic,iHit);
+
+       // check for wrong hits
+       
+       {
+         if( !t.TransportToX( row.X() ) ) continue;
+         Float_t dy = t.GetY() - h.Y();
+         Float_t dz = t.GetZ() - h.Z();
+         if( dy*dy > 3.5*3.5*(t.GetErr2Y() + h.ErrY()*h.ErrY() ) ) continue;
+         if( dz*dz > 3.5*3.5*(t.GetErr2Z() + h.ErrZ()*h.ErrZ() ) ) continue;
+         /*
+           Float_t m[3] = {row.X(), h.Y(), h.Z() };
+           Float_t mV[6] = {fParam.ErrX()*fParam.ErrX(), 0, h.ErrY()*h.ErrY(), 0, 0, h.ErrZ()*h.ErrZ() };
+           Float_t mG[6];
+           t.TransportBz(fParam.Bz(),m);
+           t.GetConnectionMatrix(fParam.Bz(),m, mG);
+           Float_t chi2 = t.GetChi2( m, mV, mG )/2.;
+           if( chi2>10. ) continue;
+         */
+       }       
+       
+       fOutTrackHits[fNOutTrackHits] = h.ID();
        fNOutTrackHits++;
-       tmp.NHits()++;
+       if( fNOutTrackHits>fNHitsTotal ){
+         //cout<<"fNOutTrackHits>fNHitsTotal"<<endl;
+         //exit(0);
+         return;
+       }
+       out.NHits()++;
       }
     }
-  }  
-  
+    if( out.NHits() > 3 ){
+      fNOutTracks++;
+    }else {
+      fNOutTrackHits = fNOutTrackHitsOld;
+    }
+  }
+  //cout<<"end writing"<<endl;
 #ifdef DRAW
   AliHLTTPCCADisplay::Instance().Ask();
   //AliHLTTPCCADisplay::Instance().DrawMCTracks(fParam.fISec);
@@ -582,66 +1056,40 @@ void AliHLTTPCCATracker::FindTracks()
 }
 
 
+void AliHLTTPCCATracker::FitTrack( AliHLTTPCCATrack &track, Float_t t0[] ) const 
+{      
+  //* Fit the track 
 
-void AliHLTTPCCATracker::FitTrack( AliHLTTPCCATrack &track, Int_t nIter )
-{    
-  // fit the track with nIter iterations
-
-  AliHLTTPCCATrackPar &t = track.Param();
-  t.Init();
-  
-  AliHLTTPCCACell &c1 = GetTrackCell(track,0);
-  AliHLTTPCCACell &c2 = GetTrackCell(track,track.NCells()-1);
-  AliHLTTPCCARow &row1 = GetTrackCellRow(track,0);
-  AliHLTTPCCARow &row2 = GetTrackCellRow(track,track.NCells()-1);
-  Double_t t0[7];
-  t0[0]=row1.X();
-  t0[1]=c1.Y();
-  t0[2]=c1.Z();
-  t0[3]= row2.X() - row1.X();
-  t0[4]= c2.Y() - c1.Y();
-  t0[5]= c2.Z() - c1.Z();
-  Double_t tt = sqrt(t0[3]*t0[3]+t0[4]*t0[4]+t0[5]*t0[5]);
-  if( TMath::Abs(tt)>1.e-4 ){
-    t0[3]/=tt;
-    t0[4]/=tt;
-    t0[5]/=tt;
-  }else{
-    t0[4]=1;
-  }
-  t0[6] = 0;
-
-  Int_t step = track.NCells()/3;
+  AliHLTTPCCAEndPoint &p0 = ID2Point(track.PointID()[0]);      
+  AliHLTTPCCAEndPoint &p2 = ID2Point(track.PointID()[1]);      
+  AliHLTTPCCACell &c0 = ID2Cell(p0.CellID());  
+  AliHLTTPCCACell &c1 = ID2Cell(track.CellID()[1]);    
+  AliHLTTPCCACell &c2 = ID2Cell(p2.CellID());  
+  AliHLTTPCCARow &row0 = ID2Row(p0.CellID());
+  AliHLTTPCCARow &row1 = ID2Row(track.CellID()[1]);
+  AliHLTTPCCARow &row2 = ID2Row(p2.CellID());
 
-  for( Int_t iter=0; iter<nIter; iter++ ){
-    t.Init();
-    for( Int_t i=0; i<7; i++) t.Par()[i] = t0[i];
-    {
-      Double_t m[3] = {row1.X(), c1.Y(), c1.Z() };
-      t.TransportBz(fParam.Bz(),m,t0);
-    }
-    t.Init();
-    for( Int_t i=0; i<7; i++ ) t.Par()[i] = t0[i];
 
-    //AliHLTTPCCATrackPar tt = t;
-  
-    for( Int_t i=0; i<track.NCells() ; i+=step){
-      AliHLTTPCCACell &c = GetTrackCell(track,i);
-      AliHLTTPCCARow &row = GetTrackCellRow(track,i);
-      for( Int_t j=0; j<c.NHits(); j++){
-       AliHLTTPCCAHit &h = row.GetCellHit(c,j);
-       Double_t m[3] = {row.X(), h.Y(), h.Z() };
-       Double_t mV[6] = {fParam.ErrX()*fParam.ErrX(), 0, h.ErrY()*h.ErrY(), 0, 0, h.ErrZ()*h.ErrZ() };
-       Double_t mV1[6];
-       t.TransportBz(fParam.Bz(),m, t0);
-       t.GetConnectionMatrix(fParam.Bz(),m, mV1, t0);
-       t.Filter(m, mV, mV1);
-       //tt.TransportBz(fParam.Bz(),m, t0);
-       //tt.GetConnectionMatrix(fParam.Bz(),m, mV1, t0);
-       //tt.Filter(m, mV, mV1);
-      }
-    }
-    t.Normalize();
-    for( Int_t i=0; i<7; i++ ) t0[i] = t.Par()[i];
+  Float_t sp0[5] = {row0.X(), c0.Y(), c0.Z(), c0.ErrY(), c0.ErrZ() };
+  Float_t sp1[5] = {row1.X(), c1.Y(), c1.Z(), c1.ErrY(), c1.ErrZ() };
+  Float_t sp2[5] = {row2.X(), c2.Y(), c2.Z(), c2.ErrY(), c2.ErrZ() };
+  if( track.NCells()>=3 ){
+    p0.Param().ConstructXYZ3(sp0,sp1,sp2,p0.Param().CosPhi(), t0);
+    p2.Param().ConstructXYZ3(sp2,sp1,sp0,p2.Param().CosPhi(), t0);
+    //p2.Param() = p0.Param();
+    //p2.Param().TransportToX(row2.X());
+    //p2.Param().Par()[1] = -p2.Param().Par()[1];
+    //p2.Param().Par()[4] = -p2.Param().Par()[4];
+  } else {
+    p0.Param().X() = row0.X();
+    p0.Param().Y() = c0.Y();
+    p0.Param().Z() = c0.Z();
+    p0.Param().Err2Y() = c0.ErrY()*c0.ErrY();
+    p0.Param().Err2Z() = c0.ErrZ()*c0.ErrZ();
+    p2.Param().X() = row2.X();
+    p2.Param().Y() = c2.Y();
+    p2.Param().Z() = c2.Z();
+    p2.Param().Err2Y() = c2.ErrY()*c2.ErrY();
+    p2.Param().Err2Z() = c2.ErrZ()*c2.ErrZ();
   }
 }
index 6ebc214f82d85e2088317deeb52da0432ddc76b8..f9d5035426114871fb393363f87ec5545aeb5d74 100644 (file)
 #include "Rtypes.h"
 #include "AliHLTTPCCAParam.h"
 #include "AliHLTTPCCARow.h"
-#include "AliHLTTPCCATrack.h"
 
+class AliHLTTPCCATrack;
 class AliHLTTPCCAHit;
 class AliHLTTPCCACell;
 class AliHLTTPCCAOutTrack;
-
+class AliHLTTPCCATrackParam;
+class AliHLTTPCCAEndPoint;
 
 /**
  * @class AliHLTTPCCATracker
@@ -50,8 +51,8 @@ class AliHLTTPCCATracker
   void Reconstruct();
 
   void FindCells();
+  void MergeCells();
   void FindTracks();
-  void FitTrack( AliHLTTPCCATrack &track, Int_t nIter=2 );
 
   AliHLTTPCCAParam &Param(){ return fParam; }
   AliHLTTPCCARow *Rows(){ return fRows; }
@@ -64,24 +65,30 @@ class AliHLTTPCCATracker
   AliHLTTPCCATrack *Tracks(){ return  fTracks; }
   Int_t NTracks() const { return fNTracks; }
 
-  Int_t *TrackCells(){ return  fTrackCells; }
-
   Double_t *Timers(){ return fTimers; }
 
-  AliHLTTPCCACell &GetTrackCell( AliHLTTPCCATrack &t, Int_t i ) const {
-    Int_t ind = fTrackCells[t.IFirstCell()+i];
-    AliHLTTPCCARow &row = fRows[ind%256];
-    return row.Cells()[ind>>8];
+  static Int_t IRowICell2ID( Int_t iRow, Int_t iCell ){ 
+    return (iCell<<8)+iRow; 
+  }
+  static Int_t ID2IRow( Int_t CellID ){ 
+    return ( CellID%256 ); 
   }
-  AliHLTTPCCARow &GetTrackCellRow( AliHLTTPCCATrack &t, Int_t i ) const {
-    Int_t ind = fTrackCells[t.IFirstCell()+i];
-    return fRows[ind%256];    
+  static Int_t ID2ICell( Int_t CellID ){ 
+    return ( CellID>>8 ); 
+  }  
+  AliHLTTPCCACell &ID2Cell( Int_t CellID ) const{
+    return fRows[CellID%256].Cells()[CellID>>8];
   }
-  Int_t GetTrackCellIRow( AliHLTTPCCATrack &t, Int_t i ) const {
-    Int_t ind = fTrackCells[t.IFirstCell()+i];
-    return ind%256;    
+  AliHLTTPCCARow &ID2Row( Int_t CellID ) const{
+    return fRows[CellID%256];
+  }
+  
+  AliHLTTPCCAEndPoint &ID2Point( Int_t PointID ) const{
+    return fRows[PointID%256].EndPoints()[PointID>>8];
   }
+
+  void FitTrack( AliHLTTPCCATrack &track, Float_t *t0 = 0 ) const;
+
  protected:
   
   AliHLTTPCCAParam fParam; // parameters
@@ -92,12 +99,13 @@ class AliHLTTPCCATracker
   Int_t fNOutTrackHits;  // number of hits in fOutTrackHits array
   AliHLTTPCCAOutTrack *fOutTracks; // output array of the reconstructed tracks
   Int_t fNOutTracks; // number of tracks in fOutTracks array
-  Int_t *fTrackCells; // indices of cells for reconstructed tracks
+
   Int_t fNHitsTotal;// total number of hits in event
   AliHLTTPCCATrack *fTracks;   // reconstructed tracks
   Int_t fNTracks;// number of reconstructed tracks
   Int_t *fCellHitPointers;// global array of cell->hit pointers
-
+  AliHLTTPCCACell *fCells;// global array of cells
+  AliHLTTPCCAEndPoint *fEndPoints;// global array of endpoints
   Double_t fTimers[10]; // running CPU time for different parts of the algorithm
 
   ClassDef(AliHLTTPCCATracker,1);
index 29c75baca1b41bf0dde69e33b42b521542daf6f7..362eeabd13f322328af3859c77e11c5c5c133c14 100644 (file)
@@ -1,20 +1,20 @@
 // @(#) $Id$
-/**************************************************************************
- * This file is property of and copyright by the ALICE HLT Project        * 
- * ALICE Experiment at CERN, All rights reserved.                         *
- *                                                                        *
- * Primary Authors: Jochen Thaeder <thaeder@kip.uni-heidelberg.de>        *
- *                  Ivan Kisel <kisel@kip.uni-heidelberg.de>              *
- *                  for The ALICE HLT Project.                            *
- *                                                                        *
- * Permission to use, copy, modify and distribute this software and its   *
- * documentation strictly for non-commercial purposes is hereby granted   *
- * without fee, provided that the above copyright notice appears in all   *
- * copies and that both the copyright notice and this permission notice   *
- * appear in the supporting documentation. The authors make no claims     *
- * about the suitability of this software for any purpose. It is          *
- * provided "as is" without express or implied warranty.                  *
- **************************************************************************/
+//***************************************************************************
+// This file is property of and copyright by the ALICE HLT Project          * 
+// ALICE Experiment at CERN, All rights reserved.                           *
+//                                                                          *
+// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
+//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
+//                  for The ALICE HLT Project.                              *
+//                                                                          *
+// Permission to use, copy, modify and distribute this software and its     *
+// documentation strictly for non-commercial purposes is hereby granted     *
+// without fee, provided that the above copyright notice appears in all     *
+// copies and that both the copyright notice and this permission notice     *
+// appear in the supporting documentation. The authors make no claims       *
+// about the suitability of this software for any purpose. It is            *
+// provided "as is" without express or implied warranty.                    *
+//***************************************************************************
  
 ///////////////////////////////////////////////////////////////////////////////
 //                                                                           //
@@ -32,6 +32,7 @@ using namespace std;
 #include "AliHLTTPCCATracker.h"
 #include "AliHLTTPCCAHit.h"
 #include "AliHLTTPCCAOutTrack.h"
+#include "AliHLTTPCCAParam.h"
 
 #include "AliHLTTPCSpacePointData.h"
 #include "AliHLTTPCClusterDataFormat.h"
@@ -40,6 +41,7 @@ using namespace std;
 #include "AliHLTTPCTrackArray.h"
 #include "AliHLTTPCTrackletDataFormat.h"
 #include "AliHLTTPCDefinitions.h"
+#include "AliExternalTrackParam.h"
 #include "TStopwatch.h"
 #include "TMath.h"
 
@@ -49,7 +51,11 @@ ClassImp(AliHLTTPCCATrackerComponent)
 AliHLTTPCCATrackerComponent::AliHLTTPCCATrackerComponent()
   :
   fTracker(NULL),
-  fBField(0)
+  fBField(0),
+  fMinNTrackClusters(30),
+  fFullTime(0),
+  fRecoTime(0),
+  fNEvents(0)
 {
   // see header file for class documentation
   // or
@@ -62,7 +68,11 @@ AliHLTTPCCATrackerComponent::AliHLTTPCCATrackerComponent(const AliHLTTPCCATracke
   :
   AliHLTProcessor(),
   fTracker(NULL),
-  fBField(0)
+  fBField(0),
+  fMinNTrackClusters(30),
+  fFullTime(0),
+  fRecoTime(0),
+  fNEvents(0)
 {
   // see header file for class documentation
   HLTFatal("copy constructor untested");
@@ -127,7 +137,11 @@ int AliHLTTPCCATrackerComponent::DoInit( int argc, const char** argv )
   //
 
   if ( fTracker ) return EINPROGRESS;
-  
+
+  fFullTime = 0;
+  fRecoTime = 0;
+  fNEvents = 0;
+
   fTracker = new AliHLTTPCCATracker();
   
   // read command line
@@ -148,12 +162,32 @@ int AliHLTTPCCATrackerComponent::DoInit( int argc, const char** argv )
          return EINVAL;
        }
 
-      Logging( kHLTLogDebug, "HLT::TPCCATracker::DoInit", "Reading command line",
+      Logging( kHLTLogInfo, "HLT::TPCCATracker::DoInit", "Reading command line",
               "Magnetic field value is set to %f kG", fBField );
 
       i += 2;
       continue;
     }
+
+    if ( !strcmp( argv[i], "MinNTrackClusters" ) ){
+      if ( i+1 >= argc )
+       {
+         Logging( kHLTLogError, "HLT::TPCCATracker::DoInit", "Missing MinNTrackClusters", "Missing MinNTrackClusters specifier." );
+         return ENOTSUP;
+       }
+      fMinNTrackClusters = (Int_t ) strtod( argv[i+1], &cpErr );
+      if ( *cpErr )
+       {
+         Logging( kHLTLogError, "HLT::TPCCATracker::DoInit", "Missing multiplicity", "Cannot convert MinNTrackClusters '%s'.", argv[i+1] );
+         return EINVAL;
+       }
+
+      Logging( kHLTLogInfo, "HLT::TPCCATracker::DoInit", "Reading command line",
+              "MinNTrackClusters is set to %i ", fMinNTrackClusters );
+
+      i += 2;
+      continue;
+    }
     
     Logging(kHLTLogError, "HLT::TPCCATracker::DoInit", "Unknown Option", "Unknown option '%s'", argv[i] );
     return EINVAL;
@@ -187,7 +221,7 @@ int AliHLTTPCCATrackerComponent::DoEvent
 
   // Event reconstruction in one TPC slice with CA Tracker
 
-  Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "DoEvent", "DoEvent()" );
+  //Logging( kHLTLogWarning, "HLT::TPCCATracker::DoEvent", "DoEvent", "CA::DoEvent()" );
   if ( evtData.fBlockCnt<=0 )
     {
       Logging( kHLTLogWarning, "HLT::TPCCATracker::DoEvent", "DoEvent", "no blocks in event" );
@@ -256,7 +290,7 @@ int AliHLTTPCCATrackerComponent::DoEvent
   }
   
   if( slice<0 ){
-    Logging( kHLTLogWarning, "HLT::TPCCATracker::DoEvent", "DoEvent", "no slices found in event" );
+    Logging( kHLTLogWarning, "HLT::TPCCATracker::DoEvent", "DoEvent", "CA:: no slices found in event" );
     return 0;
   }
 
@@ -290,7 +324,7 @@ int AliHLTTPCCATrackerComponent::DoEvent
     Double_t padPitch = 0.4;
     Double_t sigmaZ = 0.228808;
     
-     Double_t rowX[NRows];
+    Double_t *rowX = new Double_t [NRows];
     for( Int_t irow=0; irow<NRows; irow++){
       rowX[irow] = AliHLTTPCTransform::Row2X( irow );
     }     
@@ -302,7 +336,7 @@ int AliHLTTPCCATrackerComponent::DoEvent
     param.ZErrorCorrection() = 2;
 
     fTracker->Initialize( param ); 
-
+    delete[] rowX;
   }
 
     
@@ -346,10 +380,10 @@ int AliHLTTPCCATrackerComponent::DoEvent
   
   fTracker->StartEvent();
 
-  AliHLTTPCCAHit vHits[nHitsTotal]; // CA hit array
-  Double_t vHitStoreX[nHitsTotal];       // hit X coordinates
-  Int_t vHitStoreID[nHitsTotal];            // hit ID's
-  Int_t vHitRowID[nHitsTotal];            // hit ID's
+  AliHLTTPCCAHit *vHits = new AliHLTTPCCAHit [nHitsTotal]; // CA hit array
+  Double_t *vHitStoreX = new Double_t [nHitsTotal];       // hit X coordinates
+  Int_t *vHitStoreID = new Int_t [nHitsTotal];            // hit ID's
+  Int_t *vHitRowID = new Int_t [nHitsTotal];            // hit ID's
 
   Int_t nHits = 0;
  
@@ -387,6 +421,7 @@ int AliHLTTPCCATrackerComponent::DoEvent
 
       h.Y() = pSP->fY;
       h.Z() = pSP->fZ;
+      if( TMath::Abs(h.Z())>230.) continue;
       h.ErrY() = TMath::Sqrt(TMath::Abs(pSP->fSigmaY2));
       h.ErrZ() = TMath::Sqrt(TMath::Abs(pSP->fSigmaZ2));  
       if( h.ErrY()<.1 ) h.ErrY() = .1;
@@ -435,6 +470,8 @@ int AliHLTTPCCATrackerComponent::DoEvent
 
     //Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Wrtite output","track %d with %d hits", itr, t.NHits());
 
+    if( t.NHits()<fMinNTrackClusters ) continue;
+
     // calculate output track size
 
     UInt_t dSize = sizeof(AliHLTTPCTrackSegmentData) + t.NHits()*sizeof(UInt_t);
@@ -450,58 +487,33 @@ int AliHLTTPCCATrackerComponent::DoEvent
     Int_t iFirstHit = fTracker->OutTrackHits()[t.FirstHitRef()];
     Int_t iLastHit = fTracker->OutTrackHits()[t.FirstHitRef()+t.NHits()-1];
     
-    AliHLTTPCCAHit &firstHit = vHits[iFirstHit];
-    AliHLTTPCCAHit &lastHit = vHits[iLastHit];
-   
-    t.Param().TransportBz(Bz, vHitStoreX[iFirstHit], firstHit.Y(), firstHit.Z() );
-
-    currOutTracklet->fX = t.Param().Par()[0];
-    currOutTracklet->fY = t.Param().Par()[1];
-    currOutTracklet->fZ = t.Param().Par()[2];
-    Double_t qp = t.Param().Par()[6];
-    Double_t p = TMath::Abs(qp)>1.e-5 ?1./TMath::Abs(qp) :1.e5;
-    Double_t ex = t.Param().Par()[3];
-    Double_t ey = t.Param().Par()[4];
-    Double_t ez = t.Param().Par()[5];
-    Double_t et = TMath::Sqrt( ex*ex + ey*ey );
-    
-    currOutTracklet->fCharge = (qp>0) ?+1 :(qp<0 ?-1 :0);
-    currOutTracklet->fPt = p*et;
-
-    Double_t h3 =  TMath::Abs(ex) >1.e-5 ? p*ex/et :0;
-    Double_t h4 =  TMath::Abs(ey) >1.e-5 ? p*ey/et :0;
-    Double_t h5;
-    Double_t h6 =  - currOutTracklet->fCharge * p * currOutTracklet->fPt;
-  
-    currOutTracklet->fPterr = ( h3*h3*t.Param().Cov()[9] + h4*h4*t.Param().Cov()[14] + h6*h6*t.Param().Cov()[27] 
-                               + 2.*(h3*h4*t.Param().Cov()[13]+h3*h6*t.Param().Cov()[24]+h4*h6*t.Param().Cov()[25] )
-                               );    
-    currOutTracklet->fPsi = TMath::ATan2(ey, ex);
-    
-    h3 =  ex/(et*et);
-    h4 = -ey/(et*et);
-    currOutTracklet->fPsierr = h3*h3*t.Param().Cov()[9] + h4*h4*t.Param().Cov()[14] + 2.*h3*h4*t.Param().Cov()[13];
-    
-    currOutTracklet->fTgl = TMath::Abs(et)>1.e-5  ? ez/et :1.e5;
-      
-    if( TMath::Abs(et) >1.e-2 ){
-      h3 = -ez*ex/et/et;
-      h4 = -ez*ey/et/et;
-      h5 = 1.;
-      currOutTracklet->fTglerr =  ( h3*h3*t.Param().Cov()[9] + h4*h4*t.Param().Cov()[14] + h5*h5*t.Param().Cov()[20] 
-                                   + 2.*(h3*h4*t.Param().Cov()[13]+h3*h5*t.Param().Cov()[18]+h4*h5*t.Param().Cov()[19] )
-                                   )/et/et;
-    }else{
-      currOutTracklet->fTglerr =  1.e-2;
-    }
-
-    currOutTracklet->fCharge = -currOutTracklet->fCharge;
-    
-    t.Param().TransportBz(Bz, vHitStoreX[iLastHit], lastHit.Y(), lastHit.Z() );
-     
-    currOutTracklet->fLastX = t.Param().Par()[0];
-    currOutTracklet->fLastY = t.Param().Par()[1];
-    currOutTracklet->fLastZ = t.Param().Par()[2];
+    AliHLTTPCCATrackParam par = t.StartPoint();
+
+    par.TransportToX( vHitStoreX[iFirstHit] );
+
+    AliExternalTrackParam tp;
+    par.GetExtParam( tp, 0, fBField );
+
+    currOutTracklet->fX = tp.GetX();
+    currOutTracklet->fY = tp.GetY();
+    currOutTracklet->fZ = tp.GetZ();
+    currOutTracklet->fCharge = (Int_t ) tp.GetSign();
+    currOutTracklet->fPt = TMath::Abs(tp.GetSignedPt());
+    Double_t snp =  tp.GetSnp() ;
+    if( snp>.999 ) snp=.999;
+    if( snp>-.999 ) snp=-.999;
+    currOutTracklet->fPsi = TMath::ASin( snp );
+    currOutTracklet->fTgl = tp.GetTgl();
+    Double_t h = -currOutTracklet->fPt*currOutTracklet->fPt;
+    currOutTracklet->fPterr = h*h*tp.GetSigma1Pt2();
+    h = 1./TMath::Sqrt(1-snp*snp);
+    currOutTracklet->fPsierr = h*h*tp.GetSigmaSnp2();
+    currOutTracklet->fTglerr = tp.GetSigmaTgl2();
+
+    par.TransportToX( vHitStoreX[iLastHit] );     
+    currOutTracklet->fLastX = par.GetX();
+    currOutTracklet->fLastY = par.GetY();
+    currOutTracklet->fLastZ = par.GetZ();
 
 #ifdef INCLUDE_TPC_HOUGH
 #ifdef ROWHOUGHPARAMS
@@ -524,7 +536,11 @@ int AliHLTTPCCATrackerComponent::DoEvent
     mySize+=dSize;
     outPtr->fTrackletCnt++; 
   }
-  
+
+  delete[] vHits;
+  delete[] vHitStoreX;
+  delete[] vHitStoreID;
+  delete[] vHitRowID;
   
   AliHLTComponentBlockData bd;
   FillBlockData( bd );
@@ -535,13 +551,17 @@ int AliHLTTPCCATrackerComponent::DoEvent
   
   size = mySize;
   
-  timerReco.Stop();
+  timer.Stop();
+
+  fFullTime+= timer.CpuTime();
+  fRecoTime+= timerReco.CpuTime();
+  fNEvents++;
 
   // Set log level to "Warning" for on-line system monitoring
 
-  Logging( kHLTLogWarning, "HLT::TPCCATracker::DoEvent", "Tracks",
+  Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Tracks",
           "CATracker slice %d: output %d tracks;  input %d clusters, patches %d..%d, rows %d..%d; reco time %d/%d us", 
-          slice, ntracks, nClusters, minPatch, maxPatch, row[0], row[1], (Int_t) (timer.RealTime()*1.e6), (Int_t) (timerReco.RealTime()*1.e6) );
+          slice, ntracks, nClusters, minPatch, maxPatch, row[0], row[1], (Int_t) (fFullTime/fNEvents*1.e6), (Int_t) (fRecoTime/fNEvents*1.e6) );
 
   return ret;
 
index fab039d6485ae50c4d1b554aee2c9a6e2e9138af..83883edde8173e5335f1fef77f603c66629b021d 100644 (file)
@@ -73,7 +73,12 @@ private:
   
   /** magnetic field */
   Double_t fBField;                                            // see above
-  
+  Int_t fMinNTrackClusters; //* required min number of clusters on the track
+
+  Double_t fFullTime; //! total time for DoEvent() [s]
+  Double_t fRecoTime; //! total reconstruction time [s]
+  Long_t    fNEvents;  //! number of reconstructed events
+
   ClassDef(AliHLTTPCCATrackerComponent, 0);
   
 };
diff --git a/HLT/TPCLib/tracking-ca/AliTPCtrackerCA.cxx b/HLT/TPCLib/tracking-ca/AliTPCtrackerCA.cxx
new file mode 100644 (file)
index 0000000..b31be58
--- /dev/null
@@ -0,0 +1,326 @@
+// $Id$
+//***************************************************************************
+// This file is property of and copyright by the ALICE HLT Project          * 
+// ALICE Experiment at CERN, All rights reserved.                           *
+//                                                                          *
+// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
+//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
+//                  for The ALICE HLT Project.                              *
+//                                                                          *
+// Permission to use, copy, modify and distribute this software and its     *
+// documentation strictly for non-commercial purposes is hereby granted     *
+// without fee, provided that the above copyright notice appears in all     *
+// copies and that both the copyright notice and this permission notice     *
+// appear in the supporting documentation. The authors make no claims       *
+// about the suitability of this software for any purpose. It is            *
+// provided "as is" without express or implied warranty.                    *
+//***************************************************************************
+
+#include "AliTPCtrackerCA.h"
+
+#include <TTree.h>
+#include <Riostream.h>
+#include "AliCluster.h"
+#include "AliTPCClustersRow.h"
+#include "AliTPCParam.h"
+#include "AliRun.h"
+#include "AliRunLoader.h"
+#include "AliStack.h"
+
+#include "AliHLTTPCCATracker.h"
+#include "AliHLTTPCCAGBHit.h"
+#include "AliHLTTPCCAGBTracker.h"
+#include "AliHLTTPCCAGBTrack.h"
+#include "AliHLTTPCCAMCTrack.h"
+#include "AliHLTTPCCAOutTrack.h"
+#include "AliHLTTPCCAPerformance.h"
+#include "AliHLTTPCCAParam.h"
+
+#include "TMath.h"
+#include "AliTPCLoader.h"
+#include "AliTPC.h"
+#include "AliTPCclusterMI.h"
+#include "AliTPCTransform.h"
+#include "AliTPCcalibDB.h"
+#include "AliTPCReconstructor.h"
+#include "AliTPCtrack.h"
+#include "AliESDtrack.h"
+#include "AliESDEvent.h"
+
+
+ClassImp(AliTPCtrackerCA)
+
+AliTPCtrackerCA::AliTPCtrackerCA()
+  :AliTracker(),fParam(0), fClusters(0), fNClusters(0), fHLTTracker(0),fHLTPerformance(0),fDoHLTPerformance(0)
+{
+  //* default constructor
+}
+
+AliTPCtrackerCA::AliTPCtrackerCA(const AliTPCtrackerCA &):
+  AliTracker(),fParam(0), fClusters(0), fNClusters(0), fHLTTracker(0),fHLTPerformance(0),fDoHLTPerformance(0)
+{
+  //* dummy
+}
+
+AliTPCtrackerCA & AliTPCtrackerCA::operator=(const AliTPCtrackerCA& )
+{
+  //* dummy 
+  return *this;
+}
+
+
+AliTPCtrackerCA::~AliTPCtrackerCA() 
+{
+  //* destructor
+  if( fClusters ) delete[] fClusters;
+  if( fHLTTracker ) delete fHLTTracker;
+  if( fHLTPerformance ) delete fHLTPerformance;
+}
+
+AliTPCtrackerCA::AliTPCtrackerCA(const AliTPCParam *par): 
+  AliTracker(),fParam(par), fClusters(0), fNClusters(0), fHLTTracker(0), fHLTPerformance(0),fDoHLTPerformance(0)
+{
+  //* constructor
+
+  DoHLTPerformance() = 0;
+
+  fHLTTracker = new AliHLTTPCCAGBTracker;
+  fHLTTracker->SetNSlices( fParam->GetNSector()/2 );
+
+  if( fDoHLTPerformance ){
+    fHLTPerformance = new AliHLTTPCCAPerformance;
+    fHLTPerformance->SetTracker( fHLTTracker );
+  }
+
+  for( int iSlice=0; iSlice<fHLTTracker->NSlices(); iSlice++ ){
+  
+    Double_t bz = AliTracker::GetBz();
+
+    Double_t inRmin = fParam->GetInnerRadiusLow();
+    //Double_t inRmax = fParam->GetInnerRadiusUp();
+    //Double_t outRmin = fParam->GetOuterRadiusLow(); 
+    Double_t outRmax = fParam->GetOuterRadiusUp();
+    Double_t plusZmin = 0.0529937; 
+    Double_t plusZmax = 249.778; 
+    Double_t minusZmin = -249.645; 
+    Double_t minusZmax = -0.0799937; 
+    Double_t dalpha = 0.349066;
+    Double_t alpha = 0.174533 + dalpha*iSlice;
+    
+    Bool_t zPlus = (iSlice<18 );
+    Double_t zMin =  zPlus ?plusZmin :minusZmin;
+    Double_t zMax =  zPlus ?plusZmax :minusZmax;
+    //TPCZmin = -249.645, ZMax = 249.778    
+    //Double_t rMin =  inRmin;
+    //Double_t rMax =  outRmax;
+        
+    Double_t padPitch = 0.4;
+    Double_t sigmaZ = 0.228808;
+
+    Int_t NRows = fParam->GetNRowLow()+fParam->GetNRowUp();
+
+    Double_t rowX[200];
+    for( Int_t irow=0; irow<fParam->GetNRowLow(); irow++){
+      rowX[irow] = fParam->GetPadRowRadiiLow(irow);
+    }     
+    for( Int_t irow=0; irow<fParam->GetNRowUp(); irow++){
+      rowX[fParam->GetNRowLow()+irow] = fParam->GetPadRowRadiiUp(irow);
+    }      
+    AliHLTTPCCAParam param;
+    param.Initialize( iSlice, NRows, rowX, alpha, dalpha,
+                     inRmin, outRmax, zMin, zMax, padPitch, sigmaZ, bz );
+    param.YErrorCorrection() = .33;//1;
+    param.ZErrorCorrection() = .33;//2;
+    param.MaxTrackMatchDRow() = 5;
+    param.TrackConnectionFactor() = 5.;
+    fHLTTracker->Slices()[iSlice].Initialize( param ); 
+  }
+}
+
+
+
+Int_t AliTPCtrackerCA::LoadClusters (TTree * tree)
+{ 
+  fNClusters = 0;
+  if( fClusters ) delete[] fClusters;
+
+  fHLTTracker->StartEvent();
+  if( fDoHLTPerformance ) fHLTPerformance->StartEvent();
+
+  if( !fParam ) return 1;
+
+  // load mc tracks
+  if( fDoHLTPerformance ){
+    if( !gAlice ) return 0;
+    AliRunLoader *rl = gAlice->GetRunLoader(); 
+    if( !rl ) return 0;
+    rl->LoadKinematics();
+    AliStack *stack = rl->Stack();
+    if( !stack ) return 0 ;
+
+    fHLTPerformance->SetNMCTracks( stack->GetNtrack() );
+    
+    for( Int_t itr=0; itr<stack->GetNtrack(); itr++ ){
+      TParticle *part = stack->Particle(itr);
+      fHLTPerformance->ReadMCTrack( itr, part );
+    }
+  }   
+  
+  TBranch * br = tree->GetBranch("Segment");
+  if( !br ) return 1;
+
+  AliTPCClustersRow *clrow = new AliTPCClustersRow;
+  clrow->SetClass("AliTPCclusterMI");
+  clrow->SetArray(0);
+  clrow->GetArray()->ExpandCreateFast(10000);
+  
+  br->SetAddress(&clrow);
+  
+  //
+  Int_t NEnt=Int_t(tree->GetEntries());
+
+  fNClusters = 0;
+  for (Int_t i=0; i<NEnt; i++) {
+    br->GetEntry(i);
+    Int_t sec,row;
+    fParam->AdjustSectorRow(clrow->GetID(),sec,row);
+    fNClusters += clrow->GetArray()->GetEntriesFast();
+  }
+
+  fClusters = new AliTPCclusterMI [fNClusters];
+  fHLTTracker->SetNHits( fNClusters );
+  if( fDoHLTPerformance ) fHLTPerformance->SetNHits( fNClusters );
+  int ind=0;
+  for (Int_t i=0; i<NEnt; i++) {
+    br->GetEntry(i);
+    Int_t sec,row;
+    fParam->AdjustSectorRow(clrow->GetID(),sec,row);
+    int NClu = clrow->GetArray()->GetEntriesFast();
+    Double_t x = fParam->GetPadRowRadii(sec,row);
+    for (Int_t icl=0; icl<NClu; icl++){
+      Int_t lab0 = -1;
+      Int_t lab1 = -1;
+      Int_t lab2 = -1;
+      AliTPCclusterMI* cluster = (AliTPCclusterMI*)(clrow->GetArray()->At(icl));
+      if( !cluster ) continue;
+      lab0 = cluster->GetLabel(0);
+      lab1 = cluster->GetLabel(1);
+      lab2 = cluster->GetLabel(2);
+
+      AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
+      if (!transform) {
+       AliFatal("Tranformations not in calibDB");
+      }
+      Double_t xx[3]={cluster->GetRow(),cluster->GetPad(),cluster->GetTimeBin()};
+      Int_t id[1]={cluster->GetDetector()};
+      transform->Transform(xx,id,0,1);  
+      //if (!AliTPCReconstructor::GetRecoParam()->GetBYMirror()){
+      if (cluster->GetDetector()%36>17){
+       xx[1]*=-1;
+      }
+      //}
+
+      cluster->SetX(xx[0]);
+      cluster->SetY(xx[1]);
+      cluster->SetZ(xx[2]);
+
+      TGeoHMatrix  *mat = fParam->GetClusterMatrix(cluster->GetDetector());
+      Double_t pos[3]= {cluster->GetX(),cluster->GetY(),cluster->GetZ()};
+      Double_t posC[3]={cluster->GetX(),cluster->GetY(),cluster->GetZ()};
+      if (mat) mat->LocalToMaster(pos,posC);
+      else{
+       // chack Loading of Geo matrices from GeoManager - TEMPORARY FIX
+      }
+      cluster->SetX(posC[0]);
+      cluster->SetY(posC[1]);
+      cluster->SetZ(posC[2]);
+
+      Double_t y = cluster->GetY();
+      Double_t z = cluster->GetZ();        
+
+      if( sec>=36 ){
+       sec = sec - 36;
+       row = row + fParam->GetNRowLow(); 
+      }
+      
+      Int_t index = ind++;
+      fClusters[index] = *cluster;
+      fHLTTracker->ReadHit( x, y, z, 
+                           TMath::Sqrt(cluster->GetSigmaY2()), TMath::Sqrt(cluster->GetSigmaZ2()), 
+                           index, sec, row );
+      if( fDoHLTPerformance ) fHLTPerformance->ReadHitLabel(index, lab0, lab1, lab2 );
+    }
+  }
+  delete clrow;
+  return 0;
+}
+
+AliCluster * AliTPCtrackerCA::GetCluster(Int_t index) const
+{
+  return &(fClusters[index]);
+}
+
+Int_t AliTPCtrackerCA::Clusters2Tracks( AliESDEvent *event )
+{
+  //cout<<"Start of AliTPCtrackerCA"<<endl;
+
+  fHLTTracker->FindTracks();
+  if( fDoHLTPerformance ) fHLTPerformance->Performance();
+
+  if( event ){
+   
+    for( Int_t itr=0; itr<fHLTTracker->NTracks(); itr++ ){
+      AliTPCtrack tTPC;
+      AliHLTTPCCAGBTrack &tCA = fHLTTracker->Tracks()[itr];
+      AliHLTTPCCATrackParam &par = tCA.Param();        
+
+      par.GetExtParam( tTPC, tCA.Alpha(), fHLTTracker->Slices()[0].Param().Bz() );
+      
+      tTPC.SetMass(0.13957);
+      int nhits = tCA.NHits();
+      if( nhits>kMaxRow ) nhits = kMaxRow;
+      tTPC.SetNumberOfClusters(nhits);
+      for( Int_t ih=0; ih<nhits; ih++ ){
+       Int_t index = fHLTTracker->TrackHits()[tCA.FirstHitRef()+ih];
+       Int_t ext_index = fHLTTracker->Hits()[index].ID();
+       tTPC.SetClusterIndex(ih, ext_index);
+      }
+      CookLabel(&tTPC,0.1);    
+      {
+       Double_t xTPC=83.65;
+       if (tTPC.AliExternalTrackParam::PropagateTo(xTPC,5)) {    
+         Double_t y=tTPC.GetY();
+         Double_t ymax=xTPC*TMath::Tan(1.74532920122146606e-01); 
+         if (y > ymax) {
+           if (tTPC.Rotate(2*1.74532920122146606e-01)) tTPC.AliExternalTrackParam::PropagateTo(xTPC,5);
+         } else if (y <-ymax) {
+           if (tTPC.Rotate(-2*1.74532920122146606e-01)) tTPC.AliExternalTrackParam::PropagateTo(xTPC,5);
+         }         
+       }
+      }
+
+      AliESDtrack tESD;
+      tESD.UpdateTrackParams( &(tTPC),AliESDtrack::kTPCin);
+      //tESD.SetStatus( AliESDtrack::kTPCrefit );
+      //tESD.SetTPCPoints(tTPC.GetPoints());
+      //tESD.myTPC = tTPC;
+      event->AddTrack(&tESD);
+    }
+  }
+
+  //cout<<"End of AliTPCtrackerCA"<<endl;
+  return 0;
+}
+
+
+Int_t AliTPCtrackerCA::RefitInward (AliESDEvent *)
+{ 
+  //* not implemented yet
+  return 0; 
+}
+
+Int_t AliTPCtrackerCA::PropagateBack(AliESDEvent *)
+{ 
+  //* not implemented yet
+  return 0; 
+}
diff --git a/HLT/TPCLib/tracking-ca/AliTPCtrackerCA.h b/HLT/TPCLib/tracking-ca/AliTPCtrackerCA.h
new file mode 100644 (file)
index 0000000..05ad6df
--- /dev/null
@@ -0,0 +1,62 @@
+//-*- Mode: C++ -*-
+// $Id$
+
+//* This file is property of and copyright by the ALICE HLT Project        * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//* See cxx source for full Copyright notice                               *
+
+#ifndef ALITPCTRACKERCA_H
+#define ALITPCTRACKERCA_H
+
+#include "AliTracker.h"
+
+class AliTPCParam;
+class AliESD;   
+class TTree;
+class AliHLTTPCCAGBTracker;
+class AliHLTTPCCAPerformance;
+class AliTPCclusterMI;
+class AliTPCtrack;
+
+/**
+ * @class AliTPCtrackerCA
+ * 
+ * Interface from HLT TPC tracker AliHLTTPCCAGBTracker to off-line
+ * The reconstruction algorithm is based on the Cellular Automaton method
+ *
+ */
+class AliTPCtrackerCA : public AliTracker 
+{
+public:
+  AliTPCtrackerCA();
+  AliTPCtrackerCA(const AliTPCParam *par); 
+  AliTPCtrackerCA(const AliTPCtrackerCA &);
+  AliTPCtrackerCA & operator=(const AliTPCtrackerCA& );
+  virtual ~AliTPCtrackerCA();
+  //
+  Int_t RefitInward (AliESDEvent *);
+  Int_t PropagateBack(AliESDEvent *);
+  //
+  Int_t Clusters2Tracks (AliESDEvent *esd);
+
+  Int_t LoadClusters (TTree * tree);
+  void   UnloadClusters(){ return ; }
+  AliCluster * GetCluster(Int_t index) const;
+  Bool_t &DoHLTPerformance(){ return fDoHLTPerformance; }
+  //
+ protected:
+
+  const AliTPCParam *fParam;  //* TPC parameters
+  AliTPCclusterMI *fClusters; //* array of clusters
+  Int_t fNClusters;           //* N clusters
+  AliHLTTPCCAGBTracker *fHLTTracker; //* pointer to the HLT tracker
+  AliHLTTPCCAPerformance *fHLTPerformance; //* performance calculations
+  Bool_t fDoHLTPerformance; //* flag for call AliHLTTPCCAPerformance
+
+  ClassDef(AliTPCtrackerCA,1) 
+};
+
+
+#endif
+
+
index c92dfec1e14bd3147396aadd6db17ac6b5b05449..b2df7daf7ac3cabc7660f5d6dba04ff5a09f9a74 100644 (file)
@@ -47,16 +47,25 @@ CLASS_HDRS:=        AliHLTTPCTransform.h \
                AliHLTTPCEsdWriterComponent.h \
                AliHLTTPCHistogramHandlerComponent.h \
                AliHLTTPCClusterConverterComponent.h \
-               tracking-ca/AliHLTTPCCACell.h \
-               tracking-ca/AliHLTTPCCADisplay.h \
-               tracking-ca/AliHLTTPCCAHit.h \
-               tracking-ca/AliHLTTPCCAOutTrack.h \
-               tracking-ca/AliHLTTPCCAParam.h \
+               tracking-ca/AliHLT3DTrackParam.h \
+               tracking-ca/AliHLTTPCCATrack.h \
+               tracking-ca/AliHLTTPCCACell.h     \
+               tracking-ca/AliHLTTPCCAEndPoint.h     \
+               tracking-ca/AliHLTTPCCADisplay.h  \
+               tracking-ca/AliHLTTPCCATracker.h \
+               tracking-ca/AliHLTTPCCAHit.h      \
+               tracking-ca/AliHLTTPCCAOutTrack.h  \
+               tracking-ca/AliHLTTPCCATrackParam.h \
+               tracking-ca/AliHLTTPCCAParam.h     \
                tracking-ca/AliHLTTPCCARow.h \
+               tracking-ca/AliHLTTPCCAGrid.h \
+               tracking-ca/AliHLTTPCCAGBHit.h  \
+               tracking-ca/AliHLTTPCCAMCTrack.h  \
+               tracking-ca/AliHLTTPCCAGBTrack.h  \
+               tracking-ca/AliHLTTPCCAGBTracker.h \
+               tracking-ca/AliHLTTPCCAPerformance.h \
+               tracking-ca/AliTPCtrackerCA.h \
                tracking-ca/AliHLTTPCCATrackerComponent.h \
-               tracking-ca/AliHLTTPCCATracker.h \
-               tracking-ca/AliHLTTPCCATrack.h \
-               tracking-ca/AliHLTTPCCATrackPar.h \
                comp/AliHLTTPCCompDataCompressorHelper.h \
                comp/AliHLTTPCCompDumpComponent.h \
                comp/AliHLTTPCCompModelAnalysis.h \