CA track merger class added
authorsgorbuno <sgorbuno@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 31 Mar 2009 12:10:24 +0000 (12:10 +0000)
committersgorbuno <sgorbuno@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 31 Mar 2009 12:10:24 +0000 (12:10 +0000)
15 files changed:
HLT/TPCLib/tracking-ca/AliHLTTPCCADataCompressor.h [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCADisplay.cxx
HLT/TPCLib/tracking-ca/AliHLTTPCCAGBTracker.cxx
HLT/TPCLib/tracking-ca/AliHLTTPCCAGBTracker.h
HLT/TPCLib/tracking-ca/AliHLTTPCCAMergedTrack.h [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCAMerger.cxx [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCAMerger.h [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCAMergerOutput.h [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCAParam.cxx
HLT/TPCLib/tracking-ca/AliHLTTPCCAParam.h
HLT/TPCLib/tracking-ca/AliHLTTPCCASliceOutput.h [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCASliceTrack.h [new file with mode: 0644]
HLT/TPCLib/tracking-ca/AliHLTTPCCATrackParam.h
HLT/TPCLib/tracking-ca/AliHLTTPCCATracker.cxx
HLT/TPCLib/tracking-ca/AliHLTTPCCATracker.h

diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCADataCompressor.h b/HLT/TPCLib/tracking-ca/AliHLTTPCCADataCompressor.h
new file mode 100644 (file)
index 0000000..83f00f9
--- /dev/null
@@ -0,0 +1,86 @@
+//-*- Mode: C++ -*-
+// ************************************************************************
+// 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 ALIHLTTPCCADATACOMPRESSOR_H
+#define ALIHLTTPCCADATACOMPRESSOR_H
+
+#include "AliHLTTPCCADef.h"
+
+/**
+ * @class AliHLTTPCCADataCompressor
+ *
+ * The AliHLTTPCCADataCompressor class is used to
+ * pack and unpack diffferent data, such as TPC cluster IDs, posistion, amplitude etc
+ *
+ */
+class AliHLTTPCCADataCompressor
+{
+public:
+  
+  GPUhd() static UInt_t IRowIClu2IDrc( UInt_t iRow, UInt_t iCluster ){ 
+    return (iCluster<<8)+iRow; 
+  }
+
+  GPUhd() static UInt_t IDrc2IRow( UInt_t IDrc ){ return ( IDrc%256 ); }  
+  GPUhd() static UInt_t IDrc2IClu( UInt_t IDrc ){ return ( IDrc>>8  ); }  
+
+
+  GPUhd() static UInt_t ISliceIRowIClu2IDsrc( UInt_t iSlice, UInt_t iRow, UInt_t iCluster ){ 
+    return (iCluster<<14) + (iRow<<6) + iSlice; 
+  }
+
+  GPUhd() static UInt_t IDsrc2ISlice( UInt_t IDsrc ){  return (  IDsrc%64      ); }
+  GPUhd() static UInt_t IDsrc2IRow  ( UInt_t IDsrc ){  return ( (IDsrc>>6)%256 ); }  
+  GPUhd() static UInt_t IDsrc2IClu  ( UInt_t IDsrc ){  return (  IDsrc>>14     ); }  
+
+
+  GPUhd() static UShort_t YZ2UShort( Float_t Y, Float_t Z );
+  GPUhd() static Float_t  UShort2Y ( UShort_t iYZ );
+  GPUhd() static Float_t  UShort2Z ( UShort_t iYZ );
+  
+};
+
+
+// Inline methods
+
+
+GPUhd() inline UShort_t AliHLTTPCCADataCompressor::YZ2UShort( Float_t Y, Float_t Z )
+{ 
+  // compress Y and Z coordinates in range [-3., 3.] to 16 bits
+
+  const Float_t kMult = 255./6.;
+  Y = (Y+3.)*kMult;
+  Z = (Z+3.)*kMult;
+  if( Y<0. ) Y = 0.;
+  else if( Y>255. ) Y = 255.;
+  if( Z<0. ) Z = 0.;
+  else if( Z>255. ) Z = 255.;
+  UInt_t iY = static_cast<UInt_t>( Y );
+  UInt_t iZ = static_cast<UInt_t>( Z );
+  return static_cast<UShort_t>( (iY<<8) + iZ );
+}  
+
+GPUhd() inline Float_t AliHLTTPCCADataCompressor::UShort2Y( UShort_t iYZ )
+{ 
+  // extract Y coordinate from the compressed 16bits format to [-3.,3.]
+
+  const Float_t kMult = 6./255.; 
+  Float_t y = (iYZ >> 8);
+  return y*kMult - 3.;
+}  
+
+GPUhd() inline Float_t AliHLTTPCCADataCompressor::UShort2Z( UShort_t iYZ )
+{ 
+  // extract Z coordinate from the compressed 16bits format to [-3.,3.]
+
+  const Float_t kMult = 6./255.; 
+  Float_t z = (iYZ % 256);
+  return z*kMult - 3.;
+}
+
+#endif
index 5ffa20d..029a454 100644 (file)
@@ -668,11 +668,12 @@ Bool_t AliHLTTPCCADisplay::DrawTrack( AliHLTTPCCATrackParam t, Double_t Alpha, c
       if( mc.P()>=1. ) color = kRed;   
     }  
   }
-
+  std::cout<<"mark 1"<<std::endl;
   if( t.SinPhi()>.999 )  t.SetSinPhi( .999 );
   else if( t.SinPhi()<-.999 )  t.SetSinPhi( -.999 );
   if( t.CosPhi()>=0 ) t.SetCosPhi( TMath::Sqrt(1-t.SinPhi()*t.SinPhi() ));
   else t.SetCosPhi( -TMath::Sqrt(1-t.SinPhi()*t.SinPhi() ));
+  std::cout<<"mark 2"<<std::endl;
 
   //  Int_t iSlice = fSlice->Param().ISlice();
 
@@ -712,8 +713,10 @@ Bool_t AliHLTTPCCADisplay::DrawTrack( AliHLTTPCCATrackParam t, Double_t Alpha, c
     SetSliceTransform( alpha );
 
     //t.GetDCAPoint( x1, y1, z1, x1, y1, z1 );      
+  std::cout<<"mark 3"<<std::endl;
     Bool_t ok = tt.TransportToX(x1,.999);
-    if( 0&&ok ){    
+  std::cout<<"mark 4"<<std::endl;
+  if( 1||ok ){    
       x1 = tt.X();
       y1 = tt.Y();
       z1 = tt.Z();
@@ -728,14 +731,13 @@ Bool_t AliHLTTPCCADisplay::DrawTrack( AliHLTTPCCATrackParam t, Double_t Alpha, c
       x0=h.X()+j; y0=h.Y(); z1=h.Z();
       x1 = x0*hCos + y0*hSin;
       y1 = y0*hCos - x0*hSin;
-
       ok = tt.TransportToX(x1,.999);
-      if( 1||ok ){    
+      if( ok ){    
        x1 = tt.X();
        y1 = tt.Y();
        z1 = tt.Z();
       }
-
+      
       Slice2View(x1, y1, &x1, &y1 );
       vx[mHits] = x1;
       vy[mHits] = y1;
index d654c46..f094c5c 100644 (file)
@@ -24,8 +24,9 @@
 #include "AliHLTTPCCATracker.h"
 #include "AliHLTTPCCAGBTrack.h"
 #include "AliHLTTPCCATrackParam.h"
-//#include "AliHLTTPCCAEventHeader.h"
-
+#include "AliHLTTPCCAMerger.h"
+#include "AliHLTTPCCAMergerOutput.h"
+#include "AliHLTTPCCADataCompressor.h"
 #include "AliHLTTPCCAMath.h"
 #include "TStopwatch.h"
 
@@ -289,7 +290,8 @@ void AliHLTTPCCAGBTracker::FindTracks()
   //std::cout<<"Refit time = "<<timerM.CpuTime()*1.e3<<"ms"<<std::endl;
 
   TStopwatch timerMerge;
-  Merging();
+  //Merging(); 
+  Merging1(); 
   timerMerge.Stop();
   fStatTime[9]+=timerMerge.CpuTime();  
   //fTime+=timerMerge.CpuTime();
@@ -303,6 +305,86 @@ void AliHLTTPCCAGBTracker::FindTracks()
 #endif //DRAW
 }
 
+void AliHLTTPCCAGBTracker::Merging1()
+{
+  // test 
+
+#ifdef DRAW
+  AliHLTTPCCADisplay &disp = AliHLTTPCCADisplay::Instance();
+  AliHLTTPCCADisplay::Instance().SetTPCView();
+  AliHLTTPCCADisplay::Instance().DrawTPC();
+  AliHLTTPCCADisplay::Instance().DrawGBHits( *this );
+  disp.Ask(); 
+  std::cout<<"Slice tracks:"<<std::endl;
+  for( Int_t iSlice=0; iSlice<fNSlices; iSlice++ ){
+    AliHLTTPCCATracker &slice = fSlices[iSlice];
+    disp.SetCurrentSlice(&slice);    
+    for( Int_t itr=0; itr<*slice.NOutTracks(); itr++ ){
+      disp.DrawSliceOutTrack( itr, kBlue, 2. );
+    }
+  }
+  //AliHLTTPCCADisplay::Instance().DrawGBHits( *this );
+  disp.Ask(); 
+#endif //DRAW  
+
+
+  AliHLTTPCCAMerger merger;
+  merger.SetSliceParam( fSlices[0].Param() );
+  const AliHLTTPCCASliceOutput * sliceOutput[fNSlices];
+  for( Int_t i=0; i<fNSlices; i++ ) sliceOutput[i] = fSlices[i].Output();  
+  merger.Reconstruct( sliceOutput );  
+  
+  const AliHLTTPCCAMergerOutput &out = *(merger.Output());
+  
+  
+  if( fTrackHits ) delete[] fTrackHits;
+  fTrackHits = 0;
+  if(fTracks ) delete[] fTracks;
+  fTracks = 0;
+  fTrackHits = new Int_t [out.NTrackClusters()];
+  fTracks = new AliHLTTPCCAGBTrack[out.NTracks()];  
+  fNTracks = 0;
+
+  Int_t nTrackHits = 0;
+  
+  for( Int_t itr=0; itr<out.NTracks(); itr++ ){
+    const AliHLTTPCCAMergedTrack &track = out.Track( itr );
+
+    AliHLTTPCCAGBTrack &trackGB = fTracks[fNTracks];
+    trackGB.SetFirstHitRef( nTrackHits );
+    trackGB.SetNHits( track.NClusters() );
+    trackGB.SetParam( track.InnerParam() );
+    trackGB.SetAlpha( track.InnerAlpha() );
+    trackGB.SetDeDx( 0 );
+
+    for( Int_t icl=0; icl<track.NClusters(); icl++ ){
+      UInt_t  iDsrc = out.ClusterIDsrc( track.FirstClusterRef() + icl );
+      UInt_t iSlice = AliHLTTPCCADataCompressor::IDsrc2ISlice( iDsrc );
+      UInt_t iRow   = AliHLTTPCCADataCompressor::IDsrc2IRow( iDsrc );
+      UInt_t iClu   = AliHLTTPCCADataCompressor::IDsrc2IClu( iDsrc );    
+      fTrackHits[nTrackHits+icl] = fFirstSliceHit[iSlice] + fSlices[iSlice].Row(iRow).FirstHit() + iClu;
+    }              
+    nTrackHits+= track.NClusters();
+    fNTracks++;
+  }
+
+#ifdef DRAW
+  std::cout<<"Global tracks: "<<std::endl;
+  AliHLTTPCCADisplay::Instance().ClearView();
+  AliHLTTPCCADisplay::Instance().SetTPCView();
+  AliHLTTPCCADisplay::Instance().DrawTPC();
+  AliHLTTPCCADisplay::Instance().DrawGBHits( *this );
+  for( Int_t itr=0; itr<fNTracks; itr++ ){
+    std::cout<<itr<<" nhits= "<<fTracks[itr].NHits()<<std::endl;
+    AliHLTTPCCADisplay::Instance().DrawGBTrack( itr, kBlue, 2. );    
+    //AliHLTTPCCADisplay::Instance().Ask();
+  }
+  AliHLTTPCCADisplay::Instance().Ask();
+#endif
+
+}
+
+
 
 void AliHLTTPCCAGBTracker::FindTracks0()
 {
index 22b9d94..8da2a22 100644 (file)
@@ -84,6 +84,7 @@ public:
                          Float_t x2, Float_t y2, Float_t b00, Float_t b10, Float_t b11  );
 
   void Merging();
+  void Merging1();
 
   AliHLTTPCCATracker *Slices() const { return fSlices; }
   AliHLTTPCCAGBHit *Hits() const { return fHits; }
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCAMergedTrack.h b/HLT/TPCLib/tracking-ca/AliHLTTPCCAMergedTrack.h
new file mode 100644 (file)
index 0000000..771c4e3
--- /dev/null
@@ -0,0 +1,57 @@
+//-*- Mode: C++ -*-
+// ************************************************************************
+// 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 ALIHLTTPCCAMERGEDTRACK_H
+#define ALIHLTTPCCAMERGEDTRACK_H
+
+#include "AliHLTTPCCATrackParam.h"
+
+/**
+ * @class AliHLTTPCCAMergedTrack
+ * AliHLTTPCCAMergedTrack class is used to store TPC tracks,
+ * which are reconstructed by the TPCCATracker slice tracker.
+ * 
+ * The class contains:
+ * - fitted track parameters at its first row, the covariance matrix, \Chi^2, NDF (number of degrees of freedom ) 
+ * - n of clusters assigned to the track
+ * - index of its first cluster in corresponding cluster arrays
+ *
+ * The class is used to transport the data between AliHLTTPCCATracker{Component} and AliHLTTPCCAGBMerger{Component}
+ *
+ */
+class AliHLTTPCCAMergedTrack
+{
+ public:
+
+  GPUhd() Int_t NClusters()                         const { return fNClusters;       }
+  GPUhd() Int_t FirstClusterRef()                   const { return fFirstClusterRef; }
+  GPUhd() const AliHLTTPCCATrackParam &InnerParam() const { return fInnerParam;      }
+  GPUhd() const AliHLTTPCCATrackParam &OuterParam() const { return fOuterParam;      }
+  GPUhd() Float_t InnerAlpha()                      const { return fInnerAlpha;      }
+  GPUhd() Float_t OuterAlpha()                      const { return fOuterAlpha;      }
+
+  GPUhd() void SetNClusters      ( Int_t v )                  { fNClusters = v;       }
+  GPUhd() void SetFirstClusterRef( Int_t v )                  { fFirstClusterRef = v; }
+  GPUhd() void SetInnerParam( const AliHLTTPCCATrackParam &v) { fInnerParam = v;      }
+  GPUhd() void SetOuterParam( const AliHLTTPCCATrackParam &v) { fOuterParam = v;      }
+  GPUhd() void SetInnerAlpha( Float_t v )                       { fInnerAlpha = v;      }
+  GPUhd() void SetOuterAlpha( Float_t v )                       { fOuterAlpha = v;      }
+
+ private:
+  
+  AliHLTTPCCATrackParam fInnerParam; //* fitted track parameters at the TPC inner radius
+  AliHLTTPCCATrackParam fOuterParam; //* fitted track parameters at the TPC outer radius
+  Float_t fInnerAlpha;               //* alpha angle for the inner parameters
+  Float_t fOuterAlpha;               //* alpha angle for the outer parameters
+  Int_t fFirstClusterRef;            //* index of the first track cluster in corresponding cluster arrays
+  Int_t fNClusters;                  //* number of track clusters
+};
+
+
+#endif
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCAMerger.cxx b/HLT/TPCLib/tracking-ca/AliHLTTPCCAMerger.cxx
new file mode 100644 (file)
index 0000000..cf51209
--- /dev/null
@@ -0,0 +1,759 @@
+// $Id: AliHLTTPCCAMerger.cxx 30732 2009-01-22 23:02:02Z sgorbuno $
+// **************************************************************************
+// 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 "AliHLTTPCCASliceTrack.h"
+#include "AliHLTTPCCATracker.h"
+#include "AliHLTTPCCAGBTrack.h"
+#include "AliHLTTPCCATrackParam.h"
+
+#include "AliHLTTPCCAMerger.h"
+
+#include "AliHLTTPCCAMath.h"
+#include "TStopwatch.h"
+
+#include "AliHLTTPCCATrackParam.h"
+#include "AliHLTTPCCASliceTrack.h"
+#include "AliHLTTPCCASliceOutput.h"
+#include "AliHLTTPCCAMergedTrack.h"
+#include "AliHLTTPCCAMergerOutput.h"
+#include "AliHLTTPCCADataCompressor.h"
+#include "AliHLTTPCCAParam.h"
+
+
+AliHLTTPCCAMerger::AliHLTTPCCAMerger()
+  :
+  fSliceParam(),
+  fkSlices(0),
+  fOutput(0),  
+  fTrackInfos(0),
+  fMaxTrackInfos(0),
+  fClusterInfos(0),
+  fMaxClusterInfos(0)
+{
+  //* constructor
+}
+
+
+AliHLTTPCCAMerger::AliHLTTPCCAMerger(const AliHLTTPCCAMerger&)
+  : 
+  fSliceParam(),
+  fkSlices(0),
+  fOutput(0),  
+  fTrackInfos(0),
+  fMaxTrackInfos(0),
+  fClusterInfos(0),
+  fMaxClusterInfos(0)
+{
+  //* dummy
+}
+
+const AliHLTTPCCAMerger &AliHLTTPCCAMerger::operator=(const AliHLTTPCCAMerger&) const
+{
+  //* dummy
+  return *this;
+}
+
+AliHLTTPCCAMerger::~AliHLTTPCCAMerger()
+{
+  //* destructor
+  if( fTrackInfos ) delete[] fTrackInfos;
+  if( fClusterInfos ) delete[] fClusterInfos;
+  if( fOutput ) delete[] ((char*)(fOutput));
+}
+
+
+void AliHLTTPCCAMerger::Reconstruct( const AliHLTTPCCASliceOutput **SliceOutput )
+{
+  //* main merging routine
+
+  fkSlices = SliceOutput;
+  UnpackSlices();
+  Merging();
+}
+
+void AliHLTTPCCAMerger::UnpackSlices()
+{
+  //* unpack the cluster information from the slice tracks and initialize track info array
+
+  // get N tracks and N clusters in event
+  
+  Int_t nTracksTotal=0;
+  Int_t nTrackClustersTotal=0;
+  for( Int_t iSlice=0; iSlice<fgkNSlices; iSlice++ ){
+    nTracksTotal+=fkSlices[iSlice]->NTracks();
+    nTrackClustersTotal+=fkSlices[iSlice]->NTrackClusters();    
+  }
+
+  // book/clean memory if necessary
+  {
+    if( nTracksTotal>fMaxTrackInfos || ( fMaxTrackInfos>100 && nTracksTotal< 0.5*fMaxTrackInfos ) ){
+      if( fTrackInfos ) delete[] fTrackInfos;
+      fMaxTrackInfos = (Int_t ) (nTracksTotal*1.2);
+      fTrackInfos = new AliHLTTPCCASliceTrackInfo[fMaxTrackInfos];
+    }
+
+    if( nTrackClustersTotal>fMaxClusterInfos || ( fMaxClusterInfos>1000 && nTrackClustersTotal< 0.5*fMaxClusterInfos ) ){
+      if( fClusterInfos ) delete[] fClusterInfos;
+      fMaxClusterInfos = (Int_t ) (nTrackClustersTotal*1.2);
+      fClusterInfos = new AliHLTTPCCAClusterInfo [fMaxClusterInfos];
+    }
+
+    if( fOutput ) delete[] ( (char*)(fOutput));
+    Int_t size = fOutput->EstimateSize(nTracksTotal, nTrackClustersTotal);
+    fOutput = (AliHLTTPCCAMergerOutput*)(new float2[size/sizeof(float2)+1]);
+  }
+
+  // unpack track and cluster information
+  
+  Int_t nTracksCurrent = 0; 
+  Int_t nClustersCurrent = 0;
+
+  for( Int_t iSlice=0; iSlice<fgkNSlices; iSlice++ ){
+
+    const AliHLTTPCCASliceOutput &slice = *(fkSlices[iSlice]);
+    fSliceTrackInfoStart[ iSlice ] = nTracksCurrent;
+    fSliceNTrackInfos[ iSlice ] = 0;
+
+    for( Int_t itr=0; itr<slice.NTracks(); itr++ ){
+  
+      const AliHLTTPCCASliceTrack &sTrack = slice.Track( itr );
+      AliHLTTPCCATrackParam t0 = sTrack.Param();
+      Int_t nCluNew = 0;
+      
+      for( Int_t iTrClu=0; iTrClu<sTrack.NClusters(); iTrClu++ ){
+       
+       // unpack cluster information
+       
+       AliHLTTPCCAClusterInfo &clu = fClusterInfos[nClustersCurrent + nCluNew];
+       Int_t ic = sTrack.FirstClusterRef() + iTrClu;
+
+       clu.SetISlice( iSlice );
+       clu.SetIRow( AliHLTTPCCADataCompressor::IDrc2IRow( slice.ClusterIDrc( ic ) ) );
+       clu.SetIClu( AliHLTTPCCADataCompressor::IDrc2IClu( slice.ClusterIDrc( ic ) ) ); 
+       clu.SetPackedAmp( slice.ClusterPackedAmp( ic ) );
+       float2 yz = slice.ClusterUnpackedYZ( ic );
+       clu.SetY( yz.x );
+       clu.SetZ( yz.y );
+
+       if( !t0.TransportToX( fSliceParam.RowX( clu.IRow() ), .999 ) ) continue;
+       Float_t err2Y, err2Z;
+       fSliceParam.GetClusterErrors2( clu.IRow(), clu.Z(), t0.SinPhi(), t0.CosPhi(), t0.DzDs(), err2Y, err2Z );
+       
+       clu.SetErr2Y( err2Y );
+       clu.SetErr2Z( err2Z );
+       nCluNew++ ;
+      }
+      if( nCluNew<.8*sTrack.NClusters() ) continue;
+      
+      // refit the track 
+      
+      Int_t hits[1000];
+      Int_t nHits = nCluNew; 
+      for( Int_t i=0; i<nHits; i++ ) hits[i] = nClustersCurrent + i;
+
+      AliHLTTPCCATrackParam startPoint = sTrack.Param();
+      AliHLTTPCCATrackParam endPoint = startPoint;
+      Float_t startAlpha = fSliceParam.Alpha( iSlice );
+      Float_t endAlpha = startAlpha;
+      
+      if( !FitTrack( endPoint, endAlpha, startPoint, startAlpha, hits, nHits, 0 ) ) continue;
+      startPoint = endPoint;
+      startAlpha = endAlpha;
+      if( !FitTrack( startPoint, startAlpha, endPoint, endAlpha, hits, nHits, 1 ) ) continue;
+      if( nHits<.8*sTrack.NClusters() ) continue;
+
+      // store the track
+      
+      AliHLTTPCCASliceTrackInfo &track = fTrackInfos[nTracksCurrent];      
+      track.fInnerParam = startPoint;
+      track.fInnerAlpha = startAlpha;
+      track.fOuterParam = endPoint;
+      track.fOuterAlpha = endAlpha;
+      track.fFirstClusterRef = nClustersCurrent;
+      track.fNClusters = nHits;
+      track.fPrevNeighbour = -1;
+      track.fNextNeighbour = -1;
+      track.fUsed = 0;
+      
+      for( Int_t i=0; i<nHits; i++ ) 
+       fClusterInfos[nClustersCurrent + i] = fClusterInfos[hits[i]];
+      nTracksCurrent++;
+      fSliceNTrackInfos[ iSlice ]++;
+      nClustersCurrent+=nHits;      
+    }
+  }
+}
+
+
+
+Bool_t AliHLTTPCCAMerger::FitTrack( AliHLTTPCCATrackParam &T, Float_t &Alpha, 
+                                   AliHLTTPCCATrackParam t0, Float_t Alpha0, 
+                                   Int_t hits[], Int_t &NTrackHits, Bool_t dir )
+{
+  // Fit the track
+
+  AliHLTTPCCATrackParam::AliHLTTPCCATrackFitParam fitPar;
+  AliHLTTPCCATrackParam t = t0;
+  
+  Bool_t first = 1;
+  t0.CalculateFitParameters( fitPar, fSliceParam.Bz() );
+
+  Int_t hitsNew[1000];
+  Int_t nHitsNew = 0;
+
+  for( Int_t ihit=0; ihit<NTrackHits; ihit++){
+    Int_t jhit = dir ?(NTrackHits-1-ihit) :ihit;
+    AliHLTTPCCAClusterInfo &h = fClusterInfos[hits[jhit]];
+    Int_t iSlice = h.ISlice();
+
+    Float_t sliceAlpha =  fSliceParam.Alpha( iSlice );
+
+    if( CAMath::Abs( sliceAlpha - Alpha0)>1.e-4 ){
+      if( ! t.RotateNoCos(  sliceAlpha - Alpha0, t0, .999 ) ) continue;
+      Alpha0 = sliceAlpha;
+    }
+
+    Float_t x = fSliceParam.RowX( h.IRow() );
+    
+    if( !t.TransportToXWithMaterial( x, t0, fitPar ) ) continue;
+
+    if( first ){
+      t.SetCov( 0, 10 );
+      t.SetCov( 1,  0 );
+      t.SetCov( 2, 10 );
+      t.SetCov( 3,  0 );
+      t.SetCov( 4,  0 );
+      t.SetCov( 5,  1 );
+      t.SetCov( 6,  0 );
+      t.SetCov( 7,  0 );
+      t.SetCov( 8,  0 );
+      t.SetCov( 9,  1 );
+      t.SetCov(10,  0 );
+      t.SetCov(11,  0 );
+      t.SetCov(12,  0 );
+      t.SetCov(13,  0 );
+      t.SetCov(14,  1 );
+      t.SetChi2( 0 );
+      t.SetNDF( -5 );
+      t0.CalculateFitParameters( fitPar, fSliceParam.Bz() );
+    }
+  
+    if( !t.Filter2NoCos( h.Y(), h.Z(), h.Err2Y(), h.Err2Z() ) ) continue;                  
+    first = 0;
+
+    hitsNew[nHitsNew++] = hits[jhit];
+  }
+  
+
+  if( CAMath::Abs(t.Kappa())<1.e-8 ) t.SetKappa( 1.e-8 );
+  
+  Bool_t ok=1;
+  
+  const Float_t *c = t.Cov();
+  for( Int_t i=0; i<15; i++ ) ok = ok && finite(c[i]);
+  for( Int_t i=0; i<5; i++ ) ok = ok && finite(t.Par()[i]);
+  ok = ok && (t.GetX()>50);
+  
+  if( c[0]<=0 || c[2]<=0 || c[5]<=0 || c[9]<=0 || c[14]<=0 ) ok = 0;
+  if( c[0]>5. || c[2]>5. || c[5]>2. || c[9]>2 || c[14]>2 ) ok = 0;
+  
+  if( CAMath::Abs(t.SinPhi())>.99 ) ok = 0;
+  else if( t0.CosPhi()>=0 ) t.SetCosPhi( CAMath::Sqrt(1.-t.SinPhi()*t.SinPhi()) );
+  else t.SetCosPhi( -CAMath::Sqrt(1.-t.SinPhi()*t.SinPhi()) );
+
+  if( ok ){
+    T = t;
+    Alpha = Alpha0;
+    NTrackHits = nHitsNew;
+    for( Int_t i=0; i<NTrackHits; i++ ){
+      hits[dir ?(NTrackHits-1-i) :i] = hitsNew[i];
+    }
+  }
+  return ok;
+}
+
+
+Float_t AliHLTTPCCAMerger::GetChi2( Float_t x1, Float_t y1, Float_t a00, Float_t a10, Float_t a11, 
+                                   Float_t x2, Float_t y2, Float_t b00, Float_t b10, Float_t b11  )
+{
+  //* Calculate Chi2/ndf deviation   
+
+  Float_t d[2]={ x1-x2, y1-y2 };
+
+  Float_t mSi[3] = { a00 + b00, a10 + b10, a11 + b11 };
+
+  Float_t s = ( mSi[0]*mSi[2] - mSi[1]*mSi[1] );
+
+  if( s < 1.E-10 ) return 10000.;
+    
+  Float_t mS[3] = { mSi[2], -mSi[1], mSi[0] };      
+
+  return TMath::Abs( ( ( mS[0]*d[0] + mS[1]*d[1] )*d[0]
+                      +(mS[1]*d[0] + mS[2]*d[1] )*d[1] )/s/2);
+
+}
+
+  
+
+void AliHLTTPCCAMerger::MakeBorderTracks( Int_t iSlice, Int_t iBorder, AliHLTTPCCABorderTrack B[], Int_t &nB )
+{
+  //* prepare slice tracks for merging with next/previous/same sector
+  //* each track transported to the border line, 
+  //* in some cases both inner and outer parameters of the track are transported 
+
+  static int statAll=0, statOK=0;  
+  nB = 0;  
+  Float_t dAlpha = fSliceParam.DAlpha() /2;
+  Float_t x0 = 0;
+
+  if( iBorder==0 ){ // transport to the left age of the sector and rotate horisontally
+    dAlpha = dAlpha - CAMath::Pi()/2 ;
+  } else if( iBorder==1 ){ //  transport to the right age of the sector and rotate horisontally
+    dAlpha = -dAlpha - CAMath::Pi()/2 ;  
+  } else if( iBorder==2 ){ // transport to the left age of the sector and rotate vertically
+    dAlpha = dAlpha;
+    x0 = fSliceParam.RowX( 63 );
+  }else if( iBorder==3 ){ // transport to the right age of the sector and rotate vertically
+    dAlpha = -dAlpha;
+    x0 =  fSliceParam.RowX( 63 );
+  } else if( iBorder==4 ){ // transport to the middle of the sector, w/o rotation
+    dAlpha = 0;
+    x0 = fSliceParam.RowX(63);
+  }
+
+  for (Int_t itr=0; itr<fSliceNTrackInfos[iSlice]; itr++) {
+
+    AliHLTTPCCASliceTrackInfo &track = fTrackInfos[ fSliceTrackInfoStart[iSlice] + itr ];
+
+    AliHLTTPCCATrackParam t0 = track.fInnerParam;
+    AliHLTTPCCATrackParam t1 = track.fOuterParam;
+
+    const Float_t maxSin = CAMath::Sin(60./180.*CAMath::Pi());
+
+    Bool_t ok0 = t0.Rotate( dAlpha, maxSin );
+    Bool_t ok1 = t1.Rotate( dAlpha, maxSin );
+    
+    Bool_t do0 = ok0;
+    Bool_t do1 = ok1 && ( !ok0 || t1.CosPhi()*t0.CosPhi()<0 );
+    
+    if( ok0 && !do1 && ok1 && (t1.X() < t0.X()) ){
+      do0 = 0;
+      do1 = 1;
+    }
+
+    if( do0 ){
+      AliHLTTPCCABorderTrack &b = B[nB];
+      b.fOK = 1;
+      b.fITrack = itr;
+      b.fNHits = track.fNClusters;
+      b.fIRow = fClusterInfos[ track.fFirstClusterRef + 0 ].IRow();
+      b.fParam = t0;
+      b.fX = t0.GetX();
+      if( b.fParam.TransportToX( x0, maxSin ) ) nB++;
+    }
+    if( do1 ){
+      AliHLTTPCCABorderTrack &b = B[nB];
+      b.fOK = 1;
+      b.fITrack = itr;
+      b.fNHits = track.fNClusters;
+      b.fIRow = fClusterInfos[ track.fFirstClusterRef + track.fNClusters-1 ].IRow();
+      b.fParam = t1;    
+      b.fX = t0.GetX();
+      if( b.fParam.TransportToX( x0, maxSin ) ) nB++;
+    }
+    if( do0 || do1 ) statOK++;
+    statAll++;
+  }
+}
+
+
+
+void AliHLTTPCCAMerger::SplitBorderTracks( Int_t iSlice1, AliHLTTPCCABorderTrack B1[], Int_t N1,
+                                          Int_t iSlice2, AliHLTTPCCABorderTrack B2[], Int_t N2 
+                                          )
+{
+  //* split two sets of tracks
+
+  Float_t factor2ys = 1.;//1.5;//SG!!!
+  Float_t factor2zt = 1.;//1.5;//SG!!!
+  Float_t factor2k = 2.0;//2.2;
+
+  factor2k  = 3.5*3.5*factor2k*factor2k;
+  factor2ys = 3.5*3.5*factor2ys*factor2ys;
+  factor2zt = 3.5*3.5*factor2zt*factor2zt;
+
+  Int_t minNPartHits = 10;//SG!!!
+  Int_t minNTotalHits = 20;
+
+  //Float_t maxDX = fSliceParam.RowX(40) -  fSliceParam.RowX(0);
+
+  for (Int_t i1=0; i1<N1; i1++) {      
+    AliHLTTPCCABorderTrack &b1 = B1[i1];
+    if( !b1.fOK ) continue;
+    if( b1.fNHits < minNPartHits ) continue;
+    AliHLTTPCCATrackParam &t1 = b1.fParam;
+    Int_t iBest2 = -1;
+    Int_t lBest2 = 0;
+    Int_t start2 = (iSlice1!=iSlice2) ?0 :i1+1;
+    for (Int_t i2=start2; i2<N2; i2++) {
+      AliHLTTPCCABorderTrack &b2 = B2[i2];
+      if( !b2.fOK ) continue;
+      if( b2.fNHits < minNPartHits ) continue;
+      if( b2.fNHits < lBest2 ) continue;
+      if( b1.fNHits + b2.fNHits < minNTotalHits ) continue;
+
+      //if( TMath::Abs(b1.fX - b2.fX)>maxDX ) continue;
+
+      AliHLTTPCCATrackParam &t2 = b2.fParam;
+
+      Float_t c= t2.CosPhi()*t1.CosPhi()>=0 ?1 :-1;
+      Float_t dk = t2.Kappa() - c*t1.Kappa(); 
+      Float_t s2k = t2.Err2Kappa() + t1.Err2Kappa();
+      
+      if( dk*dk>factor2k*s2k ) continue;     
+
+
+      Float_t chi2ys = GetChi2( t1.Y(),c*t1.SinPhi(),t1.Cov()[0],c*t1.Cov()[3],t1.Cov()[5], 
+                               t2.Y(),  t2.SinPhi(),t2.Cov()[0],  t2.Cov()[3],t2.Cov()[5] );
+
+      if( chi2ys>factor2ys ) continue;
+
+      Float_t chi2zt = GetChi2( t1.Z(),c*t1.DzDs(),t1.Cov()[2],c*t1.Cov()[7],t1.Cov()[9], 
+                               t2.Z(),  t2.DzDs(),t2.Cov()[2],  t2.Cov()[7],t2.Cov()[9] );
+            
+      if( chi2zt>factor2zt ) continue;
+      
+      lBest2 = b2.fNHits;
+      iBest2 = b2.fITrack;
+    }
+      
+    if( iBest2 <0 ) continue;
+
+    AliHLTTPCCASliceTrackInfo &newTrack1 = fTrackInfos[fSliceTrackInfoStart[iSlice1]+b1.fITrack ];
+    
+    AliHLTTPCCASliceTrackInfo &newTrack2 = fTrackInfos[fSliceTrackInfoStart[iSlice2]+iBest2 ];
+
+    Int_t old1 = newTrack2.fPrevNeighbour;
+  
+    if( old1 >= 0 ){
+      AliHLTTPCCASliceTrackInfo &oldTrack1 = fTrackInfos[fSliceTrackInfoStart[iSlice1]+old1];
+      if( oldTrack1.fNClusters  < newTrack1.fNClusters ){
+       newTrack2.fPrevNeighbour = -1;
+       oldTrack1.fNextNeighbour = -1;  
+      } else continue;
+    }
+    Int_t old2 = newTrack1.fNextNeighbour;
+    if( old2 >= 0 ){
+      AliHLTTPCCASliceTrackInfo &oldTrack2 = fTrackInfos[fSliceTrackInfoStart[iSlice2]+old2];
+      if( oldTrack2.fNClusters < newTrack2.fNClusters ){
+       oldTrack2.fPrevNeighbour = -1;
+      } else continue;
+    }
+    newTrack1.fNextNeighbour = iBest2; 
+    newTrack2.fPrevNeighbour = b1.fITrack;     
+  }  
+  
+}
+
+
+void AliHLTTPCCAMerger::Merging()
+{
+  //* track merging between slices
+
+
+  // for each slice set number of the next neighbouring slice
+     
+  Int_t nextSlice[100], prevSlice[100];
+
+  for( Int_t iSlice=0; iSlice<fgkNSlices; iSlice++ ){
+    nextSlice[iSlice] = iSlice + 1;
+    prevSlice[iSlice] = iSlice - 1;
+  }
+  Int_t mid = fgkNSlices/2 - 1 ;
+  Int_t last = fgkNSlices - 1 ;
+  if( mid<0 ) mid = 0; // to avoid compiler warning
+  if( last<0 ) last = 0; // 
+  nextSlice[ mid ] = 0;
+  prevSlice[ 0 ] = mid;
+  nextSlice[ last ] = fgkNSlices/2;
+  prevSlice[ fgkNSlices/2 ] = last;
+  
+  Int_t maxNSliceTracks = 0;
+  for( Int_t iSlice=0; iSlice<fgkNSlices; iSlice++ ){
+    if( maxNSliceTracks < fSliceNTrackInfos[iSlice] ) maxNSliceTracks = fSliceNTrackInfos[iSlice];
+  }
+  
+  if(1){// merging track segments withing one slice 
+    
+    AliHLTTPCCABorderTrack bord[maxNSliceTracks*10];
+    
+    AliHLTTPCCASliceTrackInfo *tmpT = new AliHLTTPCCASliceTrackInfo[maxNSliceTracks];
+    AliHLTTPCCAClusterInfo *tmpH = new AliHLTTPCCAClusterInfo[fMaxClusterInfos];
+
+    for( Int_t iSlice=0; iSlice<fgkNSlices; iSlice++ ){         
+
+      Int_t nBord=0;
+      MakeBorderTracks( iSlice, 4, bord, nBord );   
+      SplitBorderTracks( iSlice, bord, nBord, iSlice, bord, nBord );    
+
+      Int_t nTr=0, nH=0;
+      Int_t sliceFirstClusterRef = 0;
+      for( Int_t itr=0; itr<fSliceNTrackInfos[iSlice]; itr++ ){
+       AliHLTTPCCASliceTrackInfo &track = fTrackInfos[ fSliceTrackInfoStart[iSlice]+itr];
+       if( itr==0 ) sliceFirstClusterRef = track.fFirstClusterRef;
+       track.fPrevNeighbour = -1;
+       if( track.fNextNeighbour == -2 ){
+         track.fNextNeighbour = -1;
+         continue;
+       }
+       AliHLTTPCCASliceTrackInfo &trackNew = tmpT[nTr];
+       trackNew = track;
+       trackNew.fFirstClusterRef = sliceFirstClusterRef + nH;
+
+       for( Int_t ih=0; ih<track.fNClusters; ih++ ) tmpH[nH+ih] = fClusterInfos[track.fFirstClusterRef+ih];
+       nTr++;
+       nH+=track.fNClusters;
+
+       int jtr =  track.fNextNeighbour;
+
+       if( jtr<0 ) continue;
+       AliHLTTPCCASliceTrackInfo &neighTrack = fTrackInfos[ fSliceTrackInfoStart[iSlice]+jtr];
+       
+       track.fNextNeighbour = -1;
+       neighTrack.fNextNeighbour = -2;
+
+       for( Int_t ih=0; ih<neighTrack.fNClusters; ih++ ) 
+         tmpH[nH+ih] = fClusterInfos[neighTrack.fFirstClusterRef+ih];
+
+       trackNew.fNClusters += neighTrack.fNClusters;
+       trackNew.fNextNeighbour = -1;
+       nH+=neighTrack.fNClusters;
+       if( neighTrack.fInnerParam.X() < track.fInnerParam.X() ) trackNew.fInnerParam = neighTrack.fInnerParam;
+       if( neighTrack.fOuterParam.X() > track.fOuterParam.X() ) trackNew.fOuterParam = neighTrack.fOuterParam;
+      }
+      
+      fSliceNTrackInfos[iSlice] = nTr;
+      for( Int_t itr=0; itr<nTr; itr++ ) fTrackInfos[ fSliceTrackInfoStart[iSlice]+itr] = tmpT[itr];
+      for( Int_t ih=0; ih<nH; ih++ ) fClusterInfos[sliceFirstClusterRef + ih] = tmpH[ih];
+
+    }
+    delete[] tmpT;
+    delete[] tmpH;
+  }
+
+
+  //* merging tracks between slices      
+
+  
+  // arrays for the rotated track parameters
+
+  AliHLTTPCCABorderTrack 
+    *bCurr0 = new AliHLTTPCCABorderTrack[maxNSliceTracks*10], 
+    *bNext0 = new AliHLTTPCCABorderTrack[maxNSliceTracks*10],
+    *bCurr = new AliHLTTPCCABorderTrack[maxNSliceTracks*10], 
+    *bNext = new AliHLTTPCCABorderTrack[maxNSliceTracks*10];
+
+  for( Int_t iSlice=0; iSlice<fgkNSlices; iSlice++ ){
+    
+    Int_t jSlice = nextSlice[iSlice];
+    
+    Int_t nCurr0 = 0, nNext0 = 0;
+    Int_t nCurr = 0, nNext = 0;
+
+    MakeBorderTracks( iSlice, 0, bCurr, nCurr );
+    MakeBorderTracks( jSlice, 1, bNext, nNext );
+    MakeBorderTracks( iSlice, 2, bCurr0, nCurr0 );
+    MakeBorderTracks( jSlice, 3, bNext0, nNext0 );
+    
+    SplitBorderTracks( iSlice, bCurr0, nCurr0, jSlice, bNext0, nNext0 );   
+    SplitBorderTracks( iSlice, bCurr, nCurr, jSlice, bNext, nNext );    
+  }
+
+  if( bCurr0 ) delete[] bCurr0;
+  if( bNext0 ) delete[] bNext0;
+  if( bCurr  ) delete[] bCurr;
+  if( bNext  ) delete[] bNext;  
+
+
+  //static Int_t nRejected = 0;
+    
+  Int_t nOutTracks = 0;
+  Int_t nOutTrackClusters = 0;
+
+  AliHLTTPCCAMergedTrack *outTracks = new AliHLTTPCCAMergedTrack[fMaxTrackInfos];
+  UInt_t   *outClusterIDsrc = new UInt_t [fMaxClusterInfos];
+  UChar_t  *outClusterPackedAmp = new UChar_t [fMaxClusterInfos];
+  
+  for( Int_t iSlice = 0; iSlice<fgkNSlices; iSlice++ ){
+
+    for( Int_t itr=0; itr<fSliceNTrackInfos[iSlice]; itr++ ){
+
+      AliHLTTPCCASliceTrackInfo &track = fTrackInfos[fSliceTrackInfoStart[iSlice]+itr];
+
+      if( track.fUsed ) continue;
+      if( track.fPrevNeighbour>=0 ) continue;
+
+      AliHLTTPCCATrackParam startPoint = track.fInnerParam, endPoint = track.fOuterParam;
+      Float_t startAlpha = track.fInnerAlpha, endAlpha = track.fOuterAlpha;      
+
+      Int_t hits[2000];
+      Int_t firstHit = 1000;
+      Int_t nHits = 0;
+      Int_t jSlice = iSlice;
+      Int_t jtr = itr;
+
+      {
+       track.fUsed = 1;
+       for( Int_t jhit=0; jhit<track.fNClusters; jhit++){
+         Int_t id = track.fFirstClusterRef + jhit;
+         hits[firstHit+jhit] = id;
+       }
+       nHits=track.fNClusters;
+       jtr = track.fNextNeighbour;
+       jSlice = nextSlice[iSlice];                     
+      }
+
+      while( jtr >=0 ){
+       AliHLTTPCCASliceTrackInfo &segment = fTrackInfos[fSliceTrackInfoStart[jSlice]+jtr];
+       if( segment.fUsed ) break;
+       segment.fUsed = 1;
+       Bool_t dir = 0;
+       Int_t startHit = firstHit+ nHits;
+       Float_t d00 = startPoint.GetDistXZ2(segment.fInnerParam );
+       Float_t d01 = startPoint.GetDistXZ2(segment.fOuterParam );
+       Float_t d10 = endPoint.GetDistXZ2(segment.fInnerParam);
+       Float_t d11 = endPoint.GetDistXZ2(segment.fOuterParam );
+       if( d00<=d01 && d00<=d10 && d00<=d11 ){
+         startPoint = segment.fOuterParam;
+         startAlpha = segment.fOuterAlpha;
+         dir = 1;
+         firstHit -= segment.fNClusters;
+         startHit = firstHit;
+       }else if( d01<=d10 && d01<=d11 ){
+         startPoint = segment.fInnerParam;
+         startAlpha = segment.fInnerAlpha;
+         dir = 0;
+         firstHit -= segment.fNClusters;
+         startHit = firstHit;
+       }else if( d10<=d11 ){
+         endPoint = segment.fOuterParam;
+         endAlpha = segment.fOuterAlpha;
+         dir = 0;
+       }else{
+         endPoint = segment.fInnerParam;
+         endAlpha = segment.fInnerAlpha;
+         dir = 1;
+       }
+       
+       for( Int_t jhit=0; jhit<segment.fNClusters; jhit++){
+         Int_t id = segment.fFirstClusterRef + jhit;
+         hits[startHit+(dir ?(segment.fNClusters-1-jhit) :jhit)] = id;
+       }
+       nHits+=segment.fNClusters;
+       jtr = segment.fNextNeighbour;
+       jSlice = nextSlice[jSlice];                     
+      }
+
+      if( endPoint.X() < startPoint.X() ){ // swap
+       for( Int_t i=0; i<nHits; i++ ) hits[i] = hits[firstHit+nHits-1-i];
+       firstHit = 0;
+      }
+      
+      if( nHits < 30 ) continue;     //SG!!!
+
+      // refit 
+
+      // need best t0!!!SG
+
+      endPoint = startPoint;
+      if( !FitTrack( endPoint, endAlpha, startPoint, startAlpha, hits+firstHit, nHits, 0 ) ) continue;
+      if( !FitTrack( startPoint, startAlpha, endPoint, endAlpha, hits+firstHit, nHits, 1 ) ) continue;
+
+      if( nHits < 30 ) continue;     //SG!!!    
+      
+      AliHLTTPCCATrackParam &p = startPoint;
+      AliHLTTPCCATrackParam::AliHLTTPCCATrackFitParam fitPar;
+      p.CalculateFitParameters( fitPar, fSliceParam.Bz() );
+      
+      {
+       Double_t xTPC=83.65; //SG!!!
+       Double_t dAlpha = 0.00609235;
+       
+       if( p.TransportToXWithMaterial( xTPC, fitPar ) ){
+         Double_t y=p.GetY();
+         Double_t ymax=xTPC*CAMath::Tan(dAlpha/2.); 
+         if (y > ymax) {
+           if( p.Rotate( dAlpha ) ){ startAlpha+=dAlpha;  p.TransportToXWithMaterial( xTPC, fitPar ); }
+         } else if (y <-ymax) {
+           if( p.Rotate( -dAlpha ) ){  startAlpha-=dAlpha; p.TransportToXWithMaterial( xTPC, fitPar );}
+         }
+       }
+      }
+      
+      {
+       Bool_t ok=1;
+       
+       const Float_t *c = p.Cov();
+       for( Int_t i=0; i<15; i++ ) ok = ok && finite(c[i]);
+       for( Int_t i=0; i<5; i++ ) ok = ok && finite(p.Par()[i]);
+       ok = ok && (p.GetX()>50);
+       
+       if( c[0]<=0 || c[2]<=0 || c[5]<=0 || c[9]<=0 || c[14]<=0 ) ok = 0;
+       if( c[0]>5. || c[2]>5. || c[5]>2. || c[9]>2 || c[14]>2 ) ok = 0;
+       if(!ok) continue;       
+      }
+
+      AliHLTTPCCAMergedTrack &mergedTrack = outTracks[nOutTracks];
+      mergedTrack.SetNClusters(nHits);
+      mergedTrack.SetFirstClusterRef(nOutTrackClusters);
+      mergedTrack.SetInnerParam(startPoint);
+      mergedTrack.SetInnerAlpha(startAlpha);
+      mergedTrack.SetOuterParam(endPoint);
+      mergedTrack.SetOuterAlpha(endAlpha);
+      for( Int_t i = 0; i<nHits; i++ ){
+       AliHLTTPCCAClusterInfo &clu = fClusterInfos[hits[firstHit+i]];
+       outClusterIDsrc[nOutTrackClusters+i] = 
+         AliHLTTPCCADataCompressor::ISliceIRowIClu2IDsrc(clu.ISlice(), clu.IRow(), clu.IClu());
+       outClusterPackedAmp[nOutTrackClusters+i]=clu.PackedAmp();
+      }
+      
+      nOutTracks++;
+      nOutTrackClusters+= nHits;
+    }
+  }
+
+  fOutput->SetNTracks( nOutTracks );
+  fOutput->SetNTrackClusters( nOutTrackClusters );
+  fOutput->SetPointers();
+
+  for( Int_t itr=0; itr<nOutTracks; itr++ ) fOutput->SetTrack( itr, outTracks[itr] );
+
+  for( Int_t ic=0; ic<nOutTrackClusters; ic++ ){
+    fOutput->SetClusterIDsrc( ic, outClusterIDsrc[ic] );
+    fOutput->SetClusterPackedAmp( ic, outClusterPackedAmp[ic] );
+  }
+  delete[] outTracks;
+  delete[] outClusterIDsrc;
+  delete[] outClusterPackedAmp;
+}
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCAMerger.h b/HLT/TPCLib/tracking-ca/AliHLTTPCCAMerger.h
new file mode 100644 (file)
index 0000000..d72da55
--- /dev/null
@@ -0,0 +1,130 @@
+//-*- Mode: C++ -*-
+// ************************************************************************
+// 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 ALIHLTTPCCAMERGER_H
+#define ALIHLTTPCCAMERGER_H
+
+#include "AliHLTTPCCADef.h"
+#include "AliHLTTPCCAParam.h"
+
+#if !defined(HLTCA_GPUCODE)
+#include <iostream>
+#endif
+
+class AliHLTTPCCATrackParam;
+class AliHLTTPCCASliceTrack;
+class AliHLTTPCCASliceOutput;
+class AliHLTTPCCAMergedTrack;
+class AliHLTTPCCAMergerOutput;
+
+/**
+ * @class AliHLTTPCCAMerger
+ * 
+ */
+class AliHLTTPCCAMerger
+{
+
+public:
+
+  AliHLTTPCCAMerger();
+  AliHLTTPCCAMerger(const AliHLTTPCCAMerger&);
+  const AliHLTTPCCAMerger &operator=(const AliHLTTPCCAMerger&) const;
+  ~AliHLTTPCCAMerger();
+
+  void SetSliceParam( const AliHLTTPCCAParam &v ){ fSliceParam = v; }
+
+  void Reconstruct( const AliHLTTPCCASliceOutput **Slices );
+
+  const AliHLTTPCCAMergerOutput * Output() const { return fOutput; }
+  
+ private:
+  
+  class AliHLTTPCCAClusterInfo{
+
+  public:
+    
+    UInt_t  ISlice()    const { return fISlice;    }
+    UInt_t  IRow()      const { return fIRow;      }
+    UInt_t  IClu()      const { return fIClu;      }
+    UChar_t PackedAmp() const { return fPackedAmp; }
+    Float_t Y()         const { return fY;         }
+    Float_t Z()         const { return fZ;         }
+    Float_t Err2Y()     const { return fErr2Y;     }
+    Float_t Err2Z()     const { return fErr2Z;     }
+    
+    void SetISlice    ( UInt_t v  ) { fISlice    = v; }
+    void SetIRow      ( UInt_t v  ) { fIRow      = v; }
+    void SetIClu      ( UInt_t v  ) { fIClu      = v; }
+    void SetPackedAmp ( UChar_t v ) { fPackedAmp = v; }
+    void SetY         ( Float_t v ) { fY         = v; } 
+    void SetZ         ( Float_t v ) { fZ         = v; } 
+    void SetErr2Y     ( Float_t v ) { fErr2Y     = v; } 
+    void SetErr2Z     ( Float_t v ) { fErr2Z     = v; } 
+
+  private:
+
+    UInt_t fISlice;            // slice number
+    UInt_t fIRow;              // row number
+    UInt_t fIClu;              // cluster number
+    UChar_t fPackedAmp; // packed cluster amplitude
+    Float_t fY;                // y position (slice coord.system)
+    Float_t fZ;                // z position (slice coord.system)
+    Float_t fErr2Y;            // Squared measurement error of y position
+    Float_t fErr2Z;            // Squared measurement error of z position
+  };
+
+  struct AliHLTTPCCASliceTrackInfo{
+
+    AliHLTTPCCATrackParam fInnerParam; // inner parameters
+    AliHLTTPCCATrackParam fOuterParam; // outer parameters
+    Float_t fInnerAlpha;                 // alpha angle for inner parameters
+    Float_t fOuterAlpha;                 // alpha angle for outer parameters
+    Int_t fNClusters;                  // N clusters
+    Int_t fFirstClusterRef; //index of the first track cluster in the global cluster array
+    Int_t fPrevNeighbour; // neighbour in the previous slise
+    Int_t fNextNeighbour; // neighbour in the next slise
+    Bool_t fUsed;         // is the slice track already merged
+  };
+
+  struct AliHLTTPCCABorderTrack{
+
+    AliHLTTPCCABorderTrack(): fParam(), fITrack(0), fIRow(0), fNHits(0), fX(0), fOK(0){};
+    AliHLTTPCCATrackParam fParam; // track parameters at the border
+    Int_t fITrack;               // track index
+    Int_t fIRow;                 // row number of the closest cluster
+    Int_t fNHits;                // n hits
+    Float_t fX;                  // X coordinate of the closest cluster
+    Bool_t fOK;                  // is the trak rotated and extrapolated correctly
+  };
+  
+  void MakeBorderTracks( Int_t iSlice, Int_t iBorder, AliHLTTPCCABorderTrack B[], Int_t &nB);
+  void SplitBorderTracks( Int_t iSlice1, AliHLTTPCCABorderTrack B1[], Int_t N1,
+                         Int_t iSlice2, AliHLTTPCCABorderTrack B2[], Int_t N2 );
+
+  static Float_t GetChi2( Float_t x1, Float_t y1, Float_t a00, Float_t a10, Float_t a11, 
+                         Float_t x2, Float_t y2, Float_t b00, Float_t b10, Float_t b11  );
+
+  void UnpackSlices();
+  void Merging();
+   
+  Bool_t FitTrack( AliHLTTPCCATrackParam &T, Float_t &Alpha, 
+                  AliHLTTPCCATrackParam t0, Float_t Alpha0, Int_t hits[], Int_t &NHits,  Bool_t dir=0 );
+  
+  static const Int_t fgkNSlices = 36;       //* N slices 
+  AliHLTTPCCAParam fSliceParam;           //* slice parameters (geometry, calibr, etc.)
+  const AliHLTTPCCASliceOutput **fkSlices;       //* array of input slice tracks  
+  AliHLTTPCCAMergerOutput *fOutput;       //* array of output merged tracks  
+  AliHLTTPCCASliceTrackInfo *fTrackInfos; //* additional information for slice tracks
+  Int_t fMaxTrackInfos;                   //* booked size of fTrackInfos array
+  AliHLTTPCCAClusterInfo *fClusterInfos;  //* information about track clusters
+  Int_t fMaxClusterInfos;                 //* booked size of fClusterInfos array
+  Int_t fSliceTrackInfoStart[fgkNSlices];   //* slice starting index in fTrackInfos array;
+  Int_t fSliceNTrackInfos[fgkNSlices];                //* N of slice track infos in fTrackInfos array;
+};
+
+#endif
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCAMergerOutput.h b/HLT/TPCLib/tracking-ca/AliHLTTPCCAMergerOutput.h
new file mode 100644 (file)
index 0000000..c4341a3
--- /dev/null
@@ -0,0 +1,92 @@
+//-*- Mode: C++ -*-
+// ************************************************************************
+// 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 ALIHLTTPCCAMERGEROUTPUT_H
+#define ALIHLTTPCCAMERGEROUTPUT_H
+
+#include "AliHLTTPCCADef.h"
+#include "AliHLTTPCCAMergedTrack.h"
+
+/**
+ * @class AliHLTTPCCAMergerOutput
+ *
+ * AliHLTTPCCAMergerOutput class is used to store the output of AliHLTTPCCATracker{Component}
+ * and transport the output to AliHLTTPCCAMerger{Component}
+ *
+ * The class contains all the necessary information about TPC tracks, reconstructed in one slice.
+ * This includes the reconstructed track parameters and some compressed information 
+ * about the assigned clusters: clusterId, position and amplitude.
+ *
+ */
+class AliHLTTPCCAMergerOutput
+{
+ public:
+
+  AliHLTTPCCAMergerOutput()
+    :fNTracks(0), fNTrackClusters(0),fTracks(0),fClusterIDsrc(0),fClusterPackedAmp(0) {}
+
+  AliHLTTPCCAMergerOutput( const AliHLTTPCCAMergerOutput & )
+    :fNTracks(0), fNTrackClusters(0),fTracks(0),fClusterIDsrc(0),fClusterPackedAmp(0) {}
+  
+  const AliHLTTPCCAMergerOutput& operator=( const AliHLTTPCCAMergerOutput &/*v*/ ) const { 
+    return *this; 
+  }
+
+  ~AliHLTTPCCAMergerOutput(){}
+
+
+  GPUhd() Int_t NTracks()                    const { return fNTracks;              }
+  GPUhd() Int_t NTrackClusters()             const { return fNTrackClusters;       }
+
+  GPUhd() const AliHLTTPCCAMergedTrack &Track( Int_t i ) const { return fTracks[i]; }
+  GPUhd() UInt_t   ClusterIDsrc     ( Int_t i )  const { return fClusterIDsrc[i]; }
+  GPUhd() UChar_t  ClusterPackedAmp( Int_t i )  const { return fClusterPackedAmp[i]; }
+
+  GPUhd() static Int_t EstimateSize( Int_t nOfTracks, Int_t nOfTrackClusters );
+  GPUhd() void SetPointers();
+
+  GPUhd() void SetNTracks       ( Int_t v )  { fNTracks = v;        }
+  GPUhd() void SetNTrackClusters( Int_t v )  { fNTrackClusters = v; }
+
+  GPUhd() void SetTrack( Int_t i, const AliHLTTPCCAMergedTrack &v ) {  fTracks[i] = v; }
+  GPUhd() void SetClusterIDsrc( Int_t i, UInt_t v ) {  fClusterIDsrc[i] = v; }
+  GPUhd() void SetClusterPackedAmp( Int_t i, UChar_t v ) {  fClusterPackedAmp[i] = v; }
+
+ private:
+  
+  Int_t fNTracks;                 // number of reconstructed tracks
+  Int_t fNTrackClusters;          // total number of track clusters
+  AliHLTTPCCAMergedTrack *fTracks; // pointer to reconstructed tracks
+  UInt_t   *fClusterIDsrc;         // pointer to cluster IDs ( packed IRow and ICluster)
+  UChar_t  *fClusterPackedAmp;    // pointer to packed cluster amplitudes
+
+};
+
+
+
+GPUhd() inline Int_t AliHLTTPCCAMergerOutput::EstimateSize( Int_t nOfTracks, Int_t nOfTrackClusters )
+{
+  // calculate the amount of memory [bytes] needed for the event
+
+  const Int_t kClusterDataSize = sizeof(UInt_t) + sizeof(UChar_t);
+
+  return sizeof(AliHLTTPCCAMergerOutput) + sizeof(AliHLTTPCCAMergedTrack)*nOfTracks + kClusterDataSize*nOfTrackClusters;
+}
+
+
+GPUhd() inline void AliHLTTPCCAMergerOutput::SetPointers()
+{
+  // set all pointers
+
+  fTracks            = (AliHLTTPCCAMergedTrack*)((&fClusterPackedAmp)+1);
+  fClusterIDsrc      = (UInt_t*)  ( fTracks            + fNTracks );
+  fClusterPackedAmp  = (UChar_t*) ( fClusterIDsrc + fNTrackClusters );
+}
+
+#endif
index a661fbd..cf90b19 100644 (file)
@@ -146,6 +146,23 @@ GPUd() Float_t AliHLTTPCCAParam::GetClusterError2( Int_t yz, Int_t type, Float_t
   return CAMath::Abs(v); 
 }
 
+GPUd() void AliHLTTPCCAParam::GetClusterErrors2( Int_t iRow, Float_t z, Float_t sinPhi, Float_t cosPhi, Float_t DzDs, Float_t &Err2Y, Float_t &Err2Z ) const
+{
+  //
+  // Use calibrated cluster error from OCDB
+  //
+
+  z = CAMath::Abs((250.-0.275)-CAMath::Abs(z));
+  Int_t    type = (iRow<63) ? 0: ( (iRow>126) ? 1:2 );
+  Float_t cosPhiInv = CAMath::Abs(cosPhi)>1.e-2 ?1./cosPhi :0;
+  Float_t angleY = sinPhi*cosPhiInv ;
+  Float_t angleZ = DzDs*cosPhiInv ; // SG was bug??? 
+
+  Err2Y = GetClusterError2(0,type, z,angleY);  
+  Err2Z = GetClusterError2(1,type, z,angleZ);
+}
+
+
 GPUh() void AliHLTTPCCAParam::WriteSettings( std::ostream &out ) const 
 {
   // write settings to the file
index e5783d5..f6254c3 100644 (file)
@@ -52,6 +52,7 @@ class AliHLTTPCCAParam
   GPUhd() Float_t RowX( Int_t iRow ) const { return fRowX[iRow]; }  
 
   GPUd() Float_t Alpha() const { return fAlpha;}
+  GPUd() Float_t Alpha( Int_t iSlice ) const { return 0.174533 + DAlpha()*iSlice;}
   GPUd() Float_t DAlpha() const { return fDAlpha;}
   GPUd() Float_t CosAlpha() const { return fCosAlpha;}
   GPUd() Float_t SinAlpha() const { return fSinAlpha;}
@@ -99,6 +100,7 @@ class AliHLTTPCCAParam
 
 
   GPUd() Float_t GetClusterError2(Int_t yz, Int_t type, Float_t z, Float_t angle ) const;
+  GPUd() void GetClusterErrors2( Int_t iRow, Float_t z, Float_t sinPhi, Float_t cosPhi, Float_t DzDs, Float_t &Err2Y, Float_t &Err2Z ) const;
 
   void WriteSettings( std::ostream &out ) const;
   void ReadSettings( std::istream &in );
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCASliceOutput.h b/HLT/TPCLib/tracking-ca/AliHLTTPCCASliceOutput.h
new file mode 100644 (file)
index 0000000..903500d
--- /dev/null
@@ -0,0 +1,88 @@
+//-*- Mode: C++ -*-
+// ************************************************************************
+// 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 ALIHLTTPCCASLICEOUTPUT_H
+#define ALIHLTTPCCASLICEOUTPUT_H
+
+#include "AliHLTTPCCADef.h"
+
+class AliHLTTPCCASliceTrack;
+
+/**
+ * @class AliHLTTPCCASliceOutput
+ *
+ * AliHLTTPCCASliceOutput class is used to store the output of AliHLTTPCCATracker{Component}
+ * and transport the output to AliHLTTPCCAGBMerger{Component}
+ *
+ * The class contains all the necessary information about TPC tracks, reconstructed in one slice.
+ * This includes the reconstructed track parameters and some compressed information 
+ * about the assigned clusters: clusterId, position and amplitude.
+ *
+ */
+class AliHLTTPCCASliceOutput
+{
+ public:
+
+  GPUhd() Int_t NTracks()                    const { return fNTracks;              }
+  GPUhd() Int_t NTrackClusters()             const { return fNTrackClusters;       }
+
+  GPUhd() const AliHLTTPCCASliceTrack &Track( Int_t i ) const { return fTracks[i]; }
+  GPUhd() UInt_t   ClusterIDrc     ( Int_t i )  const { return fClusterIDrc[i]; }
+  GPUhd() UShort_t ClusterPackedYZ ( Int_t i )  const { return fClusterPackedYZ[i]; }
+  GPUhd() UChar_t  ClusterPackedAmp( Int_t i )  const { return fClusterPackedAmp[i]; }
+  GPUhd() float2   ClusterUnpackedYZ ( Int_t i )  const { return fClusterUnpackedYZ[i]; }
+
+  GPUhd() static Int_t EstimateSize( Int_t nOfTracks, Int_t nOfTrackClusters );
+  GPUhd() void SetPointers();
+
+  GPUhd() void SetNTracks       ( Int_t v )  { fNTracks = v;        }
+  GPUhd() void SetNTrackClusters( Int_t v )  { fNTrackClusters = v; }
+
+  GPUhd() void SetTrack( Int_t i, const AliHLTTPCCASliceTrack &v ) {  fTracks[i] = v; }
+  GPUhd() void SetClusterIDrc( Int_t i, UInt_t v ) {  fClusterIDrc[i] = v; }
+  GPUhd() void SetClusterPackedYZ( Int_t i, UShort_t v ) {  fClusterPackedYZ[i] = v; }
+  GPUhd() void SetClusterPackedAmp( Int_t i, UChar_t v ) {  fClusterPackedAmp[i] = v; }
+  GPUhd() void SetClusterUnpackedYZ( Int_t i, float2 v ) {  fClusterUnpackedYZ[i] = v; }
+
+ private:
+  
+  Int_t fNTracks;                 // number of reconstructed tracks
+  Int_t fNTrackClusters;          // total number of track clusters
+  AliHLTTPCCASliceTrack *fTracks; // pointer to reconstructed tracks
+  UInt_t   *fClusterIDrc;         // pointer to cluster IDs ( packed IRow and ICluster)
+  UShort_t *fClusterPackedYZ;     // pointer to packed cluster YZ coordinates 
+  float2   *fClusterUnpackedYZ;   // pointer to cluster coordinates (temporary data, for debug proposes)
+  UChar_t  *fClusterPackedAmp;    // pointer to packed cluster amplitudes
+
+};
+
+
+
+GPUhd() inline Int_t AliHLTTPCCASliceOutput::EstimateSize( Int_t nOfTracks, Int_t nOfTrackClusters )
+{
+  // calculate the amount of memory [bytes] needed for the event
+
+  const Int_t kClusterDataSize = sizeof(UInt_t) + sizeof(UShort_t) + sizeof(float2)+ sizeof(UChar_t);
+
+  return sizeof(AliHLTTPCCASliceOutput) + sizeof(AliHLTTPCCASliceTrack)*nOfTracks + kClusterDataSize*nOfTrackClusters;
+}
+
+
+GPUhd() inline void AliHLTTPCCASliceOutput::SetPointers()
+{
+  // set all pointers
+
+  fTracks            = (AliHLTTPCCASliceTrack*)((&fClusterPackedAmp)+1);
+  fClusterUnpackedYZ = (float2*)  ( fTracks   + fNTracks );
+  fClusterIDrc       = (UInt_t*)  ( fClusterUnpackedYZ + fNTrackClusters );
+  fClusterPackedYZ   = (UShort_t*)( fClusterIDrc       + fNTrackClusters );
+  fClusterPackedAmp  = (UChar_t*) ( fClusterPackedYZ + fNTrackClusters );
+}
+
+#endif
diff --git a/HLT/TPCLib/tracking-ca/AliHLTTPCCASliceTrack.h b/HLT/TPCLib/tracking-ca/AliHLTTPCCASliceTrack.h
new file mode 100644 (file)
index 0000000..926835e
--- /dev/null
@@ -0,0 +1,49 @@
+//-*- Mode: C++ -*-
+// ************************************************************************
+// 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 ALIHLTTPCCASLICETRACK_H
+#define ALIHLTTPCCASLICETRACK_H
+
+#include "AliHLTTPCCATrackParam.h"
+
+/**
+ * @class AliHLTTPCCASliceTrack
+ * AliHLTTPCCASliceTrack class is used to store TPC tracks,
+ * which are reconstructed by the TPCCATracker slice tracker.
+ * 
+ * The class contains:
+ * - fitted track parameters at its first row, the covariance matrix, \Chi^2, NDF (number of degrees of freedom ) 
+ * - n of clusters assigned to the track
+ * - index of its first cluster in corresponding cluster arrays
+ *
+ * The class is used to transport the data between AliHLTTPCCATracker{Component} and AliHLTTPCCAGBMerger{Component}
+ *
+ */
+class AliHLTTPCCASliceTrack
+{
+ public:
+
+  GPUhd() Int_t NClusters()                    const { return fNClusters;       }
+  GPUhd() Int_t FirstClusterRef()              const { return fFirstClusterRef; }
+  GPUhd() const AliHLTTPCCATrackParam &Param() const { return fParam;           }
+
+  GPUhd() void SetNClusters( Int_t v )                   { fNClusters = v;       }
+  GPUhd() void SetFirstClusterRef( Int_t v)              { fFirstClusterRef = v; }
+  GPUhd() void SetParam( const AliHLTTPCCATrackParam &v) { fParam = v;           }
+
+ private:
+  
+  AliHLTTPCCATrackParam fParam; //* fitted track parameters at its innermost cluster
+  Int_t fFirstClusterRef;       //* index of the index of the first track cluster in corresponding cluster arrays
+  Int_t fNClusters;             //* number of track clusters
+
+};
+
+
+#endif
index 7c25fcd..7e20cd2 100644 (file)
@@ -30,11 +30,6 @@ class AliHLTTPCCATrackParam
     Float_t fBethe, fE,fTheta2, fEP2, fSigmadE2, fK22,fK33,fK43,fK44;// parameters
   };
 
-#if !defined(HLTCA_GPUCODE)
-  AliHLTTPCCATrackParam(): fX(0),fCosPhi(1),fChi2(0), fNDF(0){}
-  ~AliHLTTPCCATrackParam(){}
-#endif
-
   GPUd() Float_t X()     const { return fX;    }
   GPUd() Float_t Y()     const { return fP[0]; }
   GPUd() Float_t Z()     const { return fP[1]; }
@@ -134,7 +129,6 @@ private:
   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
-
 };
 
 
index 564a270..0f857fd 100644 (file)
@@ -35,6 +35,9 @@
 #include "AliHLTTPCCATrackletSelector.h"
 #include "AliHLTTPCCAProcess.h"
 #include "AliHLTTPCCAUsedHitsInitialiser.h"
+#include "AliHLTTPCCASliceTrack.h"
+#include "AliHLTTPCCASliceOutput.h"
+#include "AliHLTTPCCADataCompressor.h"
 
 #include "AliHLTTPCCATrackParam.h"
 
@@ -80,6 +83,7 @@ AliHLTTPCCATracker::AliHLTTPCCATracker()
   fTracks(0), 
   fNTrackHits(0),
   fTrackHits(0),
+  fOutput(0),
   fNOutTracks(0),
   fOutTracks(0), 
   fNOutTrackHits(0),
@@ -112,6 +116,7 @@ AliHLTTPCCATracker::AliHLTTPCCATracker( const AliHLTTPCCATracker& )
   fTracks(0), 
   fNTrackHits(0),
   fTrackHits(0),
+  fOutput(0),
   fNOutTracks(0),
   fOutTracks(0), 
   fNOutTrackHits(0),
@@ -181,86 +186,6 @@ GPUd() void AliHLTTPCCATracker::StartEvent()
 }
 
 
-/*
-GPUhd() void  AliHLTTPCCATracker::SetPointers()
-{
-  // set all pointers to the event memory
-
-  Int_t gridSizeTotal = 2*(2*fNHitsTotal + 10*Param().NRows());
-  gridSizeTotal *=100;//SG!!!
-  ULong_t mem = (ULong_t) fCommonMemory;  
-  UInt_t sI = sizeof(Int_t);
-  UInt_t sF = sizeof(Float_t);
-  UInt_t sS = sizeof(Short_t);
-  UInt_t s4 = sizeof(uint4);
-
-  fInputEvent = (Char_t*) mem;  
-  fInputEventSize = (1+fParam.NRows()*2 + 1)*sI + (fNHitsTotal*2)*sF;
-  mem+= fInputEventSize;
-
-  mem = ( mem/s4 + 1 )*s4;
-  fRowData = (uint4*) mem;
-  fRowDataSize = ( 2*fNHitsTotal*sS +  //  yz
-                  gridSizeTotal*sS + // grid
-                  2*fNHitsTotal*sS +  // link up,link down
-                  fParam.NRows()*s4   // row alignment
-                  );
-  mem += fRowDataSize;
-
-  mem = ( mem/sI + 1 )*sI;
-
-  fHitInputIDs = (Int_t*) mem;
-  mem+= fNHitsTotal*sI;
-
-  fHitWeights = (Int_t*) mem;
-  mem+=  fNHitsTotal*sI;
-
-  fNTracklets = (Int_t*) mem;
-  mem+= sI;
-
-  fTrackletStartHits = (Int_t*) mem;
-  mem+= fNHitsTotal*sI;
-
-  mem = ( mem/sizeof(AliHLTTPCCATracklet) + 1 )*sizeof(AliHLTTPCCATracklet);
-
-  fTracklets = (AliHLTTPCCATracklet *) mem;
-  mem+= fNHitsTotal*sizeof(AliHLTTPCCATracklet);
-  
-  mem = ( mem/sI + 1 )*sI;
-
-  fNTracks = (Int_t*) mem;
-  mem+= sI;
-
-  mem = ( mem/sizeof(AliHLTTPCCATrack) + 1 )*sizeof(AliHLTTPCCATrack);
-
-  fTracks = (AliHLTTPCCATrack*) mem;
-  mem+= fNHitsTotal*sizeof(AliHLTTPCCATrack);
-  
-  mem = ( mem/sI + 1 )*sI;
-  fNTrackHits = (Int_t*) mem;
-  mem+= sI;
-
-  fTrackHits = (Int_t*) mem;
-  mem+= 100*fNHitsTotal*sI;//SG!!!
-
-  fNOutTracks = (Int_t*) mem;
-  mem+= sI;
-
-  mem = ( mem/sizeof(AliHLTTPCCAOutTrack) + 1 )*sizeof(AliHLTTPCCAOutTrack);
-  
-  fOutTracks = (AliHLTTPCCAOutTrack*) mem;
-  mem+= fNHitsTotal*sizeof(AliHLTTPCCAOutTrack);
-
-  mem = ( mem/sI + 1 )*sI;
-  fNOutTrackHits = (Int_t*) mem;
-  mem+= sI;
-  fOutTrackHits = (Int_t*) mem;
-  mem+= 100*fNHitsTotal*sI; //SG!!!
-
-  fCommonMemorySize = mem - (ULong_t) fCommonMemory;
-}
-*/
-
 
 GPUhd() void  AliHLTTPCCATracker::SetPointersCommon()
 {
@@ -346,7 +271,7 @@ GPUhd() void  AliHLTTPCCATracker::SetPointersHits( Int_t MaxNHits )
 }
 
 
-GPUhd() void  AliHLTTPCCATracker::SetPointersTracks( Int_t MaxNTracks )
+GPUhd() void  AliHLTTPCCATracker::SetPointersTracks( Int_t MaxNTracks, Int_t MaxNHits )
 {
   // set all pointers to the tracks memory
 
@@ -364,12 +289,18 @@ GPUhd() void  AliHLTTPCCATracker::SetPointersTracks( Int_t MaxNTracks )
   fTracks = (AliHLTTPCCATrack*) mem;
   mem+= MaxNTracks*sizeof(AliHLTTPCCATrack);  
   
+  // memory for output
+
+  mem = ( mem/sizeof(AliHLTTPCCASliceOutput) + 1 )*sizeof(AliHLTTPCCASliceOutput);
+  fOutput = (AliHLTTPCCASliceOutput*) mem;
+  mem+= AliHLTTPCCASliceOutput::EstimateSize(MaxNTracks, MaxNHits);
+  
   // memory for output tracks
 
   mem = ( mem/sizeof(AliHLTTPCCAOutTrack) + 1 )*sizeof(AliHLTTPCCAOutTrack);
   
   fOutTracks = (AliHLTTPCCAOutTrack*) mem;
-  mem+= fNHitsTotal*sizeof(AliHLTTPCCAOutTrack);  
+  mem+= MaxNTracks*sizeof(AliHLTTPCCAOutTrack);  
 
   // calculate the size
 
@@ -625,8 +556,17 @@ GPUh() void AliHLTTPCCATracker::Reconstruct()
   TStopwatch timer0;
 
   //SetupRowData();
-  if( fNHitsTotal < 1 ) return;
+  if( fNHitsTotal < 1 ){
+    {
+      SetPointersTracks(1, 1); // to calculate the size
+      fTrackMemory = reinterpret_cast<Char_t*> ( new uint4 [ fTrackMemorySize/sizeof(uint4) + 100] );   
+      SetPointersTracks(1, 1); // set pointers for tracks
+      fOutput->SetNTracks(0);
+      fOutput->SetNTrackClusters(0);
+    }
 
+    return;
+  }
 #ifdef DRAW
 
   AliHLTTPCCADisplay::Instance().ClearView();  
@@ -680,9 +620,9 @@ GPUh() void AliHLTTPCCATracker::Reconstruct()
 
 
   {
-    SetPointersTracks(nStartHits); // to calculate the size
+    SetPointersTracks(nStartHits, fNHitsTotal); // to calculate the size
     fTrackMemory = reinterpret_cast<Char_t*> ( new uint4 [ fTrackMemorySize/sizeof(uint4) + 100] );   
-    SetPointersTracks(nStartHits); // set pointers for hits
+    SetPointersTracks(nStartHits, fNHitsTotal); // set pointers for hits
   }
 
   Int_t nMemThreads = AliHLTTPCCATrackletConstructor::NMemThreads();
@@ -768,11 +708,68 @@ GPUh() void AliHLTTPCCATracker::WriteOutput()
   // write output
 
   TStopwatch timer;
+
+  //cout<<"output: nTracks = "<<*fNTracks<<", nHitsTotal="<<fNHitsTotal<<std::endl;  
+
+  
+  fOutput->SetNTracks( *fNTracks );
+  fOutput->SetNTrackClusters( *fNTrackHits );
+  fOutput->SetPointers();
+
+  Int_t nStoredHits = 0;
+
+  for( Int_t iTr=0; iTr<*fNTracks; iTr++){
+    AliHLTTPCCATrack &iTrack = fTracks[iTr];       
  
+    AliHLTTPCCASliceTrack out;
+    out.SetFirstClusterRef( nStoredHits );
+    out.SetNClusters( iTrack.NHits() );    
+    out.SetParam( iTrack.Param() );
+
+    fOutput->SetTrack( iTr, out );
+
+    Int_t iID = iTrack.FirstHitID();
+    for( Int_t ith=0; ith<iTrack.NHits(); ith++ ){
+      Int_t ic = (fTrackHits[iID+ith]);
+      Int_t iRow = ID2IRow(ic);
+      Int_t ih = ID2IHit(ic);
+      const AliHLTTPCCARow &row = fRows[iRow];      
+  
+      Float_t y0 = row.Grid().YMin();
+      Float_t z0 = row.Grid().ZMin();
+      Float_t stepY = row.HstepY();
+      Float_t stepZ = row.HstepZ();      
+      //Float_t x = row.X();
+
+      const uint4 *tmpint4 = RowData() + row.FullOffset();
+      const ushort2 *hits = reinterpret_cast<const ushort2*>(tmpint4);
+      ushort2 hh = hits[ih];
+
+      Float_t y = y0 + hh.x*stepY;
+      Float_t z = z0 + hh.y*stepZ;
+
+      Int_t inpIDtot = fHitInputIDs[row.FirstHit()+ih];
+      Int_t inpID = inpIDtot - row.FirstHit();
+
+      UInt_t hIDrc = AliHLTTPCCADataCompressor::IRowIClu2IDrc(iRow,inpID);
+      UShort_t hPackedYZ = 0;
+      UChar_t hPackedAmp = 0;
+      float2 hUnpackedYZ = CAMath::MakeFloat2(y,z);
+      
+      fOutput->SetClusterIDrc( nStoredHits, hIDrc  );
+      fOutput->SetClusterPackedYZ( nStoredHits, hPackedYZ );
+      fOutput->SetClusterPackedAmp( nStoredHits, hPackedAmp);
+      fOutput->SetClusterUnpackedYZ( nStoredHits, hUnpackedYZ );
+      nStoredHits++;
+    }
+  }
+  
+  // old stuff 
+
   *fNOutTrackHits = 0;
   *fNOutTracks = 0;
 
-  //cout<<"output: nTracks = "<<*fNTracks<<", nHitsTotal="<<fNHitsTotal<<std::endl;  
 
   for( Int_t iTr=0; iTr<*fNTracks; iTr++){
 
@@ -812,6 +809,8 @@ GPUh() void AliHLTTPCCATracker::WriteOutput()
       (*fNOutTrackHits) = nOutTrackHitsOld;
     }
   }
+
+
   timer.Stop();
   fTimers[5]+=timer.CpuTime();
 }
@@ -946,14 +945,7 @@ GPUd() void AliHLTTPCCATracker::GetErrors2( Int_t iRow, Float_t z, Float_t sinPh
   // Use calibrated cluster error from OCDB
   //
 
-  z = CAMath::Abs((250.-0.275)-CAMath::Abs(z));
-  Int_t    type = (iRow<63) ? 0: ( (iRow>126) ? 1:2 );
-  Float_t cosPhiInv = CAMath::Abs(cosPhi)>1.e-2 ?1./cosPhi :0;
-  Float_t angleY = sinPhi*cosPhiInv ;
-  Float_t angleZ = DzDs*cosPhiInv ; // SG was bug??? 
-
-  Err2Y = fParam.GetClusterError2(0,type, z,angleY);  
-  Err2Z = fParam.GetClusterError2(1,type, z,angleZ);
+  fParam.GetClusterErrors2( iRow, z, sinPhi, cosPhi, DzDs, Err2Y, Err2Z );
 }
 
 GPUd() void AliHLTTPCCATracker::GetErrors2( Int_t iRow, const AliHLTTPCCATrackParam &t, Float_t &Err2Y, Float_t &Err2Z ) const
@@ -962,14 +954,7 @@ GPUd() void AliHLTTPCCATracker::GetErrors2( Int_t iRow, const AliHLTTPCCATrackPa
   // Use calibrated cluster error from OCDB
   //
 
-  Float_t z = CAMath::Abs((250.-0.275)-CAMath::Abs(t.GetZ()));
-  Int_t    type = (iRow<63) ? 0: ( (iRow>126) ? 1:2 );
-  Float_t cosPhiInv = CAMath::Abs(t.GetCosPhi())>1.e-2 ?1./t.GetCosPhi() :0;
-  Float_t angleY = t.GetSinPhi()*cosPhiInv ;
-  Float_t angleZ = t.GetDzDs()*cosPhiInv ; // SG was bug??? 
-
-  Err2Y = fParam.GetClusterError2(0,type, z,angleY);  
-  Err2Z = fParam.GetClusterError2(1,type, z,angleZ);
+  fParam.GetClusterErrors2( iRow, t.GetZ(), t.SinPhi(), t.CosPhi(), t.DzDs(), Err2Y, Err2Z );
 }
 
 
index 6e0bd50..c686ad6 100644 (file)
@@ -21,7 +21,7 @@ class AliHLTTPCCATrack;
 class AliHLTTPCCAOutTrack;
 class AliHLTTPCCATrackParam;
 class AliHLTTPCCATracklet;
-
+class AliHLTTPCCASliceOutput;
 
 /**
  * @class AliHLTTPCCATracker
@@ -82,7 +82,7 @@ class AliHLTTPCCATracker
   void FitTrackFull( AliHLTTPCCATrack &track, Float_t *t0 = 0 ) const;
   GPUhd() void SetPointersCommon();
   GPUhd() void SetPointersHits( Int_t MaxNHits );
-  GPUhd() void SetPointersTracks( Int_t MaxNTracks );
+  GPUhd() void SetPointersTracks( Int_t MaxNTracks, Int_t MaxNHits );
 
 #if !defined(HLTCA_GPUCODE)  
   GPUh() void WriteEvent( std::ostream &out );
@@ -118,6 +118,8 @@ class AliHLTTPCCATracker
   GPUhd() Int_t *NTrackHits()  const { return fNTrackHits; }
   GPUhd() Int_t *TrackHits() const { return fTrackHits; }
 
+  GPUhd() const AliHLTTPCCASliceOutput * Output() const { return fOutput; }
+
   GPUhd()  Int_t *NOutTracks() const { return  fNOutTracks; }
   GPUhd()  AliHLTTPCCAOutTrack *OutTracks() const { return  fOutTracks; }
   GPUhd()  Int_t *NOutTrackHits() const { return  fNOutTrackHits; }
@@ -165,6 +167,10 @@ class AliHLTTPCCATracker
 
   // output
 
+  AliHLTTPCCASliceOutput *fOutput;
+
+  // obsolete output
+
   Int_t *fNOutTracks; // number of tracks in fOutTracks array
   AliHLTTPCCAOutTrack *fOutTracks; // output array of the reconstructed tracks
   Int_t *fNOutTrackHits;  // number of hits in fOutTrackHits array