StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
AliHLTTPCCAStartHitsFinder.cxx
1 // @(#) $Id: AliHLTTPCCAStartHitsFinder.cxx,v 1.1 2016/02/05 23:27:29 fisyak Exp $
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 // Developed by: Igor Kulakov <I.Kulakov@gsi.de> *
11 // Maksym Zyzak <M.Zyzak@gsi.de> *
12 // *
13 // Permission to use, copy, modify and distribute this software and its *
14 // documentation strictly for non-commercial purposes is hereby granted *
15 // without fee, provided that the above copyright notice appears in all *
16 // copies and that both the copyright notice and this permission notice *
17 // appear in the supporting documentation. The authors make no claims *
18 // about the suitability of this software for any purpose. It is *
19 // provided "as is" without express or implied warranty. *
20 // *
21 //***************************************************************************
22 
23 #include "AliHLTTPCCAStartHitsFinder.h"
24 #include "AliHLTTPCCATracker.h"
25 #include "AliHLTArray.h"
26 #include "AliHLTTPCCAMath.h"
27 
28 #ifdef USE_TBB
29 #include <tbb/parallel_sort.h>
30 #endif //USE_TBB
31 
33 // depends on:
34 // - linkUp/linkDown data for the rows above and below the row to process
35 //
36 // changes atomically:
37 // - number of tracklets
38 //
39 // writes
40 // - tracklet start-hit ids
41 //
42 // only when all rows are done, is NTracklets known
44 
45 //X template<typename Int, typename Float>
46 //X struct SeedRowData {
47 //X Int fRow;
48 //X Int fHitIndex;
49 //X };
50 //X
51 //X typedef std::vector<SeedRowData<ushort_v, sfloat_v> > SeedDataVector; // contains ushort_v::Size complete seeds
52 //X typedef std::vector<SeedRowData<unsigned short, float> > SeedDataScalar; // contains one complete seed
53 //X
54 //X void AliHLTTPCCAStartHitsFinder::run( AliHLTTPCCATracker &tracker, const SliceData &data )
55 //X {
56 //X SeedDataVector seed;
57 //X const int lastRow = Parameters::NumberOfRows - 4;
58 //X for ( int rowIndex = 2; rowIndex <= lastRow; ++rowIndex ) {
59 //X // inside the row we're looking for hits that are linked upwards but not downwards, those start
60 //X // a seed
61 //X const int maxStorageSize = ( row.NHits() + short_v::Size - 1 ) / short_v::Size;
62 //X short_v linkUpCompressedStorage[maxStorageSize];
63 //X ushort_v hitIndexesCompressedStorage[maxStorageSize];
64 //X short *linkUpCompressed = &linkUpCompressedStorage[0];
65 //X unsigned short *hitIndexesCompressed = &hitIndexesCompressedStorage[0];
66 //X for ( int hitIndex = 0; hitIndex < row.NHits(); hitIndex += short_v::Size ) {
67 //X const short_v linkUp = data.HitLinkUpData( row, hitIndex );
68 //X foreach_bit( int i, linkUp != -1 ) {
69 //X *linkUpCompressed++ = linkUp[i];
70 //X *hitIndexesCompressed++ = hitIndex + i;
71 //X }
72 //X }
73 //X }
74 //X }
75 
76 void AliHLTTPCCAStartHitsFinder::run( AliHLTTPCCATracker &tracker, SliceData &data, int iter )
77 {
78  // enum {
79  // kArraySize = 10240,
80  // kMaxStartHits = kArraySize - 1 - short_v::Size
81  // };
82 
83  AliHLTTPCCAStartHitId *const startHits = tracker.TrackletStartHits();
84 
85  //TODO parallel_for
86  const int rowStep = AliHLTTPCCAParameters::RowStep;
87  const int lastRow = tracker.Param().NRows() - rowStep*2;
88  for ( int rowIndex = 0; rowIndex <= lastRow; ++rowIndex ) {
89 
90 #ifdef USE_TBB
91  int hitsStartOffset = CAMath::AtomicAdd( tracker.NTracklets(), 0 );
92 #else //USE_TBB
93  const int hitsStartOffset = *tracker.NTracklets(); // number of start hits from other jobs
94 #endif //USE_TBB
95  //X short_m leftMask( Vc::Zero );
96  const AliHLTTPCCARow &row = data.Row( rowIndex );
97 // const AliHLTTPCCARow &middleRow = data.Row( rowIndex + rowStep );
98  int startHitsCount = 0;
99 
100 
101  // look through all the hits and look for
102  const int numberOfHits = row.NHits();
103  for ( int hitIndex = 0; hitIndex < numberOfHits; hitIndex += short_v::Size ) {
104  const short_v hitIndexes = short_v( Vc::IndexesFromZero ) + hitIndex;
105  short_m validHitsMask = hitIndexes < numberOfHits;
106  validHitsMask &= ( short_v(data.HitDataIsUsed( row ), static_cast<ushort_v>(hitIndexes) ) == short_v( Vc::Zero ) ); // not-used hits can be connected only with not-used, so only one check is needed
107 
108  // hits that have a link up but none down == the start of a Track
109  const short_v &middleHitIndexes = data.HitLinkUpData( row, hitIndex );
110  validHitsMask &= ( data.HitLinkDownData( row, hitIndex ) < short_v( Vc::Zero ) ) && ( middleHitIndexes >= short_v( Vc::Zero ) );
111  if ( !validHitsMask.isEmpty() ) { // start hit has been found
112 
113  // find the length
114  int iRow = rowIndex + 1*rowStep;
115  int nRows = 2;
116  short_v upperHitIndexes = middleHitIndexes;
117  for (;!validHitsMask.isEmpty() && nRows < AliHLTTPCCAParameters::NeighboursChainMinLength[iter];) {
118  upperHitIndexes = short_v( data.HitLinkUpData( data.Row( iRow ) ), static_cast<ushort_v>( upperHitIndexes ), validHitsMask );
119  validHitsMask &= upperHitIndexes >= short_v( Vc::Zero );
120  nRows++;
121  iRow += rowStep;
122  }
123  // check if the length is enough
124  short_m goodChains = validHitsMask;
125  if ( !goodChains.isEmpty() ) {
126  // set all hits in the chain as used
127  data.SetHitAsUsed( row, static_cast<ushort_v>( hitIndexes ), goodChains );
128 
129  int iRow2 = rowIndex + 1*rowStep;
130  ushort_v nHits(Vc::Zero);
131  nHits(goodChains) = 2;
132  AliHLTTPCCARow curRow2;
133  short_v upperHitIndexes2 = middleHitIndexes;
134  for (;!goodChains.isEmpty();) {
135  curRow2 = data.Row( iRow2 );
136 
137  data.SetHitAsUsed( curRow2, static_cast<ushort_v>( upperHitIndexes2 ), goodChains );
138  upperHitIndexes2 = short_v( data.HitLinkUpData( curRow2 ), static_cast<ushort_v>( upperHitIndexes2 ), goodChains );
139  goodChains &= upperHitIndexes2 >= short_v( Vc::Zero );
140  nHits(goodChains)++;
141  iRow2 += rowStep;
142  }
143 
144  foreach_bit( int i, validHitsMask ) {
145  startHits[hitsStartOffset + startHitsCount++].Set( rowIndex, hitIndex + i, nHits[i] );
146  }
147 
148  // // check free space
149  // if ( ISUNLIKELY( startHitsCount >= kMaxStartHits ) ) { // TODO take in account stages kMax for one stage should be smaller
150  // break;
151  // }
152  } // if good Chains
153 
154  } // if start hit
155  } // for iHit
156 
157 #ifdef USE_TBB
158  hitsStartOffset = CAMath::AtomicAdd( tracker.NTracklets(), startHitsCount ); // number of start hits from other jobs
159 #else
160  *tracker.NTracklets() += startHitsCount;
161 #endif //USE_TBB
162  } // for rowIndex
163 
164 // std::cout << *tracker.NTracklets() << " start hits have been found." << std::endl;
165 #ifdef USE_TBB
166  tbb::parallel_sort( startHits, startHits + *tracker.NTracklets() );
167 #else //USE_TBB
168  std::sort( startHits, startHits + *tracker.NTracklets() );
169 #endif //USE_TBB
170 }
const AliHLTTPCCARow & Row(int rowIndex) const