FairRoot/PandaRoot
PndCAGBTracker.cxx
Go to the documentation of this file.
1 // $Id: PndCAGBTracker.cxx,v 1.12 2010/09/01 10:38:27 ikulakov 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 // List of most recent changes: *
23 // 29-05-17 Adjustment of initialization for PANDA data (Irina Rostovtseva) *
24 //***************************************************************************
25 #include "PndCAStationSTT.h"
26 #include "PndCAGBTracker.h"
27 #include "PndCAGBHit.h"
28 #include "PndCAGBTrack.h"
29 #include "PndCATrackParam.h"
30 
31 #include "PndCAMath.h"
33 #include "PndCAPerformance.h"
34 #include "TStopwatch.h"
35 
36 #include "PndCATarget.h"
37 #include "PndCAHits.h"
38 #include "PndCAHitsV.h"
39 #include "PndCATracks.h"
40 
41 #include <algorithm>
42 #include <fstream>
43 #include <iostream>
44 #include <sstream>
45 using namespace std;
46 
47 //TODO DELL ME!!!
48 #include "PndCAPerformance.h"
49 #include "PndCAMCPoint.h"
50 #include "PndCAPerformanceBase.h"
51 
52 #ifdef CATRACKER_DISPLAY
53 #include "PndCADisplay.h"
54 #endif
55 
57  int fPrevHit; // index of previous TrackHitRecord of same track in an array of records
58  unsigned short fIHit;
59  char fStation;
60 };
61 
62 vector<TrackHitRecord> gTrackHitRecords;
63 
64 const int StartStationShift = 1;//3;
65 
66 PndCANPlets::PndCANPlets( const PndCANPletsV& p ):PndCAStationArray<PndCANPlet>( p.NStations(), p.OnStation(0).HitsRef() ){
67  for( int iS = 0; iS < NStations(); ++iS ) {
69 
71 
72  tOnSta.clear();
73  tOnSta.reserve(ts.size()*float_v::Size);
74  for( unsigned int iT = 0; iT < ts.size(); iT++ ) {
75  const PndCANPletV& t = ts[iT];
76  foreach_bit( unsigned int iV, t.IsValid() ) {
77  tOnSta.push_back( PndCANPlet( PndCATrackParam( t.Param(), iV ) ) );
78  PndCANPlet &nPlet = tOnSta.back();
79  int irec=t.fLastHit[iV];
80  if( irec<0 ) continue;
81  int nHits = t.N();
82  nPlet.fIHit.clear();
83  nPlet.fIHit.resize(nHits);
84  for( int i=nHits-1; i>=0; i--){
85  if( irec<0 ){
86  cout<<"CA tracker: something wrong with hit links!!!"<<endl;
87  exit(0);
88  break;
89  }
91  nPlet.fIHit[i] = ( PndCATES(rec.fStation,rec.fIHit) );
92  irec = rec.fPrevHit;
93  }
94  }
95  }
96  }
97 }
98 
99 bool SINGLE_THREADED = false;
100 
102  :
103  fHits(),
104  fNHits( 0 ),
105  fTrackHits( 0 ),
106  fTracks( 0 ),
107  fNTracks( 0 ),
108  fTime( 0 ),
109  fStatNEvents( 0 ),
110  fSliceTrackerTime( 0 ),
111  fSliceTrackerCpuTime( 0 ),
112  fGTi(),
113  fTi(1),
114  fStatGTi(),
115  fStatTi(1)
116 {
117  //* constructor
118  for ( int i = 0; i < 20; i++ ) fStatTime[i] = 0;
119 
120 
121  fGTi.Add("init ");
122  fGTi.Add("iters ");
123  fGTi.Add("tracker");
124  fGTi.Add("fitter ");
125 
126  fTi.SetNIter( 1 ); // for iterations
127  fTi.Add("init ");
128 
129  fTi.Add("1plet ");
130  fTi.Add("2plet ");
131  fTi.Add("3plet ");
132  fTi.Add("4plet ");
133  fTi.Add("5plet ");
134  fTi.Add("6plet ");
135  fTi.Add("convrt");
136 
137  fTi.Add("plets ");
138 
139  fTi.Add("nghbrs");
140  fTi.Add("tracks");
141  fTi.Add("merger");
142  fTi.Add("finish");
143 
144  fStatGTi = fGTi;
145  fStatTi = fTi;
146 }
147 
149 {
150  fNHits = 0;
151  fTrackHits = 0;
152  fTracks = 0;
153  fNTracks = 0;
154  fTime = 0.;
155  fStatNEvents = 0;
156  fSliceTrackerTime = 0.;
158  for ( int i = 0; i < 20; ++i ) {
159  fStatTime[i] = 0.;
160  }
161  gTrackHitRecords.reserve(10000);
162 }
163 
165 {
166  //* destructor
167  StartEvent();
168 }
169 
171 {
172  //* clean up track and hit arrays
173 
174  delete[] fTrackHits;
175  fTrackHits = 0;
176  delete[] fTracks;
177  fTracks = 0;
178  fNHits = 0;
179  fNTracks = 0;
180  gTrackHitRecords.resize(0);
181 }
182 
183 
184 
185 inline void ConvertTrackParamToVector( PndCATrackParam t0[uint_v::Size],
186  PndCATrackParamVector &t, int &nTracksV)
187 {
188  float_v tmpVec;
189  int_v tmpVecShort;
190  float_v::Memory tmpFloat;
191  int_v::Memory tmpShort;
192 
193  for(int iV=0; iV < nTracksV; iV++) tmpFloat[iV] = t0[iV].X();
194  tmpVec.load( tmpFloat );
195  t.SetX(tmpVec);
196  for(int iV=0; iV < nTracksV; iV++) tmpFloat[iV] = t0[iV].SignCosPhi();
197  tmpVec.load( tmpFloat );
198  t.SetSignCosPhi(tmpVec);
199 
200  for(int iP=0; iP<5; iP++)
201  {
202  for(int iV=0; iV < nTracksV; iV++) tmpFloat[iV] = t0[iV].Par()[iP];
203  tmpVec.load( tmpFloat );
204  t.SetPar(iP,tmpVec);
205  }
206  for(int iC=0; iC<15; iC++)
207  {
208  for(int iV=0; iV < nTracksV; iV++) tmpFloat[iV] = t0[iV].Cov()[iC];
209  tmpVec.load( tmpFloat );
210  t.SetCov(iC,tmpVec);
211  }
212  for(int iV=0; iV < nTracksV; iV++) tmpFloat[iV] = t0[iV].Chi2();
213  tmpVec.load( tmpFloat );
214  t.SetChi2(tmpVec);
215  for(int iV=0; iV < nTracksV; iV++) tmpShort[iV] = t0[iV].NDF();
216  tmpVecShort.load( tmpShort );
217  t.SetNDF(tmpVecShort);
218 }
219 
220 
221 
222 
224 {
225  //* main tracking routine
226  fTime = 0;
227  fStatNEvents++;
228 
229  // cout << " NHits = " << fNHits << endl;
230 #ifdef CATRACKER_DISPLAY
231  PndCADisplay &disp = PndCADisplay::Instance();
232  disp.Init();
233  disp.SetTPC( fParameters );
234  disp.SetGB( this );
235  disp.DrawTPC();
236  disp.DrawGBPoints();
237  disp.Ask();
238  disp.DrawGBHits( *this );
239  //disp.Update();
240  disp.Ask();
241 #endif
242 
243  TStopwatch timer1;
244  TStopwatch timer2;
245 
246  fSliceTrackerTime = 0;
248  fTime = 0;
249  for ( int i = 0; i < 20; ++i ) {
250  fStatTime[i] = 0.;
251  }
252 
253  //#ifdef USE_TIMERS
254  timer1.Start();
255  //#endif /// USE_TIMERS
256 
257 
258 #ifdef USE_DBG_TIMERS
259  fGTi.Clear();
260  fTi.Clear();
261 #endif
262 
263 #ifdef USE_DBG_TIMERS
264  TStopwatch timer;
265  timer.Start(1);
266 #endif
267 
268  CATrackFinder();
269 
270 #ifdef USE_DBG_TIMERS
271  timer.Stop();
272  fGTi["tracker"] = timer;
273  timer.Start(1);
274 #endif
275 
276 #ifdef USE_DBG_TIMERS
277  timer.Stop();
278  fGTi["fitter "] = timer;
279 #endif
280 
281 
282 
283  //#ifdef USE_TIMERS
284  timer1.Stop();
285  fStatTime[12] = timer1.RealTime();
286  //#endif /// USE_TIMERS
288 
289  fSliceTrackerTime += timer1.RealTime();
290  fSliceTrackerCpuTime += timer1.CpuTime();
291  //fTime+=timerMerge.RealTime();
292  //std::cout<<"Merge time = "<<timerMerge.RealTime()*1.e3<<"ms"<<std::endl;
293  //std::cout<<"End CA merging"<<std::endl;
294  fTime += timer1.RealTime();
295 
296 #ifdef USE_DBG_TIMERS
297  static int stat_N = 0;
298  stat_N++;
299 
300  cout << endl << " --- Timers, ms --- " << endl;
301  fTi.Calc();
302  fStatTi += fTi;
303  L1CATFTimerInfo tmp_ti = fStatTi/0.001/stat_N; // ms
304 
305  tmp_ti.PrintReal();
306  fStatGTi += fGTi;
307  L1CATFIterTimerInfo tmp_gti = fStatGTi/0.001/stat_N; // ms
308  tmp_gti.PrintReal( 1 );
309 #endif
310 
311 #ifdef CATRACKER_DISPLAY
312  for( int i=0; i<fNTracks; i++ ){
313  disp.DrawRecoTrack(i);
314  }
315  disp.Ask();
316 #endif
317 }
318 
320 {
321  //* write settings to the file
322  UNUSED_PARAM1(out); // TODO
323 // out << fSlices[iSlice].Param();
324 }
325 
326 void PndCAGBTracker::ReadSettings( std::istringstream &in )
327 {
328  //* Read settings from the file
329 // PndCAParam param;
330  in >> fParameters;
331 
332 // fSlices[iSlice].Initialize( param );
333 }
334 
335 void PndCAGBTracker::WriteEvent( FILE *file ) const
336 {
337  // write event to the file
338 
339  const int nHits = NHits();
340  int written = std::fwrite( &nHits, sizeof( int ), 1, file );
341  assert( written == 1 );
342  written = std::fwrite( &fHits[0], sizeof( PndCAGBHit ), nHits, file );
343  assert( written == nHits );
344  std::fflush( file );
345  UNUSED_PARAM1(written);
346 }
347 
348 
349 
350 bool PndCAGBTracker::SaveTracksInFile(string prefix) const
351 {
352  ofstream out((prefix+"tracks.data").data());
353  if ( !out.is_open() ) return 0;
354 
355  // ostream& out = cout;
356 
357  out << fNTracks << std::endl;
358  for ( int itr = 0; itr < fNTracks; itr++ ) {
359  PndCAGBTrack &t = fTracks[itr];
360 
361  for ( int ih = t.FirstHitRef(), i = 0; i < t.NHits(); ih++, i++ ) {
362  out << fTrackHits[ih] << " ";
363  }
364  out << endl;
365  }
366  return 1;
367 }
368 
369 // void PndCAGBTracker::ReadTracks( std::istream &in )
370 // {
371 // //* Read tracks from file
372 //
373 // in >> fTime;
374 // fSliceTrackerTime = fTime;
375 // fStatTime[0] += fTime;
376 // fStatNEvents++;
377 // delete[] fTrackHits;
378 // fTrackHits = 0;
379 // int nTrackHits = 0;
380 // in >> nTrackHits;
381 // fTrackHits = new int [nTrackHits];
382 // for ( int ih = 0; ih < nTrackHits; ih++ ) {
383 // in >> TrackHits()[ih];
384 // }
385 // delete[] fTracks;
386 // fTracks = 0;
387 // in >> fNTracks;
388 // fTracks = new PndCAGBTrack[fNTracks];
389 // for ( int itr = 0; itr < fNTracks; itr++ ) {
390 // PndCAGBTrack &t = Tracks()[itr];
391 // in >> t;
392 // }
393 // }
394 
395 void PndCAGBTracker::SetHits( std::vector<PndCAGBHit> &hits)
396 {
397  const int NHits2 = hits.size();
398 
399  fNHits = 0;
400  fHits.resize(0);
401  fHits.reserve(NHits2);
402  //cout<<"Z min, max: "<<fParameters.MinZ()<<" "<<fParameters.MaxZ()<<endl;
403  for (int iH = 0; iH < NHits2; iH++){
404  PndCAGBHit l = hits[iH];
405  //cout<<"hit z: "<<l.Z()<<" r: "<<l.R()<<endl;
406  if( fabs(l.Angle())>10 ){
407  //cout<<"read angle "<<l.Angle()<<" station "<<(int) l.IRow()<<endl;
408  continue; // skip forward detectors
409  }
410  if( l.IRow() >= PndCAParameters::MaxNStations ){
411  cout<<"CA tracker: wrong hit station number: "<<(int) l.IRow()<<" out of "<<PndCAParameters::MaxNStations<<endl;
413  continue;
414  }
415  fHits.push_back(l);
416  }
417  fNHits = fHits.size();
418 } // need for StRoot
419 
420 void PndCAGBTracker::SaveHitsInFile(string prefix) const
421 {
422  ofstream ofile((prefix+"hits.data").data(),std::ios::out|std::ios::app);
423  const int Size = fHits.size();
424  ofile << Size << std::endl;
425  for (unsigned int i = 0; i < fHits.size(); i++){
426  const PndCAGBHit &l = fHits[i];
427  ofile << l;
428  }
429  ofile.close();
430 
431 }
432 
433 // void PndCAGBTracker::SaveSettingsInFile(string prefix) const
434 // {
435 // ofstream ofile((prefix+"settings.data").data(),std::ios::out|std::ios::app);
436 // WriteSettings(ofile);
437 // }
438 
440 {
441  ifstream ifile((prefix+"hits.data").data());
442  if ( !ifile.is_open() ) return 0;
443  int Size;
444  ifile >> Size;
445 
446  fHits.clear();
447  fHits.reserve(Size);
448  fNHits = 0;
449  for (int i = 0; i < Size; i++){
450  PndCAGBHit l;
451  ifile >> l;
452  if( fabs(l.Angle())>10 ){
453  //cout<<"read angle "<<l.Angle()<<" station "<<(int) l.IRow()<<endl;
454  continue; // skip forward detectors
455  }
456  if( l.IRow() >= PndCAParameters::MaxNStations ){
457  cout<<"CA tracker: wrong hit station number: "<<(int) l.IRow()<<" out of "<<PndCAParameters::MaxNStations<<endl;
458  l.SetIRow( PndCAParameters::MaxNStations-1);
459  continue;
460  }
461  fHits.push_back(l);
462  }
463  fNHits=fHits.size();
464  ifile.close();
465  return 1;
466 }
467 
468 // bool PndCAGBTracker::ReadSettingsFromFile(string prefix)
469 // {
470 // ifstream ifile((prefix+"settings.data").data());
471 // if ( !ifile.is_open() ) return 0;
472 // ReadSettings(ifile);
473 // return 1;
474 // }
475 
477 {
478 
479 #ifdef USE_DBG_TIMERS
480  TStopwatch timer;
481  timer.Start(1);
482 #endif
483 
484  // prepare memory for tracks
485  if(fTracks) delete [] fTracks;
486  if(fTrackHits) delete [] fTrackHits;
487  fTracks = new PndCAGBTrack[5000]; // TODO
488  fTrackHits = new int[3000*PndCAParameters::MaxNStations]; // TODO
489  fNTracks = 0;
490 
491  // std::sort( fHits.Data(), fHits.Data() + fNHits, PndCAGBHit::Compare ); to make convertion faster
492  PndCAHits hits( NStations(), fHits.size()*3/NStations() ); // suppose approximately eaqul nHits per station
493 
494  //
495  {
496  const int nHits = fHits.size();
497  for (int i = 0; i < nHits; i++){
498  PndCAGBHit &h = fHits[i];
499  h.SetIsLeft( false );
500  if(h.IRow() < PndCAParameters::NMVDStations) continue;
501  const float k = 1.5; // diff between real size and sigma
502  const float errT = 0.02/k; // tangential error 2 mm
503  const float errN = sqrt(h.Err2R()); // normal error
504  {
505  const double beta = 0.5*atan(2*h.ErrX12()/(h.Err2X2() - h.Err2X1())); // strip angle
506  const double C11 = errN*errN;
507  const double C22 = h.Err2X2();
508  const double s = sin(beta);
509  const double c = cos(beta);
510  h.SetErr2X0( errT*errT );
511  h.SetErrX12( -s*c*(C11-C22) );
512  h.SetErr2X1( c*c*C11+s*s*C22 );
513  h.SetErr2X2( s*s*C11+c*c*C22 );
514  }
515  }
516  }
517 
518  // convert hits & create left-right hits
519  //cout<<"Original hits (no l/r) total: "<<fNHits<<endl;
520  for( int iH = 0; iH < fNHits; ++iH ) {
521  PndCAHit h( fHits[iH], iH );
523  hits.Add( h );
524  } else {
525  float u = h.fX1;
526  h.fIsLeft=false;
527  h.fX1 = u + h.fR;
528  hits.Add( h );
529  h.fIsLeft = true;
530  h.fX1 = u - h.fR;
531  hits.Add( h );
532  }
533  }
534 
535  double p6 = TMath::TwoPi()/6.;
536  double p12 = p6/2.;
537 
538  for( int ist=0; ist<NStations(); ist++){
539  //cout<<"station "<<ist<<endl;
540  const PndCAStation &station = GetParameters().Station( ist );
541  const float sb = station.f.sin;
542  const float cb = station.f.cos;
543  PndCAElementsOnStation<PndCAHit> &stHits = hits.OnStation( ist );
544  //cout<<"station "<<ist<<": nhits "<<stHits.size()<<endl;
545  for( unsigned int ih=0; ih<stHits.size(); ih++ ){
546  PndCAHit &hit = stHits[ih];
547  //cout<<(int)ist<<" "<<station.r<<" "<<hit.X0()<<" "<<hit.R()<<endl;
548  hit.fU = cb*hit.X1() + sb*hit.X2();
549  hit.fDR = ( hit.IsLeft() ? hit.R() :-hit.R() );
550  hit.fU += hit.fDR;
551  double ang = hit.Angle();
552  //cout<<"angle "<<ang<<endl;
553  if( ang<0 ) ang+=TMath::TwoPi();
554  hit.fAngle = ang;
555  hit.fISec = TMath::Nint( (ang-p12)/p6);
557  //cout<< hit.fAngle - (p12+p6*hit.fISec)<<endl;
558  //if( fabs(hit.fAngle - (p12+p6*hit.fISec) )>.001 ) exit(0);
559  }
560  if( hit.fISec<0 || hit.fISec>=6 ){
561  cout<<"CA tracker: Wrong hit sector "<<hit.fISec<<endl;
562  exit(0);
563  }
564  }
565  }
566 
567  //hits.Sort();
568 
569  for( int ista=0; ista<NStations(); ista++){
570 
571  PndCAStationSTT &sta = fStations[ista];
572  sta.Init();
573  const PndCAStation &station = GetParameters().Station( ista );
574 
575  sta.fSin = float_v(station.f.sin);
576  sta.fCos = float_v(station.f.cos);
577 
578  const PndCAElementsOnStation<PndCAHit> &stHits = hits.OnStationConst( ista );
579  for( unsigned int ih=0; ih<stHits.size(); ih++ ){
580  const PndCAHit &hit = stHits[ih];
582  h1d.fISta = ista;
583  h1d.fISec = hit.fISec;
584  h1d.fOrigID = ih;
585  h1d.fU = hit.U();
586  h1d.fDR = hit.DR();
587  sta.fHits1D.push_back(h1d);
588  }
589  std::sort( sta.fHits1D.begin(),sta.fHits1D.end() );
590  int lastSec=-1;
591  for( unsigned int ih=0; ih<sta.fHits1D.size(); ih++ ){
592  const PndCAHitSTT &hit = sta.fHits1D[ih];
593  int iSec = hit.fISec;
594  if( iSec > lastSec ){
595  sta.fSectors[iSec].fFirstHit = ih;
596  sta.fSectors[iSec].fNHits = 0;
597  lastSec = iSec;
598  }
599  sta.fSectors[iSec].fNHits++;
600  }
601  }
602 
603  // estimate PV
604  float xT = 0, yT = 0, zT = 0;
605 
606 #ifdef USE_DBG_TIMERS
607  timer.Stop();
608  fGTi["init "] = timer;
609  timer.Start(1);
610  TStopwatch itimer;
611 #endif
612 
614  // set parameters; TODO depend on iteration
615  const float kCorr = 1;//.2; // correction on pulls width
616  const float kCorr2 = kCorr*kCorr;
617  fPick_m = 3.*kCorr;
618  fPick_r = 5.*kCorr;
619  fPickNeighbour = 3.*kCorr;
620  TRACK_PROB_CUT = 0.01;
621  TRACK_CHI2_CUT = 10.*kCorr2;
622  TRIPLET_CHI2_CUT = 15.*kCorr2; // TMath::Prob(20,-3+1+6) = TMath::Prob(15,2) = 5e-04
623 
624  // Set correction in order to take into account overlaping
625  // The reason is that low momentum tracks are too curved and goes not from target direction. That's why hit sort is not work idealy
626  fMaxDX0 = 0;
627 
628 //fMaxInvMom = 2;
629  fMaxInvMom = 5;
630 //fTarget = PndCATarget( xT, yT, zT, 1, 1, fMaxInvMom/3.f, GetParameters().VtxFieldValue(), 3 ); // 3 so triplets can have NDF=1
631  fTarget = PndCATarget( xT, yT, zT, 1, 1, fMaxInvMom, GetParameters().VtxFieldValue(), 3 ); // 3 so triplets can have NDF=1
632  fMaxDX0 = 0;
633 
634 #ifdef USE_DBG_TIMERS
635  itimer.Stop();
636  fTi[0]["init "] = itimer;
637  itimer.Start(1);
638  TStopwatch ptimer;
639  ptimer.Start(1);
640 #endif
641 
642  //cout<<"MaxCellLength = "<<PndCAParameters::MaxCellLength<<endl;
643 
644 #ifdef USE_DBG_TIMERS
645  itimer.Stop();
646  fTi[0]["0plet "] = itimer;
647  itimer.Start(1);
648 #endif
649 
650  // reconstruct
651  int maxCellLength = PndCAParameters::MaxCellLength;
652  maxCellLength = 6;
653 
654  PndCANPletsV pletsV( NStations(), &hits );
655 
656  int iMin = ( maxCellLength < PndCAParameters::LastCellLength ) ? maxCellLength : PndCAParameters::LastCellLength;
657 
658  for( char iS = 0; iS < NStations()- iMin; iS+=StartStationShift ) {
659  CreateNPlets( fTarget, hits, pletsV.OnStation(iS), iS, maxCellLength-1 );
660  }
661 
662 #ifdef USE_DBG_TIMERS
663  itimer.Stop();
664  std::stringstream ss;
665  ss << 0 << "plet ";
666  fTi[0][ss.str()] = itimer;
667  itimer.Start(1);
668 #endif
669 
670  PndCANPlets triplets(pletsV);
671 
672 
673 #ifdef USE_DBG_TIMERS
674  itimer.Stop();
675  fTi[0]["convrt"] = itimer;
676  ptimer.Stop();
677  fTi[0]["plets "] = ptimer;
678 
679  itimer.Start(1);
680 #endif
681 
683  FindNeighbours( triplets );
684 
685 #ifdef USE_DBG_TIMERS
686  itimer.Stop();
687  fTi[0]["nghbrs"] = itimer;
688  itimer.Start(1);
689 #endif
690 
691  PndCATracks tracks(&hits);
692  CreateTracks( triplets, tracks );
693  //cout<<"n tracks after CreateTracks: "<<tracks.size()<<endl;
694 
695 #ifdef USE_DBG_TIMERS
696  itimer.Stop();
697  fTi[0]["tracks"] = itimer;
698  itimer.Start(1);
699 #endif
700 
701  Merge( tracks );
702 
703 #ifdef USE_DBG_TIMERS
704  itimer.Stop();
705  fTi[0]["merger"] = itimer;
706  itimer.Start(1);
707 #endif
708 
709  // save tracks in compact format
710 
711 
712  int curHit = 0; // counters, used to save tracks in output format
713  int curTr = 0;
714 
715  const int NRTracks = tracks.size();
716 
717  for(int iT=0; iT<NRTracks; iT++)
718  {
719  const int NTHits = tracks[iT].NHits();
720  PndCAGBTrack &oT = fTracks[curTr];
721  oT.SetNHits( NTHits );
722  oT.SetFirstHitRef( curHit );
723  //#ifdef USE_CA_FIT
724  oT.SetOuterParam( tracks[iT].Fit( hits, fTarget, GetParameters() ) );
725  oT.SetInnerParam( tracks[iT].Fit( hits, fTarget, GetParameters(), false ) );
726  //#endif
727 
728  for(int iH=0; iH < NTHits; iH++)
729  {
730  fTrackHits[curHit] = tracks.Hit(iH, iT).Id();
731  curHit++;
732  }
733  curTr++;
734  }
735  fNTracks += NRTracks;
736 
737  hits.Clean(); // remove used hits
738 
739 #ifdef USE_DBG_TIMERS
740  itimer.Stop();
741  fTi[0]["finish"] = itimer;
742  itimer.Start(1);
743 #endif
744 
745 #ifdef USE_DBG_TIMERS
746  timer.Stop();
747  fGTi["iters "] = timer;
748 #endif
749 
750 }
751 
752 
753 
754 
755 inline bool IsRightNeighbour( const PndCANPlet& a, const PndCANPlet& b, float pick, float& chi2 ){
756  int start = (a.N() < b.N() ) ? 0 : a.N() - b.N();
757  for( int i = start; i<a.N()-StartStationShift; i++){
758  if ( a.IHit(i+StartStationShift) != b.IHit(i) ){
759  return false;
760  }
761  }
762  chi2 = fabs(a.QMomentum() - b.QMomentum())/sqrt(a.QMomentumErr2() + b.QMomentumErr2());
763  if ( chi2 > pick ) return false; // neighbours must have same qp
764  chi2 *= chi2;
765  return true;
766 }
767 
768 // find and store neighbours triplets
769 // to make recursive search faster saves only neighbours with level = level - 1
771 {
772  for( int iS = triplets.NStations() - 1; iS >= 0; --iS ) { // CHECKME
773  PndCAElementsOnStation<PndCANPlet>& ts1 = triplets.OnStation( iS );
774 
775  for( unsigned int iT1 = 0; iT1 < ts1.size(); ++iT1 ) {
776  PndCANPlet& t1 = ts1[iT1];
777 
778  int neighIStation = t1.ISta(0) + StartStationShift;
779 
780  if ( neighIStation >= triplets.NStations() ) continue; // triplets can't start from this station
781  PndCAElementsOnStation<PndCANPlet>& ts2 = triplets.OnStation( neighIStation );
782 
783  char maxLevel = -1; // maxLevel of neighbour triplets
784  vector< pair<float,unsigned int> > neighCands; // save neighbour candidates
785  for( unsigned int iT2 = 0; iT2 < ts2.size(); ++iT2 ) {
786  const PndCANPlet& t2 = ts2[iT2];
787  float chi2;
788  if( !IsRightNeighbour( t1, t2, fPick, chi2 ) ) continue;
789 
790  if ( maxLevel < t2.Level() ) maxLevel = t2.Level();
791  if ( maxLevel == t2.Level() ) neighCands.push_back(pair<float,unsigned int>(chi2 + t2.Chi2Level(),iT2));
792  }
793  t1.Level() = maxLevel + 1;
794 
795  // save
796  for( unsigned int iN = 0; iN < neighCands.size(); ++iN ) {
797  const PndCANPlet& t2 = ts2[ neighCands[iN].second ];
798 
799  if ( maxLevel == t2.Level() ) {
800  t1.Neighbours().push_back( neighCands[iN] );
801  }
802  }
803  sort( t1.Neighbours().begin(), t1.Neighbours().end() );
804  if ( t1.NNeighbours() ) {
805  t1.Chi2Level() = t1.Chi2Neighbours(0);
806  const pair<float,unsigned int> tmp = t1.Neighbours()[0]; // leave only one. CHECKME for 1000tracks events
807  t1.Neighbours().clear();
808  t1.Neighbours().push_back( tmp );
809  }
810  } // iTrip1
811 
812  //sort( ts1.begin(), ts1.end(), PndCANPlet::compare );
813  } // iStation
814 }
815 
816 void PndCAGBTracker::CreateTracks( const PndCANPlets& triplets, PndCATracks& tracks )
817 {
818  const int Nlast = PndCAParameters::LastCellLength; // N hits in the rightmost triplet
819 
820  int min_level = 1; // min level to start triplet. So min track length = min_level+3.
821 
822  // collect consequtive: the longest tracks, shorter, more shorter and so on
823  for (int ilev = NStations()-Nlast; ilev >= min_level; ilev--){ // choose length
824  PndCATracks vtrackcandidate( tracks.HitsRef() );
825 
826  // how many levels to check
827  const unsigned char min_best_l = (ilev > min_level) ? ilev-1 : min_level; // lose maximum one hit and find all hits for min_level
828  // const unsigned char min_best_l = ilev + 3; // find all hits (slower)
829 
830  // find candidates
831  for( int istaF = 0; istaF <= NStations()-Nlast-ilev; istaF++ ){
832  const PndCAElementsOnStation<PndCANPlet>& tsF = triplets.OnStation( istaF );
833  for( unsigned int iTrip=0; iTrip < tsF.size(); iTrip++ ){
834  const PndCANPlet* tripF = &(tsF[iTrip]);
835 
836  if (0) { // ghost supression !!!
837  if ( tripF->Level() == 0 ) continue; // ghost suppression // find track with 3 hits only if it was created from a chain of triplets, but not from only one triplet
838  if ( tripF->Level() < ilev ) continue; // try only triplets, which can start track with ilev+3 length. w\o it have more ghosts, but efficiency either
839  if ( (ilev == 0) && (tripF->ISta(0) != 0) ) continue; // ghost supression // collect only MAPS tracks-triplets
840  }
841  else
842  if ( tripF->Level() < min_best_l ) continue;
843 
844  PndCATrack curr_tr;
845 
846  bool isUsed = false;
847  for( int i = 0; i < tripF->N(); i++ ) {
848  if( triplets.OnStation( tripF->ISta(0) ).GetHit( i, iTrip ).IsUsed() ) {
849  isUsed = true;
850  break;
851  }
852  curr_tr.AddHit( tripF->IHit(i) );
853  }
854  if (isUsed) continue;
855  curr_tr.Level()++;
856  curr_tr.Chi2() = tripF->Param().Chi2();
857 
858  PndCATrack best_tr = curr_tr;
859  unsigned int nCalls = 0;
860  FindBestCandidate(istaF, best_tr, iTrip, curr_tr, min_best_l, triplets, nCalls );
861 
862  if ( best_tr.Level() < min_best_l ) continue;
863  if ( best_tr.NHits() < PndCAParameters::MinimumHitsForRecoTrack ) continue;
864 
865 // if ( best_tr.Fit( *tracks.HitsRef(), fTarget, GetParameters(), tripF->QMomentum() ).QPt() > 0.5*fMaxInvMom ) continue; // fit to determine Chi2 and NDF
866 
867  vtrackcandidate.push_back(best_tr);
868  // best_tr.SetHitsAsUsed(*tracks.HitsRef()); TODO
869  // tracks.push_back(best_tr);
870  }
871  } // istaF
872 
873  // select and save best candidates
874  vtrackcandidate.SelectAndSaveTracks( tracks );
875  } // ilev
876 
877 }
878 
879 // --------- Merger ---------
880 
881 
882 void PndCAGBTracker::InvertCholetsky(float a[15]) const
883 {
884  float d[5], uud, u[5][5];
885  for(int i=0; i<5; i++)
886  {
887  d[i]=0.f;
888  for(int j=0; j<5; j++)
889  u[i][j]=0.;
890  }
891 
892  for(int i=0; i<5; i++)
893  {
894  uud=0.;
895  for(int j=0; j<i; j++)
896  uud += u[j][i]*u[j][i]*d[j];
897  uud = a[i*(i+3)/2] - uud;
898 
899  if(fabs(uud)<1.e-12) uud = 1.e-12;
900  d[i] = uud/fabs(uud);
901  u[i][i] = sqrt(fabs(uud));
902 
903  for(int j=i+1; j<5; j++)
904  {
905  uud = 0.;
906  for(int k=0; k<i; k++)
907  uud += u[k][i]*u[k][j]*d[k];
908  uud = a[j*(j+1)/2+i] - uud;
909  u[i][j] = d[i]/u[i][i]*uud;
910  }
911  }
912 
913  float u1[5];
914 
915  for(int i=0; i<5; i++)
916  {
917  u1[i] = u[i][i];
918  u[i][i] = 1.f/u[i][i];
919  }
920  for(int i=0; i<4; i++)
921  {
922  u[i][i+1] = - u[i][i+1]*u[i][i]*u[i+1][i+1];
923  }
924  for(int i=0; i<3; i++)
925  {
926  u[i][i+2] = u[i][i+1]*u1[i+1]*u[i+1][i+2]-u[i][i+2]*u[i][i]*u[i+2][i+2];
927  }
928  for(int i=0; i<2; i++)
929  {
930  u[i][i+3] = u[i][i+2]*u1[i+2]*u[i+2][i+3] - u[i][i+3]*u[i][i]*u[i+3][i+3];
931  u[i][i+3] -= u[i][i+1]*u1[i+1]*(u[i+1][i+2]*u1[i+2]*u[i+2][i+3] - u[i+1][i+3]);
932  }
933  u[0][4] = u[0][2]*u1[2]*u[2][4] - u[0][4]*u[0][0]*u[4][4];
934  u[0][4] += u[0][1]*u1[1]*(u[1][4] - u[1][3]*u1[3]*u[3][4] - u[1][2]*u1[2]*u[2][4]);
935  u[0][4] += u[3][4]*u1[3]*(u[0][3] - u1[2]*u[2][3]*(u[0][2] - u[0][1]*u1[1]*u[1][2]));
936 
937  for(int i=0; i<5; i++)
938  a[i+10] = u[i][4]*d[4]*u[4][4];
939  for(int i=0; i<4; i++)
940  a[i+6] = u[i][3]*u[3][3]*d[3] + u[i][4]*u[3][4]*d[4];
941  for(int i=0; i<3; i++)
942  a[i+3] = u[i][2]*u[2][2]*d[2] + u[i][3]*u[2][3]*d[3] + u[i][4]*u[2][4]*d[4];
943  for(int i=0; i<2; i++)
944  a[i+1] = u[i][1]*u[1][1]*d[1] + u[i][2]*u[1][2]*d[2] + u[i][3]*u[1][3]*d[3] + u[i][4]*u[1][4]*d[4];
945  a[0] = u[0][0]*u[0][0]*d[0] + u[0][1]*u[0][1]*d[1] + u[0][2]*u[0][2]*d[2] + u[0][3]*u[0][3]*d[3] + u[0][4]*u[0][4]*d[4];
946 }
947 
948 void PndCAGBTracker::MultiplySS(float const C[15], float const V[15], float K[5][5]) const
949 {
950 //multiply 2 symmetric matricies
951  K[0][0] = C[0]*V[ 0] + C[1]*V[ 1] + C[3]*V[ 3] + C[6]*V[ 6] + C[10]*V[10];
952  K[0][1] = C[0]*V[ 1] + C[1]*V[ 2] + C[3]*V[ 4] + C[6]*V[ 7] + C[10]*V[11];
953  K[0][2] = C[0]*V[ 3] + C[1]*V[ 4] + C[3]*V[ 5] + C[6]*V[ 8] + C[10]*V[12];
954  K[0][3] = C[0]*V[ 6] + C[1]*V[ 7] + C[3]*V[ 8] + C[6]*V[ 9] + C[10]*V[13];
955  K[0][4] = C[0]*V[10] + C[1]*V[11] + C[3]*V[12] + C[6]*V[13] + C[10]*V[14];
956 
957  K[1][0] = C[1]*V[ 0] + C[2]*V[ 1] + C[4]*V[ 3] + C[7]*V[ 6] + C[11]*V[10];
958  K[1][1] = C[1]*V[ 1] + C[2]*V[ 2] + C[4]*V[ 4] + C[7]*V[ 7] + C[11]*V[11];
959  K[1][2] = C[1]*V[ 3] + C[2]*V[ 4] + C[4]*V[ 5] + C[7]*V[ 8] + C[11]*V[12];
960  K[1][3] = C[1]*V[ 6] + C[2]*V[ 7] + C[4]*V[ 8] + C[7]*V[ 9] + C[11]*V[13];
961  K[1][4] = C[1]*V[10] + C[2]*V[11] + C[4]*V[12] + C[7]*V[13] + C[11]*V[14];
962 
963  K[2][0] = C[3]*V[ 0] + C[4]*V[ 1] + C[5]*V[ 3] + C[8]*V[ 6] + C[12]*V[10];
964  K[2][1] = C[3]*V[ 1] + C[4]*V[ 2] + C[5]*V[ 4] + C[8]*V[ 7] + C[12]*V[11];
965  K[2][2] = C[3]*V[ 3] + C[4]*V[ 4] + C[5]*V[ 5] + C[8]*V[ 8] + C[12]*V[12];
966  K[2][3] = C[3]*V[ 6] + C[4]*V[ 7] + C[5]*V[ 8] + C[8]*V[ 9] + C[12]*V[13];
967  K[2][4] = C[3]*V[10] + C[4]*V[11] + C[5]*V[12] + C[8]*V[13] + C[12]*V[14];
968 
969  K[3][0] = C[6]*V[ 0] + C[7]*V[ 1] + C[8]*V[ 3] + C[9]*V[ 6] + C[13]*V[10];
970  K[3][1] = C[6]*V[ 1] + C[7]*V[ 2] + C[8]*V[ 4] + C[9]*V[ 7] + C[13]*V[11];
971  K[3][2] = C[6]*V[ 3] + C[7]*V[ 4] + C[8]*V[ 5] + C[9]*V[ 8] + C[13]*V[12];
972  K[3][3] = C[6]*V[ 6] + C[7]*V[ 7] + C[8]*V[ 8] + C[9]*V[ 9] + C[13]*V[13];
973  K[3][4] = C[6]*V[10] + C[7]*V[11] + C[8]*V[12] + C[9]*V[13] + C[13]*V[14];
974 
975  K[4][0] = C[10]*V[ 0] + C[11]*V[ 1] + C[12]*V[ 3] + C[13]*V[ 6] + C[14]*V[10];
976  K[4][1] = C[10]*V[ 1] + C[11]*V[ 2] + C[12]*V[ 4] + C[13]*V[ 7] + C[14]*V[11];
977  K[4][2] = C[10]*V[ 3] + C[11]*V[ 4] + C[12]*V[ 5] + C[13]*V[ 8] + C[14]*V[12];
978  K[4][3] = C[10]*V[ 6] + C[11]*V[ 7] + C[12]*V[ 8] + C[13]*V[ 9] + C[14]*V[13];
979  K[4][4] = C[10]*V[10] + C[11]*V[11] + C[12]*V[12] + C[13]*V[13] + C[14]*V[14];
980 }
981 
982 void PndCAGBTracker::MultiplyMS(float const C[5][5], float const V[15], float K[15]) const
983 {
984 //multiply symmetric and nonsymmetric matricies
985  K[0] = C[0][0]*V[0] + C[0][1]*V[1] + C[0][2]*V[3] + C[0][3]*V[6] + C[0][4]*V[10];
986 
987  K[1] = C[1][0]*V[0] + C[1][1]*V[1] + C[1][2]*V[3] + C[1][3]*V[6] + C[1][4]*V[10];
988  K[2] = C[1][0]*V[1] + C[1][1]*V[2] + C[1][2]*V[4] + C[1][3]*V[7] + C[1][4]*V[11];
989 
990  K[3] = C[2][0]*V[0] + C[2][1]*V[1] + C[2][2]*V[3] + C[2][3]*V[6] + C[2][4]*V[10];
991  K[4] = C[2][0]*V[1] + C[2][1]*V[2] + C[2][2]*V[4] + C[2][3]*V[7] + C[2][4]*V[11];
992  K[5] = C[2][0]*V[3] + C[2][1]*V[4] + C[2][2]*V[5] + C[2][3]*V[8] + C[2][4]*V[12];
993 
994  K[6] = C[3][0]*V[0] + C[3][1]*V[1] + C[3][2]*V[3] + C[3][3]*V[6] + C[3][4]*V[10];
995  K[7] = C[3][0]*V[1] + C[3][1]*V[2] + C[3][2]*V[4] + C[3][3]*V[7] + C[3][4]*V[11];
996  K[8] = C[3][0]*V[3] + C[3][1]*V[4] + C[3][2]*V[5] + C[3][3]*V[8] + C[3][4]*V[12];
997  K[9] = C[3][0]*V[6] + C[3][1]*V[7] + C[3][2]*V[8] + C[3][3]*V[9] + C[3][4]*V[13];
998 
999  K[10] = C[4][0]*V[ 0] + C[4][1]*V[ 1] + C[4][2]*V[ 3] + C[4][3]*V[ 6] + C[4][4]*V[10];
1000  K[11] = C[4][0]*V[ 1] + C[4][1]*V[ 2] + C[4][2]*V[ 4] + C[4][3]*V[ 7] + C[4][4]*V[11];
1001  K[12] = C[4][0]*V[ 3] + C[4][1]*V[ 4] + C[4][2]*V[ 5] + C[4][3]*V[ 8] + C[4][4]*V[12];
1002  K[13] = C[4][0]*V[ 6] + C[4][1]*V[ 7] + C[4][2]*V[ 8] + C[4][3]*V[ 9] + C[4][4]*V[13];
1003  K[14] = C[4][0]*V[10] + C[4][1]*V[11] + C[4][2]*V[12] + C[4][3]*V[13] + C[4][4]*V[14];
1004 }
1005 
1006 void PndCAGBTracker::MultiplySR(float const C[15], float const r_in[5], float r_out[5]) const
1007 {
1008 //multiply vector and symmetric matrix
1009  r_out[0] = r_in[0]*C[ 0] + r_in[1]*C[ 1] + r_in[2]*C[ 3] +r_in[3]*C[ 6] + r_in[4]*C[10];
1010  r_out[1] = r_in[0]*C[ 1] + r_in[1]*C[ 2] + r_in[2]*C[ 4] +r_in[3]*C[ 7] + r_in[4]*C[11];
1011  r_out[2] = r_in[0]*C[ 3] + r_in[1]*C[ 4] + r_in[2]*C[ 5] +r_in[3]*C[ 8] + r_in[4]*C[12];
1012  r_out[3] = r_in[0]*C[ 6] + r_in[1]*C[ 7] + r_in[2]*C[ 8] +r_in[3]*C[ 9] + r_in[4]*C[13];
1013  r_out[4] = r_in[0]*C[10] + r_in[1]*C[11] + r_in[2]*C[12] +r_in[3]*C[13] + r_in[4]*C[14];
1014 }
1015 
1016 void PndCAGBTracker::FilterTracks(float const r[5], float const C[15], float const m[5], float const V[15], float R[5], float W[15], float &chi2) const
1017 {
1018  float S[15];
1019  for(int i=0; i<15; i++)
1020  {
1021  W[i] = C[i];
1022  S[i] = C[i] + V[i];
1023  }
1024  for(int i=0; i<5; i++)
1025  R[i] = r[i];
1026 
1027  InvertCholetsky(S);
1028 
1029  float K[5][5];
1030  MultiplySS(C,S,K);
1031  float dzeta[5];
1032  for(int i=0; i<5; i++) dzeta[i] = m[i] - r[i];
1033  float KC[15];
1034  MultiplyMS(K,C,KC);
1035  for(int i=0; i< 15; i++)
1036  W[i] -= KC[i];
1037 
1038  float kd;
1039  for(int i=0; i<5; i++)
1040  {
1041  kd = 0.f;
1042  for(int j=0; j<5; j++)
1043  kd += K[i][j]*dzeta[j];
1044  R[i] += kd;
1045  }
1046  float S_dzeta[5];
1047  MultiplySR(S, dzeta, S_dzeta);
1048  chi2 = dzeta[0]*S_dzeta[0] + dzeta[1]*S_dzeta[1] + dzeta[2]*S_dzeta[2] + dzeta[3]*S_dzeta[3] + dzeta[4]*S_dzeta[4];
1049 }
1050 
1052 {
1053  const int NTracksS = tracks.size();
1054  vector< vector< pair<float,int> > > InNeighbour(NTracksS);
1055  vector< vector< pair<float,int> > > OutNeighbour(NTracksS);
1056 
1057  vector<PndCATrackParam> fittedTracks;
1058  fittedTracks.reserve(NTracksS);
1059  for ( int iT1 = 0; iT1 < NTracksS; iT1++ ) {
1060  PndCATrack& t1 = tracks[iT1];
1061  // CHECKME why fit backward doesn't help. CHECKME why fit without target doesn't work
1062  PndCATrackParam p1 = t1.Fit( *tracks.HitsRef(), fTarget, GetParameters() );
1063  fittedTracks.push_back(p1);
1064  }
1065 
1066  for ( int iT1 = 0; iT1 < NTracksS; iT1++ ) {
1067  PndCATrack& t1 = tracks[iT1];
1068  if ( t1.NHits() <= 0 ) continue;
1069 
1070  const PndCATrackParam &p1 = fittedTracks[iT1];
1071 
1072  for ( int iT2 = 0; iT2 < NTracksS; iT2++ ) {
1073  PndCATrack& t2 = tracks[iT2];
1074  if ( t2.NHits() <= 0 ) continue;
1075 
1076  const int nStaDiff = t2.IHits().front().s - t1.IHits().back().s;
1077  if ( nStaDiff <= 0 ) continue;
1078 
1079  PndCATrackParam p2 = fittedTracks[iT2];
1080  // if ( t2.NHits() >= t1.NHits() ) // CHECK me: why it is better to always use p2
1081  p2.Transport( (*tracks.HitsRef())[t1.IHits().back()], GetParameters().cBz() );
1082  // else
1083  // p1.Transport( (*tracks.HitsRef())[t2.IHits().back()], GetParameters().cBz() );
1084 
1085  float C[15], r[5], chi2(0);
1086  FilterTracks( p1.Par(), p1.Cov(), p2.Par(), p2.Cov(), r, C, chi2);
1087 
1088  if ( chi2 > 20 ) continue; // TMath::Prob(20,5) = 1.25e-03
1089  chi2 += 10*nStaDiff; // nStaDiff is more important than chi2 - this is an empiric choice
1090  OutNeighbour[iT1].push_back( pair<float,int>( chi2, iT2 ) );
1091  InNeighbour[iT2].push_back( pair<float,int>( chi2, iT1 ) );
1092  } // iT2
1093  } // iT1
1094 
1095  // sort by chi2
1096  for ( int iT1 = 0; iT1 < NTracksS; iT1++ ) {
1097  sort( InNeighbour[iT1].begin(), InNeighbour[iT1].end() );
1098  sort( OutNeighbour[iT1].begin(), OutNeighbour[iT1].end() );
1099  }
1100 
1101  // combine best neighbours. TODO: speed up by sorting all pairs together by chi2
1102  bool allPairsFound = false;
1103  while( !allPairsFound ) {
1104  allPairsFound = true;
1105 
1106  // { // dbg
1107  // cout << " new " << endl;
1108  // for ( int iT1 = 0; iT1 < NTracksS; iT1++ ) {
1109  // for( unsigned int iN = 0; iN < InNeighbour[iT1].size(); iN++ ) {
1110  // cout << iT1 << " " << iN << " I " << InNeighbour[iT1][iN].first << " " << InNeighbour[iT1][iN].second << endl;
1111  // }
1112  // for( unsigned int iN = 0; iN < OutNeighbour[iT1].size(); iN++ ) {
1113  // cout << iT1 << " " << iN << " O " << OutNeighbour[iT1][iN].first << " " << OutNeighbour[iT1][iN].second << endl;
1114  // }
1115  // }
1116  // }
1117 
1118  for ( int iT1 = 0; iT1 < NTracksS; iT1++ ) {
1119  PndCATrack& t1 = tracks[iT1];
1120  if ( t1.NHits() <= 0 ) continue;
1121 
1122  // find best unused outer track
1123  int iT2 = -1;
1124  for( unsigned int iN = 0; iN < OutNeighbour[iT1].size(); iN++ ) {
1125  iT2 = OutNeighbour[iT1][iN].second;
1126  if( iT2 >= 0 ) {
1127  break;
1128  }
1129  }
1130  if (iT2 < 0) continue;
1131 
1132  // find best unused inner track for outer track
1133  int iT21 = -1;
1134  for( unsigned int iN = 0; iN < InNeighbour[iT2].size(); iN++ ) {
1135  iT21 = InNeighbour[iT2][iN].second;
1136  if( iT21 >= 0 ) {
1137  break;
1138  }
1139  }
1140  assert(iT21 >= 0); // at least iT1 should be found
1141 
1142  if ( iT1 != iT21 ) {
1143  allPairsFound = false;
1144  continue; // find them at the next iteration
1145  }
1146  PndCATrack& t2 = tracks[iT2];
1147 
1148  // atach track
1149  for ( int ih = 0; ih < t2.NHits(); ih++ ) {
1150  t1.AddHit( t2.IHits()[ih] );
1151  }
1152  t2.IHits().clear();
1153 
1154  // clean connections
1155  for( unsigned int iN = 0; iN < OutNeighbour[iT1].size(); iN++ ) {
1156  const int iT22 = OutNeighbour[iT1][iN].second;
1157  if ( iT22 < 0 ) continue;
1158  for( unsigned int iN2 = 0; iN2 < InNeighbour[iT22].size(); iN2++ ) {
1159  if( InNeighbour[iT22][iN2].second == iT1 ) {
1160  InNeighbour[iT22][iN2].second = -1;
1161  break;
1162  }
1163  }
1164  }
1165  for( unsigned int iN = 0; iN < InNeighbour[iT2].size(); iN++ ) {
1166  const int iT22 = InNeighbour[iT2][iN].second;
1167  if ( iT22 < 0 ) continue;
1168  for( unsigned int iN2 = 0; iN2 < OutNeighbour[iT22].size(); iN2++ ) {
1169  if( OutNeighbour[iT22][iN2].second == iT2 ) {
1170  OutNeighbour[iT22][iN2].second = -1;
1171  break;
1172  }
1173  }
1174  }
1175  for( unsigned int iN = 0; iN < OutNeighbour[iT2].size(); iN++ ) {
1176  const int iT22 = OutNeighbour[iT2][iN].second;
1177  if ( iT22 < 0 ) continue;
1178  for( unsigned int iN2 = 0; iN2 < InNeighbour[iT22].size(); iN2++ ) {
1179  if( InNeighbour[iT22][iN2].second == iT2 ) {
1180  InNeighbour[iT22][iN2].second = iT1;
1181  break;
1182  }
1183  }
1184  }
1185  OutNeighbour[iT1] = OutNeighbour[iT2];
1186  InNeighbour[iT2].clear();
1187  OutNeighbour[iT2].clear();
1188  // check the newly created track
1189  iT1--;
1190  }
1191  } // allPairsFound
1192 
1193  // remove tracks, which were atached to other tracks
1194 
1195  PndCATracks tracks_saved = tracks;
1196  tracks.clear();
1197  for ( int iT1 = 0; iT1 < NTracksS; iT1++ ) {
1198  PndCATrack& t1 = tracks_saved[iT1];
1199  if (t1.NHits() != 0)
1200  tracks.push_back(t1);
1201  }
1202  // currently is not needed
1203 }
1204 
1205 
1206 
1208  PndCATrack &bT, // best track
1209  int currITrip, // index of current triplet
1210  PndCATrack &cT, // current track
1211  unsigned char min_best_l,
1212  const PndCANPlets& triplets,
1213  unsigned int& nCalls)
1214 {
1215 // if (nCalls > 100) return; // avoid long processing in confusing cases
1216  nCalls++;
1217 
1218  const PndCAElementsOnStation<PndCANPlet>& trs = triplets.OnStation( ista );
1219  const PndCANPlet* curr_trip = &(trs[currITrip]);
1220 
1221  if (curr_trip->Level() == 0){ // the end of the track -> check and store
1222 
1223  // -- finish with current track
1224 
1225 // if( cT.Level() < min_best_l - 1 ) return; // suppose that only one hit can be added by extender
1226 // cT.Fit( *trs.HitsRef(), fTarget, GetParameters() ); // fit to determine Chi2 and NDF // takes 20 times more time then the rest
1227 
1228  // -- select the best
1229  if ( (cT.NDF() > bT.NDF()) || ( (cT.NDF() == bT.NDF()) && (cT.Chi2() < bT.Chi2()) ) )
1230  bT = cT;
1231 
1232  } else
1233  { // level != 0
1234 
1235  // try to extend. try all possible triplets
1236  int NNeighs = curr_trip->NNeighbours();
1237  for (int in = 0; in < NNeighs; in++) {
1238  int newITrip = curr_trip->INeighbours(in);
1239  const PndCANPlet* new_trip = &(triplets.OnStation( curr_trip->ISta(0) + StartStationShift )[newITrip]);
1240 
1241  // check new triplet
1242  bool isUsed = false;
1243  const int newTripLength = new_trip->N();
1244  ASSERT( newTripLength - curr_trip->N() >= -1, newTripLength << " - " << curr_trip->N() );
1245  for( int i = curr_trip->N() - 1; i < newTripLength; i++ ) {
1246  if( triplets.OnStation( new_trip->ISta(0) ).GetHit( i, newITrip ).IsUsed() ) {
1247  isUsed = true;
1248  break;
1249  }
1250  }
1251 
1252  if (isUsed) {
1253  // cT.Fit( *trs.HitsRef(), fTarget, GetParameters() ); // fit to determine Chi2 and NDF
1254 
1255  // no used hits allowed -> compare and store track
1256  if ( (cT.NDF() > bT.NDF()) || ( (cT.NDF() == bT.NDF()) && (cT.Chi2() < bT.Chi2()) ) )
1257  bT = cT;
1258  }
1259  else{ // add new triplet to the current track
1260 
1261  // restore current track
1262  // save current tracklet
1263  PndCATrack nT = cT; // new track
1264 
1265  // add new triplet
1266  nT.Level()++;
1267  int start = curr_trip->N() - StartStationShift;
1268  if( start<0 ) start = 0;
1269  for( int i = start; i < newTripLength; i++ ) {
1270  nT.AddHit( new_trip->IHit(i) );
1271  }
1272 
1273  const float qp1 = curr_trip->QMomentum();
1274  const float qp2 = new_trip->QMomentum();
1275  float dqp = fabs(qp1 - qp2);
1276  float Cqp = curr_trip->QMomentumErr();
1277  Cqp += new_trip->QMomentumErr();
1278  dqp = dqp/Cqp;
1279  nT.Chi2() += dqp*dqp;
1280  FindBestCandidate(new_trip->ISta(0), bT, newITrip, nT, min_best_l, triplets, nCalls);
1281  } // add triplet to track
1282  } // for neighbours
1283  } // level = 0
1284 }
1285 
1286 
1287 
1288 
1290 {
1291 
1292  //const PndCAStation &station = GetParameters().Station( iS );
1293 
1294  const PndCAElementsOnStation<PndCAHit>& hs = hits.OnStation(iS);
1295 
1296  r.clear();
1297  r.reserve(hs.size()/float_v::Size + 1);
1298 
1299  TrackHitRecord hitRecord;
1300  hitRecord.fPrevHit = -1;
1301  hitRecord.fStation = iS;
1302 
1303  for( unsigned int iH = 0; iH < hs.size(); iH += float_v::Size ) {
1304  float_m valid = static_cast<float_m>(uint_v::IndexesFromZero() < uint_v(hs.size() - iH) );
1305 
1306  PndCAHitV hit( &(hs[iH]), valid );
1307  PndCATrackParamVector param;
1308  float_m active = hit.IsValid();
1309 
1310  if(1){ // start from target
1311 
1312  //float_v d2QMom_Init=float_v(25.0);
1313  //param.InitCovMatrix(d2QMom_Init);
1314  param.InitByTarget(target);
1315  param.InitDirection( hit.X0() - target.X0(), hit.X1() - target.X1(), hit.X2() - target.X2() );
1316 
1317  param.SetAngle( hit.Angle() );
1318  param.SetISec( hit.ISec() );
1319  active &= param.Transport0ToX( hit.X0(), GetParameters().cBz(), float_m(true) );
1320  active &= param.Filter( hit, GetParameters(), active );
1321 
1322  } else { // start from hit -> does not work for some reason
1323  /*
1324  param.InitByHit( hit, GetParameters(), target.DQMom() );
1325  param.InitDirection( hit.X0() - target.X0(), hit.X1() - target.X1(), hit.X2() - target.X2() ); // works only of t.X() = Y() = 0
1326  param.SetAngle( hit.Angle() );
1327  param.SetISec( hit.ISec() );
1328  active &= param.AddTarget( target, active );
1329  */
1330  }
1331 
1332  if( active.isEmpty() ) continue;
1333  uint_v iHit = uint_v::IndexesFromZero() + iH;
1334  r.resize(r.size()+1);
1335  PndCANPletV &nPlet = r.back();
1336  nPlet.fNHits=1;
1337  nPlet.fParam=param;
1338  nPlet.fIsValid = active;
1339  nPlet.fLastHit = -1;
1340  foreach_bit( unsigned int iBit, active ) {
1341  hitRecord.fIHit = iHit[iBit];
1342  nPlet.fLastHit[iBit] = gTrackHitRecords.size();
1343  gTrackHitRecords.push_back(hitRecord);
1344  }
1345  }
1346 }
1347 
1349  PndCAElementsOnStation<PndCANPletV> &nPlets, int iS, int cellLength )
1350 {
1351  //if( iS<PndCAParameters::NMVDStations ) return;//SG!!
1352 
1355  tmp0.fHitsRef = &hits;
1356  tmp0.fISta = iS;
1357  tmp1.fHitsRef = &hits;
1358  tmp1.fISta = iS;
1359 
1360  PndCAElementsOnStation<PndCANPletV> *rCurr = &tmp0;
1361  PndCAElementsOnStation<PndCANPletV> *rNext = &tmp1;
1362 
1363  Create1Plets( target, hits, *rCurr, iS );
1364 
1365  for( int iLen=1; iLen<=cellLength; iLen++){
1366  if ( rCurr->size() <= 0 ) break;
1367  if ( (*rCurr)[0].N() >= GetParameters().Station( iS ).CellLength ) break;
1368  rNext->clear();
1369  PickUpHits( *rCurr, *rNext, iS+iLen );
1371  rCurr=rNext;
1372  rNext = rr;
1373  //cout<<" station "<<iS<<" created "<<rCurr->size()<<" plets of length "<<iLen<<endl;
1374  }
1375  nPlets = *rCurr;
1376 }
1377 
1378 
1379 struct FitStore{
1380  float_v F0, F1, F2, du, err2U;
1382  int_v fLastHit;
1383  int fNHits;
1384  int_v iHit;
1385 };
1386 
1387 vector<FitStore> store(3000);
1388 
1389 
1391 {
1392 
1393  //new(&r) PndCAElementsOnStation<PndCANPletV>( a.HitsRef() );
1394 
1395  r.SetStation( a.IStation() );
1396  r.clear();
1397 
1398  if ( a.size() <= 0 ) return;
1399 
1400  r.reserve(5*a.size());
1401 
1402  //const float_v Pick2 = float_v(3.5*3.5);//fPick*fPick;
1403  const float_v Pick2 = float_v(10.0*10.0);//fPick*fPick;
1404 
1405  //int iS = a.IStation()+ N-1;
1406 
1407  const PndCAHits* allHits = a.HitsRef();
1408  const PndCAElementsOnStation<PndCAHit> &hits = allHits->OnStationConst( iS );
1409 
1410  const PndCAStation &station = GetParameters().Station( iS );
1411  PndCAStationSTT &stationMy = fStations[iS];
1412 
1413  const float_v p6 = float_v(TMath::TwoPi()/6.);
1414  const float_v p12 = float_v(TMath::TwoPi()/12.);
1415 
1416  if ( station.NDF == 1 ) { // STT tubes
1417 
1418  const float_v sb = stationMy.fSin;
1419  const float_v cb = stationMy.fCos;
1420 
1421  store.resize(1);
1422 
1423  unsigned int vN = 0, vM=0;
1424  float_v err2R = stationMy.fResolution;
1425  for( unsigned int iD1 = 0; iD1 < a.size(); ++iD1 ) {
1426  PndCANPletV& D1 = a[iD1];
1427  float_m valid1G = D1.IsValid();
1428  if( valid1G.isEmpty() ) continue;
1429  PndCATrackParamVector &param = D1.ParamRef();
1431  float_v secAngle = p12+p6*param.ISec();
1432  valid1G &= param.Rotate( -param.Angle() + secAngle, .999f, valid1G );
1433  }
1434  valid1G &= param.Transport0( int_v(iS), GetParameters(), valid1G );
1435  if( valid1G.isEmpty() ) continue;
1436 
1437  D1.SetValid( valid1G );
1438 
1439  const float_v& c00 = param.fC[0];
1440  const float_v& c10 = param.fC[1];
1441  const float_v& c11 = param.fC[2];
1442  const float_v& c20 = param.fC[3];
1443  const float_v& c21 = param.fC[4];
1444 
1445  // F = CH'
1446  const float_v F0 = cb*c00 + sb*c10;
1447  const float_v F1 = cb*c10 + sb*c11;
1448  const float_v F2 = cb*c20 + sb*c21;
1449  const float_v HCH = ( F0*cb + F1*sb );
1450  const float_v err2U = ( HCH + err2R);
1451  const float_v pickUp2 = Pick2*err2U;
1452  float_v trSinPhiU = cb*param.SinPhi() + sb*param.DzDs();
1453  float_v trU = cb*param.Y() + sb*param.Z();
1454  float_v trUCorr = -rsqrt(float_v(1.f) - trSinPhiU*trSinPhiU );
1455 
1456  int secMin = param.fISec.min(valid1G);
1457  int secMax = param.fISec.max(valid1G);
1458 
1459  for( int iSec=secMin; iSec<=secMax; iSec++){
1460 
1461  int_m sectorOK = valid1G & ( int_v(iSec) == param.ISec() );
1462  if( sectorOK.isEmpty() ) continue;
1463 
1464  PndCAStationSTTSector &sector = stationMy.fSectors[iSec];
1465 
1466  //if( sector.fNHits>30 ) continue; //SG!!!
1467  for( int jh=0; jh<sector.fNHits; jh++ ){
1468  PndCAHitSTT &h1d = stationMy.fHits1D[sector.fFirstHit + jh];
1469  //if( iS==18+4 ) cout<<iSec<<" "<<jh<<" "<<h1d.fU<<" "<<h1d.fDR<<endl;
1470  float_v hitU = h1d.fU + h1d.fDR*trUCorr;
1471  const float_v du = trU - hitU;
1472 
1473  float_m active = sectorOK;
1474  active &= ( du*du <= pickUp2 );
1475  if ( active.isEmpty() ) continue;
1476 
1477  //active &= abs( param.fP[2]*err2U - F2*du ) < float_v(.999f)*err2U;
1478  //if( active.isEmpty() ) continue;
1479 
1480  foreach_bit( unsigned int iBit, active ) {
1481  if( vM==float_v::Size ){
1482  vM = 0;
1483  vN++;
1484  store.resize(vN+1);
1485  }
1486  FitStore &s = store[vN];
1487  s.F0[vM] = F0[iBit];
1488  s.F1[vM] = F1[iBit];
1489  s.F2[vM] = F2[iBit];
1490 
1491  s.du[vM] = du[iBit];
1492  s.err2U[vM] = err2U[iBit];
1493  s.iHit[vM] = h1d.fOrigID;
1494  s.fLastHit[vM] = D1.fLastHit[iBit];
1495  s.fNHits = D1.fNHits;
1496  s.param.SetTrackParam( param, vM, iBit );
1497  vM++;
1498  }
1499  } // ih
1500  } // iSec
1501  } // iD1
1502 
1503  for( unsigned int i=0; i<=vN; i++ ){
1504  if( i==vN && vM==0 ) break;
1505  FitStore &s = store[i];
1506  TrackHitRecord hitRecord;
1507  hitRecord.fStation = iS;
1508  r.resize( r.size()+1 );
1509  PndCANPletV &nPlet = r.back();
1510  nPlet.fLastHit = int_v(-1);
1511  nPlet.fNHits = s.fNHits+1;
1512  nPlet.fParam = s.param;
1513  unsigned int nBit = (i<vN) ?( (unsigned int)float_v::Size ) :vM;
1514 
1515  nPlet.fIsValid = (uint_v::IndexesFromZero()<nBit);
1516 
1517  for( unsigned int iBit=0; iBit<nBit; iBit++ ){
1518  hitRecord.fIHit = s.iHit[iBit];
1519  hitRecord.fPrevHit = s.fLastHit[iBit];
1520  nPlet.fLastHit[iBit] = gTrackHitRecords.size();
1521  gTrackHitRecords.push_back(hitRecord);
1522  }
1523 
1524  PndCATrackParamVector &p = nPlet.fParam;
1525  const float_v& c30 = p.fC[6];
1526  const float_v& c31 = p.fC[7];
1527  const float_v& c40 = p.fC[10];
1528  const float_v& c41 = p.fC[11];
1529 
1530  const float_v zeta = s.du;
1531  const float_v wi = float_v(1.f)/s.err2U;
1532  const float_v zetawi = zeta * wi;
1533 
1534  const float_v F0 = s.F0;
1535  const float_v F1 = s.F1;
1536  const float_v F2 = s.F2;
1537  const float_v F3 = cb*c30 + sb*c31;
1538  const float_v F4 = cb*c40 + sb*c41;
1539 
1540  const float_v K0 = F0*wi;
1541  const float_v K1 = F1*wi;
1542  const float_v K2 = F2*wi;
1543  const float_v K3 = F3*wi;
1544  const float_v K4 = F4*wi;
1545 
1546  p.fNDF += 1;
1547  p.fChi2 += zeta * zetawi;
1548 
1549  p.fP[ 0] += - F0*zetawi;
1550  p.fP[ 1] += - F1*zetawi;
1551  p.fP[ 2] += - F2*zetawi;
1552  p.fP[ 3] += - F3*zetawi;
1553  p.fP[ 4] += - F4*zetawi;
1554 
1555  p.fC[ 0] -= K0*F0;
1556 
1557  p.fC[ 1] -= K1*F0;
1558  p.fC[ 2] -= K1*F1;
1559 
1560  p.fC[ 3] -= K2*F0;
1561  p.fC[ 4] -= K2*F1;
1562  p.fC[ 5] -= K2*F2;
1563 
1564  p.fC[ 6] -= K3*F0;
1565  p.fC[ 7] -= K3*F1;
1566  p.fC[ 8] -= K3*F2;
1567  p.fC[ 9] -= K3*F3;
1568 
1569  p.fC[10] -= K4*F0;
1570  p.fC[11] -= K4*F1;
1571  p.fC[12] -= K4*F2;
1572  p.fC[13] -= K4*F3;
1573  p.fC[14] -= K4*F4;
1574  }
1575 
1576  } else { // NDF = 2
1577  //return;
1578  for( unsigned int iD1 = 0; iD1 < a.size(); ++iD1 ) {
1579  PndCANPletV& D1 = a[iD1];
1580  float_m valid1G = D1.IsValid();
1581  if( valid1G.isEmpty() ) continue;
1582  //PndCATrackParamVector &param = D1.ParamRef();
1583  //valid1G &= param.Transport( int_v(iS), GetParameters(), valid1G );
1584  //D1.SetValid( valid1G );
1585 
1586  for( unsigned int ih=0; ih<hits.size(); ih++ ){
1587  const PndCAHit &hit = hits[ih];
1588  float_m active = valid1G;// & ( abs(hit.Angle() - param.Angle())<.1f );
1589  PndCATrackParamVector param = D1.ParamRef();
1590  active &= param.Transport0( hit, GetParameters(), valid1G );
1591 
1592  if ( active.isEmpty() ) continue;
1593  const float_v dx1 = hit.X1() - param.X1();
1594  active &= dx1*dx1 < Pick2*(param.Err2X1() + hit.Err2X1());
1595  const float_v dx2 = hit.X2() - param.X2();
1596  active &= dx2*dx2 < Pick2*(param.Err2X2() + hit.Err2X2());
1597  if ( active.isEmpty() ) continue;
1598  active &= param.Accept( hit, GetParameters(), active, TRIPLET_CHI2_CUT );
1599  if ( active.isEmpty() ) continue;
1600  PndCATrackParamVector param1 = param;
1601  active &= param1.Filter( hit, GetParameters(), active, TRIPLET_CHI2_CUT );
1602  if ( active.isEmpty() ) continue;
1603 
1604  TrackHitRecord hitRecord;
1605  hitRecord.fStation = iS;
1606  hitRecord.fIHit = ih;
1607  param1.fISec = hit.fISec;
1608  PndCANPletV nPlet( D1, param1, active );
1609  nPlet.fLastHit = -1;
1610  foreach_bit( unsigned int iBit, active ) {
1611  nPlet.fLastHit[iBit] = gTrackHitRecords.size();
1612  hitRecord.fPrevHit = D1.fLastHit[iBit];
1613  gTrackHitRecords.push_back(hitRecord);
1614  }
1615  r.push_back( nPlet );
1616  } //
1617  } //
1618 
1619  }
1620 
1621 }
1622 
void SetValid(float_m v)
Definition: PndCANPletsV.h:32
void Add(string name)
Definition: PndCATimer.h:54
const PndCAHit & Hit(int iH, int iT) const
Definition: PndCATracks.h:88
float fAngle
Definition: PndCAHits.h:78
void MultiplyMS(float const C[5][5], float const V[15], float K[15]) const
Double_t p
Definition: anasim.C:58
const unsigned int & INeighbours(int i) const
Definition: PndCANPlets.h:51
friend F32vec4 cos(const F32vec4 &a)
Definition: P4_F32vec4.h:112
int ISta(int IH) const
Definition: PndCANPlets.h:36
const int StartStationShift
cout<<"the track theta is "<< trackthe<< endl;mc_x[j]=vecmc.X();mc_y[j]=vecmc.Y();mc_z[j]=vecmc.Z()-1110;r_mc[j]=TMath::Sqrt(mc_x[j]*mc_x[j]+mc_y[j]*mc_y[j]);std::cout<<"the r_mc[j] is "<< r_mc[j]<< std::endl;std::cout<<"the mc_z[j] is "<< mc_z[j]<< std::endl;r_mc_err[j]=0;z_mc_err[j]=0;rc_x[j]=vecrc.X();rc_y[j]=vecrc.Y();rc_z[j]=vecrc.Z()-1110;r_rc[j]=TMath::Sqrt(rc_x[j]*rc_x[j]+rc_y[j]*rc_y[j]);std::cout<<"the r_rc[j] is "<< r_rc[j]<< std::endl;std::cout<<"the rc_z[j] is "<< rc_z[j]<< std::endl;r_rc_err[j]=0;z_rc_err[j]=0;double tempmc=TMath::Sqrt(mc_x[0]*mc_x[0]+mc_y[0]*mc_y[0]);mcfirstthe=TMath::ATan(tempmc/(mc_z[0]+1110));cout<<"the first hit theta is "<< mcfirstthe<< endl;}TGraphErrors *mctrack=new TGraphErrors(4, mc_z, r_mc, z_mc_err, r_mc_err);mctrack-> Fit("trackFit","ONF")
PndCATrackParamVector param
void InitByTarget(const PndCATarget &target)
TCanvas * c11
float Angle() const
Definition: PndCAHits.h:51
Int_t t2
Definition: hist-t7.C:106
double r
Definition: RiemannTest.C:14
float_m fIsValid
Definition: PndCANPletsV.h:38
TObjArray * d
bool Transport(const PndCAHit &hit, float Bz)
unsigned short fIHit
float_m Rotate(const float_v &alpha, PndCATrackLinearisationVector &t0, const float maxSinPhi=.999f, const float_m &mask=float_m(true))
int IRow() const
Definition: PndCAGBHit.h:57
float ErrX12() const
Definition: PndCAGBHit.h:54
float_m Transport0ToX(const float_v &x, const float_v &Bz, const float_m &mask)
void Add(string name)
Definition: PndCATimer.h:91
float Chi2() const
unsigned int NNeighbours() const
Definition: PndCANPlets.h:53
Int_t i
Definition: run_full.C:25
__m128 m
Definition: P4_F32vec4.h:28
TTree * b
PndCATFIterTimerInfo fStatGTi
void SetAngle(const float_v &v)
TFile * file
void SetSignCosPhi(const float_v &v)
double fStatTime[fNTimers]
int FirstHitRef() const
Definition: PndCAGBTrack.h:31
exit(0)
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:29
bool IsRightNeighbour(const PndCANPlet &a, const PndCANPlet &b, float pick, float &chi2)
void SetChi2(const float_v &v)
char & NDF()
Definition: PndCATracks.h:35
const float * Par() const
friend F32vec4 sin(const F32vec4 &a)
Definition: P4_F32vec4.h:111
TLorentzVector s
Definition: Pnd2DStar.C:50
TCanvas * c10
int N() const
Definition: PndCANPletsV.h:26
float X2() const
Definition: PndCAHits.h:36
float U() const
Definition: PndCAHits.h:44
PndCATFIterTimerInfo fGTi
PndCATFTimerInfo fTi
TCanvas * c21
const PndCAStation & Station(short i) const
Definition: PndCAParam.h:46
PndCAParam fParameters
PndCAElementsOnStation< T > & OnStation(char i)
Definition: PndCAHits.h:107
const char & IStation() const
float_v X1() const
Definition: PndCAHitsV.h:44
float DR() const
Definition: PndCAHits.h:43
float Angle() const
Definition: PndCAGBHit.h:92
void MultiplySR(float const C[15], float const r_in[5], float r_out[5]) const
void SetErr2X0(float v)
Definition: PndCAGBHit.h:86
void SetNIter(int n)
Definition: PndCATimer.h:83
float X2() const
Definition: PndCATarget.h:25
float X1() const
Definition: PndCAHits.h:35
void MultiplySS(float const C[15], float const V[15], float K[5][5]) const
const PndCAHits * fHitsRef
Int_t t1
Definition: hist-t7.C:106
PndCAStripInfo f
Definition: PndCAStation.h:21
void SetISec(const int_v &v)
PndCANPlets(int nSta, const PndCAHits *hits)
Definition: PndCANPlets.h:84
int Pic_FED Eff_lEE C()
float_m Filter(const PndCAHitV &hit, const PndCAParam &param, const float_m &mask=float_m(true), const float_v &chi2Cut=10e10f)
int Id() const
Definition: PndCAHits.h:30
void FindBestCandidate(int ista, PndCATrack &best_tr, int currITrip, PndCATrack &curr_tr, unsigned char min_best_l, const PndCANPlets &triplets, unsigned int &nCalls)
void SetTrackParam(const PndCATrackParamVector &param, const float_m &m=float_m(true))
void Create1Plets(const PndCATarget &target, const PndCAHits &hits, PndCAElementsOnStation< PndCANPletV > &singlets, int iStation)
float_m IsValid() const
Definition: PndCAHitsV.h:30
float_m Transport0(const int_v &ista, const PndCAParam &param, const float_m &mask=float_m(true))
int_v ISec() const
Definition: PndCAHitsV.h:54
float Err2X1() const
Definition: PndCAHits.h:38
void SetErrX12(float v)
Definition: PndCAGBHit.h:88
int_v fLastHit
Definition: PndCANPletsV.h:35
Int_t a
Definition: anaLmdDigi.C:126
float_m Accept(const PndCAHit &hit, const PndCAParam &param, const float_m &mask=float_m(true), const float_v &chi2Cut=10e10f) const
float Err2X2() const
Definition: PndCAGBHit.h:55
void PickUpHits(PndCAElementsOnStation< PndCANPletV > &a, PndCAElementsOnStation< PndCANPletV > &r, int iS)
PndCAHits * HitsRef()
Definition: PndCATracks.h:93
#define W
Definition: createSTT.C:76
const PndCATrackParamVector & Param() const
Definition: PndCANPletsV.h:28
int nHits
Definition: RiemannTest.C:16
Int_t t0
Definition: hist-t7.C:106
PndCATrackParamVector fParam
Definition: PndCANPletsV.h:37
float fDR
Definition: PndCAHits.h:74
void SetErr2X1(float v)
Definition: PndCAGBHit.h:87
vector< PndCATES > fIHit
Definition: PndCANPlets.h:71
void SetNHits(int v)
Definition: PndCAGBTrack.h:38
const PndCAElementsOnStation< T > & OnStationConst(char i) const
Definition: PndCAHits.h:109
PndCAElementsOnStation< PndCANPlet > & OnStation(char i)
void SetCov(int i, const float_v &v)
bool ReadHitsFromFile(string prefix)
float Err2X2() const
Definition: PndCAHits.h:40
friend F32vec4 rsqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:32
TStopwatch timer
Definition: hit_dirc.C:51
bool SINGLE_THREADED
float X0() const
Definition: PndCATarget.h:23
float QMomentum() const
Definition: PndCANPlets.h:41
float fU
Definition: PndCAHits.h:74
const float * Cov() const
float_v X2() const
Definition: PndCAHitsV.h:45
PndCAGBTrack * fTracks
void SetInnerParam(const PndCATrackParam &v)
Definition: PndCAGBTrack.h:40
int NHits() const
TFile * f
Definition: bump_analys.C:12
void InitDirection(float_v r0, float_v r1, float_v r2)
void WriteSettings(std::ostream &out) const
vector< PndCAGBHit > fHits
float fR
Definition: PndCAHits.h:71
bool SaveTracksInFile(string prefix) const
vector< FitStore > store(3000)
friend F32vec4 fabs(const F32vec4 &a)
Definition: P4_F32vec4.h:47
TFile * out
Definition: reco_muo.C:20
const float & Chi2Neighbours(int i) const
Definition: PndCANPlets.h:52
float fX1
Definition: PndCAHits.h:68
void SetHits(std::vector< PndCAGBHit > &hits)
void Merge(PndCATracks &tracks)
void FindNeighbours(PndCANPlets &triplets)
vector< PndCAHitSTT > fHits1D
vector< TrackHitRecord > gTrackHitRecords
void ConvertTrackParamToVector(PndCATrackParam t0[uint_v::Size], PndCATrackParamVector &t, int &nTracksV)
TPad * p2
Definition: hist-t7.C:117
float cBz() const
Definition: PndCAParam.h:49
float QMomentumErr2() const
Definition: PndCANPlets.h:43
int N() const
Definition: PndCANPlets.h:33
double X
Definition: anaLmdDigi.C:68
float Err2R() const
Definition: PndCAGBHit.h:61
void CreateTracks(const PndCANPlets &triplets, PndCATracks &tracks)
TCanvas * c20
char & Level()
Definition: PndCANPlets.h:45
vector< pair< float, unsigned int > > & Neighbours()
Definition: PndCANPlets.h:54
vector< PndCATES > & IHits()
Definition: PndCATracks.h:21
void InvertCholetsky(float a[15]) const
float QMomentumErr() const
Definition: PndCANPlets.h:42
void PrintReal(int f=0)
Definition: L1Timer.h:68
void SetX(const float_v &v)
int fISec
Definition: PndCAHits.h:76
float & Chi2Level()
Definition: PndCANPlets.h:48
float_v Angle() const
Definition: PndCAHitsV.h:59
void WriteEvent(FILE *out) const
void SetIsLeft(bool v)
Definition: PndCAGBHit.h:96
static float TwoPi()
Definition: PndCAMath.h:61
PndCATFTimerInfo fStatTi
PndCATrackParamVector & ParamRef()
Definition: PndCANPletsV.h:29
#define ASSERT(v, msg)
Definition: PndCADef.h:56
PndMultiFieldPar * Par
Definition: sim_emc_apd.C:115
float_m IsValid() const
Definition: PndCANPletsV.h:31
PndCAStationSTT fStations[50]
bool IsLeft() const
Definition: PndCAHits.h:48
double Chi2(const double *xx)
void FilterTracks(float const r[5], float const C[15], float const m[5], float const V[15], float R[5], float W[15], float &chi2) const
const PndCATrackParam Fit(const PndCAHits &hits, const PndCATarget &target, const PndCAParam &caParam, bool dir=true)
Definition: PndCATracks.h:122
void SetErr2X2(float v)
Definition: PndCAGBHit.h:89
void SetPar(int i, const float_v &v)
void PrintReal()
Definition: L1Timer.h:116
TPad * p1
Definition: hist-t7.C:116
void SetOuterParam(const PndCATrackParam &v)
Definition: PndCAGBTrack.h:41
float R() const
Definition: PndCAHits.h:42
void CreateNPlets(const PndCATarget &target, const PndCAHits &hits, PndCAElementsOnStation< PndCANPletV > &triplets, int iStation, int cellLength)
bool fIsLeft
Definition: PndCAHits.h:75
TTree * t
Definition: bump_analys.C:13
void SetIRow(int v)
Definition: PndCAGBHit.h:83
int NHits() const
Definition: PndCATracks.h:19
const PndCAHits * HitsRef() const
float_v TRIPLET_CHI2_CUT
PndSdsMCPoint * hit
Definition: anasim.C:70
CbmHit * hits[nHits]
Definition: RiemannTest.C:19
float & Chi2()
Definition: PndCATracks.h:33
double fSliceTrackerCpuTime
float Err2X1() const
Definition: PndCAGBHit.h:53
PndCATarget fTarget
Int_t rec
Definition: autocutx.C:47
PndPidEmcAssociatorTask * ts
int NHits() const
Definition: PndCAGBTrack.h:30
const PndCATrackParam & Param() const
Definition: PndCANPlets.h:38
Double_t R
Definition: checkhelixhit.C:61
void SetFirstHitRef(int v)
Definition: PndCAGBTrack.h:39
const PndCAParam & GetParameters() const
char IStation() const
Definition: PndCAHits.h:28
int Nint(float x)
Definition: PndCAMath.h:117
float X1() const
Definition: PndCATarget.h:24
int NStations() const
void AddHit(char iS, int iH)
Definition: PndCATracks.h:24
float_v X0() const
Definition: PndCAHitsV.h:43
void SaveHitsInFile(string prefix) const
const PndCATES & IHit(int IH) const
Definition: PndCANPlets.h:35
char & Level()
Definition: PndCATracks.h:37
PndCAStationSTTSector fSectors[fgNSectors]
void ReadSettings(std::istringstream &in)
double fSliceTrackerTime