//-*- 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" #include "AliHLTTPCCATrackParam.h" #include "AliHLTTPCCASliceTrack.h" #include #if !defined(HLTCA_GPUCODE) #include #endif class AliHLTTPCCATrackParamVector; class AliHLTTPCCASliceTrack; class AliHLTTPCCASliceOutput; class AliHLTTPCCAMergedTrack; class AliHLTTPCCAMergerOutput; class AliHLTTPCCATracker; /** * @class AliHLTTPCCAMerger * */ class AliHLTTPCCAClusterInfo; class AliHLTTPCCAMerger { class AliHLTTPCCABorderTrack { public: int TrackID() const { return fTrackID; } float b() const{ return fb; } float bErr2() const{ return fbErr2; } float p() const{ return fp; } float pErr2() const{ return fpErr2; } unsigned int InnerRow() const {return fInnerRow;} unsigned int OuterRow() const {return fOuterRow;} void SetInnerRow(unsigned int v) {fInnerRow = v;} void SetOuterRow(unsigned int v) {fOuterRow = v;} void SetTrackID ( int v ) { fTrackID = v; } void Setb (float v) { fb = v; } void SetbErr2 (float v) { fbErr2 = v; } void Setp (float v) { fp = v; } void SetpErr2 (float v) { fpErr2 = v; } private: float fb; float fbErr2; float fp; float fpErr2; int fTrackID; // track index unsigned int fInnerRow; unsigned int fOuterRow; }; public: class AliHLTTPCCASliceTrackInfo; AliHLTTPCCAMerger(); ~AliHLTTPCCAMerger(); AliHLTTPCCAMerger( const AliHLTTPCCAMerger& ); const AliHLTTPCCAMerger &operator=( const AliHLTTPCCAMerger& ) const; void Clear(); // accsessors void SetSliceParam( const AliHLTTPCCAParam &v ) { fSliceParam = v; } void SetSliceData( int index, const AliHLTTPCCASliceOutput *SliceData ); void SetSlices ( int i, AliHLTTPCCATracker *sl ); static void SetDoNotMergeBorders(int i = 0) {fgDoNotMergeBorders = i;} const AliHLTTPCCAMergerOutput * Output() const { return fOutput; } int NTimers() { return fNTimers; } float Timer( int i ) { return fTimers[i]; }; // process void UnpackSlices(); void Reconstruct(); private: void FindNeighbourTracks(int number=0); void Merging(int number=0); float_m AddNeighbour( const uint_v& jIndexes, const int& nVecElements, const float_m& isNeighbour, int hits[2000][uint_v::Size], uint_v& firstHit, AliHLTTPCCATrackParamVector& vStartPoint, AliHLTTPCCATrackParamVector& vEndPoint, float_v& vStartAlpha, float_v& vEndAlpha, uint_v& vNHits ); void MakeBorderTracks( AliHLTTPCCABorderTrack B[], unsigned int &nB, unsigned char &iSlice ); void MergeBorderTracks( AliHLTTPCCABorderTrack B1[], int N1, unsigned int iSlice1, AliHLTTPCCABorderTrack B2[], int N2, unsigned int iSlice2, int number, const unsigned int FirstTrIR[], const unsigned int LastTrIR[]); void FindMinMaxIndex( int N2, const unsigned int FirstTrIR[], const unsigned int LastTrIR[], int minIRow, int maxIRow, int &min, int &max ); void CheckTracksMatch( int number, const AliHLTTPCCATrackParamVector &InParT1, const AliHLTTPCCATrackParamVector &OutParT1, const float_v &OutAlphaT1, const float_v &InAlphaT1, const AliHLTTPCCATrackParamVector &InParT2, const AliHLTTPCCATrackParamVector &OutParT2, const float_v &OutAlphaT2, const float_v &InAlphaT2, const float_v dxArr[4], const float_v dyArr[4], const float_v &sinS1_E2v, const float_v &sinS2_E1v, float_v &minL2v, const float &bestChi2, float_v& min_chi2, float_m& active ); // helping functions void ConvertPTrackParamToVector( const AliHLTTPCCATrackParam *t0[uint_v::Size], AliHLTTPCCATrackParamVector &t, const int &nTracksV); float_m FitTrack( AliHLTTPCCATrackParamVector &t, float_v &Alpha0V, int hits[2000][uint_v::Size], uint_v &firstHits, uint_v &NTrackHits, int &nTracksV, float_m active0 = float_m(true), bool dir = 1 ); unsigned int HitIndex( const uint_v& firstHits, const uint_v& nHits, bool dir, int iV, unsigned int i ) { // vectorized is slower return static_cast(firstHits[iV]) + static_cast(dir ? ( nHits[iV] - 1 - i ) : i); } void InvertCholetsky(float_v a[15]); void MultiplySS(const float_v C[15], const float_v V[15], float_v K[5][5]); void MultiplyMS(const float_v C[5][5], const float_v V[15], float_v K[15]); void MultiplySR(const float_v C[15], const float_v r_in[5], float_v r_out[5]); void FilterTracks(const float_v r[5], const float_v C[15], const float_v m[5], const float_v V[15], float_v R[5], float_v W[15], float_v &chi2, const float_m &mask = float_m( true )); static bool CompareInnerRow (const AliHLTTPCCABorderTrack &b1, const AliHLTTPCCABorderTrack &b2) { return (b1.InnerRow() > b2.InnerRow()) || ( (b1.InnerRow() == b2.InnerRow()) && (b1.b() > b2.b()) ) ; } static bool CompareOuterRow (const AliHLTTPCCABorderTrack &b1, const AliHLTTPCCABorderTrack &b2) { return (b1.OuterRow() < b2.OuterRow())/* || ( (b1.OuterRow() == b2.OuterRow()) && (b1.b() > b2.b()) )*/ ; } static const int fgkNSlices = AliHLTTPCCAParameters::NumberOfSlices; //* N slices static int fgDoNotMergeBorders; AliHLTTPCCAParam fSliceParam; //* slice parameters (geometry, calibr, etc.) const AliHLTTPCCASliceOutput *fkSlices[fgkNSlices]; //* array of input slice tracks AliHLTTPCCATracker *slices[fgkNSlices]; //* array of input slice tracks int fMaxClusterInfos; //* booked size of fClusterInfos array AliHLTTPCCAClusterInfo *fClusterInfos; //* information about track clusters int fMaxTrackInfos; //* booked size of fTrackInfos array Vc::vector fTrackInfos; //* additional information for slice tracks int fSliceTrackInfoStart[fgkNSlices]; //* slice starting index in fTrackInfos array; int fSliceNTrackInfos[fgkNSlices]; //* N of slice track infos in fTrackInfos array; AliHLTTPCCAMergerOutput *fOutput; //* array of output merged tracks static const int fNTimers = 8; float fTimers[fNTimers]; // AliHLTTPCCAHitMemory fHitMemory; }; class AliHLTTPCCAMerger::AliHLTTPCCASliceTrackInfo { public: AliHLTTPCCASliceTrackInfo(): ChiPrev(1e10f),ChiNext(1e10f),fInnerRow(-1),fOuterRow(-1), fInnerAlpha(0.f),fOuterAlpha(0.f),fNClusters(0), fPrevNeighbour(-1),fNextNeighbour(-1),fSlicePrevNeighbour(-1),fSliceNextNeighbour(-1),fUsed(false), fInnerParam(),fOuterParam(){} const AliHLTTPCCATrackParam &InnerParam() const { return fInnerParam; } const AliHLTTPCCATrackParam &OuterParam() const { return fOuterParam; } float InnerAlpha() const { return fInnerAlpha; } float OuterAlpha() const { return fOuterAlpha; } unsigned int NClusters() const { return fNClusters; } int FirstClusterRef() const { return fFirstClusterRef; } int PrevNeighbour() const { return fPrevNeighbour; } int NextNeighbour() const { return fNextNeighbour; } unsigned int SlicePrevNeighbour() const { return fSlicePrevNeighbour; } unsigned int SliceNextNeighbour() const { return fSliceNextNeighbour; } int Used() const { return fUsed; } void SetInnerParam( const AliHLTTPCCATrackParam &v ) { fInnerParam = v; } void SetOuterParam( const AliHLTTPCCATrackParam &v ) { fOuterParam = v; } void SetInnerAlpha( float v ) { fInnerAlpha = v; } void SetOuterAlpha( float v ) { fOuterAlpha = v; } void SetNClusters ( unsigned int v ) { fNClusters = v; } void SetFirstClusterRef( int v ) { fFirstClusterRef = v; } void SetPrevNeighbour( int v ) { fPrevNeighbour = v; } void SetNextNeighbour( int v ) { fNextNeighbour = v; } void SetSlicePrevNeighbour( unsigned char v ) { fSlicePrevNeighbour = v; } void SetSliceNextNeighbour( unsigned char v ) { fSliceNextNeighbour = v; } void SetUsed( bool v ) { fUsed = v; } #ifdef DO_TPCCATRACKER_EFF_PERFORMANCE int orig_track_id; unsigned char fSlice; int number; #endif // DO_TPCCATRACKER_EFF_PERFORMANCE public: float ChiPrev; //characteristic of the link quality to the inner neighbour (for overlaped tracks it is chi2, for not overlaped - distance between tracks) float ChiNext; //characteristic of the link quality to the outer neighbour unsigned char fInnerRow; // number of the inner row of the track unsigned char fOuterRow; // number of the outer row of the track float fInnerAlpha; // The angle of the sector, where inner parameters are float fOuterAlpha; // The angle of the sector, where outers parameters are unsigned int fNClusters; //Clusters number of the track int fFirstClusterRef; // index of the first track cluster in the global cluster array (AliHLTTPCCAMerger::fClusterInfos) int fPrevNeighbour; // The number of the inner (previous) neighbour in the tracks array (AliHLTTPCCAMerger::fTrackInfos) int fNextNeighbour; // The number of the outer (previous) neighbour in the tracks array (AliHLTTPCCAMerger::fTrackInfos) unsigned int fSlicePrevNeighbour; // The number of the sector, which contains inner neighbour unsigned int fSliceNextNeighbour; // The number of the sector, which contains outer neighbour int fUsed; // is the slice track already merged (=1 -> merged, 0 -> not merged) private: AliHLTTPCCATrackParam fInnerParam; // Parameters of the track at the inner point AliHLTTPCCATrackParam fOuterParam; // Parameters of the track at the outer point }; #include "AliHLTTPCCATrackParamVector.h" inline void AliHLTTPCCAMerger::ConvertPTrackParamToVector( const AliHLTTPCCATrackParam *t0[uint_v::Size], AliHLTTPCCATrackParamVector &t, const int &nTracksV) { float_v tmpFloat; int_v tmpShort; for(int iV=0; iV < nTracksV; iV++) if(t0[iV]) tmpFloat[iV] = t0[iV]->X(); t.SetX(tmpFloat); for(int iV=0; iV < nTracksV; iV++) if(t0[iV]) tmpFloat[iV] = t0[iV]->SignCosPhi(); t.SetSignCosPhi(tmpFloat); for(int iP=0; iP<5; iP++) { for(int iV=0; iV < nTracksV; iV++) if(t0[iV]) tmpFloat[iV] = t0[iV]->Par()[iP]; t.SetPar(iP,tmpFloat); } for(int iC=0; iC<15; iC++) { for(int iV=0; iV < nTracksV; iV++) if(t0[iV]) tmpFloat[iV] = t0[iV]->Cov()[iC]; t.SetCov(iC,tmpFloat); } for(int iV=0; iV < nTracksV; iV++) if(t0[iV]) tmpFloat[iV] = t0[iV]->Chi2(); t.SetChi2(tmpFloat); for(int iV=0; iV < nTracksV; iV++) if(t0[iV]) tmpShort[iV] = t0[iV]->NDF(); t.SetNDF(tmpShort); } inline void AliHLTTPCCAMerger::InvertCholetsky(float_v a[15]) { float_v d[5], uud, u[5][5]; for(int i=0; i<5; i++) { d[i]=0.f; for(int j=0; j<5; j++) u[i][j]=0.; } for(int i=0; i<5; i++) { uud=0.; for(int j=0; j