CbmRoot
CbmL1RichENNRingFinderParallel.cxx
Go to the documentation of this file.
1 /*
2  *====================================================================
3  *
4  * CBM Level 1 Reconstruction
5  *
6  * Authors: I.Kisel, S.Gorbunov
7  *
8  * e-mail : ikisel@kip.uni-heidelberg.de
9  *
10  *====================================================================
11  *
12  * Standalone RICH ring finder based on the Elastic Neural Net
13  *
14  *====================================================================
15  */
16 
17 #define PRINT_TIMING
18 
19 // CBM includes
21 
22 #include "CbmRichHit.h"
23 #include "CbmRichRing.h"
24 
25 #include "TClonesArray.h"
26 #include "TStopwatch.h"
27 
28 #include "assert.h"
29 #include <algorithm>
30 #include <cmath>
31 #include <iostream>
32 #include <vector>
33 
34 using std::cout;
35 using std::endl;
36 using std::fabs;
37 using std::ios;
38 using std::sqrt;
39 using std::vector;
40 
42  : fRecoTime(0), fNEvents(0) {
43  fVerbose = verbose;
44 #ifdef PRINT_TIMING
45  TString name_tmp[NTimers] = {
46 
47  "All",
48 
49  "Ring finding",
50  "Ring finding: Prepare data",
51  "Ring finding: Init of param",
52  "Ring finding: Hit selection",
53  "Ring finding: Final fit",
54  "Ring finding: Store ring",
55 
56  "Selection",
57 
58  "Sort",
59  "Repack",
60  "Copy data"};
61  for (int i = 0; i < NTimers; i++) {
62  fTimersNames[i] = name_tmp[i];
63  }
64 #endif // PRINT_TIMING
65 }
66 
68 
69 
71 
72 Int_t CbmL1RichENNRingFinderParallel::DoFind(TClonesArray* HitArray,
73  TClonesArray* /*ProjArray*/,
74  TClonesArray* RingArray) {
75  if (!RingArray || !HitArray) return 0;
76 
77  RingArray->Clear();
78 #ifdef PRINT_TIMING
79  for (int i = 0; i < NTimers; i++) {
80  fTimers[i].Reset();
81  }
82 #endif // PRINT_TIMING
83 
84 #ifdef PRINT_TIMING
85  GetTimer("Copy data").Start(0);
86 #endif // PRINT_TIMING
87  vector<ENNRingHit> Up;
88  vector<ENNRingHit> Down;
89 
90  const Int_t nhits = HitArray->GetEntriesFast();
91 
92  for (register Int_t i = 0; i < nhits; ++i) {
93  CbmRichHit* hit = L1_DYNAMIC_CAST<CbmRichHit*>(HitArray->At(i));
94  if (!hit) continue;
95  ENNRingHit tmp;
96  tmp.x = hit->GetX();
97  tmp.y = hit->GetY();
98  tmp.outIndex = i;
99  tmp.quality = 0;
100  if (tmp.y > 0.) {
101  Up.push_back(tmp);
102  } else {
103  Down.push_back(tmp);
104  }
105  }
106 
107 
108 #ifdef PRINT_TIMING
109  GetTimer("Copy data").Stop();
110 #endif // PRINT_TIMING
111 
112 #ifdef PRINT_TIMING
113  GetTimer("Sort").Start(0);
114 #endif // PRINT_TIMING
115  sort(Up.begin(), Up.end(), ENNHit::Compare);
116  sort(Down.begin(), Down.end(), ENNHit::Compare);
117 
118  // save local-out indices correspondece
119  vector<Int_t> outIndicesUp; // indices in HitArray indexed by index in Up
120  vector<Int_t> outIndicesDown; // indices in HitArray indexed by index in Down
121  outIndicesUp.resize(Up.size());
122  outIndicesDown.resize(Down.size());
123  for (THitIndex k = 0; k < Up.size(); k++) {
124  Up[k].localIndex = k;
125  outIndicesUp[k] = Up[k].outIndex;
126  }
127  for (THitIndex k = 0; k < Down.size(); k++) {
128  Down[k].localIndex = k;
129  outIndicesDown[k] = Down[k].outIndex;
130  }
131 
132 #ifdef PRINT_TIMING
133  GetTimer("Sort").Stop();
134 #endif // PRINT_TIMING
135 
136 #ifdef PRINT_TIMING
137  GetTimer("Repack").Start(0);
138 #endif // PRINT_TIMING
139 
140  // save local-out indices correspondece
143  UpV.resize((Up.size() + fvecLen - 1) / fvecLen);
144  DownV.resize((Down.size() + fvecLen - 1) / fvecLen);
145  for (THitIndex k = 0; k < Up.size(); k++) {
146  int k_4 = k % fvecLen, k_V = k / fvecLen;
147  ENNHitV& hits = UpV[k_V]; // TODO change on ENNHitV
148  hits.CopyHit(Up[k], k_4);
149  }
150  for (THitIndex k = 0; k < Down.size(); k++) {
151  int k_4 = k % fvecLen, k_V = k / fvecLen;
152  ENNHitV& hits = DownV[k_V];
153  hits.CopyHit(Down[k], k_4);
154  }
155 
156 #ifdef PRINT_TIMING
157  GetTimer("Repack").Stop();
158 #endif // PRINT_TIMING
159 
160  vector<ENNRing> R;
161 
162  float HitSize = .5;
163  THitIndex MinRingHits = 5;
164  float RMin = 2.;
165  float RMax = 5.;
166 
167  TStopwatch timer;
168 
169  ENNRingFinder(Up.size(), UpV, R, HitSize, MinRingHits, RMin, RMax);
170  ENNRingFinder(Down.size(), DownV, R, HitSize, MinRingHits, RMin, RMax);
171 
172  timer.Stop();
173 
174 #ifdef PRINT_TIMING
175  GetTimer("Copy data").Start(0);
176 #endif // PRINT_TIMING
177  Int_t NRings = 0;
178  for (vector<ENNRing>::iterator i = R.begin(); i != R.end(); ++i) {
179  if (!i->on) continue;
180  new ((*RingArray)[NRings]) CbmRichRing();
181  CbmRichRing* ring = L1_DYNAMIC_CAST<CbmRichRing*>(RingArray->At(NRings));
182  NRings++;
183  ring->SetCenterX(i->x);
184  ring->SetCenterY(i->y);
185  ring->SetRadius(i->r);
186  ring->SetChi2(i->chi2);
187  const THitIndex NHits = i->localIHits.size();
188  for (THitIndex j = 0; j < NHits; j++) {
189  if (i->y > 0.)
190  ring->AddHit(outIndicesUp[i->localIHits[j]]);
191  else
192  ring->AddHit(outIndicesDown[i->localIHits[j]]);
193  }
194  }
195 #ifdef PRINT_TIMING
196  GetTimer("Copy data").Stop();
197 #endif // PRINT_TIMING
198 
199  fNEvents++;
200  fRecoTime += timer.RealTime();
201  cout.setf(ios::fixed);
202  cout.setf(ios::showpoint);
203  cout.precision(4);
204  cout << "L1ENN Reco time stat/this [ms] : " << fRecoTime * 1000. / fNEvents
205  << "/" << timer.RealTime() * 1000. << endl;
206 
207 #ifdef PRINT_TIMING
208  static float timeStat[NTimers];
209  static bool firstCall = 1;
210  if (firstCall) {
211  for (int i = 0; i < NTimers; i++) {
212  timeStat[i] = 0;
213  }
214  firstCall = 0;
215  }
216 
217  cout.width(30);
218  cout << "Timing statEvents / curEvent[ms] | statEvents[%] : " << endl;
219  cout.flags(ios::left | ios::oct | ios::showpoint | ios::fixed);
220  cout.precision(3);
221  for (int i = 0; i < NTimers; i++) {
222  timeStat[i] += fTimers[i].RealTime();
223  cout.width(30);
224  cout << fTimersNames[i] << " timer = " << timeStat[i] * 1000. / fNEvents
225  << " / " << fTimers[i].RealTime() * 1000. << " | "
226  << timeStat[i] / timeStat[1] * 100 << endl;
227  }
228 #endif // PRINT_TIMING
229  return NRings;
230 }
231 
232 
234  const int NHits,
236  vector<ENNRing>& Rings,
237  float HitSize,
238  THitIndex MinRingHits,
239  fvec /*RMin*/,
240  fvec RMax) {
241 #ifdef PRINT_TIMING
242  GetTimer("All").Start(0);
243 #endif // PRINT_TIMING
244  // INITIALIZATION
245 
246  const fvec MinRingHits_v = MinRingHits;
247  const fvec Rejection = .5;
248  const float ShadowSize = HitSize / 4;
249  const int StartHitMaxQuality = 15;
250  const int SearchHitMaxQuality = 100; // TODO DELME
251 
252  const fvec R2MinCut = 3. * 3., R2MaxCut = 7. * 7.;
253  // const fvec R2Min = RMin*RMin, R2Max = RMax*RMax;
254  const fvec HitSize2 = 2 * HitSize;
255  // const fvec HitSize4 = 4 * HitSize;
256  const fvec HitSizeSq_v = HitSize * HitSize;
257  const float HitSizeSq = HitSizeSq_v[0];
258  // const fvec HitSizeSq4 = HitSize2 * HitSize2;
259  const float AreaSize = 2 * RMax[0] + HitSize;
260  const float AreaSize2 = AreaSize * AreaSize;
261 
262  // typedef vector<ENNRingHit>::iterator iH;
263  // typedef vector<ENNRingHit*>::iterator iP;
264 
265  THitIndex NInRings = Rings.size();
266 
267  // MAIN LOOP OVER HITS
268 #ifdef PRINT_TIMING
269  GetTimer("Ring finding").Start(0);
270 #endif // PRINT_TIMING
272  nsL1vector<ENNHitV>::TSimd PickUpArea;
273  const int MaxAreaHits = 200; // TODO take into account NHits
274 
275  SearchArea.resize(MaxAreaHits, ENNSearchHitV());
276  PickUpArea.resize(MaxAreaHits);
277 
278  // TODO 1
279 #if 0
280  nsL1vector<ENNRingV>::TSimd rings_tmp; // simd hits for tmp store
281  rings_tmp.resize(100); // TODO use NRings
282  int nRings_tmp = 0;
283 #endif
284 
285  // ENNRingHit* ileft = &(Hits[0]), *iright = ileft;//, i_main = ileft;
286  int ileft = 0, iright = ileft;
287  // int ileft[fvecLen] = {0, 0, 0, 0};
288  // int iright[fvecLen] = {0, 0, 0, 0};
289 
290  THitIndex i_mains[fvecLen] = {0};
291 
292  THitIndex i_main_array
293  [NHits]; // need for proceed in paralled almost independent areas
294  for (THitIndex i = 0; i < NHits; i++) {
295  i_main_array[i] = i; // TODO
296  }
297 
298 
299  for (THitIndex ii_main = 0; ii_main < NHits;) {
300 
301 #ifdef PRINT_TIMING
302  GetTimer("Ring finding: Prepare data").Start(0);
303 #endif // PRINT_TIMING
304 
305 
306  fvec S0, S1, S2, S3, S4, S5, S6, S7;
307  fvec X = 0, Y = 0, R = 0, R2 = 0;
308 
309  fvec validRing = (fvec(0) <= fvec(0)); // mask of the valid rings
310 
311  fvec SearchAreaSize = 0; // number of hits to fit and search ring
312  fvec PickUpAreaSize = 0;
313 
314  for (int i_4 = 0; (i_4 < fvecLen) && (ii_main < NHits); ii_main++) {
315  const THitIndex i_main = i_main_array[ii_main];
316  const int i_main_4 = i_main % fvecLen, i_main_V = i_main / fvecLen;
317  ENNHitV* i = &HitsV[i_main_V];
318  if (i->quality[i_main_4] >= StartHitMaxQuality)
319  continue; // already found hit
320 
321  i_mains[i_4] = i_main;
322 
323  float left = i->x[i_main_4] - AreaSize;
324  float right = i->x[i_main_4] + AreaSize;
325 
326  // while( (HitsV[ileft[i_4]/fvecLen] .x[ileft[i_4]%fvecLen] < left ) ) ++ileft[i_4];
327  // while( (iright[i_4] < NHits) && (HitsV[iright[i_4]/fvecLen].x[ileft[i_4]%fvecLen] < right) ) ++iright[i_4];
328  // for( int j = ileft[i_4]; j < iright[i_4]; ++j ){
329  while ((HitsV[ileft / fvecLen].x[ileft % fvecLen] < left))
330  ++ileft; // TODO SIMDize
331  while ((iright < NHits)
332  && (HitsV[iright / fvecLen].x[ileft % fvecLen] < right))
333  ++iright;
334 
335  for (int j = ileft; j < iright; ++j) {
336  const int j_4 = j % fvecLen, j_V = j / fvecLen;
337  ENNSearchHitV& sHit = SearchArea[int(SearchAreaSize[i_4])];
338  sHit.CopyHit(HitsV[j_V], j_4, i_4);
339 
340  sHit.ly[i_4] = sHit.y[i_4] - i->y[i_main_4];
341  // if( fabs(sHit.ly) > AreaSize ) continue;
342  sHit.lx[i_4] = sHit.x[i_4] - i->x[i_main_4];
343  sHit.S0 = sHit.lx * sHit.lx;
344  sHit.S1 = sHit.ly * sHit.ly;
345  sHit.lr2 = sHit.S0 + sHit.S1;
346  // if(( sHit.lr2 > AreaSize2 ) || ( j == i )) continue; // no difference in speed
347  if (sHit.lr2[i_4] > AreaSize2) continue;
348  if (ISUNLIKELY(j == i_main)) continue;
349 
350  if (sHit.quality[i_4]
351  >= SearchHitMaxQuality) { // CHECKME do we really need PickUpArea
352  PickUpArea[static_cast<int>(PickUpAreaSize[i_4]++)].CopyHit(
353  HitsV[j_V], j_4, i_4);
354  continue;
355  }
356 
357  SearchAreaSize[i_4]++;
358  } // hits
359 
360  // if( NAreaHits+1 < MinRingHits ) continue;
361  if (SearchAreaSize[i_4] < MinRingHits - 1) continue;
362  i_4++;
363  } // i_4
364 
365  ENNHitV iHit;
366  int MaxSearchAreaSize = 0;
367  int MaxPickUpAreaSize = 0;
368  for (int i_4 = 0; i_4 < fvecLen; i_4++) {
369  iHit.CopyHit(HitsV[i_mains[i_4] / fvecLen], i_mains[i_4] % fvecLen, i_4);
370  MaxSearchAreaSize = (MaxSearchAreaSize < SearchAreaSize[i_4])
371  ? int(SearchAreaSize[i_4])
372  : MaxSearchAreaSize;
373  MaxPickUpAreaSize = (MaxPickUpAreaSize < PickUpAreaSize[i_4])
374  ? int(PickUpAreaSize[i_4])
375  : MaxPickUpAreaSize;
376  }
377 #ifdef PRINT_TIMING
378  GetTimer("Ring finding: Prepare data").Stop();
379  // assert( MaxSearchAreaSize[i_4] <= MaxAreaHits );
380 #endif // PRINT_TIMING
381 
382 #ifdef PRINT_TIMING
383  GetTimer("Ring finding: Init of param").Start(0);
384 #endif // PRINT_TIMING
385  for (int isa = 0; isa < MaxSearchAreaSize;
386  isa++) { // TODO don't work w\o this because of nan in wights
387  ENNSearchHitV& sHit = SearchArea[isa];
388  const fvec validHit = (fvec(isa) < SearchAreaSize) & validRing;
389  sHit.lx = if3(validHit, sHit.lx, 0);
390  sHit.ly = if3(validHit, sHit.ly, 0);
391  sHit.lr2 = if3(validHit, sHit.lr2, 0);
392  }
393 
394  // initialize hits in the search area
395  fvec Dmax = 0.;
396  S0 = S1 = S2 = S3 = S4 = 0.;
397  for (int ih = 0; ih < MaxSearchAreaSize; ih++) {
398  ENNSearchHitV& sHit = SearchArea[ih];
399  const fvec validHit = (fvec(ih) < SearchAreaSize) & validRing;
400 
401  fvec& lr2 = sHit.lr2;
402  fvec lr = sqrt(lr2);
403  Dmax = if3((lr > Dmax) & validHit, lr, Dmax);
404 
405  sHit.S2 = sHit.lx * sHit.ly;
406  sHit.S3 = sHit.lx * lr2;
407  sHit.S4 = sHit.ly * lr2;
408  sHit.C = -lr * .5;
409 
410  const fvec w = if3(validHit, if3(lr > fvec(1.E-4), 1. / lr, 1), 0);
411  const fvec w2 = w * w;
412  sHit.Cx = w * sHit.lx;
413  sHit.Cy = w * sHit.ly;
414  S0 += w2 * sHit.S0;
415  S1 += w2 * sHit.S1;
416  S2 += w2 * sHit.S2;
417  S3 += w2 * sHit.S3;
418  S4 += w2 * sHit.S4;
419  }
420 
421  // end of initialization of the search area
422 #ifdef PRINT_TIMING
423  GetTimer("Ring finding: Init of param").Stop();
424  // assert( MaxSearchAreaSize[i_4] <= MaxAreaHits );
425 #endif // PRINT_TIMING
426 
427 #ifdef PRINT_TIMING
428  // loop for minimization of E and noise rejection
429  GetTimer("Ring finding: Hit selection").Start(0);
430 #endif // PRINT_TIMING
431  do {
432  // calculate parameters of the current ring
433  fvec tmp = S0 * S1 - S2 * S2;
434 
435  // if( fabs(tmp) < 1.E-10 ) break; // CHECKME
436  tmp = 0.5 / tmp;
437  X = (S3 * S1 - S4 * S2) * tmp;
438  Y = (S4 * S0 - S3 * S2) * tmp;
439  R2 = X * X + Y * Y;
440  R = sqrt(R2);
441 
442  const fvec Dcut = Dmax * Rejection; // cut for noise hits
443  // float RingCut = HitSize4 * R ; // closeness
444  S0 = S1 = S2 = S3 = S4 = 0.0;
445  Dmax = -1.;
446 
447  for (THitIndex ih = 0; ih < MaxSearchAreaSize; ih++) {
448  const fvec validHit = (fvec(ih) < SearchAreaSize) & validRing;
449  // ENNHit *j = &(SearchArea[ih]);
450  ENNSearchHitV& sHit = SearchArea[ih];
451  const fvec dx = sHit.lx - X;
452  const fvec dy = sHit.ly - Y;
453  const fvec d = fabs(sqrt(dx * dx + dy * dy) - R);
454  const fvec dSq = d * d;
455  sHit.on_ring = (d <= HitSize) & validHit;
456  const fvec dp =
457  if3(sHit.on_ring, -1, fabs(sHit.C + sHit.Cx * X + sHit.Cy * Y));
458  Dmax = if3(((dp <= Dcut) & (dp > Dmax)), dp, Dmax);
459 
460  fvec w = if3((sHit.on_ring),
461  1. / (HitSizeSq_v + fabs(dSq)),
462  1. / (1.e-5 + fabs(dSq)));
463  w = if3((dp <= Dcut) & validHit, w, 0);
464  S0 += w * sHit.S0;
465  S1 += w * sHit.S1;
466  S2 += w * sHit.S2;
467  S3 += w * sHit.S3;
468  S4 += w * sHit.S4;
469  }
470 
471  } while (NotEmpty(Dmax > fvec(0.)));
472 
473 
474 #ifdef PRINT_TIMING
475  GetTimer("Ring finding: Hit selection").Stop();
476  // store the ring if it is found
477 
478  GetTimer("Ring finding: Final fit").Start(0);
479 #endif // PRINT_TIMING
480 
481  fvec NRingHits = 1;
482  { // final fit of 3 parameters (X,Y,R)
483  S0 = S1 = S2 = S3 = S4 = S5 = S6 = S7 = 0.0;
484  for (THitIndex ih = 0; ih < MaxSearchAreaSize; ih++) {
485  ENNSearchHitV& sHit = SearchArea[ih];
486  const fvec w = bool2int(SearchArea[ih].on_ring);
487  S0 += w * sHit.S0;
488  S1 += w * sHit.S1;
489  S2 += w * sHit.S2;
490  S3 += w * sHit.S3;
491  S4 += w * sHit.S4;
492  S5 += w * sHit.lx;
493  S6 += w * sHit.ly;
494  S7 += w * sHit.lr2;
495  NRingHits += w;
496  }
497  const fvec s0 = S6 * S0 - S2 * S5;
498  const fvec s1 = S0 * S1 - S2 * S2;
499  const fvec s2 = S0 * S4 - S2 * S3;
500  // if( fabs(s0) < 1.E-6 || fabs(s1) < 1.E-6 ) continue; // CHECKME
501  const fvec tmp = s1 * (S5 * S5 - NRingHits * S0) + s0 * s0;
502  const fvec A = ((S0 * S7 - S3 * S5) * s1 - s2 * s0) / tmp;
503  Y = (s2 + s0 * A) / s1 * 0.5;
504  X = (S3 + S5 * A - S2 * Y * 2) / S0 * 0.5;
505  R2 = X * X + Y * Y - A;
506  // if( R2 < 0 ) continue; // will be rejected letter by R2 > R2Min
507  R = sqrt(R2);
508  } // end of the final fit
509 
510  validRing = !((NRingHits < MinRingHits_v) | (R2 > R2MaxCut)
511  | (R2 < R2MinCut)); // ghost suppresion // TODO constants
512 // cout << validRing << endl;
513 #ifdef PRINT_TIMING
514  GetTimer("Ring finding: Final fit").Stop();
515 #endif // PRINT_TIMING
516 
517 
518 #ifdef PRINT_TIMING
519  GetTimer("Ring finding: Store ring").Start(0);
520 #endif // PRINT_TIMING
521  if (ISUNLIKELY(Empty(validRing))) continue;
522 
524 #if 0 // TODO 1
525  {
526  ENNRingV &ringV = rings_tmp[nRings_tmp++];
527 
528  ringV.localIHits.reserve(25);
529  ringV.x = iHit.x + X;
530  ringV.y = iHit.y + Y;
531  ringV.r = R;
532  ringV.localIHits.push_back(iHit.localIndex);
533  ringV.NHits = 1;
534  ringV.chi2 = 0;
535  nsL1vector<fvec>::TSimd Shadow; // save hit indices of hits, which's quality will be changed
536  Shadow.reserve(25);
537  Shadow.push_back(iHit.localIndex);
538  for( THitIndex ih = 0; ih < MaxSearchAreaSize; ih++){
539  fvec validHit = ih < SearchAreaSize;
540 
541  ENNSearchHitV &sHit = SearchArea[ih];
542  const fvec dx = sHit.x - ringV.x;
543  const fvec dy = sHit.y - ringV.y;
544  const fvec d = fabs( sqrt(dx*dx+dy*dy) - ringV.r );
545  validHit = validHit & ( d <= HitSize );
546  ringV.chi2 += d*d;
547  ringV.localIHits.push_back( if3( validHit, sHit.localIndex, -1 ) );
548  ringV.NHits += bool2int(validHit);
549  validHit = validHit & ( d <= ShadowSize ); // TODO check *4
550  if ( Empty (validHit) ) continue; // CHECKME
551  Shadow.push_back( if3( validHit, sHit.localIndex, -1 ) );
552  }
553  for( int ipu = 0; ipu < MaxPickUpAreaSize; ipu++ ) {
554  fvec validHit = ipu < PickUpAreaSize;
555 
556  ENNHitV &puHit = PickUpArea[ipu];
557  const fvec dx = puHit.x - ringV.x;
558  const fvec dy = puHit.y - ringV.y;
559  const fvec d = fabs( sqrt(dx*dx+dy*dy) - ringV.r );
560  validHit = validHit & ( d <= HitSize );
561  if ( Empty (validHit) ) continue;
562  ringV.chi2 += d*d;
563  ringV.localIHits.push_back( if3( validHit, puHit.localIndex, -1 ) );
564  ringV.NHits += bool2int(validHit);
565  validHit = validHit & ( d <= ShadowSize ); // TODO check *4
566  if ( Empty (validHit) ) continue; // CHECKME
567  Shadow.push_back( if3( validHit, puHit.localIndex, -1 ) );
568  }
569 
570  ringV.chi2 = ringV.chi2 / (( ringV.NHits - 3)*HitSizeSq);
571  const fvec quality = ringV.NHits;
572 
573 
574  // for( iP j = ringV.Hits.begin(); j != ringV.Hits.end(); ++j ){
575  // if( (*j)->quality<quality ) (*j)->quality = quality;
576  // }
577 
578  //quality *= ShadowOpacity;
579  for( int i_4 = 0; (i_4 < fvecLen); i_4++) {
580  const int NShadow = Shadow.size();
581  for( int is = 0; is < NShadow; is++ ) { // CHECKME change loops to speed up?
582  cout << i_4 << Shadow[is] << endl;
583  float ih_f = (Shadow[is])[i_4]-200;
584  if (ih_f == -1) continue;
585  int ih = static_cast<int>(ih_f); // TODO ! problem in conversion...
586  float ih_f2 = static_cast<float>(ih);
587  cout << ih_f << " " << ih << " " << ih_f2 << " " << ih%fvecLen << " " << ih/fvecLen << endl;
588 
589  const THitIndex ih_4 = ih%fvecLen;
590  ENNHitV & hitV = HitsV[ih/fvecLen];
591 
592  // hitV.quality[ih_4] = ( hitV.quality[ih_4] < quality[i_4] ) ? quality[i_4] : hitV.quality[ih_4];
593  // shHit->quality = if3( shHit->quality < quality, quality, shHit->quality );
594  }
595  } // i_4
596  }
597 #endif // 0
598 
600  for (int i_4 = 0; (i_4 < fvecLen); i_4++) {
601  // if( NRingHits < MinRingHits || R2 > R2Max || R2 < R2Min ) continue;
602 
603  if (/*ISUNLIKELY*/ (!validRing[i_4])) continue;
604 
605  ENNRing voidRing;
606  Rings.push_back(voidRing);
607  ENNRing& ring = Rings.back();
608  ring.localIHits.reserve(15);
609  ring.x = iHit.x[i_4] + X[i_4];
610  ring.y = iHit.y[i_4] + Y[i_4];
611  ring.r = R[i_4];
612  ring.localIHits.push_back(static_cast<THitIndex>(iHit.localIndex[i_4]));
613  ring.NHits = 1;
614  ring.chi2 = 0;
615  vector<THitIndex>
616  Shadow; // save hit indices of hits, which's quality will be changed
617  Shadow.reserve(15);
618  Shadow.push_back(static_cast<THitIndex>(iHit.localIndex[i_4]));
619  for (THitIndex ih = 0; ih < SearchAreaSize[i_4]; ih++) {
620  ENNSearchHitV& sHit = SearchArea[ih];
621  const float dx = sHit.x[i_4] - ring.x;
622  const float dy = sHit.y[i_4] - ring.y;
623  const float d = fabs(sqrt(dx * dx + dy * dy) - R[i_4]);
624  if (ISLIKELY(d <= HitSize)) {
625  ring.chi2 += d * d;
626  ring.localIHits.push_back(int(sHit.localIndex[i_4]));
627  ring.NHits++;
628  if (d <= ShadowSize)
629  Shadow.push_back(static_cast<THitIndex>(sHit.localIndex[i_4]));
630  }
631  }
632  for (int ipu = 0; ipu < PickUpAreaSize[i_4]; ipu++) {
633  ENNHitV& puHit = PickUpArea[ipu];
634  const float dx = puHit.x[i_4] - ring.x;
635  const float dy = puHit.y[i_4] - ring.y;
636  const float d = fabs(sqrt(dx * dx + dy * dy) - ring.r);
637  if (ISLIKELY(d <= HitSize)) {
638  ring.chi2 += d * d;
639  ring.localIHits.push_back(
640  static_cast<THitIndex>(puHit.localIndex[i_4]));
641  ring.NHits++;
642  if (d <= ShadowSize)
643  Shadow.push_back(static_cast<THitIndex>(puHit.localIndex[i_4]));
644  }
645  }
646  if (ISUNLIKELY(ring.NHits < MinRingHits)) {
647  Rings.pop_back();
648  continue;
649  }
650  ring.chi2 = ring.chi2 / ((ring.NHits - 3) * HitSizeSq);
651  int quality = ring.NHits;
652 
653  // for( iP j = ring.Hits.begin(); j != ring.Hits.end(); ++j ){
654  // if( (*j)->quality<quality ) (*j)->quality = quality;
655  // }
656 
657  //quality *= ShadowOpacity;
658  const int NShadow = Shadow.size();
659  for (int is = 0; is < NShadow; is++) {
660  const THitIndex ih = Shadow[is];
661  const THitIndex ih_4 = ih % fvecLen;
662  ENNHitV& hitV = HitsV[ih / fvecLen];
663 
664  hitV.quality[ih_4] =
665  (hitV.quality[ih_4] < quality) ? quality : hitV.quality[ih_4];
666  // shHit->quality = if3( shHit->quality < quality, quality, shHit->quality );
667  }
668  } // i_4
669 
670 
671 #ifdef PRINT_TIMING
672  GetTimer("Ring finding: Store ring").Stop();
673 #endif // PRINT_TIMING
674  } // i_main
675 #ifdef PRINT_TIMING
676  GetTimer("Ring finding").Stop();
677 
678  // SELECTION OF RINGS
679  GetTimer("Selection").Start(0);
680 #endif // PRINT_TIMING
681  typedef vector<ENNRing>::iterator iR;
682  iR Rbeg = Rings.begin() + NInRings;
683  iR Rend = Rings.end();
684 
685 //#define NEW_SELECTION
686 #ifdef NEW_SELECTION // TODO optimize. at the moment just creates additional ghosts
687 
688  sort(Rings.begin() + NInRings, Rings.end(), ENNRing::CompareENNHRings);
689 
690  const int NHitsV = HitsV.size();
691  for (int ih = 0; ih < NHitsV; ih++)
692  HitsV[ih].quality = 0.;
693 
694  for (iR ir = Rbeg; ir != Rend; ++ir) {
695  ir->on = 0;
696  ir->NOwn = ir->NHits;
697  }
698 
699  for (iR i = Rbeg; i != Rend; ++i) {
700  if (i->skip) continue;
701  for (iR j = i + 1; j != Rend; ++j) {
702  if (j->skip) continue;
703 
704  float dist = j->r + i->r + HitSize2[0];
705  float distCentr =
706  sqrt((j->x - i->x) * (j->x - i->x) + (j->y - i->y) * (j->y - i->y));
707  if (distCentr > dist) continue;
708  Int_t NOverlaped = 0;
709 
710  const THitIndex maxI = i->localIHits.size();
711  const THitIndex maxJ = j->localIHits.size();
712  for (THitIndex n = 0; n < maxI; n++)
713  for (THitIndex m = 0; m < maxJ; ++m)
714  if (i->localIHits[n] == j->localIHits[m]) NOverlaped++;
715  ENNRing* BigRing = 0;
716  if (NOverlaped > 0.7 * maxI) BigRing = &(*i);
717  if (NOverlaped > 0.7 * maxJ) BigRing = &(*j);
718  if (BigRing != 0) {
719  std::vector<THitIndex> newIndices;
720  for (THitIndex n = 0; n < maxI; n++) {
721  bool IsNew = 1;
722  for (THitIndex m = 0; m < maxJ; ++m)
723  if (i->localIHits[n] == j->localIHits[m]) IsNew = 0;
724  if (IsNew) newIndices.push_back(i->localIHits[n]);
725  }
726  if (maxI > maxJ) {
727  j->x = i->x;
728  j->y = i->y;
729  j->r = i->r;
730  }
731  const THitIndex newISize = newIndices.size();
732  for (THitIndex in = 0; in < newISize; in++)
733  j->localIHits.push_back(newIndices[in]);
734  i->skip = 1;
735  i->on = 0;
736  break;
737  }
738 
739  } // j
740  } // i
741 
742 
743  for (iR i = Rbeg; i != Rend; ++i) {
744  if (!(i->skip)) {
745  i->on = 1;
746  float S0, S1, S2, S3, S4, S5, S6, S7, X, Y, R;
747  S0 = S1 = S2 = S3 = S4 = S5 = S6 = S7 = 0.0;
748 
749 
750  const THitIndex firstIh = i->localIHits[0];
751  const ENNHitV& firstHit = HitsV[firstIh / fvecLen];
752  const int firstIh_4 = firstIh % fvecLen;
753  const THitIndex maxI = i->localIHits.size();
754 
755  vector<ENNSearchHitV> shits;
756  shits.resize(maxI);
757  for (THitIndex iih = 0; iih < maxI; iih++) {
758  const THitIndex ih = i->localIHits[iih];
759  const ENNHitV& hit = HitsV[ih / fvecLen];
760  const int ih_4 = ih % fvecLen;
761  ENNSearchHitV& shit = shits[iih];
762 
763  shit.ly[0] = hit.y[ih_4] - firstHit.y[firstIh_4];
764  shit.lx[0] = hit.x[ih_4] - firstHit.x[firstIh_4];
765  shit.S0[0] = shit.lx[0] * shit.lx[0];
766  shit.S1[0] = shit.ly[0] * shit.ly[0];
767  shit.lr2[0] = shit.S0[0] + shit.S1[0];
768  float lr2 = shit.lr2[0];
769  float lr = sqrt(lr2);
770  shit.S2[0] = shit.lx[0] * shit.ly[0];
771  shit.S3[0] = shit.lx[0] * lr2;
772  shit.S4[0] = shit.ly[0] * lr2;
773  shit.C[0] = -lr * 0.5;
774  float w;
775  if (lr > 1.E-4)
776  w = 1. / lr;
777  else
778  w = 1.;
779  shit.Cx[0] = w * shit.lx[0];
780  shit.Cy[0] = w * shit.ly[0];
781  }
782  float Dmax = -1.;
783 
784  X = i->x - firstHit.x[firstIh_4];
785  Y = i->y - firstHit.y[firstIh_4];
786  R = i->r;
787  int search_stop = 0;
788  do { // final fit of 3 parameters (X,Y,R)
789  float Dcut = Dmax * Rejection[0];
790  int n = 0;
791  S0 = S1 = S2 = S3 = S4 = S5 = S6 = S7 = 0.0;
792 
793  for (THitIndex ih = 0; ih < maxI; ih++) {
794  ENNSearchHitV& shit = shits[ih];
795 
796  float dx = shit.lx[0] - X;
797  float dy = shit.ly[0] - Y;
798  float d = fabs(sqrt(dx * dx + dy * dy) - R);
799  shit.on_ring[0] = (d <= HitSize2[0]);
800  float w;
801  if (shit.on_ring[0]) {
802  n++;
803  w = 1;
804  } else {
805  float dp = fabs(shit.C[0] + shit.Cx[0] * X + shit.Cy[0] * Y);
806  if (dp > Dcut) continue;
807  if (dp > Dmax) Dmax = dp;
808  n++;
809  w = 10. / (1.e-5 + fabs(d * d));
810  }
811 
812  S0 += w * shit.S0[0];
813  S1 += w * shit.S1[0];
814  S2 += w * shit.S2[0];
815  S3 += w * shit.S3[0];
816  S4 += w * shit.S4[0];
817  S5 += w * shit.lx[0];
818  S6 += w * shit.ly[0];
819  S7 += w * shit.lr2[0];
820  } // ih
821 
822  float s0 = S6 * S0 - S2 * S5;
823  float s1 = S0 * S1 - S2 * S2;
824  float s2 = S0 * S4 - S2 * S3;
825 
826  if (fabs(s0) < 1.E-6 || fabs(s1) < 1.E-6) continue;
827  float tmp = s1 * (S5 * S5 - n * S0) + s0 * s0;
828  float A = ((S0 * S7 - S3 * S5) * s1 - s2 * s0) / tmp;
829  Y = (s2 + s0 * A) / s1 / 2;
830  X = (S3 + S5 * A - S2 * Y * 2) / S0 / 2;
831  float R2 = X * X + Y * Y - A;
832 
833  if (R2 < 0) continue;
834  R = sqrt(R2);
835  if (Dmax <= 0) search_stop++;
836  } while (search_stop < 2.);
837 
838  i->r = R;
839  i->x = X + firstHit.x[firstIh_4];
840  i->y = Y + firstHit.y[firstIh_4];
841 
842  if (R < 2.5 || R > 7.5) {
843  i->on = 0;
844  i->skip = 1;
845  continue;
846  }
847 
848  std::vector<THitIndex> newHits;
849  i->chi2 = 0;
850 
851  for (THitIndex iih = 0; iih < maxI; iih++) {
852  const THitIndex ih = i->localIHits[iih];
853  const ENNHitV& hit = HitsV[ih / fvecLen];
854  ENNSearchHitV& shit = shits[iih];
855  const int ih_4 = ih % fvecLen;
856 
857  float dx = hit.x[ih_4] - i->x;
858  float dy = hit.y[ih_4] - i->y;
859  float d = fabs(sqrt(dx * dx + dy * dy) - i->r);
860  shit.on_ring[ih_4] = (d <= HitSize);
861  if (shit.on_ring[ih_4]) {
862  newHits.push_back(ih);
863  i->chi2 += d * d;
864  }
865  }
866 
867  i->localIHits.clear();
868  i->localIHits = newHits;
869  i->NHits = i->localIHits.size();
870  i->NOwn = i->NHits;
871 
872  if (i->localIHits.size() < MinRingHits) {
873  i->on = 0;
874  i->skip = 1;
875  continue;
876  }
877  i->chi2 =
878  i->chi2 / ((i->localIHits.size() - 3) * HitSize * HitSize); //.3/.3;
879  }
880  }
881 
882  sort(Rings.begin() + NInRings, Rings.end(), ENNRing::CompareENNHRings);
883  iR best;
884  for (iR i = Rbeg; i != Rend; ++i) {
885  i->on = 0;
886  if (i->skip) continue;
887  if (i->NOwn > 5) {
888  best = i;
889  const THitIndex maxI = i->localIHits.size();
890  for (THitIndex n = 0; n < maxI; n++) {
891  const THitIndex ih = i->localIHits[n];
892  ENNHitV& hit = HitsV[ih / fvecLen];
893  const int ih_4 = ih % fvecLen;
894  hit.quality[ih_4] = 1;
895  }
896  for (iR j = i + 1; j != Rend; ++j) {
897  if (i->skip) continue;
898  float dist = j->r + best->r + HitSize2[0];
899  if (fabs(j->x - best->x) > dist || fabs(j->y - best->y) > dist)
900  continue;
901  j->NOwn = 0;
902  const THitIndex maxJ = j->localIHits.size();
903  for (THitIndex m = 0; m < maxJ; m++) {
904  const THitIndex ihm = j->localIHits[m];
905  const ENNHitV& hitm = HitsV[ihm / fvecLen];
906  if (hitm.quality[ihm % fvecLen] == 0) j->NOwn++;
907  }
908  }
909  i->on = 1;
910  i->skip = 1;
911  } else
912  i->skip = 1;
913  }
914 #else // NEW_SELECTION
915 
916  const int NHitsV = HitsV.size();
917  for (int ih = 0; ih < NHitsV; ih++)
918  HitsV[ih].quality = 0.;
919  for (iR ir = Rbeg; ir != Rend; ++ir) {
920  ir->on = 0;
921  ir->NOwn = ir->NHits;
922  ir->skip = ((ir->NHits < MinRingHits) || (ir->NHits <= 6 && ir->chi2 > .3));
923  }
924 
925  do {
926  iR best = Rend;
927  THitIndex bestOwn = 0;
928  float bestChi2 = 1.E20;
929  for (iR ir = Rbeg; ir != Rend; ++ir) {
930  // const bool skip = ir->skip || ( ( ir->NOwn < 1.0*MinRingHits ) ||
931  // ( ir->NHits < 10 && ir->NOwn < 1.00*ir->NHits ) ||
932  // ( ir->NOwn < .60*ir->NHits ) );
933  if (ir->skip) continue; // faster with if
934  const bool skip = ((ir->NOwn < 1.0 * MinRingHits)
935  || (ir->NHits < 10 && ir->NOwn < 1.00 * ir->NHits)
936  || (ir->NOwn < .60 * ir->NHits));
937  ir->skip = skip;
938  const bool isBetter =
939  !skip
940  & ((ir->NOwn > 1.2 * bestOwn)
941  || (ir->NOwn >= 1. * bestOwn && ir->chi2 < bestChi2));
942  bestOwn = (isBetter) ? ir->NOwn : bestOwn; //Hits;
943  bestChi2 = (isBetter) ? ir->chi2 : bestChi2;
944  best = (isBetter) ? ir : best;
945  }
946  if (best == Rend) break;
947  best->skip = 1;
948  best->on = 1;
949  const THitIndex NHitsBest = best->localIHits.size();
950  for (THitIndex iih = 0; iih < NHitsBest; iih++) {
951  const THitIndex ih = best->localIHits[iih];
952  HitsV[ih / fvecLen].quality[ih % fvecLen] = 1;
953  }
954  for (iR ir = Rbeg; ir != Rend; ++ir) {
955  if (ir->skip) continue;
956  float dist = ir->r + best->r + HitSize2[0];
957  if (fabs(ir->x - best->x) > dist || fabs(ir->y - best->y) > dist)
958  continue;
959  ir->NOwn = 0;
960  const THitIndex NHitsCur = ir->localIHits.size();
961  for (THitIndex iih = 0; iih < NHitsCur; iih++) {
962  const THitIndex ih = ir->localIHits[iih];
963  ir->NOwn += (HitsV[ih / fvecLen].quality[ih % fvecLen] == 0);
964  }
965  }
966  } while (1);
967 #endif // else NEW_SELECTION
968 
969 #ifdef PRINT_TIMING
970  GetTimer("Selection").Stop();
971  GetTimer("All").Stop();
972 #endif // PRINT_TIMING
973 }
974 
976  int i = 0;
977  for (; (i < NTimers) && (fTimersNames[i] != t); i++)
978  ;
979  assert(i < NTimers);
980  return fTimers[i];
981 }
CbmL1RichENNRingFinderParallel::ENNRingV::y
fvec y
Definition: CbmL1RichENNRingFinderParallel.h:167
CbmRichRing::SetRadius
void SetRadius(Float_t r)
Definition: CbmRichRing.h:57
CbmRichRing::SetCenterX
void SetCenterX(Float_t x)
Definition: CbmRichRing.h:55
CbmL1RichENNRingFinderParallel::THitIndex
unsigned short THitIndex
Definition: CbmL1RichENNRingFinderParallel.h:37
F32vec4
Definition: L1/vectors/P4_F32vec4.h:47
CbmL1RichENNRingFinderParallel::ENNRingV::x
fvec x
Definition: CbmL1RichENNRingFinderParallel.h:165
CbmPixelHit::GetX
Double_t GetX() const
Definition: CbmPixelHit.h:83
ISLIKELY
#define ISLIKELY(x)
Definition: CbmL1Def.h:40
CbmL1RichENNRingFinderParallel::ENNSearchHitV::Cy
fvec Cy
Definition: CbmL1RichENNRingFinderParallel.h:115
CbmL1RichENNRingFinderParallel::fTimers
TStopwatch fTimers[NTimers]
Definition: CbmL1RichENNRingFinderParallel.h:210
CbmL1RichENNRingFinderParallel::ENNHitV::quality
fvec quality
Definition: CbmL1RichENNRingFinderParallel.h:63
CbmL1RichENNRingFinderParallel::Init
void Init()
Definition: CbmL1RichENNRingFinderParallel.cxx:70
CbmL1RichENNRingFinderParallel::fRecoTime
Float_t fRecoTime
Definition: CbmL1RichENNRingFinderParallel.h:206
CbmPixelHit::GetY
Double_t GetY() const
Definition: CbmPixelHit.h:84
CbmL1RichENNRingFinderParallel::ENNRingHit::outIndex
THitIndex outIndex
Definition: CbmL1RichENNRingFinderParallel.h:53
CbmL1RichENNRingFinderParallel::ENNSearchHitV::S4
fvec S4
Definition: CbmL1RichENNRingFinderParallel.h:114
sqrt
friend F32vec4 sqrt(const F32vec4 &a)
Definition: L1/vectors/P4_F32vec4.h:41
CbmL1RichENNRingFinderParallel::fNEvents
Int_t fNEvents
Definition: CbmL1RichENNRingFinderParallel.h:207
fvec
F32vec4 fvec
Definition: L1/vectors/P4_F32vec4.h:249
CbmL1RichENNRingFinderParallel::ENNRingV::NHits
fvec NHits
Definition: CbmL1RichENNRingFinderParallel.h:170
CbmL1RichENNRingFinderParallel::ENNRingV::chi2
fvec chi2
Definition: CbmL1RichENNRingFinderParallel.h:168
i
int i
Definition: L1/vectors/P4_F32vec4.h:25
CbmL1RichENNRingFinderParallel::GetTimer
TStopwatch & GetTimer(TString t)
Definition: CbmL1RichENNRingFinderParallel.cxx:975
CbmL1RichENNRingFinderParallel::ENNHitV::CopyHit
void CopyHit(ENNHit &a, int i)
Definition: CbmL1RichENNRingFinderParallel.h:65
CbmL1RichENNRingFinderParallel::fTimersNames
TString fTimersNames[NTimers]
Definition: CbmL1RichENNRingFinderParallel.h:211
CbmL1RichENNRingFinderParallel::ENNRingV
Definition: CbmL1RichENNRingFinderParallel.h:155
CbmL1RichENNRingFinderParallel::ENNRing::x
float x
Definition: CbmL1RichENNRingFinderParallel.h:139
CbmRichRing
Definition: CbmRichRing.h:17
Empty
#define Empty(a)
Definition: L1/vectors/P4_F32vec4.h:119
CbmL1RichENNRingFinderParallel::ENNSearchHitV::lr2
fvec lr2
Definition: CbmL1RichENNRingFinderParallel.h:113
CbmRichRing.h
CbmL1RichENNRingFinderParallel::ENNSearchHitV::S0
fvec S0
Definition: CbmL1RichENNRingFinderParallel.h:114
CbmL1RichENNRingFinderParallel::ENNRingFinder
void ENNRingFinder(const int NHits, nsL1vector< ENNHitV >::TSimd &HitsV, std::vector< ENNRing > &Rings, float HitSize=1., THitIndex MinRingHits=5, fvec RMin=2., fvec RMax=6.)
Definition: CbmL1RichENNRingFinderParallel.cxx:233
CbmL1RichENNRingFinderParallel::ENNSearchHitV::C
fvec C
Definition: CbmL1RichENNRingFinderParallel.h:115
CbmL1RichENNRingFinderParallel::~CbmL1RichENNRingFinderParallel
~CbmL1RichENNRingFinderParallel()
Definition: CbmL1RichENNRingFinderParallel.cxx:67
CbmL1RichENNRingFinderParallel::ENNSearchHitV::S2
fvec S2
Definition: CbmL1RichENNRingFinderParallel.h:114
CbmL1RichENNRingFinderParallel.h
if3
#define if3(a, b, c)
Definition: L1/vectors/P4_F32vec4.h:116
CbmL1RichENNRingFinderParallel::ENNRing::y
float y
Definition: CbmL1RichENNRingFinderParallel.h:139
CbmL1RichENNRingFinderParallel::ENNHit::quality
int quality
Definition: CbmL1RichENNRingFinderParallel.h:43
CbmL1RichENNRingFinderParallel::ENNHit::Compare
static bool Compare(const ENNHit &h1, const ENNHit &h2)
Definition: CbmL1RichENNRingFinderParallel.h:46
fvecLen
const int fvecLen
Definition: L1/vectors/P4_F32vec4.h:251
CbmL1RichENNRingFinderParallel::ENNRing::r
float r
Definition: CbmL1RichENNRingFinderParallel.h:139
CbmL1RichENNRingFinderParallel::ENNHitV
Definition: CbmL1RichENNRingFinderParallel.h:58
d
double d
Definition: P4_F64vec2.h:24
CbmL1RichENNRingFinderParallel::ENNRing::localIHits
std::vector< THitIndex > localIHits
Definition: CbmL1RichENNRingFinderParallel.h:145
CbmL1RichENNRingFinderParallel::ENNSearchHitV::lx
fvec lx
Definition: CbmL1RichENNRingFinderParallel.h:110
CbmL1RichENNRingFinderParallel::ENNRingHit
Definition: CbmL1RichENNRingFinderParallel.h:52
CbmRichRing::SetChi2
void SetChi2(Double_t chi2)
Definition: CbmRichRing.h:64
CbmL1RichENNRingFinderParallel::ENNHitV::localIndex
fvec localIndex
Definition: CbmL1RichENNRingFinderParallel.h:64
CbmL1RichENNRingFinderParallel::ENNSearchHitV
Definition: CbmL1RichENNRingFinderParallel.h:94
CbmL1RichENNRingFinderParallel::ENNRing::CompareENNHRings
static bool CompareENNHRings(const ENNRing &r1, const ENNRing &r2)
Definition: CbmL1RichENNRingFinderParallel.h:147
CbmL1RichENNRingFinderParallel::ENNSearchHitV::S1
fvec S1
Definition: CbmL1RichENNRingFinderParallel.h:114
CbmL1RichENNRingFinderParallel::ENNHit::y
float y
Definition: CbmL1RichENNRingFinderParallel.h:42
CbmL1RichENNRingFinderParallel::ENNRingV::localIHits
std::vector< fvec > localIHits
Definition: CbmL1RichENNRingFinderParallel.h:171
CbmL1RichENNRingFinderParallel::ENNSearchHitV::ly
fvec ly
Definition: CbmL1RichENNRingFinderParallel.h:113
CbmL1RichENNRingFinderParallel::ENNRing::chi2
float chi2
Definition: CbmL1RichENNRingFinderParallel.h:140
CbmL1RichENNRingFinderParallel::ENNRing
Definition: CbmL1RichENNRingFinderParallel.h:120
x
Double_t x
Definition: CbmMvdSensorDigiToHitTask.cxx:68
NotEmpty
#define NotEmpty(a)
Definition: L1/vectors/P4_F32vec4.h:118
CbmRichRing::AddHit
void AddHit(UInt_t pHit)
Definition: CbmRichRing.h:34
fabs
friend F32vec4 fabs(const F32vec4 &a)
Definition: L1/vectors/P4_F32vec4.h:60
CbmL1RichENNRingFinderParallel::ENNHit::x
float x
Definition: CbmL1RichENNRingFinderParallel.h:40
nsL1::vector::TSimd
std::vector< T > TSimd
Definition: L1/vectors/PSEUDO_F32vec1.h:148
CbmL1RichENNRingFinderParallel::ENNSearchHitV::on_ring
fvec on_ring
Definition: CbmL1RichENNRingFinderParallel.h:116
m
__m128 m
Definition: L1/vectors/P4_F32vec4.h:26
ISUNLIKELY
#define ISUNLIKELY(x)
Definition: CbmL1Def.h:41
CbmL1RichENNRingFinderParallel::ENNSearchHitV::S3
fvec S3
Definition: CbmL1RichENNRingFinderParallel.h:114
CbmRichRingFinder::fVerbose
Int_t fVerbose
Definition: CbmRichRingFinder.h:66
hits
static vector< vector< QAHit > > hits
Definition: CbmTofHitFinderTBQA.cxx:114
CbmL1RichENNRingFinderParallel::ENNSearchHitV::Cx
fvec Cx
Definition: CbmL1RichENNRingFinderParallel.h:115
CbmL1RichENNRingFinderParallel::ENNRing::NHits
THitIndex NHits
Definition: CbmL1RichENNRingFinderParallel.h:142
CbmL1RichENNRingFinderParallel::DoFind
Int_t DoFind(TClonesArray *hitArray, TClonesArray *projArray, TClonesArray *ringArray)
Definition: CbmL1RichENNRingFinderParallel.cxx:72
CbmL1RichENNRingFinderParallel::ENNHitV::x
fvec x
Definition: CbmL1RichENNRingFinderParallel.h:60
CbmRichRing::SetCenterY
void SetCenterY(Float_t y)
Definition: CbmRichRing.h:56
CbmL1RichENNRingFinderParallel::NTimers
@ NTimers
Definition: CbmL1RichENNRingFinderParallel.h:209
CbmRichHit.h
CbmL1RichENNRingFinderParallel::ENNHitV::y
fvec y
Definition: CbmL1RichENNRingFinderParallel.h:62
CbmL1RichENNRingFinderParallel::CbmL1RichENNRingFinderParallel
CbmL1RichENNRingFinderParallel(Int_t verbose=0)
Definition: CbmL1RichENNRingFinderParallel.cxx:41
CbmL1RichENNRingFinderParallel::ENNRingV::r
fvec r
Definition: CbmL1RichENNRingFinderParallel.h:167
CbmRichHit
Definition: CbmRichHit.h:19
bool2int
friend F32vec4 bool2int(const F32vec4 &a)
Definition: L1/vectors/P4_F32vec4.h:122