LCOV - code coverage report
Current view: top level - HLT/TPCLib/tracking-ca - AliHLTTPCCAMerger.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 465 0.0 %
Date: 2016-06-14 17:26:59 Functions: 0 40 0.0 %

          Line data    Source code
       1             : // $Id: AliHLTTPCCAMerger.cxx 30732 2009-01-22 23:02:02Z sgorbuno $
       2             : // **************************************************************************
       3             : // This file is property of and copyright by the ALICE HLT Project          *
       4             : // ALICE Experiment at CERN, All rights reserved.                           *
       5             : //                                                                          *
       6             : // Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
       7             : //                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
       8             : //                  for The ALICE HLT Project.                              *
       9             : //                                                                          *
      10             : // Permission to use, copy, modify and distribute this software and its     *
      11             : // documentation strictly for non-commercial purposes is hereby granted     *
      12             : // without fee, provided that the above copyright notice appears in all     *
      13             : // copies and that both the copyright notice and this permission notice     *
      14             : // appear in the supporting documentation. The authors make no claims       *
      15             : // about the suitability of this software for any purpose. It is            *
      16             : // provided "as is" without express or implied warranty.                    *
      17             : //                                                                          *
      18             : //***************************************************************************
      19             : 
      20             : #include <stdio.h>
      21             : #include "AliHLTTPCCASliceOutTrack.h"
      22             : #include "AliHLTTPCCATracker.h"
      23             : #include "AliHLTTPCCATrackParam.h"
      24             : 
      25             : #include "AliHLTTPCCAMerger.h"
      26             : 
      27             : #include "AliHLTTPCCAMath.h"
      28             : #include "TStopwatch.h"
      29             : 
      30             : #include "AliHLTTPCCATrackParam.h"
      31             : #include "AliHLTTPCCASliceOutput.h"
      32             : #include "AliHLTTPCCAMergedTrack.h"
      33             : #include "AliHLTTPCCAMergerOutput.h"
      34             : #include "AliHLTTPCCADataCompressor.h"
      35             : #include "AliHLTTPCCAParam.h"
      36             : #include "AliHLTTPCCATrackLinearisation.h"
      37             : #include "AliHLTTPCCADataCompressor.h"
      38             : 
      39             : class AliHLTTPCCAMerger::AliHLTTPCCASliceTrackInfo
      40             : {
      41             : 
      42             :   public:
      43             : 
      44           0 :     const AliHLTTPCCATrackParam &InnerParam() const { return fInnerParam;      }
      45           0 :     const AliHLTTPCCATrackParam &OuterParam() const { return fOuterParam;      }
      46           0 :     float InnerAlpha()                      const { return fInnerAlpha;      }
      47           0 :     float OuterAlpha()                      const { return fOuterAlpha;      }
      48           0 :     int   NClusters()                       const { return fNClusters;       }
      49           0 :     int   FirstClusterRef()                 const { return fFirstClusterRef; }
      50           0 :     int   PrevNeighbour()                   const { return fPrevNeighbour;   }
      51           0 :     int   NextNeighbour()                   const { return fNextNeighbour;   }
      52           0 :     bool  Used()                            const { return fUsed;            }
      53             : 
      54           0 :     void SetInnerParam( const AliHLTTPCCATrackParam &v ) { fInnerParam = v;      }
      55           0 :     void SetOuterParam( const AliHLTTPCCATrackParam &v ) { fOuterParam = v;      }
      56           0 :     void SetInnerAlpha( float v )                      { fInnerAlpha = v;      }
      57           0 :     void SetOuterAlpha( float v )                      { fOuterAlpha = v;      }
      58           0 :     void SetNClusters ( int v )                        { fNClusters = v;       }
      59           0 :     void SetFirstClusterRef( int v )                   { fFirstClusterRef = v; }
      60           0 :     void SetPrevNeighbour( int v )                     { fPrevNeighbour = v;   }
      61           0 :     void SetNextNeighbour( int v )                     { fNextNeighbour = v;   }
      62           0 :     void SetUsed( bool v )                             { fUsed = v;            }
      63             : 
      64             :   private:
      65             : 
      66             :     AliHLTTPCCATrackParam fInnerParam; // inner parameters
      67             :     AliHLTTPCCATrackParam fOuterParam; // outer parameters
      68             :     float fInnerAlpha;               // alpha angle for inner parameters
      69             :     float fOuterAlpha;               // alpha angle for outer parameters
      70             :     int fNClusters;                  // N clusters
      71             :     int fFirstClusterRef;  // index of the first track cluster in the global cluster array
      72             :     int fPrevNeighbour;    // neighbour in the previous slise
      73             :     int fNextNeighbour;    // neighbour in the next slise
      74             :     bool fUsed;            // is the slice track already merged
      75             : 
      76             : };
      77             : 
      78             : 
      79             : class AliHLTTPCCAMerger::AliHLTTPCCABorderTrack
      80             : {
      81             : 
      82             :   public:
      83             : 
      84           0 :     const AliHLTTPCCATrackParam &Param() const { return fParam;     }
      85           0 :     int   TrackID()                    const { return fTrackID;   }
      86           0 :     int   NClusters()                  const { return fNClusters; }
      87             :     float X()                          const { return fX;         }
      88           0 :     bool  OK()                         const { return fOK;        }
      89             : 
      90           0 :     void SetParam     ( const AliHLTTPCCATrackParam &v ) { fParam     = v; }
      91           0 :     void SetTrackID   ( int v )                        { fTrackID   = v; }
      92           0 :     void SetNClusters ( int v )                        { fNClusters = v; }
      93           0 :     void SetX         ( float v )                      { fX         = v; }
      94           0 :     void SetOK        ( bool v )                       { fOK        = v; }
      95             : 
      96             :   private:
      97             : 
      98             :     AliHLTTPCCATrackParam fParam;  // track parameters at the border
      99             :     int   fTrackID;              // track index
     100             :     int   fNClusters;            // n clusters
     101             :     float fX;                    // X coordinate of the closest cluster
     102             :     bool  fOK;                   // is the track rotated and extrapolated correctly
     103             : 
     104             : };
     105             : 
     106             : 
     107             : 
     108             : AliHLTTPCCAMerger::AliHLTTPCCAMerger()
     109             :     :
     110           0 :     fSliceParam(),
     111           0 :     fOutput( 0 ),
     112           0 :     fTrackInfos( 0 ),
     113           0 :     fMaxTrackInfos( 0 ),
     114           0 :     fClusterInfos( 0 ),
     115           0 :     fMaxClusterInfos( 0 )
     116           0 : {
     117             :   //* constructor
     118           0 :   Clear();
     119           0 : }
     120             : 
     121             : /*
     122             : AliHLTTPCCAMerger::AliHLTTPCCAMerger(const AliHLTTPCCAMerger&)
     123             :   :
     124             :   fSliceParam(),
     125             :   fkSlices(0),
     126             :   fOutput(0),
     127             :   fTrackInfos(0),
     128             :   fMaxTrackInfos(0),
     129             :   fClusterInfos(0),
     130             :   fMaxClusterInfos(0)
     131             : {
     132             : }
     133             : 
     134             : const AliHLTTPCCAMerger &AliHLTTPCCAMerger::operator=(const AliHLTTPCCAMerger&) const
     135             : {
     136             :   return *this;
     137             : }
     138             : */
     139             : 
     140             : AliHLTTPCCAMerger::~AliHLTTPCCAMerger()
     141           0 : {
     142             :   //* destructor
     143           0 :   if ( fTrackInfos ) delete[] fTrackInfos;
     144           0 :   if ( fClusterInfos ) delete[] fClusterInfos;
     145           0 :   if ( fOutput ) delete[] ( ( float2* )( fOutput ) );
     146           0 : }
     147             : 
     148             : void AliHLTTPCCAMerger::Clear()
     149             : {
     150           0 :   for ( int i = 0; i < fgkNSlices; ++i ) {
     151           0 :     fkSlices[i] = 0;
     152           0 :     fSliceNTrackInfos[ i ] = 0;
     153           0 :     fSliceTrackInfoStart[ i ] = 0;
     154             :   }
     155           0 :   if ( fOutput ) delete[] ( ( float2* )( fOutput ) );
     156           0 :   if ( fTrackInfos ) delete[] fTrackInfos;
     157           0 :   if ( fClusterInfos ) delete[] fClusterInfos;
     158           0 :   fOutput = 0;
     159           0 :   fTrackInfos = 0;
     160           0 :   fClusterInfos = 0;
     161           0 :   fMaxTrackInfos = 0;
     162           0 :   fMaxClusterInfos = 0;
     163           0 : }
     164             : 
     165             : 
     166             : void AliHLTTPCCAMerger::SetSliceData( int index, const AliHLTTPCCASliceOutput *sliceData )
     167             : {
     168           0 :   fkSlices[index] = sliceData;
     169           0 : }
     170             : 
     171             : void AliHLTTPCCAMerger::Reconstruct()
     172             : {
     173             :   //* main merging routine
     174             : 
     175           0 :   UnpackSlices();
     176           0 :   Merging();
     177           0 : }
     178             : 
     179             : void AliHLTTPCCAMerger::UnpackSlices()
     180             : {
     181             :   //* unpack the cluster information from the slice tracks and initialize track info array
     182             : 
     183             :   // get N tracks and N clusters in event
     184             : 
     185             :   int nTracksTotal = 0;
     186             :   int nTrackClustersTotal = 0;
     187           0 :   for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
     188           0 :     if ( !fkSlices[iSlice] ) continue;
     189           0 :     nTracksTotal += fkSlices[iSlice]->NTracks();
     190           0 :     nTrackClustersTotal += fkSlices[iSlice]->NTrackClusters();
     191           0 :   }
     192             : 
     193             :   // book/clean memory if necessary
     194             :   {
     195           0 :     if ( nTracksTotal > fMaxTrackInfos || ( fMaxTrackInfos > 100 && nTracksTotal < 0.5*fMaxTrackInfos ) ) {
     196           0 :       if ( fTrackInfos ) delete[] fTrackInfos;
     197           0 :       fMaxTrackInfos = ( int ) ( nTracksTotal * 1.2 );
     198           0 :       fTrackInfos = new AliHLTTPCCASliceTrackInfo[fMaxTrackInfos];
     199           0 :     }
     200             : 
     201           0 :     if ( nTrackClustersTotal > fMaxClusterInfos || ( fMaxClusterInfos > 1000 && nTrackClustersTotal < 0.5*fMaxClusterInfos ) ) {
     202           0 :       if ( fClusterInfos ) delete[] fClusterInfos;
     203           0 :       fMaxClusterInfos = ( int ) ( nTrackClustersTotal * 1.2 );
     204           0 :       fClusterInfos = new AliHLTTPCCAClusterInfo [fMaxClusterInfos];
     205           0 :     }
     206             : 
     207           0 :     if ( fOutput ) delete[] ( ( float2* )( fOutput ) );
     208           0 :     int size = AliHLTTPCCAMergerOutput::EstimateSize( nTracksTotal, nTrackClustersTotal );
     209           0 :     fOutput = ( AliHLTTPCCAMergerOutput* )( new float2[size/sizeof( float2 )+1] );
     210             :   }
     211             : 
     212             :   // unpack track and cluster information
     213             : 
     214             :   int nTracksCurrent = 0;
     215             :   int nClustersCurrent = 0;
     216             : 
     217           0 :   for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
     218             : 
     219           0 :     fSliceTrackInfoStart[ iSlice ] = nTracksCurrent;
     220           0 :     fSliceNTrackInfos[ iSlice ] = 0;
     221             : 
     222           0 :     if ( !fkSlices[iSlice] ) continue;
     223             : 
     224             :     const AliHLTTPCCASliceOutput &slice = *( fkSlices[iSlice] );
     225             : 
     226           0 :     const AliHLTTPCCASliceOutTrack *sliceTr = slice.GetFirstTrack();
     227             :     
     228           0 :     for ( int itr = 0; itr < slice.NTracks(); itr++ ) {
     229             : 
     230           0 :       AliHLTTPCCATrackParam t0;
     231           0 :       t0.InitParam();
     232           0 :       t0.SetParam(sliceTr->Param());
     233             :       int nCluNew = 0;
     234           0 :       int nCluOld = sliceTr->NClusters();
     235           0 :       for ( int iTrClu = 0; iTrClu < nCluOld; iTrClu++ ) {
     236             :         
     237             :         // unpack cluster information
     238             : 
     239           0 :         AliHLTTPCCAClusterInfo &clu = fClusterInfos[nClustersCurrent + nCluNew];
     240           0 :         const AliHLTTPCCASliceOutCluster &c = sliceTr->Cluster( iTrClu );
     241             :         
     242           0 :         clu.SetISlice( iSlice );
     243           0 :         clu.SetRowType( c.GetRowType() );
     244           0 :         clu.SetId( c.GetId() );
     245           0 :         clu.SetPackedAmp( 0 );
     246           0 :         clu.SetX( c.GetX() );
     247           0 :         clu.SetY( c.GetY() );
     248           0 :         clu.SetZ( c.GetZ() );
     249             : 
     250           0 :         if ( !t0.TransportToX( clu.X(), fSliceParam.GetBz( t0 ), .999 ) ) continue;
     251             : 
     252           0 :         float err2Y, err2Z;
     253           0 :         fSliceParam.GetClusterErrors2v1( clu.RowType(), clu.Z(), t0.SinPhi(), t0.GetCosPhi(), t0.DzDs(), err2Y, err2Z );
     254             : 
     255           0 :         clu.SetErr2Y( err2Y );
     256           0 :         clu.SetErr2Z( err2Z );
     257           0 :         nCluNew++ ;
     258           0 :       }
     259             : 
     260             :       // refit the track
     261             : 
     262           0 :       int nHits = nCluNew;
     263           0 :       int hits[nHits];
     264           0 :       for ( int i = 0; i < nHits; i++ ) hits[i] = nClustersCurrent + i;
     265             : 
     266           0 :       AliHLTTPCCATrackParam startPoint;
     267           0 :       startPoint.InitParam();
     268           0 :       startPoint.SetParam(sliceTr->Param());
     269           0 :       AliHLTTPCCATrackParam endPoint = startPoint;
     270           0 :       float startAlpha = fSliceParam.Alpha( iSlice );
     271           0 :       float endAlpha = startAlpha;
     272             :   
     273           0 :       sliceTr = sliceTr->GetNextTrack();
     274             :       
     275           0 :       if ( nCluNew < .8*nCluOld ) continue;
     276             : 
     277           0 :       if ( !FitTrack( endPoint, endAlpha, startPoint, startAlpha, hits, nHits, 0 ) ) continue;
     278             : 
     279           0 :       startPoint = endPoint;
     280           0 :       startAlpha = endAlpha;
     281           0 :       if ( !FitTrack( startPoint, startAlpha, endPoint, endAlpha, hits, nHits, 1 ) ) continue;
     282             : 
     283           0 :       if ( nHits < .8*nCluOld ) continue;
     284             : 
     285             :       // store the track
     286             : 
     287           0 :       AliHLTTPCCASliceTrackInfo &track = fTrackInfos[nTracksCurrent];
     288             : 
     289           0 :       track.SetInnerParam( startPoint );
     290           0 :       track.SetInnerAlpha( startAlpha );
     291           0 :       track.SetOuterParam( endPoint );
     292           0 :       track.SetOuterAlpha( endAlpha );
     293           0 :       track.SetFirstClusterRef( nClustersCurrent );
     294           0 :       track.SetNClusters( nHits );
     295           0 :       track.SetPrevNeighbour( -1 );
     296           0 :       track.SetNextNeighbour( -1 );
     297           0 :       track.SetUsed( 0 );
     298             : 
     299           0 :       for ( int i = 0; i < nHits; i++ )
     300           0 :         fClusterInfos[nClustersCurrent + i] = fClusterInfos[hits[i]];
     301           0 :       nTracksCurrent++;
     302           0 :       fSliceNTrackInfos[ iSlice ]++;
     303           0 :       nClustersCurrent += nHits;
     304           0 :     }
     305             :     //std::cout<<"Unpack slice "<<iSlice<<": ntracks "<<slice.NTracks()<<"/"<<fSliceNTrackInfos[iSlice]<<std::endl;
     306           0 :   }
     307           0 : }
     308             : 
     309             : 
     310             : 
     311             : bool AliHLTTPCCAMerger::FitTrack( AliHLTTPCCATrackParam &T, float &Alpha,
     312             :                                   AliHLTTPCCATrackParam t0, float Alpha0,
     313             :                                   int hits[], int &NTrackHits, bool dir, bool final,
     314             :                                   AliHLTTPCCAClusterInfo *infoArray )
     315             : {
     316             :   // Fit the track
     317             : 
     318           0 :   AliHLTTPCCATrackParam::AliHLTTPCCATrackFitParam fitPar;
     319           0 :   AliHLTTPCCATrackParam t = t0;
     320           0 :   AliHLTTPCCATrackLinearisation l( t0 );
     321             : 
     322             :   bool first = 1;
     323             :   bool doErrors = 1;
     324           0 :   if ( !infoArray ) {
     325           0 :     infoArray = fClusterInfos;
     326             :     doErrors = 0;
     327           0 :   }
     328             : 
     329           0 :   t.CalculateFitParameters( fitPar );
     330             : 
     331           0 :   int hitsNew[1000];
     332             :   int nHitsNew = 0;
     333             : 
     334           0 :   for ( int ihit = 0; ihit < NTrackHits; ihit++ ) {
     335             : 
     336           0 :     int jhit = dir ? ( NTrackHits - 1 - ihit ) : ihit;
     337           0 :     AliHLTTPCCAClusterInfo &h = infoArray[hits[jhit]];
     338             : 
     339           0 :     int iSlice = h.ISlice();
     340             : 
     341           0 :     float sliceAlpha =  fSliceParam.Alpha( iSlice );
     342             : 
     343           0 :     if ( CAMath::Abs( sliceAlpha - Alpha0 ) > 1.e-4 ) {
     344           0 :       if ( ! t.Rotate(  sliceAlpha - Alpha0, l, .999 ) ) continue;
     345             :       Alpha0 = sliceAlpha;
     346           0 :     }
     347             : 
     348             :     //float x = fSliceParam.RowX( h.IRow() );
     349           0 :     float x = h.X();
     350             : 
     351           0 :     if ( !t.TransportToXWithMaterial( x, l, fitPar, fSliceParam.GetBz( t ) ) ) continue;
     352             : 
     353           0 :     if ( first ) {
     354           0 :       t.SetCov( 0, 10 );
     355           0 :       t.SetCov( 1,  0 );
     356           0 :       t.SetCov( 2, 10 );
     357           0 :       t.SetCov( 3,  0 );
     358           0 :       t.SetCov( 4,  0 );
     359           0 :       t.SetCov( 5,  1 );
     360           0 :       t.SetCov( 6,  0 );
     361           0 :       t.SetCov( 7,  0 );
     362           0 :       t.SetCov( 8,  0 );
     363           0 :       t.SetCov( 9,  1 );
     364           0 :       t.SetCov( 10,  0 );
     365           0 :       t.SetCov( 11,  0 );
     366           0 :       t.SetCov( 12,  0 );
     367           0 :       t.SetCov( 13,  0 );
     368           0 :       t.SetCov( 14,  10 );
     369           0 :       t.SetChi2( 0 );
     370           0 :       t.SetNDF( -5 );
     371           0 :       t.CalculateFitParameters( fitPar );
     372           0 :     }
     373             : 
     374           0 :     float err2Y = h.Err2Y();
     375           0 :     float err2Z = h.Err2Z();
     376           0 :     if ( doErrors ) fSliceParam.GetClusterErrors2v1( h.RowType(), h.Z(), l.SinPhi(), l.CosPhi(), l.DzDs(), err2Y, err2Z );
     377           0 :     if( !final ){
     378           0 :       err2Y*= fSliceParam.ClusterError2CorrectionY();
     379           0 :       err2Z*= fSliceParam.ClusterError2CorrectionZ();
     380           0 :     }
     381             : 
     382           0 :     if ( !t.Filter( h.Y(), h.Z(), err2Y, err2Z ) ) continue;
     383             : 
     384             :     first = 0;
     385             : 
     386           0 :     hitsNew[nHitsNew++] = hits[jhit];
     387           0 :   }
     388             : 
     389           0 :   if ( CAMath::Abs( t.QPt() ) < 1.e-4 ) t.SetQPt( 1.e-4 );
     390             : 
     391           0 :   bool ok = t.CheckNumericalQuality();
     392             : 
     393           0 :   if ( CAMath::Abs( t.SinPhi() ) > .99 ) ok = 0;
     394           0 :   else if ( l.CosPhi() >= 0 ) t.SetSignCosPhi( 1 );
     395           0 :   else t.SetSignCosPhi( -1 );
     396             : 
     397           0 :   if ( ok ) {
     398           0 :     T = t;
     399           0 :     Alpha = Alpha0;
     400           0 :     NTrackHits = nHitsNew;
     401           0 :     for ( int i = 0; i < NTrackHits; i++ ) {
     402           0 :       hits[dir ?( NTrackHits-1-i ) :i] = hitsNew[i];
     403             :     }
     404           0 :   }
     405           0 :   return ok;
     406           0 : }
     407             : 
     408             : 
     409             : float AliHLTTPCCAMerger::GetChi2( float x1, float y1, float a00, float a10, float a11,
     410             :                                   float x2, float y2, float b00, float b10, float b11  )
     411             : {
     412             :   //* Calculate Chi2/ndf deviation
     413             : 
     414           0 :   float d[2] = { x1 - x2, y1 - y2 };
     415             : 
     416           0 :   float mSi[3] = { a00 + b00, a10 + b10, a11 + b11 };
     417             : 
     418           0 :   float s = ( mSi[0] * mSi[2] - mSi[1] * mSi[1] );
     419             : 
     420           0 :   if ( s < 1.E-10 ) return 10000.;
     421             : 
     422           0 :   float mS[3] = { mSi[2], -mSi[1], mSi[0] };
     423             : 
     424           0 :   return AliHLTTPCCAMath::Abs( ( ( mS[0]*d[0] + mS[1]*d[1] )*d[0]
     425           0 :                        + ( mS[1]*d[0] + mS[2]*d[1] )*d[1] ) / s / 2 );
     426             : 
     427           0 : }
     428             : 
     429             : 
     430             : 
     431             : void AliHLTTPCCAMerger::MakeBorderTracks( int iSlice, int iBorder, AliHLTTPCCABorderTrack B[], int &nB )
     432             : {
     433             :   //* prepare slice tracks for merging with next/previous/same sector
     434             :   //* each track transported to the border line,
     435             :   //* in some cases both inner and outer parameters of the track are transported
     436             : 
     437             :   static int statAll = 0, statOK = 0;
     438           0 :   nB = 0;
     439           0 :   float dAlpha = fSliceParam.DAlpha() / 2;
     440             :   float x0 = 0;
     441             : 
     442           0 :   if ( iBorder == 0 ) { // transport to the left age of the sector and rotate horisontally
     443           0 :     dAlpha = dAlpha - CAMath::Pi() / 2 ;
     444           0 :   } else if ( iBorder == 1 ) { //  transport to the right age of the sector and rotate horisontally
     445           0 :     dAlpha = -dAlpha - CAMath::Pi() / 2 ;
     446           0 :   } else if ( iBorder == 2 ) { // transport to the left age of the sector and rotate vertically
     447             :     dAlpha = dAlpha;
     448           0 :     x0 = fSliceParam.RowX( 63 );
     449           0 :   } else if ( iBorder == 3 ) { // transport to the right age of the sector and rotate vertically
     450           0 :     dAlpha = -dAlpha;
     451           0 :     x0 =  fSliceParam.RowX( 63 );
     452           0 :   } else if ( iBorder == 4 ) { // transport to the middle of the sector, w/o rotation
     453             :     dAlpha = 0;
     454           0 :     x0 = fSliceParam.RowX( 63 );
     455           0 :   }
     456             : 
     457           0 :   for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
     458             : 
     459           0 :     const AliHLTTPCCASliceTrackInfo &track = fTrackInfos[ fSliceTrackInfoStart[iSlice] + itr ];
     460             : 
     461           0 :     AliHLTTPCCATrackParam t0 = track.InnerParam();
     462           0 :     AliHLTTPCCATrackParam t1 = track.OuterParam();
     463             : 
     464           0 :     const float maxSin = CAMath::Sin( 60. / 180.*CAMath::Pi() );
     465             : 
     466           0 :     bool ok0 = t0.Rotate( dAlpha, maxSin );
     467           0 :     bool ok1 = t1.Rotate( dAlpha, maxSin );
     468             : 
     469           0 :     bool do0 = ok0;
     470           0 :     bool do1 = ok1 && ( !ok0 || t1.SignCosPhi() * t0.SignCosPhi() < 0 );
     471             : 
     472           0 :     if ( ok0 && !do1 && ok1 && ( t1.X() < t0.X() ) ) {
     473             :       do0 = 0;
     474             :       do1 = 1;
     475           0 :     }
     476             : 
     477           0 :     if ( do0 ) {
     478           0 :       AliHLTTPCCABorderTrack &b = B[nB];
     479           0 :       b.SetX( t0.GetX() );
     480             :       
     481           0 :       if ( t0.TransportToX( x0, fSliceParam.GetBz( t0 ), maxSin ) ) {
     482           0 :         b.SetOK( 1 );
     483           0 :         b.SetTrackID( itr );
     484           0 :         b.SetNClusters( track.NClusters() );        
     485           0 :         b.SetParam( t0 );
     486           0 :         nB++;
     487           0 :       }
     488           0 :     }
     489           0 :     if ( do1 ) {
     490           0 :       AliHLTTPCCABorderTrack &b = B[nB];
     491           0 :       b.SetX( t1.GetX() );
     492             :       
     493           0 :       if ( t1.TransportToX( x0, fSliceParam.GetBz( t1 ), maxSin ) ) {
     494           0 :         b.SetOK( 1 );
     495           0 :         b.SetTrackID( itr );
     496           0 :         b.SetNClusters( track.NClusters() );
     497           0 :         b.SetParam( t1 );
     498           0 :         nB++;
     499           0 :       }
     500           0 :     }
     501           0 :     if ( do0 || do1 ) statOK++;
     502           0 :     statAll++;
     503           0 :   }
     504           0 : }
     505             : 
     506             : 
     507             : 
     508             : void AliHLTTPCCAMerger::MergeBorderTracks( int iSlice1, AliHLTTPCCABorderTrack B1[], int N1,
     509             :     int iSlice2, AliHLTTPCCABorderTrack B2[], int N2
     510             :                                          )
     511             : {
     512             :   //* merge two sets of tracks
     513             : 
     514             :   //std::cout<<" Merge slices "<<iSlice1<<"+"<<iSlice2<<": tracks "<<N1<<"+"<<N2<<std::endl;
     515             :   
     516             :   float factor2ys = 1.;//1.5;//SG!!!
     517             :   float factor2zt = 1.;//1.5;//SG!!!
     518             :   float factor2k = 2.0;//2.2;
     519             : 
     520             :   factor2k  = 3.5 * 3.5 * factor2k * factor2k;
     521             :   factor2ys = 3.5 * 3.5 * factor2ys * factor2ys;
     522             :   factor2zt = 3.5 * 3.5 * factor2zt * factor2zt;
     523             : 
     524             :   int minNPartHits = 10;//SG!!!
     525             :   int minNTotalHits = 20;
     526             : 
     527             :   //float maxDX = fSliceParam.RowX(40) -  fSliceParam.RowX(0);
     528             : 
     529           0 :   for ( int i1 = 0; i1 < N1; i1++ ) {
     530           0 :     AliHLTTPCCABorderTrack &b1 = B1[i1];
     531           0 :     if ( !b1.OK() ) continue;
     532           0 :     if ( b1.NClusters() < minNPartHits ) continue;
     533           0 :     const AliHLTTPCCATrackParam &t1 = b1.Param();
     534             :     int iBest2 = -1;
     535             :     int lBest2 = 0;
     536           0 :     int start2 = ( iSlice1 != iSlice2 ) ? 0 : i1 + 1;
     537           0 :     for ( int i2 = start2; i2 < N2; i2++ ) {
     538           0 :       AliHLTTPCCABorderTrack &b2 = B2[i2];
     539           0 :       if ( !b2.OK() ) continue;
     540           0 :       if ( b2.NClusters() < minNPartHits ) continue;
     541           0 :       if ( b2.NClusters() < lBest2 ) continue;
     542           0 :       if ( b1.NClusters() + b2.NClusters() < minNTotalHits ) continue;
     543             : 
     544             :       //if( TMath::Abs(b1.fX - b2.fX)>maxDX ) continue;
     545             : 
     546           0 :       const AliHLTTPCCATrackParam &t2 = b2.Param();
     547             : 
     548           0 :       float c = t2.SignCosPhi() * t1.SignCosPhi() >= 0 ? 1 : -1;
     549           0 :       float dk = t2.QPt() - c * t1.QPt();
     550           0 :       float s2k = t2.Err2QPt() + t1.Err2QPt();
     551             :       //std::cout<<" check 1.. "<<dk/sqrt(factor2k)<<std::endl;
     552           0 :       if ( dk*dk > factor2k*s2k ) continue;
     553             : 
     554             : 
     555           0 :       float chi2ys = GetChi2( t1.Y(), c * t1.SinPhi(), t1.Cov()[0], c * t1.Cov()[3], t1.Cov()[5],
     556           0 :                               t2.Y(),  t2.SinPhi(), t2.Cov()[0],  t2.Cov()[3], t2.Cov()[5] );
     557             : 
     558             :       //std::cout<<" check 2.. "<<sqrt(chi2ys/factor2ys)<<std::endl;
     559           0 :       if ( chi2ys > factor2ys ) continue;
     560             :       
     561             : 
     562           0 :       float chi2zt = GetChi2( t1.Z(), c * t1.DzDs(), t1.Cov()[2], c * t1.Cov()[7], t1.Cov()[9],
     563           0 :                               t2.Z(),  t2.DzDs(), t2.Cov()[2],  t2.Cov()[7], t2.Cov()[9] );
     564             : 
     565             :       //std::cout<<" check 3.. "<<sqrt(chi2zt/factor2zt)<<std::endl;
     566           0 :       if ( chi2zt > factor2zt ) continue;
     567             : 
     568           0 :       lBest2 = b2.NClusters();
     569           0 :       iBest2 = b2.TrackID();
     570           0 :     }
     571             : 
     572           0 :     if ( iBest2 < 0 ) continue;
     573             : 
     574             :     //std::cout<<"Neighbour found for "<<i1<<": "<<iBest2<<std::endl;
     575           0 :     AliHLTTPCCASliceTrackInfo &newTrack1 = fTrackInfos[fSliceTrackInfoStart[iSlice1] + b1.TrackID() ];
     576           0 :     AliHLTTPCCASliceTrackInfo &newTrack2 = fTrackInfos[fSliceTrackInfoStart[iSlice2] + iBest2 ];
     577             : 
     578           0 :     int old1 = newTrack2.PrevNeighbour();
     579             : 
     580           0 :     if ( old1 >= 0 ) {
     581           0 :       AliHLTTPCCASliceTrackInfo &oldTrack1 = fTrackInfos[fSliceTrackInfoStart[iSlice1] + old1];
     582           0 :       if ( oldTrack1.NClusters()  < newTrack1.NClusters() ) {
     583           0 :         newTrack2.SetPrevNeighbour( -1 );
     584           0 :         oldTrack1.SetNextNeighbour( -1 );
     585           0 :       } else continue;
     586           0 :     }
     587           0 :     int old2 = newTrack1.NextNeighbour();
     588           0 :     if ( old2 >= 0 ) {
     589           0 :       AliHLTTPCCASliceTrackInfo &oldTrack2 = fTrackInfos[fSliceTrackInfoStart[iSlice2] + old2];
     590           0 :       if ( oldTrack2.NClusters() < newTrack2.NClusters() ) {
     591           0 :         oldTrack2.SetPrevNeighbour( -1 );
     592           0 :       } else continue;
     593           0 :     }
     594           0 :     newTrack1.SetNextNeighbour( iBest2 );
     595           0 :     newTrack2.SetPrevNeighbour( b1.TrackID() );
     596             :     //std::cout<<"Neighbourhood is set"<<std::endl;
     597           0 :   }
     598             : 
     599           0 : }
     600             : 
     601             : 
     602             : void AliHLTTPCCAMerger::Merging()
     603             : {
     604             :   //* track merging between slices
     605             : 
     606           0 :   fOutput->SetNTracks( 0 );
     607           0 :   fOutput->SetNTrackClusters( 0 );
     608           0 :   fOutput->SetPointers();
     609             : 
     610             : 
     611             :   // for each slice set number of the next neighbouring slice
     612             : 
     613           0 :   int nextSlice[100];
     614             :   //int prevSlice[100];
     615             : 
     616           0 :   for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
     617           0 :     nextSlice[iSlice] = iSlice + 1;
     618             :     //prevSlice[iSlice] = iSlice - 1;
     619             :   }
     620             :   int mid = fgkNSlices / 2 - 1 ;
     621             :   int last = fgkNSlices - 1 ;
     622           0 :   if ( mid < 0 ) mid = 0; // to avoid compiler warning
     623           0 :   if ( last < 0 ) last = 0; //
     624           0 :   nextSlice[ mid ] = 0;
     625             :   //prevSlice[ 0 ] = mid;
     626           0 :   nextSlice[ last ] = fgkNSlices / 2;
     627             :   //prevSlice[ fgkNSlices/2 ] = last;
     628             : 
     629             :   int maxNSliceTracks = 0;
     630           0 :   for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
     631           0 :     if ( maxNSliceTracks < fSliceNTrackInfos[iSlice] ) maxNSliceTracks = fSliceNTrackInfos[iSlice];
     632             :   }
     633             : 
     634             :   if ( 1 ) {// merging track segments withing one slice
     635             : 
     636           0 :     AliHLTResizableArray<AliHLTTPCCABorderTrack> bord( maxNSliceTracks*2 );
     637             : 
     638           0 :     AliHLTTPCCASliceTrackInfo *tmpT = new AliHLTTPCCASliceTrackInfo[maxNSliceTracks];
     639           0 :     AliHLTTPCCAClusterInfo *tmpH = new AliHLTTPCCAClusterInfo[fMaxClusterInfos];
     640             : 
     641           0 :     for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
     642             : 
     643           0 :       int nBord = 0;
     644           0 :       MakeBorderTracks( iSlice, 4, bord.Data(), nBord );
     645           0 :       MergeBorderTracks( iSlice, bord.Data(), nBord, iSlice, bord.Data(), nBord );
     646             : 
     647             :       int nTr = 0, nH = 0;
     648             :       int sliceFirstClusterRef = 0;
     649           0 :       for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
     650           0 :         AliHLTTPCCASliceTrackInfo &track = fTrackInfos[ fSliceTrackInfoStart[iSlice] + itr];
     651           0 :         if ( itr == 0 ) sliceFirstClusterRef = track.FirstClusterRef();
     652           0 :         track.SetPrevNeighbour( -1 );
     653           0 :         if ( track.NextNeighbour() == -2 ) {
     654           0 :           track.SetNextNeighbour( -1 );
     655           0 :           continue;
     656             :         }
     657           0 :         tmpT[nTr] = track;
     658             :         AliHLTTPCCASliceTrackInfo &trackNew = tmpT[nTr];
     659           0 :         trackNew.SetUsed(0);
     660           0 :         trackNew.SetFirstClusterRef( sliceFirstClusterRef + nH );
     661             : 
     662           0 :         for ( int ih = 0; ih < track.NClusters(); ih++ ) tmpH[nH+ih] = fClusterInfos[track.FirstClusterRef()+ih];
     663           0 :         nTr++;
     664           0 :         nH += track.NClusters();
     665             : 
     666           0 :         int jtr =  track.NextNeighbour();
     667             : 
     668           0 :         if ( jtr < 0 ) continue;
     669           0 :         AliHLTTPCCASliceTrackInfo &neighTrack = fTrackInfos[ fSliceTrackInfoStart[iSlice] + jtr];
     670             : 
     671           0 :         track.SetNextNeighbour( -1 );
     672           0 :         neighTrack.SetNextNeighbour( -2 );
     673             : 
     674           0 :         for ( int ih = 0; ih < neighTrack.NClusters(); ih++ )
     675           0 :           tmpH[nH+ih] = fClusterInfos[neighTrack.FirstClusterRef()+ih];
     676             : 
     677           0 :         trackNew.SetNClusters( trackNew.NClusters() + neighTrack.NClusters() );
     678           0 :         trackNew.SetNextNeighbour( -1 );
     679           0 :         nH += neighTrack.NClusters();
     680           0 :         if ( neighTrack.InnerParam().X() < track.InnerParam().X() ) trackNew.SetInnerParam( neighTrack.InnerParam() );
     681           0 :         if ( neighTrack.OuterParam().X() > track.OuterParam().X() ) trackNew.SetOuterParam( neighTrack.OuterParam() );
     682           0 :       }
     683             : 
     684           0 :       fSliceNTrackInfos[iSlice] = nTr;
     685           0 :       for ( int itr = 0; itr < nTr; itr++ ) fTrackInfos[ fSliceTrackInfoStart[iSlice] + itr] = tmpT[itr];
     686           0 :       for ( int ih = 0; ih < nH; ih++ ) fClusterInfos[sliceFirstClusterRef + ih] = tmpH[ih];
     687             : 
     688           0 :     }
     689           0 :     delete[] tmpT;
     690           0 :     delete[] tmpH;
     691           0 :   }
     692             : 
     693             : 
     694             :   //* merging tracks between slices
     695             : 
     696             : 
     697             :   // arrays for the rotated track parameters
     698             : 
     699             :   AliHLTTPCCABorderTrack
     700           0 :   *bCurr0 = new AliHLTTPCCABorderTrack[maxNSliceTracks*2],
     701           0 :   *bNext0 = new AliHLTTPCCABorderTrack[maxNSliceTracks*2],
     702           0 :   *bCurr = new AliHLTTPCCABorderTrack[maxNSliceTracks*2],
     703           0 :   *bNext = new AliHLTTPCCABorderTrack[maxNSliceTracks*2];
     704             : 
     705           0 :   for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
     706             : 
     707           0 :     int jSlice = nextSlice[iSlice];
     708             : 
     709           0 :     int nCurr0 = 0, nNext0 = 0;
     710           0 :     int nCurr = 0, nNext = 0;
     711             : 
     712           0 :     MakeBorderTracks( iSlice, 0, bCurr, nCurr );
     713           0 :     MakeBorderTracks( jSlice, 1, bNext, nNext );
     714           0 :     MakeBorderTracks( iSlice, 2, bCurr0, nCurr0 );
     715           0 :     MakeBorderTracks( jSlice, 3, bNext0, nNext0 );
     716             : 
     717           0 :     MergeBorderTracks( iSlice, bCurr0, nCurr0, jSlice, bNext0, nNext0 );
     718           0 :     MergeBorderTracks( iSlice, bCurr, nCurr, jSlice, bNext, nNext );
     719           0 :   }
     720             : 
     721           0 :   if ( bCurr0 ) delete[] bCurr0;
     722           0 :   if ( bNext0 ) delete[] bNext0;
     723           0 :   if ( bCurr  ) delete[] bCurr;
     724           0 :   if ( bNext  ) delete[] bNext;
     725             : 
     726             : 
     727             :   //static int nRejected = 0;
     728             : 
     729             :   int nOutTracks = 0;
     730             :   int nOutTrackClusters = 0;
     731             : 
     732           0 :   AliHLTTPCCAMergedTrack *outTracks = new AliHLTTPCCAMergedTrack[fMaxTrackInfos];
     733           0 :   unsigned int   *outClusterId = new unsigned int [fMaxClusterInfos];
     734           0 :   UChar_t  *outClusterPackedAmp = new UChar_t [fMaxClusterInfos];
     735             : 
     736           0 :   int hits[2000];
     737           0 :   for( int i=0; i<2000; i++ ) hits[i] = 0;
     738             : 
     739           0 :   for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
     740             : 
     741           0 :     for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
     742             : 
     743           0 :       AliHLTTPCCASliceTrackInfo &track = fTrackInfos[fSliceTrackInfoStart[iSlice] + itr];
     744             : 
     745           0 :       if ( track.Used() ) continue;
     746           0 :       if ( track.PrevNeighbour() >= 0 ) continue;
     747             :       //std::cout<<"Merged track candidate, nhits "<<track.NClusters()<<std::endl;
     748           0 :       AliHLTTPCCATrackParam startPoint = track.InnerParam(), endPoint = track.OuterParam();
     749           0 :       float startAlpha = track.InnerAlpha(), endAlpha = track.OuterAlpha();
     750             : 
     751             :       int firstHit = 1000;
     752           0 :       int nHits = 0;
     753             :       int jSlice = iSlice;
     754             :       int jtr = itr;
     755             : 
     756             :       {
     757           0 :         track.SetUsed( 1 );
     758           0 :         for ( int jhit = 0; jhit < track.NClusters(); jhit++ ) {
     759           0 :           int id = track.FirstClusterRef() + jhit;
     760           0 :           hits[firstHit+jhit] = id;
     761             :         }
     762           0 :         nHits = track.NClusters();
     763           0 :         jtr = track.NextNeighbour();
     764           0 :         jSlice = nextSlice[iSlice];
     765             :       }
     766             : 
     767           0 :       while ( jtr >= 0 ) {
     768           0 :         AliHLTTPCCASliceTrackInfo &segment = fTrackInfos[fSliceTrackInfoStart[jSlice] + jtr];
     769           0 :         if ( segment.Used() ) break;
     770           0 :         segment.SetUsed( 1 );
     771             :         bool dir = 0;
     772           0 :         int startHit = firstHit + nHits;
     773           0 :         float d00 = startPoint.GetDistXZ2( segment.InnerParam() );
     774           0 :         float d01 = startPoint.GetDistXZ2( segment.OuterParam() );
     775           0 :         float d10 = endPoint.GetDistXZ2( segment.InnerParam() );
     776           0 :         float d11 = endPoint.GetDistXZ2( segment.OuterParam() );
     777           0 :         if ( d00 <= d01 && d00 <= d10 && d00 <= d11 ) {
     778           0 :           startPoint = segment.OuterParam();
     779           0 :           startAlpha = segment.OuterAlpha();
     780             :           dir = 1;
     781           0 :           firstHit -= segment.NClusters();
     782             :           startHit = firstHit;
     783           0 :         } else if ( d01 <= d10 && d01 <= d11 ) {
     784           0 :           startPoint = segment.InnerParam();
     785           0 :           startAlpha = segment.InnerAlpha();
     786             :           dir = 0;
     787           0 :           firstHit -= segment.NClusters();
     788             :           startHit = firstHit;
     789           0 :         } else if ( d10 <= d11 ) {
     790           0 :           endPoint = segment.OuterParam();
     791           0 :           endAlpha = segment.OuterAlpha();
     792             :           dir = 0;
     793           0 :         } else {
     794           0 :           endPoint = segment.InnerParam();
     795           0 :           endAlpha = segment.InnerAlpha();
     796             :           dir = 1;
     797             :         }
     798           0 :                 if (firstHit < 0)
     799             :                 {
     800             :                         //Buffer too small!!!
     801             :                         firstHit = 200;
     802           0 :                         break;
     803             :                 }
     804             : 
     805           0 :         for ( int jhit = 0; jhit < segment.NClusters(); jhit++ ) {
     806           0 :           int id = segment.FirstClusterRef() + jhit;
     807           0 :           hits[startHit+( dir ?( segment.NClusters()-1-jhit ) :jhit )] = id;
     808             :         }
     809           0 :         nHits += segment.NClusters();
     810           0 :         jtr = segment.NextNeighbour();
     811           0 :         jSlice = nextSlice[jSlice];
     812           0 :       }
     813             : 
     814           0 :       if ( endPoint.X() < startPoint.X() ) { // swap
     815           0 :         for ( int i = 0; i < nHits; i++ ) hits[i] = hits[firstHit+nHits-1-i];
     816             :         firstHit = 0;
     817           0 :       }
     818             : 
     819           0 :       if ( nHits < 30 ) continue;    //SG!!!
     820             : 
     821             :       // refit
     822             : 
     823             :       // need best t0!!!SG
     824             : 
     825           0 :       endPoint = startPoint;
     826             : 
     827           0 :       if ( !FitTrack( endPoint, endAlpha, startPoint, startAlpha, hits + firstHit, nHits, 0,1 ) ) continue;
     828           0 :       if ( !FitTrack( startPoint, startAlpha, endPoint, endAlpha, hits + firstHit, nHits, 1,1 ) ) continue;
     829           0 :       if ( nHits < 30 ) continue;    //SG!!!
     830             : 
     831           0 :       AliHLTTPCCATrackParam p = startPoint;
     832             :       
     833             :       if(0){
     834             :         double xTPC = 83.65; //SG!!!
     835             :         double dAlpha = 0.349066;
     836             :         double ymax = 2.* xTPC * CAMath::Tan( dAlpha / 2. );
     837             :         
     838             :         double dRot = 0;
     839             :         if ( p.TransportToXWithMaterial( xTPC, fSliceParam.GetBz( p ) ) ) {
     840             :           double y = p.GetY();
     841             :           if ( y > ymax ) {         
     842             :             if ( p.Rotate( dAlpha ) ){
     843             :               dRot = dAlpha;
     844             :               p.TransportToXWithMaterial( xTPC, fSliceParam.GetBz( p ) );
     845             :             }
     846             :           } else if( y< -ymax ){
     847             :             if ( p.Rotate( -dAlpha ) ){
     848             :               dRot = -dAlpha;
     849             :               p.TransportToXWithMaterial( xTPC, fSliceParam.GetBz( p ) );
     850             :             }
     851             :           }
     852             :         }
     853             :         
     854             :         if ( -ymax <= p.GetY() && p.GetY() <= ymax && p.CheckNumericalQuality() ){
     855             :           startPoint = p;
     856             :           startAlpha+=dRot;
     857             :         }     
     858             :       }
     859             : 
     860           0 :       if ( !startPoint.CheckNumericalQuality() ) continue;
     861             : 
     862           0 :       AliHLTTPCCAMergedTrack &mergedTrack = outTracks[nOutTracks];
     863           0 :       mergedTrack.SetNClusters( nHits );
     864           0 :       mergedTrack.SetFirstClusterRef( nOutTrackClusters );
     865           0 :       mergedTrack.SetInnerParam( startPoint );
     866           0 :       mergedTrack.SetInnerAlpha( startAlpha );
     867           0 :       mergedTrack.SetOuterParam( endPoint );
     868           0 :       mergedTrack.SetOuterAlpha( endAlpha );
     869             : 
     870           0 :       for ( int i = 0; i < nHits; i++ ) {
     871           0 :         AliHLTTPCCAClusterInfo &clu = fClusterInfos[hits[firstHit+i]];
     872           0 :         outClusterId[nOutTrackClusters+i] = clu.Id();
     873           0 :         outClusterPackedAmp[nOutTrackClusters+i] = clu.PackedAmp();
     874             :       }
     875             : 
     876           0 :       nOutTracks++;
     877           0 :       nOutTrackClusters += nHits;
     878           0 :     }
     879             :   }
     880             : 
     881           0 :   fOutput->SetNTracks( nOutTracks );
     882             :   #ifdef HLTCA_STANDALONE
     883             :   printf("Tracks Output: %d\n", nOutTracks);
     884             :   #endif
     885           0 :   fOutput->SetNTrackClusters( nOutTrackClusters );
     886           0 :   fOutput->SetPointers();
     887             : 
     888           0 :   for ( int itr = 0; itr < nOutTracks; itr++ ) fOutput->SetTrack( itr, outTracks[itr] );
     889             : 
     890           0 :   for ( int ic = 0; ic < nOutTrackClusters; ic++ ) {
     891           0 :     fOutput->SetClusterId( ic, outClusterId[ic] );
     892           0 :     fOutput->SetClusterPackedAmp( ic, outClusterPackedAmp[ic] );
     893             :   }
     894             : 
     895           0 :   delete[] outTracks;
     896           0 :   delete[] outClusterId;
     897           0 :   delete[] outClusterPackedAmp;
     898           0 : }

Generated by: LCOV version 1.11