StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
AliHLTTPCCANeighboursFinder.h
1 /*
2  This file is property of and copyright by the ALICE HLT Project *
3  ALICE Experiment at CERN, All rights reserved. *
4  See cxx source for full Copyright notice *
5 */
6 #ifndef ALIHLTTPCCANEIGHBOURSFINDER_H
7 #define ALIHLTTPCCANEIGHBOURSFINDER_H
8 
9 #include "AliHLTTPCCATracker.h"
10 #include "AliHLTTPCCAHitArea.h"
11 
12 #ifdef USE_TBB
13 #include <tbb/blocked_range.h>
14 #endif //USE_TBB
15 
20 {
21  public:
22  class ExecuteOnRow;
23  NeighboursFinder( AliHLTTPCCATracker *tracker, SliceData &sliceData, int iIter ) : fTracker( tracker ), fData( sliceData ), fIter(iIter) {}
24  void execute();
25 
26 #ifdef USE_TBB
27  void operator()( const tbb::blocked_range<int> &r ) const;
28 #endif //USE_TBB
29 
30  private:
31  void executeOnRow( int rowIndex ) const;
32 
33  AliHLTTPCCATracker *fTracker;
34  SliceData &fData;
35  int fIter; // current iteration of finding
36 };
37 
38 #ifdef USE_TBB
39 inline void AliHLTTPCCATracker::NeighboursFinder::operator()( const tbb::blocked_range<int> &r ) const
40 {
41  for ( int i = r.begin(); i < r.end(); ++i ) {
42  executeOnRow( i );
43  }
44 }
45 #endif //USE_TBB
46 
47 inline void AliHLTTPCCATracker::NeighboursFinder::executeOnRow( int rowIndex ) const
48 {
49  debugS() << "NeighboursFinder on row " << rowIndex << std::endl;
50  const AliHLTTPCCARow &row = fData.Row( rowIndex );
51 
52  // references to the rows above and below
53  const int rowStep = AliHLTTPCCAParameters::RowStep;
54 
55  const AliHLTTPCCARow &rowUp = fData.Row( rowIndex + rowStep );
56  const AliHLTTPCCARow &rowDn = fData.Row( rowIndex - rowStep );
57 
58 
59  const int numberOfHits = row.NHits();
60  const int numberOfHitsUp = rowUp.NHits();
61  const int numberOfHitsDown = rowDn.NHits();
62  if ( numberOfHits == 0 ) {
63  debugS() << "no hits in this row" << std::endl;
64  return;
65  }
66  if ( numberOfHitsDown == 0 || numberOfHitsUp == 0 ) {
67  debugS() << "no hits in neighbouring rows" << std::endl;
68  return;
69  }
70 
71  // the axis perpendicular to the rows
72  const float xDn = fData.RowX( rowIndex - rowStep );
73  const float x = fData.RowX( rowIndex );
74  const float xUp = fData.RowX( rowIndex + rowStep );
75 
76  // distance of the rows (absolute and relative)
77  const float UpDx = xUp - x;
78  const float DnDx = xDn - x;
79  const float UpTx = xUp / x;
80  const float DnTx = xDn / x;
81 // std::cout << UpDx << " " << DnDx << std::endl;
82 
83  // UpTx/DnTx is used to move the HitArea such that central events are preferred (i.e. vertices
84  // coming from y = 0, z = 0).
85 
86  /* find the connection between hits in the row below, this hit and a hit in the row above
87  * minimizing the difference in slope, i.e.
88  * ______________________________________
89  * \ |dy1
90  * \ | dx1
91  * ___\_________________________|________
92  * \ is better than \ dx2
93  * _____\______________________dy2\______
94  *
95  *
96  * The slope is easily calculated as dy/dx ( dz/dx ).
97  * Comparison: dy1/dx1 - dy2/dx2 = dslopeY
98  * => dy1 * dx2 - dy2 * dx1 = dslopeY * dx1 * dx2
99  *
100  * y+z Comparison is done with:
101  * dslopeY^2 + dslopeZ^2
102  *
103  * The constant ( dx1^2 + dx2^2 ) is multiplied into the chi2Cut
104  */
105 
106 // static const float kAreaSize = 1.f;
107  static const float kAreaSizeY = AliHLTTPCCAParameters::NeighbourAreaSizeTgY[fIter];
108  static const float kAreaSizeZ = AliHLTTPCCAParameters::NeighbourAreaSizeTgZ[fIter];
109  static const int kMaxN = 20; // TODO minimaze
110 
111 //#define USE_CURV_CUT // TODO don't work, problem with error estimation
112 #ifdef USE_CURV_CUT
113  float curv2Cut = AliHLTTPCCAParameters::NeighbourCurvCut[fIter] * .5 * ( UpDx * DnDx * ( UpDx - DnDx ) ); // max curv^2*(dx1*dx2*(dx1+dx2))^2 = (dslopeY^2+dslopeZ^2)*(dx1*dx2)^2 = (dy1*dx2-dy2*dx1)^2+(dz1*dx2-dz2*dx1)^2
114  curv2Cut *= curv2Cut;
115  const float UpErr2 = (rowIndex - rowStep < AliHLTTPCCAParameters::NumberOfInnerRows) ? 0.06*0.06 : 0.12*0.12,
116  DnErr2 = (rowIndex + rowStep < AliHLTTPCCAParameters::NumberOfInnerRows) ? 0.06*0.06 : 0.12*0.12;
117 
118 // std::cout << UpDx << " " << DnDx << std::endl;
119 // std::cout << "before " << 4.f * ( UpDx * UpDx + DnDx * DnDx ) << " now: " << 1/4.f * ( UpDx * DnDx * ( UpDx - DnDx ) ) * ( UpDx * DnDx * ( UpDx - DnDx ) ) << std::endl;
120 #else // USE_CURV_CUT
121  const float chi2Cut = AliHLTTPCCAParameters::NeighbourChiCut[fIter]*AliHLTTPCCAParameters::NeighbourChiCut[fIter] * 4.f * ( UpDx * UpDx + DnDx * DnDx );
122 #endif // USE_CURV_CUT
123  // some step sizes on the current row. the ushorts in hits multiplied with the step size give
124  // the offset on the grid
125 
126  typedef HitArea::NeighbourData NeighbourData;
127 
128  STATIC_ASSERT( short_v::Size % float_v::Size == 0, Short_Vector_Size_is_not_a_multiple_of_Float_Vector_Size );
129  for ( int hitIndex = 0; hitIndex < numberOfHits; hitIndex += short_v::Size ) {
130 
131 // #ifdef DRAW
132 // #define DRAW_NEIGHBOURSFINDING
133 // #endif
134 #ifdef DRAW_NEIGHBOURSFINDING
135  sfloat_v neighUpY[kMaxN];
136  sfloat_v neighUpZ[kMaxN];
137 #endif
138 
139  ushort_v hitIndexes = ushort_v( Vc::IndexesFromZero ) + hitIndex;
140  const short_m &validHitsMask = hitIndexes < numberOfHits;
141 
142  // if the rows above and below both have hits (because if they don't, we don't need to
143  // bother to search for a path)
144 
145 
146  // coordinates of the hit in the current row
147  //ik 04/17/14 sfloat_v y, z, yUp, zUp, yDn, zDn;
148  sfloat_v y(Vc::Zero), z(Vc::Zero), yUp(Vc::Zero), zUp(Vc::Zero), yDn(Vc::Zero), zDn(Vc::Zero);
149  // y = fData.HitDataY( row, hitIndexes, static_cast<sfloat_m>(validHitsMask) );
150  // z = fData.HitDataZ( row, hitIndexes, static_cast<sfloat_m>(validHitsMask) );
151  y = fData.HitDataY( row, hitIndex );
152  z = fData.HitDataZ( row, hitIndex );
153 #ifdef DRAW_NEIGHBOURSFINDING
154  std::cout << " centr y = " << y << " centr z = " << z << std::endl;
155 #endif
156  yUp = y * UpTx; // suppose vertex at (0,0,0)
157  yDn = y * DnTx; // TODO change name
158  zUp = z * UpTx;
159  zDn = z * DnTx;
160 
161 #ifdef USE_CURV_CUT
162  const sfloat_v UpDy = yUp - y,
163  DnDy = yDn - y;
164  const sfloat_v UpR2 = UpDy*UpDy + UpDx*UpDx,
165  DnR2 = DnDy*DnDy + DnDx*DnDx;
166  sfloat_v chi2Cut = curv2Cut + (UpErr2/UpR2 + DnErr2/DnR2)*(UpDx*DnDx)*(UpDx*DnDx); // additional error in dSlopes TODO Take into account z. TODO Use more precise error estimation // TODO change name // TODO optimize
167  // std::cout << rowIndex << " " << curv2Cut << UpErr2/UpR2*(UpDx*DnDx)*(UpDx*DnDx) << DnErr2/DnR2*(UpDx*DnDx)*(UpDx*DnDx) << std::endl;
168  // std::cout << UpErr2 << " " << DnErr2 << " " << UpDy << " " << DnDy << " " << UpR2 << " " << DnR2 << std::endl;
169 #endif // USE_CURV_CUT
170 
171  // find all neighbours in upper area (kMaxN at max)
172  HitArea areaUp( rowUp, fData, yUp, zUp, UpDx*kAreaSizeY, UpDx*kAreaSizeZ, validHitsMask );
173 
174  ushort_v maxUpperNeighbourIndex = ushort_v(Vc::Zero);
175  int upperNeighbourIndex = 0;
176  NeighbourData neighUp[kMaxN];
177  while ( !( areaUp.GetNext( &neighUp[upperNeighbourIndex] ) ).isEmpty() ) {
178  assert( neighUp[upperNeighbourIndex].fLinks < rowUp.NHits() || !neighUp[upperNeighbourIndex].fValid );
179  debugS() << neighUp[upperNeighbourIndex];
180 
181 #ifdef DRAW_NEIGHBOURSFINDING
182  neighUpY[upperNeighbourIndex] = neighUp[upperNeighbourIndex].fY;
183  neighUpZ[upperNeighbourIndex] = neighUp[upperNeighbourIndex].fZ;
184 #endif
185  neighUp[upperNeighbourIndex].fY = DnDx * ( neighUp[upperNeighbourIndex].fY - y );
186  neighUp[upperNeighbourIndex].fZ = DnDx * ( neighUp[upperNeighbourIndex].fZ - z );
187 
188  maxUpperNeighbourIndex(neighUp[upperNeighbourIndex].fValid)++;
189  ++upperNeighbourIndex;
190 
191  //assert( (upperNeighbourIndex < kMaxN) || ("" == " too small array ") );
192  if ( ISUNLIKELY(upperNeighbourIndex >= kMaxN) ){
193  // std::cout << "W AliHLTTPCCANeighboursFinder: Warning: Too many neighbours, some of them won't be considered \ Too small array. " << std::endl;
194  break;
195  }
196  }
197 
198  int nNeighDn = 0;
199  if ( upperNeighbourIndex <= 0 ) continue;// only if there are hits in the upper area
200 
201  short_v bestDn(-1);
202  short_v bestUp(-1);
203  sfloat_v bestD = chi2Cut; // d must be smaller than chi2Cut to be considered at all
204  NeighbourData neighDn;
205 
206  // iterate over all hits in lower area
207  ushort_m nextMask;
208  HitArea areaDn( rowDn, fData, yDn, zDn, -DnDx*kAreaSizeY, -DnDx*kAreaSizeZ, validHitsMask );
209  while ( !( nextMask = areaDn.GetNext( &neighDn ) ).isEmpty() ) {
210  // for (int i0 = 0; i0 < downNeighbourIndex; i0++) {
211  // NeighbourData &neighDn = neighDown[i0];
212 
213  if ( ISUNLIKELY( ((Vc::Zero < maxUpperNeighbourIndex) && neighDn.fValid).isEmpty() ) ) continue; // no both neighbours
214 
215  assert( neighDn.fLinks < rowDn.NHits() || !neighDn.fValid );
216  debugS() << neighDn;
217 
218  nNeighDn++;
219 #ifdef DRAW_NEIGHBOURSFINDING
220  sfloat_v neighDnY = neighDn.fY;
221  sfloat_v neighDnZ = neighDn.fZ;
222 #endif
223  // store distance from (y,z) times UpDx
224  neighDn.fY = UpDx * ( neighDn.fY - y );
225  neighDn.fZ = UpDx * ( neighDn.fZ - z );
226 
227  short_m dnMask( Vc::Zero ); // mask for appropriate neibours-pairs
228 
229  // iterate over the upper hits we found before and find the one with lowest curvature
230  // (change of slope)
231 
232  // for ( int i = 0; !( (ushort_v(i) < maxUpperNeighbourIndex) && nextMask).isEmpty(); ++i ) { // slower
233  for ( int i = 0; i < upperNeighbourIndex; ++i ) {
234  sfloat_m masksf( neighDn.fValid & neighUp[i].fValid ); // only store links for actually useful data.
235  const sfloat_v dy = neighDn.fY - neighUp[i].fY;
236  const sfloat_v dz = neighDn.fZ - neighUp[i].fZ;
237 #ifdef DRAW_NEIGHBOURSFINDING
238  AliHLTTPCCADisplay::Instance().ClearView();
239  AliHLTTPCCADisplay::Instance().SetSliceView();
240  AliHLTTPCCADisplay::Instance().SetCurrentSlice(fTracker);
241  AliHLTTPCCADisplay::Instance().DrawSlice( fTracker, 1 );
242  AliHLTTPCCADisplay::Instance().DrawPoint(xDn, neighDnY[0], neighDnZ[0], 2-2 );
243  AliHLTTPCCADisplay::Instance().DrawPoint(x, y[0], z[0], 8-2 );
244  AliHLTTPCCADisplay::Instance().DrawPoint(xUp, neighUpY[i][0], neighUpZ[i][0], 4-2 );
245  AliHLTTPCCADisplay::Instance().DrawSliceHits(-1, 0.5);
246  AliHLTTPCCADisplay::Instance().Ask();
247 #endif
248  const sfloat_v d = dy * dy + dz * dz;
249  masksf &= d < bestD;
250  bestD( masksf ) = d;
251  const short_m masks( masksf );
252  dnMask |= masks;
253  bestUp( masks ) = neighUp[i].fLinks;
254  debugS() << "best up: " << masks << " " << bestUp << std::endl;
255  }
256  bestDn( dnMask ) = neighDn.fLinks;
257  debugS() << "best down: " << dnMask << " " << bestDn << std::endl;
258  }
259  // sfloat_m mask_out = bestD < chi2Cut; sfloat_v bestD_out = -1; bestD_out(mask_out) = bestD; std::cout << "-" << bestD_out << chi2Cut<< std::endl; // dbg
260 
261  //debugS() << "Links for row " << rowIndex << ", hit " << hitIndex << ": " << bestUp << " " << bestDn << std::endl;
262 
263  assert( bestD < chi2Cut || ( bestUp == -1 && bestDn == -1 ) );
264 
265  debugS() << "Set Link Data: Up = " << bestUp << ", Down = " << bestDn << std::endl;
266 
267  // store the link indexes we found
268  const short_m nonUsedMask = validHitsMask && ( short_v(fData.HitDataIsUsed( row ), hitIndexes) == short_v( Vc::Zero ) );
269  assert( ((bestUp >= -1) && (bestUp < rowUp.NHits()) && nonUsedMask) == nonUsedMask );
270  assert( ((bestDn >= -1) && (bestDn < rowDn.NHits()) && nonUsedMask) == nonUsedMask );
271  fData.SetHitLinkUpData( row, hitIndexes, bestUp, nonUsedMask);
272  fData.SetHitLinkDownData( row, hitIndexes, bestDn, nonUsedMask);
273 
274 // #ifdef DRAW TODO uncomment and fix problem with DRAW_EVERY_LINK
275 // if ( DRAW_EVERY_LINK ) {
276 // foreach_bit ( int i, validHitsMask && bestUp != -1 && bestDn != -1 ) {
277 // AliHLTTPCCADisplay::Instance().DrawSliceLink( rowIndex, hitIndex + i, -1, -1, 1 );
278 // }
279 // AliHLTTPCCADisplay::Instance().Update();
280 // }
281 // #endif
282  } // for hitIndex
283 
284 }
285 
286 
287 #endif
const AliHLTTPCCARow & Row(int rowIndex) const