FairRoot/PandaRoot
PndFTSCAGBTracker.cxx
Go to the documentation of this file.
1 // $Id: PndFTSCAGBTracker.cxx,v 1.16 2016/12/22 11:45:25 mpugach Exp $
2 // **************************************************************************
3 // This file is property of and copyright by the FIAS PANDA group *
4 // PANDA Experiment at FIAS-GSI, All rights reserved. *
5 // *
6 // Primary Authors: Ivan Kisel <I.Kisel@compeng.uni-frankfurt.de> *
7 // Igor Kulakov <I.Kulakov@gsi.de> *
8 // Mykhailo Pugach <M.Pugach@gsi.de> *
9 // Maksym Zyzak <M.Zyzak@gsi.de> *
10 // for The FIAS PANDA group . *
11 // *
12 // Permission to use, copy, modify and distribute this software and its *
13 // documentation strictly for non-commercial purposes is hereby granted *
14 // without fee, provided that the above copyright notice appears in all *
15 // copies and that both the copyright notice and this permission notice *
16 // appear in the supporting documentation. The authors make no claims *
17 // about the suitability of this software for any purpose. It is *
18 // provided "as is" without express or implied warranty. *
19 // *
20 //***************************************************************************
21 
22 
23 #ifdef DRAW
24 #include "PndFTSCADisplay.h"
25 #define MAIN_DRAW
26 #define DRAW_FIT
27 #define USE_CA_FIT //25.01.17
28 // #define DRAW_FIT_LOCAL
29 #define DRAW_CA
30 #endif //DRAW
31 
32 #ifdef STAR_HFT
33  #define START_FROM_TARGET // how to fit
34 #elif defined(PANDA_STT) || defined(PANDA_FTS)
35  #define START_FROM_TARGET
36  #define USE_CA_FIT //14.02.17
37 #else
38 #endif
39 
40 #include "PndFTSCAGBTracker.h"
41 #include "PndFTSCAGBHit.h"
42 #include "PndFTSCAGBTrack.h"
43 // #include "PndFTSCATrackParam.h"
44 #include "PndFTSArray.h"
45 #include "PndFTSCAMath.h"
46 #if !defined(PANDA_FTS)
48 #endif
49 #include "PndFTSCAPerformance.h"
50 #include "TStopwatch.h"
51 #include "L1Timer.h"
52 
53 #include "FTSCATarget.h"
54 #include "FTSCAHits.h"
55 #include "FTSCAHitsV.h"
56 #include "FTSCATracks.h"
57 
58 #include "Math/SMatrix.h"
59 #include "TMatrixD.h"
60 #include "TVectorD.h"
61 
62 
63 #include <algorithm>
64 #include <fstream>
65 #include <iostream>
66 #include <sstream>
67 using namespace std;
68 
69 //TODO DELL ME!!!
70 #include "PndFTSCAPerformance.h"
71 #include "PndFTSCAMCPoint.h"
72 #include "PndFTSPerformanceBase.h"
73 
74 
75 bool SINGLE_THREADED = false;
76 
78  :
79  fHits( 0 ),
80  fNHits( 0 ),
81  fTrackHits( 0 ),
82  fTracks( 0 ),
83  fNTracks( 0 ),
84  fTime( 0 ),
85  fStatNEvents( 0 ),
86  fSliceTrackerTime( 0 ),
87  fSliceTrackerCpuTime( 0 ),
88  fGTi(),
89  fTi(fNFindIterations),
90  fStatGTi(),
91  fStatTi(fNFindIterations)
92 {
93  //* constructor
94 
95  for ( int i = 0; i < 20; i++ ) fStatTime[i] = 0;
96 
97 
98  fGTi.Add("init ");
99  fGTi.Add("iters ");
100  fGTi.Add("tracker");
101  fGTi.Add("fitter ");
102 
103  fTi.SetNIter( fNFindIterations ); // for iterations
104  fTi.Add("init ");
105 
106  fTi.Add("1plet ");
107  fTi.Add("2plet ");
108  fTi.Add("3plet ");
109  fTi.Add("4plet ");
110  fTi.Add("5plet ");
111  fTi.Add("6plet ");
112  fTi.Add("convrt");
113 
114  fTi.Add("plets ");
115 
116  fTi.Add("nghbrs");
117  fTi.Add("tracks");
118  fTi.Add("merger");
119  fTi.Add("finish");
120 
121  fStatGTi = fGTi;
122  fStatTi = fTi;
123 }
124 
126 {
127  fNHits = 0;
128  fTrackHits = 0;
129  fTracks = 0;
130  fNTracks = 0;
131  fTime = 0.;
132  fStatNEvents = 0;
133  fSliceTrackerTime = 0.;
135  for ( int i = 0; i < 20; ++i ) {
136  fStatTime[i] = 0.;
137  }
138 }
139 
141 {
142  StartEvent();
143 }
144 
146 {
147  //* clean up track and hit arrays
148  if(fTrackHits) delete[] fTrackHits;
149  fTrackHits = 0;
150  if(fTracks) delete[] fTracks;
151  fTracks = 0;
152  fNHits = 0;
153  fNTracks = 0;
154 }
155 
156 
158 {
159  //* set the number of hits
160  fHits.Resize( nHits );
161  fNHits = nHits;
162 }
163 
165 {
166  //* Creation of ideal tracks based on hits, which correspond to the MC-points.
167 
168  PndFTSCAPerformance* perf = &PndFTSCAPerformance::Instance();
169 
170  if (fHits.Size() > 0)
171  sort( &(fHits[0]), &(fHits[fHits.Size()-1]), PndFTSCAGBHit::Compare );
172 
173  const int NMCTracks = perf->GetMCTracks()->Size();
174  vector<vector<int> > hits(NMCTracks+1);
175 
176  for(int iH=0; iH<fHits.Size(); iH++)
177  {
178  int id = fHits[iH].ID();
179  int trackId = perf->HitLabel(id).fLab[0];
180  for( int k = 1; k < 3 && trackId < 0; k++ )
181  trackId = perf->HitLabel(id).fLab[k];
182  if ( trackId < 0 ) continue;
183  hits[trackId].push_back(iH);
184  }
185 
186  int nTracks = NMCTracks;
187 
188  if(fTracks) delete [] fTracks;
189  fTracks = new PndFTSCAGBTrack[nTracks];
190  fNTracks = nTracks;
191 
192  if(fTrackHits) delete [] fTrackHits;
193  fTrackHits = new int[fHits.Size()];
194 
195  int curHit = 0;
196  int curTr = 0;
197 
198  for(int iT=0; iT<NMCTracks; iT++)
199  {
200  if ( hits[iT].size() < PndFTSCAParameters::MinimumHitsForRecoTrack ) continue;
201 
202  int nFirstMC = (*perf->GetMCTracks())[iT].FirstMCPointID();
203  //21.03 int nMCPoints = (*perf->GetMCTracks())[iT].NMCPoints();
204  fTracks[curTr].SetFirstHitRef( curHit );
205  //begin:mod
206  //21.03 PndFTSCAMCTrack curMcTrack = perf->MCTrack(curTr);
207  //21.03 int idmcpoint = curMcTrack.FirstMCPointID();
208  PndFTSCALocalMCPoint *points = &((*perf->GetMCPoints()).Data()[nFirstMC]);
209  PndFTSCATrackParam mcTrackParam;
210  // USING AS INITIAL APPROXIMATION MC-INFO
211  mcTrackParam.SetX(points[0].X());
212  mcTrackParam.SetY(points[0].Y());
213  mcTrackParam.SetTX(points[0].Px()/points[0].Pz());
214  mcTrackParam.SetTY(points[0].Py()/points[0].Pz());
215  mcTrackParam.SetQP(points[0].QP()); //(1/abs(curMcTrack.P()));
216  mcTrackParam.SetZ(points[0].Z());
217  fTracks[curTr].SetInnerParam(mcTrackParam);
218  //fTracks[curTr].SetOuterParam(mcTrackParam);
219  //end:mod
220  //fTracks[curTr].SetTrackHitIdsArraySize(hits[iT].size());
221  int curStation = -1;
222  int nHits = 0;
223  for(unsigned int iH=0; iH<hits[iT].size(); iH++)
224  {
225  int iStation = fHits[ hits[iT][iH] ].IRow();
226  if(iStation <= curStation) continue;
227 
228  fTrackHits[curHit] = hits[iT][iH];
229  //fTracks[curTr].SetHitID(iH,hits[iT][iH]);
230  curHit++;
231  nHits++;
232  curStation = iStation;
233  }
234  fTracks[curTr].SetNHits( nHits );
235  curTr++;
236  }
237  fNTracks = curTr;
238 }
239 
241 {
242  //* This function calls either the function FitTrack or FitTrackCA (ifndef USE_CA_FIT) for
243  //* fitting tracks and displays information on the screen.
244  //std::cout << "fNTracks " << fNTracks << std::endl;
245  cout<<"Fitting tracks \n";
246  for(int iTr=0; iTr<fNTracks; iTr+=uint_v::Size)
247  {
248  int nTracksVector = uint_v::Size;
249 
250  if( iTr + uint_v::Size >= fNTracks)
251  nTracksVector = fNTracks - iTr;
252 // for(int iTr=0; iTr<fNTracks; iTr+=1)
253 // {
254 // int nTracksVector = 1;
255 
256  uint_v::Memory nTrackHits;
257  uint_v::Memory memFirstHits;
258  nTrackHits = uint_v(Vc::Zero);
259  memFirstHits = uint_v(Vc::Zero);
260 
261  PndFTSCATrackParam startPoint[uint_v::Size];
262  PndFTSCATrackParam endPoint[uint_v::Size];
263 
264  for(int iv=0; iv<nTracksVector; iv++)
265  {
266  nTrackHits[iv] = fTracks[iTr+iv].NHits();
267  //if we want to consider 6plets starting from the first hit as tracks
268  //if (nTrackHits[iv]>6)
269  //nTrackHits[iv]=6;
270  memFirstHits[iv] = fTracks[iTr+iv].FirstHitRef();
271  startPoint[iv] = fTracks[iTr+iv].InnerParam();
272  endPoint[iv] = startPoint[iv];
273  }
274 
275 #ifdef DRAW_FIT
276  PndFTSCAPerformance* perf = &PndFTSCAPerformance::Instance();
277 
279  uint_v nHitsDraw(nTrackHits);
280 
281  for(unsigned int ihit = 0; ihit<nHitsDraw.max(); ihit++)
282  {
283  for(unsigned int iV=0; iV<nTracksVector; iV++)
284  {
285  if( ihit > nTrackHits[iV] - 1) continue;
286  const unsigned int jhit = ihit;
287  PndFTSCAGBHit &h = fHits[fTrackHits[memFirstHits[iV] + jhit]];
288 #ifdef DRAW_FIT_LOCAL
289  {
290  float xLoc, yLoc, zLoc;
291  PndFTSCAParameters::GlobalToCALocal( h.X(), h.Y(), h.Z(), h.Angle(), xLoc, yLoc, zLoc );
292  PndFTSCADisplay::Instance().DrawGBPoint( xLoc, yLoc, zLoc, kGreen+1);
293  }
294 
295  const int iMCP = perf->GetMCPoint( h );
296  if (iMCP < 0) continue;
297  const PndFTSCALocalMCPoint &mcPoint = (*perf->GetMCPoints())[iMCP];
298  {
299  float xLoc, yLoc, zLoc;
300  PndFTSCAParameters::GlobalToCALocal( mcPoint.X(), mcPoint.Y(), mcPoint.Z(), h.Angle(), xLoc, yLoc, zLoc );
301  PndFTSCADisplay::Instance().DrawGBPoint( xLoc, yLoc, zLoc, kRed, (Size_t)1);
302  }
303 #else
304  PndFTSCADisplay::Instance().DrawGBPoint(h.X(), h.Y(), h.Z(), h.Angle(), kGreen+1);
305 #endif
306  }
307  }
308 
309  uint_m mcmask(true);
310 
311  foreach_bit(unsigned int iV, mcmask){
312  if (mcmask[iV]==0) continue;
313  PndFTSCAGBHit &hh = fHits[fTrackHits[memFirstHits[iV] ]];
314 
315  const PndFTSPerformanceBase::PndFTSCAHitLabel &l = perf->HitLabel( hh.ID() );
316  const int MCIndex = l.fLab[0];
317  if(MCIndex>-1)
318  {
319  PndFTSCAMCTrack &mc = (*perf->GetMCTracks())[MCIndex];
320  for( int iP = 0; iP < mc.NMCPoints(); iP++ ) {
321  PndFTSCALocalMCPoint mcPoint = (*perf->GetMCPoints())[mc.FirstMCPointID()+iP];
322 #ifdef DRAW_FIT_LOCAL
323  // float xLoc, yLoc, zLoc;
324  // PndFTSCAParameters::GlobalToCALocal( mcPoint.X(), mcPoint.Y(), mcPoint.Z(), mcPoint.Angle(), xLoc, yLoc, zLoc );
325  // PndFTSCADisplay::Instance().DrawGBPoint( xLoc, yLoc, zLoc, kRed, (Size_t)1);
326 #else
327  double mcX0 = mcPoint.X();
328  double mcY0 = mcPoint.Y();
329  double mcZ = mcPoint.Z();
330  PndFTSCADisplay::Instance().DrawGBPoint((float)mcX0, (float)mcY0, (float)mcZ, kOrange+1, (Size_t)1);
331 #endif
332  }
333  }
334  }
336 #endif
337 
338  PndFTSCATrackParamVector vStartPoint;
339  PndFTSCATrackParamVector vEndPoint;
340  vStartPoint.ConvertTrackParamToVector(startPoint, nTracksVector);
341  vEndPoint.ConvertTrackParamToVector(endPoint, nTracksVector);
342 
343  float_m active0 = static_cast<float_m>( uint_v( Vc::IndexesFromZero ) < nTracksVector );
344 
345  uint_v firstHits(memFirstHits);
346 
347  float_m fitted = float_m(true);
348  fitted &= static_cast<float_m>(static_cast<uint_v>(nTrackHits) > 0);
349 #ifdef USE_CA_FIT
350 #ifdef DRAW_FIT1
351  // PndFTSCADisplay::Instance().ClearView();
352  // PndFTSCADisplay::Instance().SetTPCView();
353  // PndFTSCADisplay::Instance().DrawTPC();
354 
355  PndFTSCADisplay::Instance().DrawGBPoint(0,0,0, kMagenta, 0.5); // target
356 
358 #endif
359  for (unsigned int i=0; i<1; i++){
360  vEndPoint = vStartPoint;
361  vEndPoint.SetCov( 0, 1.f);
362  vEndPoint.SetCov( 1, 0.f);
363  vEndPoint.SetCov( 2, 10.f);
364  vEndPoint.SetCov( 3, 0.f);
365  vEndPoint.SetCov( 4, 0.f);
366  vEndPoint.SetCov( 5, 1.f);
367  vEndPoint.SetCov( 6, 0.f);
368  vEndPoint.SetCov( 7, 0.f);
369  vEndPoint.SetCov( 8, 0.f);
370  vEndPoint.SetCov( 9, 1.f);
371  vEndPoint.SetCov( 10, 0.f);
372  vEndPoint.SetCov( 11, 0.f);
373  vEndPoint.SetCov( 12, 0.f);
374  vEndPoint.SetCov( 13, 0.f);
375  vEndPoint.SetCov( 14, 10.f);
376  vEndPoint.SetChi2( 0.f);
377  vEndPoint.SetNDF(-5);
378 
379  vEndPoint.SetDirection(true);
380 
381  bool init = false;
382  if(i==0)
383  init = true;
384 
385  fitted &= FitTrackCA( vEndPoint, firstHits, nTrackHits, nTracksVector, active0, 0, init );
386  vStartPoint = vEndPoint;
387  /*cout<<"End of fit in >> direction\n";
388  cout<<vEndPoint<<endl;
389  PndFTSCADisplay::Instance().Ask();*/
390 
391  vStartPoint.SetCov( 0, 1.0f);
392  vStartPoint.SetCov( 1, 0.f);
393  vStartPoint.SetCov( 2, 10.0f);
394  vStartPoint.SetCov( 3, 0.f);
395  vStartPoint.SetCov( 4, 0.f);
396  vStartPoint.SetCov( 5, 1.f);
397  vStartPoint.SetCov( 6, 0.f);
398  vStartPoint.SetCov( 7, 0.f);
399  vStartPoint.SetCov( 8, 0.f);
400  vStartPoint.SetCov( 9, 1.f);
401  vStartPoint.SetCov( 10, 0.f);
402  vStartPoint.SetCov( 11, 0.f);
403  vStartPoint.SetCov( 12, 0.f);
404  vStartPoint.SetCov( 13, 0.f);
405  vStartPoint.SetCov( 14, 10.f);
406  vStartPoint.SetChi2( 0.f);
407  vStartPoint.SetNDF(-5);
408  vStartPoint.SetDirection(false);
409 
410  fitted &= FitTrackCA( vStartPoint, firstHits, nTrackHits, nTracksVector,active0, 1 );
411 
412  /*cout<<"End of fit in << direction\n";
413  cout<<vStartPoint<<endl;
414  PndFTSCADisplay::Instance().Ask();*/
415  }
416 #else // USE_CA_FIT
417  {
418  InitialTrackApproximation( vStartPoint, firstHits, nTrackHits, nTracksVector, active0);
419  for(int iTimes = 0; iTimes<1; iTimes++)
420  {
421  vEndPoint = vStartPoint;
422  //refit in the forward direction: going from the first hit to the last, mask "fitted" marks with 0 tracks, which are not fitted correctly
423  fitted &= FitTrack( vEndPoint, firstHits, nTrackHits, nTracksVector,active0, 0 );
424 #ifdef DRAW_FIT1
425  // PndFTSCADisplay::Instance().ClearView();
426  // PndFTSCADisplay::Instance().SetTPCView();
427  // PndFTSCADisplay::Instance().DrawTPC();
428 
429  for(int ihit = 0; ihit<nHitsDraw.max(); ihit++)
430  {
431  for(int iV=0; iV<nTracksVector; iV++)
432  {
433  if( ihit > nTrackHits[iV] - 1) continue;
434  const int jhit = ihit;
435  PndFTSCAGBHit &h = fHits[fTrackHits[memFirstHits[iV] + jhit]];
436 #ifdef DRAW_FIT_LOCAL
437  float xLoc, yLoc, zLoc;
438  PndFTSCAParameters::GlobalToCALocal( h.X(), h.Y(), h.Z(), h.Angle(), xLoc, yLoc, zLoc );
439  PndFTSCADisplay::Instance().DrawGBPoint( xLoc, yLoc, zLoc, iV);
440 #else
441  PndFTSCADisplay::Instance().DrawGBPoint(h.X(), h.Y(), h.Z(), h.Angle(),iV); //TODO kMagenta??
442 #endif
443  }
444  }
445  //20.01.17 PndFTSCADisplay::Instance().Ask();
446 #endif
447  vStartPoint = vEndPoint;
448  //refit in the backward direction: going from the last hit to the first
449  fitted &= FitTrack( vStartPoint, firstHits, nTrackHits, nTracksVector,active0, 1 );
450 #ifdef DRAW_FIT1
451  // PndFTSCADisplay::Instance().ClearView();
452  // PndFTSCADisplay::Instance().SetTPCView();
453  // PndFTSCADisplay::Instance().DrawTPC();
454 
455  for(int ihit = 0; ihit<nHitsDraw.max(); ihit++)
456  {
457  for(int iV=0; iV<nTracksVector; iV++)
458  {
459  if( ihit > nTrackHits[iV] - 1) continue;
460  const int jhit = ihit;
461  PndFTSCAGBHit &h = fHits[fTrackHits[memFirstHits[iV] + jhit]];
462 #ifdef DRAW_FIT_LOCAL
463  float xLoc, yLoc, zLoc;
464  PndFTSCAParameters::GlobalToCALocal( h.X(), h.Y(), h.Z(), h.Angle(), xLoc, yLoc, zLoc );
465  PndFTSCADisplay::Instance().DrawGBPoint( xLoc, yLoc, zLoc, iV);
466 #else
467  PndFTSCADisplay::Instance().DrawGBPoint(h.X(), h.Y(), h.Z(), h.Angle(),iV);//TODO kMagenta??
468 #endif
469  }
470  }
471  //20.01.17 PndFTSCADisplay::Instance().Ask();
472 #endif
473  }
474  }
475 #endif // USE_CA_FIT
476  for(int iV=0; iV < nTracksVector; iV++)
477  {
478  startPoint[iV] = PndFTSCATrackParam( vStartPoint, iV );
479  endPoint[iV] = PndFTSCATrackParam( vEndPoint, iV );
480  if ( !fitted[iV] ) {
481  startPoint[iV].SetAsInvalid();
482  endPoint[iV].SetAsInvalid();
483  }
484  }
485  //cout<<"begin fitted "<<(static_cast<uint_v>(nTrackHits) > 0)<<endl;
486  //cout<<"end fitted "<<fitted<<endl;
487  for(int iV = 0; iV<nTracksVector; iV++)
488  {
489  PndFTSCAGBTrack &trackGB = fTracks[iTr+iV];
490  trackGB.SetInnerParam( startPoint[iV] );
491  trackGB.SetOuterParam( endPoint[iV] );
492  trackGB.SetDeDx( 0 );
493  }
494 
495  }
496 }
497 
498 // used to check fit in CA
500  uint_v &firstHits,
501  uint_v::Memory &NTrackHits,
502  int &nTracksV, float_m active0, bool dir, bool init )
503 {
504  UNUSED_PARAM2(nTracksV, dir); // TODO clean me
505  float_m active = active0;
506 
507  uint_v NTHits(NTrackHits);
508  active &= NTHits >= 3;
509 
510  if (active.isEmpty()) return active;
511 // cout<<"active1 "<<active<<endl;
512  NTHits.setZero(static_cast<uint_m>(!active));
513  /* //nplets-case
514  bool SkipMe;
515  for (unsigned int xxx=0; xxx<42; xxx++){
516  SkipMe = false;
517  cout<<"############# \n";
518  cout<<"#6-plet start from "<<xxx+1<<" hit \n";
519  //nplets-case*/
520 // active = active0;//dummy-var
521 #if 1 // check tracks
522  const unsigned int NHitsMax = NTHits.max(); //for tracks; 6 for sixtiplets
523  unsigned int FirstHit = 0; //xxx //was 4 check part of the track begining from x-th hit
524  //const bool AddLastHit = true;
525 #else // check tracklets
526 // if (NTHits.max() < 7) return static_cast<float_m>(false);
527  const unsigned int NHitsMax = 6; // check x-lets fit
528  const unsigned int FirstHit = 15; // check part of the track begining from x-th hit
529  const bool AddLastHit = true;
530 #endif
531 
532  //active &= NTHits >= NHitsMax+FirstHit;
533  if (active.isEmpty()) return active;
534 // cout<<"active2 "<<active<<endl;
535  vector<FTSCAHitV> hits( NHitsMax );
536  //cout<<"track-begin\n";
537  for ( unsigned int ihit = FirstHit; (ihit-FirstHit) < NHitsMax; ihit++ ) {
538  const uint_m valid = ihit < NTHits;
539  uint_v::Memory id;
540 
541  const PndFTSCAGBHit **hs = new const PndFTSCAGBHit*[float_v::Size];
542  foreach_bit(unsigned int iV, valid) {
543  if ( dir )
544  id[iV] = firstHits[iV] + (NTHits[iV]-static_cast<unsigned int>(1)) - ihit;
545  else
546  id[iV] = firstHits[iV] + ihit;
547  hs[iV] = &(fHits[fTrackHits[id[iV]]]);
548  }
549  hits[ihit-FirstHit] = FTSCAHitV( hs, uint_v(id), static_cast<float_m>(valid) );
550  //cout<<"hits[ihit-FirstHit].X0() "<<hits[ihit-FirstHit].X0()<<"hits[ihit-FirstHit].X1() "<<hits[ihit-FirstHit].X1()<<endl;
551  }
552  //cout<<"track-end\n";
553  const FTSCAHitV& hit0 = hits[0];
554 
555  //Init magnetic field
556  const CAFieldValue &b2 = GetParameters().GetFieldValue( hit0.IStations(), hit0.X1(), hit0.X2(), active );
557  const float_v &z2 = GetParameters().GetX0( hit0.IStations(), active );
558  t.SetField(0, b2, z2);
559  t.SetField(1, b2, z2);
560 
561 #if (defined(USE_MC_PV) && defined(STAR_HFT))
562  const double *pv = PndFTSCAPerformance::Instance().PV(); // dbg
563  float xT = pv[0], yT = pv[1], zT = pv[2];
564 #else
565  float xT = 0, yT = 0, zT = 0;
566 #endif
567 
568  fMaxInvMom = 20.f; // 0.1 GeV tracks
569 #if defined(PANDA_STT)
570  FTSCATarget target( xT, yT, zT, 10, 10, fMaxInvMom/3.f, GetParameters(), 0 );
571 #elif defined(PANDA_FTS)
572  FTSCATarget target( xT, yT, zT, 10, 10, fMaxInvMom/3.f, GetParameters(), 0 );
573 #else
574  FTSCATarget target( xT, yT, zT, 0.1, 10, fMaxInvMom/3.f, GetParameters(), 1 );
575 #endif
576 
577 #ifdef START_FROM_TARGET // target + hit
578  // fMaxInvMom = 1.f; // 0.1 GeV tracks
579  // FTSCATarget target( xT, yT, zT, 0.03, 0.03, fMaxInvMom/3.f, GetParameters(), 2 ); // target at 0 with 3 cm error // 0.1 GeV tracks
580 // FTSCATarget target = fTarget;
581  //target.SetErrQMom(20/3.f);
582 
583  if(init)
584  {
585  //no need if mc-init
586  t.InitByTarget( target );
587  t.SetAngle( hit0.Angle() );
588  t.InitDirection( hit0.X0(), hit0.X1(), hit0.X2() );
589 
590  t.SetX(hit0.X1());
591  t.SetY(hit0.X2()); //we don't have Y at this point (strip crossing required)
592  t.SetZ(hit0.X0());
593 
594 // t.Cov(0) = hit0.Err2X1();
595 // t.Cov(1) = hit0.ErrX12();
596 // t.Cov(2) = hit0.Err2X2();
597 
598  }
599  float_v qp0 = t.QP(); //good if mc-init
601  for ( unsigned int ihit = 0; ihit < NHitsMax; ihit++ ) {
602 #elif 0/* // start from 2 hits initialization
603 #if (defined(USE_MC_PV) && defined(STAR_HFT))
604  const double *pv = PndFTSCAPerformance::Instance().PV(); // dbg
605  float xT = pv[0], yT = pv[1], zT = pv[2];
606 #else
607  float xT = 0, yT = 0, zT = 0;
608 #endif
609 
610  const FTSCAHitV& hit1 = hits[1];
611  fMaxInvMom = 1.f; // 0.05 GeV tracks
612  FTSCATarget target( xT, yT, zT, 10e10, 10e10, fMaxInvMom/3.f, GetParameters(), 0 ); // target at 0 with 3 cm error
613 
614  t.InitByTarget( target );
615  t.SetAngle( hit0.Angle() );
616 
617  float_v xg0,yg0,zg0,xg1,yg1,zg1;
618  PndFTSCAParameters::CALocalToGlobal( hit0.X0(), hit0.X1(), hit0.X2(), hit0.Angle(), xg0, yg0, zg0 );
619  PndFTSCAParameters::CALocalToGlobal( hit1.X0(), hit1.X1(), hit1.X2(), hit1.Angle(), xg1, yg1, zg1 );
620  float_v dx = xg1-xg0;
621  float_v dy = yg1-yg0;
622  float_v dz = zg1-zg0;
623  const float_v cA = CAMath::Cos( hit0.Angle() );
624  const float_v sA = CAMath::Sin( hit0.Angle() );
625 
626  t.InitDirection( dx*cA + dy*sA, -dx*sA + dy*cA, dz );
627  t.SetErr2QPt( fMaxInvMom*fMaxInvMom/9.f );
628  t.SetErr2Y( hit0.Err2X1() );
629  t.SetErr2Z( hit0.Err2X2() );
630 */
631 #else // start from hit + target
632 
633  t.InitByHit( hit0, GetParameters(), fMaxInvMom/3.f );
634  t.InitDirection( hit0.X0(), hit0.X1(), hit0.X2() );
635  t.AddTarget( target, active );
636 
637 
638 #endif // START_FROM_TARGET
639 
640  active &= float_m(uint_v(ihit)<NTHits);
641 
642  const FTSCAHitV& hit = hits[ihit];
643  //qp0 = t.QP();
644  float_m bufactive(false);
645  float_m flashback(false);
646  int_v ista(Vc::Zero);
647  ista(hit.IsValid()) = hit.IStations();
648  //cout<<"ista "<<ista<<endl;
649  //if (1)
650  if (((ista[0]==8 || ista[0]==16 || ista[0]==24 || ista[0]==32 || ista[0]==40) && !dir) || ((ista[0]==7 || ista[0]==15 || ista[0]==23 || ista[0]==31 || ista[0]==39) && dir))
651  {
652  flashback = (ista==8 || ista==16 || ista==24 || ista==32 || ista==40 ||ista==39 || ista==31 || ista==23 || ista==15 || ista==7);
653 // flashback = (ista==ista);
654  buffer.SetTrackParam(t,flashback);
655  bufactive = active;
656  }
657 
658  if(!(ihit==0))
659  {
660  if(!init)
661  active &= t.Transport( hit, GetParameters(), qp0, active ) ;
662  else
663  active &= t.Transport( hit, GetParameters(), active ) ;
664  }
665 
666  //cout<<"hit.IStations() "<<hit.IStations()<<endl;
667  //if (1)
668  if (((ista[0]==8 || ista[0]==16 || ista[0]==24 || ista[0]==32 || ista[0]==40) && !dir) || ((ista[0]==7 || ista[0]==15 || ista[0]==23 || ista[0]==31 || ista[0]==39) && dir))
669  {
670  flashback = (abs(t.Err2X())>20.f || isnan(t.Err2X())); //here to add IsNAN-condition for Err2X
671  //cout<<"flashback "<<flashback<<endl;
672  t.SetTrackParam(buffer, flashback);
673  t.SetQP(t.QP()/10.f, flashback);
674  active=bufactive;
675  t.Transport( hit, GetParameters(), qp0, flashback ) ;
676  //t.TransportByLine(hit, GetParameters(), flashback);
677 #ifdef DRAW_FIT
678  {
679  float_v xGl, yGl, zGl;
680  PndFTSCAParameters::CALocalToGlobal(t.X(), t.Y(), t.Z(), t.Angle(), xGl, yGl, zGl);
681  foreach_bit( unsigned int iV, flashback )
682  //int iV = 0;
683  {
684  if(!dir)
685  PndFTSCADisplay::Instance().DrawGBPoint( t.X()[iV], t.Y()[iV], t.Z()[iV], kPink, 2.5 );
686  else
687  PndFTSCADisplay::Instance().DrawGBPoint( t.X()[iV], t.Y()[iV], t.Z()[iV], kPink+2, 2.5 );
688  }
689  //PndFTSCADisplay::Instance().Ask();
690  }
691 #endif
692  }
693  //cout<<"transport\n"<<t<<endl;
694  //t.PrintCovMat();
695 #ifdef DRAW_FIT
696  {
697  float_v xGl, yGl, zGl;
698  PndFTSCAParameters::CALocalToGlobal(t.X(), t.Y(), t.Z(), t.Angle(), xGl, yGl, zGl);
699  foreach_bit( unsigned int iV, active )
700  //int iV = 0;
701  {
702 
703 #ifdef DRAW_FIT_LOCAL
704  PndFTSCADisplay::Instance().DrawGBPoint( t.X()[iV], t.Y()[iV], t.Z()[iV], kBlue+2, 0.75 );
705  cout << t.X()[iV] << " " << t.Y()[iV] << " " << t.Z()[iV] << endl;
706 #else
707  if(!dir)
708  PndFTSCADisplay::Instance().DrawGBPoint( t.X()[iV], t.Y()[iV], t.Z()[iV], kGray, 1.25 );
709  else
710  PndFTSCADisplay::Instance().DrawGBPoint( t.X()[iV], t.Y()[iV], t.Z()[iV], kGray+2, 1.25 );
711 #endif
712  }
713  //PndFTSCADisplay::Instance().Ask();
714  }
715 #endif
716 
717  active &= t.Filter( hit, GetParameters(), active );
718  //cout<<"filter\n"<<t<<endl;
719  //t.PrintCovMat();
720  //for tracks
721  /*cout<<t<<endl;
722  cout<<"Chi2 "<<t.Chi2()[0]<<" NDF "<<t.NDF()[0]<<" Chi2/NDF "<<double(t.Chi2()[0]/double(t.NDF()[0]))<<endl;
723  cout<<"hit ErrX "<<hit.Err2X1()[0]<<" ErrY "<<hit.Err2X2()[0]<<endl;*/
724  //for tracks
725 
726  /*if (t.NDF()[0]<2 && !SkipMe)
727  { //this block defines that we check segments which have less than 6 hits (NDF==1)
728  //cout<<"hit.Z() "<<hit.X0()[0]<<" Chi2 "<<t.Chi2()[0]<<" NDF "<<t.NDF()[0]<<" Chi2/NDF "<<double(t.Chi2()[0]/double(t.NDF()[0]))<<" Prob "<<TMath::Prob( t.Chi2()[0], t.NDF()[0] )<< " x "<<t.X()[0]<<" y "<<t.Y()[0]<<" tx "<<t.Tx()[0]<<" ty "<<t.Ty()[0]<<" qp "<<t.QP()[0]<<endl;
729  //cout<<"param ErrX "<<t.Cov(0)[0]<<" ErrY "<<t.Cov(2)[0]<<" ErrTy "<<t.Cov(9)[0]<<endl;
730  cout<<t<<endl;
731  cout<<"Chi2 "<<t.Chi2()[0]<<" NDF "<<t.NDF()[0]<<" Chi2/NDF "<<double(t.Chi2()[0]/double(t.NDF()[0]))<<endl;
732  cout<<"hit ErrX "<<hit.Err2X1()[0]<<" ErrY "<<hit.Err2X2()[0]<<endl;
733  if (t.NDF()[0]==1)
734  {
735 // cout<<"@@@backwards@@@ \n";
736 // for ( unsigned int iihit = NHitsMax-2; iihit > 0; iihit-- ) {
737 // active &= float_m(uint_v(iihit)>=0);
738 // const FTSCAHitV& hit1 = hits[iihit];
739 // active &= t.Transport( hit1, GetParameters(), qp0, active ) ;
740 // active &= t.Filter( hit1, GetParameters(), active );
741 // cout<<t<<endl;
742 // cout<<"Chi2 "<<t.Chi2()[0]<<" NDF "<<t.NDF()[0]<<" Chi2/NDF "<<double(t.Chi2()[0]/double(t.NDF()[0]))<<endl;
743 // cout<<"hit ErrX "<<hit1.Err2X1()[0]<<" ErrY "<<hit1.Err2X2()[0]<<endl;
744 // }
745 // cout<<"@@@fwd@@@ \n";
746 // for ( unsigned int iihit = 1; iihit <NHitsMax; iihit++ ) {
747 // active &= float_m(uint_v(iihit)<NTHits);
748 // const FTSCAHitV& hit1 = hits[iihit];
749 // active &= t.Transport( hit1, GetParameters(), qp0, active ) ;
750 // active &= t.Filter( hit1, GetParameters(), active );
751 // cout<<t<<endl;
752 // cout<<"Chi2 "<<t.Chi2()[0]<<" NDF "<<t.NDF()[0]<<" Chi2/NDF "<<double(t.Chi2()[0]/double(t.NDF()[0]))<<endl;
753 // cout<<"hit ErrX "<<hit1.Err2X1()[0]<<" ErrY "<<hit1.Err2X2()[0]<<endl;
754 // }
755  SkipMe=true; break;}
756  }*/
757 
758 #ifdef DRAW_FIT
759  {
760  float_v xGl, yGl, zGl;
761 // PndFTSCAParameters::CALocalToGlobal(t.X(), t.Y(), t.Z(), t.Angle(), xGl, yGl, zGl);
762  //foreach_bit( unsigned int iV, active & hit.IsValid() )
763  foreach_bit( unsigned int iV, active )
764  //int iV=0;
765  {
766  float gx,gy,gz;
767  hit.GetGlobalCoor( iV, gx, gy, gz );
768 #ifdef DRAW_FIT_LOCAL
769  PndFTSCADisplay::Instance().DrawGBPoint( hit.X0()[iV], hit.X1()[iV], hit.X2()[iV], kGreen+2,(Size_t)1);
770  PndFTSCADisplay::Instance().DrawGBPoint( t.X()[iV], t.Y()[iV], t.Z()[iV], kBlue, 0.75 );
771  cout << 0.5*atan(2*hit.ErrX12()/(hit.Err2X2() - hit.Err2X1()))[iV] << endl;
772  cout << hit.X0()[iV] << " " << hit.X1()[iV] << " " << hit.X2()[iV] << " " << t.X()[iV] << " " << t.Y()[iV] << " " << t.Z()[iV] << endl;
773 #else
774  PndFTSCADisplay::Instance().DrawGBPoint(gx, gy, gz, kRed, .75);
775  //cout<<"Adding the measurement \n";
776 // cout << hit.X0()[iV] << " " << hit.X1()[iV] << " " << hit.X2()[iV] << " " << t.X()[iV] << " " << t.Y()[iV] << " " << t.Z()[iV] << endl;
777 // std::cout << "tx " << t.Tx()[iV] << " ty " << t.Ty()[iV] << " qp " << t.QP()[iV] << std::endl;
778  if(!dir)
779  PndFTSCADisplay::Instance().DrawGBPoint( t.X()[iV], t.Y()[iV], t.Z()[iV], kBlue+2, 1. );
780  else
781  PndFTSCADisplay::Instance().DrawGBPoint( t.X()[iV], t.Y()[iV], t.Z()[iV], kBlue-2, 1. );
782 #endif
783  // cout << xGl[iV] << " " << yGl[iV] << " " << t.Z()[iV] << endl;
784  }
785  //comment out if u want to see step-by-step visualisation for track fitting
786  //PndFTSCADisplay::Instance().Ask();
787  }
788 
789 #endif
790  }
791 
792 #ifdef DRAW_FIT
794 #endif
795  //fit bckwd
796  /*cout<<"FIT BCKWD \n";
797  for ( unsigned int ihit = NHitsMax-2; ihit >= 0; ihit-- )
798  {
799  const FTSCAHitV& hit = hits[ihit];
800  active &= float_m(uint_v(ihit)<NTHits);
801  active &= t.Transport( hit, GetParameters(),qp0, active );
802  active &= t.Filter( hit, GetParameters(), active );
803  }
804  //t.InitCovMatrix(target.Err2QMom());
805  cout<<"FIT FWD \n";
806  //fit fwd
807  for ( unsigned int ihit = 1; ihit < NHitsMax; ihit++ )
808  {
809  const FTSCAHitV& hit = hits[ihit];
810  active &= float_m(uint_v(ihit)<NTHits);
811  active &= t.Transport( hit, GetParameters(),qp0, active );
812  active &= t.Filter( hit, GetParameters(), active );
813  }*/
814 #if !defined(PANDA_FTS)
815  t.SetQPt( float_v(1.e-8f), CAMath::Abs( t.QPt() ) < 1.e-8f );
816 #endif
817  //nplets-case cin.get();
818  //nplets-case }
819 
820  float_m ok = active0;
821 
822  // if track has infinite partameters or covariances, or negative diagonal elements of Cov. matrix, mark it as fitted uncorrectly
823  for ( unsigned char i = 0; i < 15; i++ ) ok &= CAMath::Finite( t.Cov(i) );
824  for ( unsigned char i = 0; i < 5; i++ ) ok &= CAMath::Finite( t.Par(i) );
825 
826  ok &= (t.Cov(0) > Vc::Zero) && (t.Cov(2) > Vc::Zero) && (t.Cov(5) > Vc::Zero) && (t.Cov(9) > Vc::Zero) && (t.Cov(14) > Vc::Zero);
827  //t.SetNDF(1);//HACK
828  return ok;
829 }
830 
832  uint_v &firstHits,
833  uint_v::Memory &NTrackHits,
834  int &nTracksV, float_m active0 )
835 {
836  //*Initial approximation for the track reconstruction by the least-square method.
837 
838  uint_v nHits(NTrackHits);
839  nHits.setZero(static_cast<uint_m>(!active0));
840  //float_m good = nHits > 2;
841 
842  unsigned int nHitsMax = nHits.max();
843 
844  float_v X(Vc::Zero), Y(Vc::Zero), R(Vc::Zero);
845  float_v lx(Vc::Zero), ly(Vc::Zero), lx2(Vc::Zero), ly2(Vc::Zero), lr2(Vc::Zero);
846  float_v x(Vc::Zero), y(Vc::Zero),
847  x2(Vc::Zero), y2(Vc::Zero), xy(Vc::Zero),
848  r2(Vc::Zero), xr2(Vc::Zero), yr2(Vc::Zero), r4(Vc::Zero);
849 
850  float_v::Memory xH0, yH0, zH0, angle0;
851  for(int iV=0; iV < nTracksV; iV++)
852  {
853  if( !(active0[iV]) ) continue;
854  PndFTSCAGBHit &h = fHits[fTrackHits[firstHits[iV]]];
855 
856  xH0[iV] = h.X();
857  yH0[iV] = h.Y();
858  zH0[iV] = h.Z();
859  angle0[iV] = h.Angle();
860  }
861  float_v xTmp(xH0);
862  float_v yTmp(yH0);
863  float_v zTmp(yH0);
864  const float_v angleV0(angle0);
865  float_v xV0, yV0, zV0(zH0);
866  PndFTSCAParameters::GlobalToCALocal(xTmp, yTmp, zV0, angleV0, xV0, yV0, zV0);
867 
868  vector<float_v> xV(nHitsMax), yV(nHitsMax), zV(nHitsMax);
869 
870  for (unsigned int ihit = 0; ihit < nHitsMax; ihit++ ) {
871 
872  float_m active = static_cast<float_m>( ihit < nHits );
873  if(active.isEmpty()) continue;
874  float_v::Memory xH, yH, zH;
875 
876  for(int iV=0; iV < nTracksV; iV++)
877  {
878  if( !(active[iV]) ) continue;
879  if( ihit > NTrackHits[iV] - 1) continue;
880  PndFTSCAGBHit &h = fHits[fTrackHits[firstHits[iV] + ihit]];
881 
882  xH[iV] = h.X();
883  yH[iV] = h.Y();
884  zH[iV] = h.Z();
885  }
886 
887  xTmp.load(xH);
888  yTmp.load(yH);
889  zTmp.load(zH);
890 
891  PndFTSCAParameters::GlobalToCALocal(xTmp, yTmp, zTmp, angleV0, xV[ihit], yV[ihit], zV[ihit]);
892  }
893 
894 #ifdef PANDA_FTS
895 
896 // float_v A0, A1=0.f, A2=0.f, A3=0.f, A4=0.f, A5=0.f, a0, a1=0.f, a2=0.f,
897 // b0, b1=0.f, b2=0.f;
898 // float_v z0, x, y, z, S, w, wz, wS;
899 //
900 // int i=NHits-1;
901 // z0 = zV[i];
902 // w = 1.f;
903 // A0 = w;
904 // a0 = w*xV[i];
905 // b0 = w*yV[i];
906 
907 // for( int ihit = 0; ihit < nHitsMax; ihit++)
908 // {
909 // float_m active = static_cast<float_m>( ihit < nHits );
910 // x = xV[i];
911 // y = yV[i];
912 // w = 1.f;
913 // z = zV[i] - z0;
914 // S = Sy[i];
915 // wz = w*z;
916 // wS = w*S;
917 // A0(active) +=w;
918 // A1(active) +=wz; A2(active) +=wz*z;
919 // A3(active) +=wS; A4(active) +=wS*z; A5(active) +=wS*S;
920 // a0(active) +=w*x; a1(active) +=wz*x; a2(active) +=wS*x;
921 // b0(active) +=w*y; b1(active) +=wz*y; b2(active) +=wS*y;
922 // }
923 //
924 //
925 
926 //
927 // float_v ANew[6] = {A0, A1, A2, A3, A4, A5};
928 // InvertCholetsky3(ANew);
929 //
930 // float_v L, L1;
931 // t.SetX( ANew[0]*a0 + ANew[1]*a1 + ANew[3]*a2 );
932 // t.SetTx( ANew[1]*a0 + ANew[2]*a1 + ANew[4]*a2 );
933 // float_v txtx1 = 1.+t.tx*t.tx;
934 // L = (ANew[3]*a0 + ANew[4]*a1 + ANew[5]*a2) /(txtx1);
935 // if(fabs(A3[0]) < 1.e-6)
936 // {
937 // ANew[0] = A0;
938 // ANew[1] = A1;
939 // ANew[2] = A2;
940 // InvertCholetsky2(ANew);
941 // t.x = ANew[0]*a0 + ANew[1]*a1;
942 // t.tx =ANew[1]*a0 + ANew[2]*a1;
943 // }
944 //
945 // L1 = L*t.tx;
946 // A1 = A1 + A3*L1;
947 // A2 = A2 + ( A4 + A4 + A5*L1 )*L1;
948 // b1+= b2 * L1;
949 // ANew[0] = A0;
950 // ANew[1] = A1;
951 // ANew[2] = A2;
952 // InvertCholetsky2(ANew);
953 //
954 // track.SetY( ANew[0]*b0 + ANew[1]*b1 );
955 // track.SetTy ( ANew[1]*b0 + ANew[2]*b1 );
956 //
957 // float_v zeroS = !float_v(fabs(A5) < float_v(1.e-8f));
958 // track.q = -L*c_light_i*rsqrt(txtx1 + t.ty*t.ty);
959 // track.qp = track.qp & zeroS;
960 // track.z = z0;
961 
962 #else
963  for( int ihit = 0; ihit < nHitsMax; ihit++)
964  {
965  float_m active = static_cast<float_m>( ihit < nHits );
966  if(active.isEmpty()) continue;
967 
968  lx = xV[ihit] - xV0;
969  ly = yV[ihit] - yV0;
970  lx2 = lx*lx;
971  ly2 = ly*ly;
972  lr2 = lx2+ly2;
973 
974  x(active) += lx;
975  y(active) += ly;
976  x2(active) += lx2;
977  y2(active) += ly2;
978  xy(active) += lx*ly;
979  r2(active) += lr2;
980  xr2(active)+= lx*lr2;
981  yr2(active)+= ly*lr2;
982  r4(active) += lr2*lr2;
983  }
984 
985  x /= static_cast<float_v>(nHits);
986  y /= static_cast<float_v>(nHits);
987  xy /= static_cast<float_v>(nHits);
988  x2 /= static_cast<float_v>(nHits);
989  y2 /= static_cast<float_v>(nHits);
990  xr2 /= static_cast<float_v>(nHits);
991  yr2 /= static_cast<float_v>(nHits);
992  r2 /= static_cast<float_v>(nHits);
993  r4 /= static_cast<float_v>(nHits);
994 
995  const float_v Cxx = x2 - x*x;
996  const float_v Cxy = xy - x*y;
997  const float_v Cyy = y2 - y*y;
998  const float_v Cxr2 = xr2 - x*r2;
999  const float_v Cyr2 = yr2 - y*r2;
1000  const float_v Cr2r2 = r4 - r2*r2;
1001 
1002  const float_v Q1 = Cr2r2*Cxy - Cxr2*Cyr2;
1003  const float_v Q2 = Cr2r2*(Cxx-Cyy) - Cxr2*Cxr2 + Cyr2*Cyr2;
1004  const float_v Phi = 0.5f * CAMath::ATan2(2.f*Q1, Q2);
1005  const float_v SinPhi = CAMath::Sin(Phi);
1006  const float_v CosPhi = CAMath::Cos(Phi);
1007  const float_v Kappa = (SinPhi*Cxr2 - CosPhi*Cyr2)/Cr2r2;
1008 
1009  const float_v Delta = SinPhi*x - CosPhi*y - Kappa*r2;
1010 
1011  const float_v Rho = 2.f*Kappa / CAMath::Sqrt(float_v(Vc::One) - 4.f*Delta*Kappa);
1012  const float_v D = 2.f*Delta / ( float_v(Vc::One) + CAMath::Sqrt(float_v(Vc::One) - 4.f*Delta*Kappa));
1013 
1014  R = float_v(Vc::One)/Rho;
1015  X = (D+R)*SinPhi;
1016  Y = -(D+R)*CosPhi;
1017 
1018  float_v kappa(Vc::Zero);
1019  kappa(good) = Rho;
1020 
1021  const float_v sinPhi0 = -X*kappa;
1022  const float_v cosPhi0 = Y*kappa;
1023 
1024  float_v dS(Vc::Zero), dS2(Vc::Zero), Z(Vc::Zero), dSZ(Vc::Zero);
1025  for ( int ihit = 0; ihit < nHitsMax; ihit++ ) {
1026 
1027  float_m active = static_cast<float_m>( ihit < nHits );
1028  if(active.isEmpty()) continue;
1029 
1030  lx(active) = xV[ihit]-xV0;
1031  ly(active) = yV[ihit]-yV0;
1032 
1033  const float_v ex = cosPhi0;
1034  const float_v ey = sinPhi0;
1035  const float_v dx = lx;
1036 
1037  float_v ey1 = kappa * dx + ey;
1038 
1039  // check for intersection with X=x
1040 
1041  float_v ex1 = 1.f - ey1 * ey1;
1042  ex1(ex1<float_v(Vc::Zero)) = float_v(Vc::Zero);
1043  ex1 = CAMath::Sqrt( ex1 );
1044  ex1( ex < Vc::Zero ) = -ex1;
1045 
1046  //27.01 const float_v dx2 = dx * dx;
1047  const float_v ss = ey + ey1;
1048  const float_v cc = ex + ex1;
1049 
1050  float_v cci = 1.f / cc;
1051  cci(CAMath::Abs(cc) < 1.e-8f) = 1.e8f;
1052  float_v exi = 1.f / ex;
1053  exi(CAMath::Abs(ex) < 1.e-8f) = 1.e8f;
1054  float_v ex1i = 1.f / ex1;
1055  ex1i(CAMath::Abs(ex1) < 1.e-8f) = 1.e8f;
1056  const float_v tg = ss * cci; // tan((phi1+phi)/2)
1057 
1058  //27.01 const float_v dy = dx * tg;
1059  float_v dl = dx * CAMath::Sqrt( 1.f + tg * tg );
1060 
1061  dl( cc < Vc::Zero ) = -dl;
1062  const float_v dSin = CAMath::Max( float_v( -1.f ), CAMath::Min( float_v( Vc::One ), dl * kappa * 0.5f ) );
1063  const float_v ds = ( CAMath::Abs( kappa ) > 1.0e-4f ) ? ( 2.f * CAMath::ASin( dSin ) / kappa ) : dl;
1064 
1065  dS(active) += ds;
1066  dS2(active) += ds*ds;
1067  Z(active) += zV[ihit];
1068  dSZ(active) += ds*zV[ihit];
1069  }
1070 
1071  float_v det = Vc::One/( static_cast<float_v>(nHits)*dS2 - dS*dS );
1072  float_v Z0(Vc::Zero), X0(Vc::Zero), Y0(Vc::Zero), dzds(Vc::Zero);
1073  Z0(good) = det*( dS2*Z - dS*dSZ);
1074  dzds(good) = det*( static_cast<float_v>(nHits)*dSZ - Z*dS );
1075 
1076  float_v signCosPhi0(Vc::One);
1077  signCosPhi0(cosPhi0<Vc::Zero) = -Vc::One;
1078 
1079 #ifdef DRAW_FIT1
1080  // PndFTSCADisplay::Instance().ClearView();
1081  // PndFTSCADisplay::Instance().SetTPCView();
1082  // PndFTSCADisplay::Instance().DrawTPC();
1083 #ifdef DRAW_FIT_LOCAL
1084  assert(0); // TODO
1085 #endif
1086  for(unsigned int ihit = 0; ihit<nHitsMax; ihit++)
1087  {
1088  for(int iV=0; iV < nTracksV; iV++)
1089  {
1090  float_m active = static_cast<float_m>( ihit < nHits );
1091  if( !(active[iV]) ) continue;
1092  if( ihit > NTrackHits[iV] - 1) continue;
1093  PndFTSCAGBHit &h = fHits[fTrackHits[firstHits[iV] + ihit]];
1094  PndFTSCADisplay::Instance().DrawGBPoint(h.X(), h.Y(), h.Z(), h.Angle(),iV);
1095  }
1096  }
1097 
1098  double xCL = (X+xV0)[0];
1099  double yCL = (Y+yV0)[0];
1100  double zCL = 0, xC=0, yC=0, zC=0;
1101  PndFTSCAParameters::CALocalToGlobal(xCL,yCL,zCL, double(angleV0[0]), xC, yC, zC );
1102  double rad = fabs(R[0]);
1103 
1104  PndFTSCADisplay::Instance().DrawArc(xC, yC, rad, -1, 1);
1105  PndFTSCADisplay::Instance().DrawGBPoint(xC, yC, 0.f, 0.f,-1);
1107 #endif
1108 
1109  track.SetAngle(angleV0);
1110  track.SetSinPhi(-sinPhi0); // -1 factor is a correction for direction (should be from inner to outer, but previous formula calculate for fromOuterToInner)
1111  track.SetSignCosPhi(-signCosPhi0);
1112  track.SetX(xV0);
1113  track.SetY(yV0);
1114  track.SetZ(Z0);
1115  track.SetDzDs(-dzds);
1116  track.SetQPt(-kappa/GetParameters().cBz());
1117 #endif
1118 }
1119 
1121  uint_v &firstHits,
1122  uint_v::Memory &NTrackHits,
1123  int &nTracksV, float_m active0, bool dir )
1124 {
1125  //* Fitting of the track by using Kalman Filter,
1126  //* taking into account changes of his parameters due crossing through the detector material.
1127 
1128 #ifdef PANDA_FTS
1129  UNUSED_PARAM6( t, firstHits, NTrackHits, nTracksV, active0, dir );
1130  return float_m(true);
1131 #else
1133 
1135 
1136  bool first = 1;
1137 
1138  t.CalculateFitParameters( fitPar );
1139 
1140  uint_v nHits(NTrackHits);
1141  nHits.setZero(static_cast<uint_m>(!active0));
1142 
1143  int nHitsMax = nHits.max();
1144 
1145  for ( unsigned int ihit = 0; ihit < nHitsMax; ihit++ ) {
1146 
1147  float_m active = active0 && static_cast<float_m>( ihit < nHits );
1148  if(active.isEmpty()) continue;
1149  float_v::Memory xH, yH, zH, hitAlpha;
1150  float_v::Memory memXOverX0, memXTimesRho;
1151 
1152  float_v::Memory err2X1h, err2x2h, errX12h;
1153  int_v::Memory mHitNDF;
1154 #ifdef DRIFT_TUBES
1155  float_v::Memory rh, isLeftH;
1156 #endif
1157 
1158  for(int iV=0; iV < nTracksV; iV++)
1159  {
1160  if( !(active[iV]) ) continue;
1161  if( ihit > NTrackHits[iV] - 1) continue;
1162  const unsigned int jhit = dir ? ( NTrackHits[iV] - 1 - ihit ) : ihit;
1163  PndFTSCAGBHit &h = fHits[fTrackHits[firstHits[iV] + jhit]];
1164 
1165  hitAlpha[iV] = h.Angle();
1166 
1167  xH[iV] = h.X();
1168  yH[iV] = h.Y();
1169  zH[iV] = h.Z();
1170 
1171  err2X1h[iV] = h.Err2X1();
1172 #ifdef PANDA_FTS // TODO why "-" ?
1173  errX12h[iV] = -h.ErrX12();
1174 #else
1175  errX12h[iV] = h.ErrX12();
1176 #endif
1177  err2x2h[iV] = h.Err2X2();
1178 #ifdef DRIFT_TUBES
1179  rh[iV] = h.R();
1180  isLeftH[iV] = h.IsLeft() ? 1.f : 0.f;
1181 #endif
1182  mHitNDF[iV] = GetParameters().Station( h.IRow() ).NDF;
1183  memXOverX0[iV] = GetParameters().GetXOverX0(h.IRow());
1184  memXTimesRho[iV] = GetParameters().GetXTimesRho(h.IRow());
1185  }
1186 
1187  const float_v err2X1(err2X1h), err2x2(err2x2h), errX12(errX12h);
1188 #ifdef DRIFT_TUBES
1189  const float_v isLeftF(isLeftH),r(rh);
1190  const float_m isLeft = isLeftF > float_v(Vc::Zero);
1191 #endif
1192  const int_v hitNDF(mHitNDF);
1193 
1194  float_v xV(xH);
1195  float_v yV(yH);
1196  float_v zV(zH);
1197  const float_v hitAlphaV(hitAlpha);
1198  const float_v xOverX0(memXOverX0);
1199  const float_v xTimesRho(memXTimesRho);
1200 
1201 #ifdef DRAW_FIT
1202 #ifdef DRAW_FIT_LOCAL
1203  assert(0); // TODO
1204 #endif
1205  for(int iV=0; iV<nTracksV; iV++)
1206  {
1207  if(!active[iV]) continue;
1208  PndFTSCADisplay::Instance().DrawGBPoint((float)xV[iV], (float)yV[iV], (float)zV[iV],(int)4,(Size_t)1);
1209  }
1210 #endif
1211 
1212  const float_m &rotated = t.Rotate( -t.Angle() + hitAlphaV, l, .999f, active);
1213 
1214  active &= rotated;
1215  if(active.isEmpty()) continue;
1216 
1217  const float_v x0 = xV, y0 = yV;
1218  PndFTSCAParameters::GlobalToCALocal(x0, y0, zV, hitAlphaV, xV, yV, zV);
1219 
1220  t.SetAngle(hitAlphaV, active);
1221  const float_m &transported = t.TransportToX0WithMaterial( xV, l, fitPar, xOverX0, xTimesRho, GetParameters().cBz(), 0.999f, active);
1222 
1223 #ifdef DRAW_FIT
1224 #ifdef DRAW_FIT_LOCAL
1225  assert(0); // TODO
1226 #endif
1227  float_v xL = t.X(), yL = t.Y(), zL = t.Z(), xGl, yGl, zGl;
1228  PndFTSCAParameters::CALocalToGlobal(xL, yL, zL, t.Angle(), xGl, yGl, zGl);
1229 
1230  for(int iV=0; iV<nTracksV; iV++)
1231  {
1232  if(!active[iV]) continue;
1233  PndFTSCADisplay::Instance().DrawGBPoint(xGl[iV], yGl[iV], zGl[iV],2,1.);
1234  }
1236 #endif
1237 
1238  active &= transported;
1239  if(active.isEmpty()) continue;
1240  if ( first ) {
1241  t.SetCov( 0, 10.f, active );
1242  t.SetCov( 1, 0.f, active );
1243  t.SetCov( 2, 10.f, active );
1244  t.SetCov( 3, 0.f, active );
1245  t.SetCov( 4, 0.f, active );
1246  t.SetCov( 5, 1.f, active );
1247  t.SetCov( 6, 0.f, active );
1248  t.SetCov( 7, 0.f, active );
1249  t.SetCov( 8, 0.f, active );
1250  t.SetCov( 9, 10.f, active );
1251  t.SetCov( 10, 0.f, active );
1252  t.SetCov( 11, 0.f, active );
1253  t.SetCov( 12, 0.f, active );
1254  t.SetCov( 13, 0.f, active );
1255  t.SetCov( 14, 10.f, active );
1256  t.SetChi2( 0.f, active);
1257  t.SetNDF( int_v(-5), static_cast<int_m>(active) );
1258  t.CalculateFitParameters( fitPar );
1259  t.SetAngle(float_v( hitAlpha ));
1260  first = 0;
1261  }
1262 
1263  float_v x1 = yV;
1264 #ifdef DRIFT_TUBES
1265  float_v sinPhi = t.SinPhi();
1266  float_v xCorr = r - r/(sqrt(1-sinPhi*sinPhi));
1267  x1(isLeft) += xCorr;
1268  x1(!isLeft) -= xCorr;
1269 #endif
1270  const float_m &filtered = t.FilterWithMaterial(x1, zV, err2X1, errX12, err2x2, 0.999f, active, hitNDF);
1271 
1272  active &= filtered;
1273  if(active.isEmpty()) continue;
1274 
1275 #ifdef DRAW_FIT
1276 #ifdef DRAW_FIT_LOCAL
1277  assert(0); // TODO
1278 #endif
1279  xL = t.X(); yL = t.Y(); zL = t.Z();
1280  PndFTSCAParameters::CALocalToGlobal(xL, yL, zL, t.Angle(), xGl, yGl, zGl);
1281 
1282  for(int iV=0; iV<nTracksV; iV++)
1283  {
1284  if(!active[iV]) continue;
1285  PndFTSCADisplay::Instance().DrawGBPoint(xGl[iV], yGl[iV], zGl[iV],3,1.);
1286  }
1288 #endif
1289 
1290  }
1291  t.SetQPt( float_v(1.e-8f), CAMath::Abs( t.QPt() ) < 1.e-8f );
1292 
1293  float_m ok = active0;
1294 
1295 // if track has infinite partameters or covariances, or negative diagonal elements of Cov. matrix, mark it as fitted uncorrectly
1296  for ( unsigned char i = 0; i < 15; i++ ) ok &= CAMath::Finite( t.Cov(i) );
1297  for ( unsigned char i = 0; i < 5; i++ ) ok &= CAMath::Finite( t.Par(i) );
1299  ok &= (t.Cov(0) > Vc::Zero) && (t.Cov(2) > Vc::Zero) && (t.Cov(5) > Vc::Zero) && (t.Cov(9) > Vc::Zero) && (t.Cov(14) > Vc::Zero);
1300  ok &= CAMath::Abs( t.SinPhi() ) < .999f;
1301 
1302  t.SetSignCosPhi( 1.f, ok && static_cast<float_m>(l.CosPhi() >= Vc::Zero) );
1303  t.SetSignCosPhi(-1.f, ok && static_cast<float_m>(l.CosPhi() < Vc::Zero) );
1304 
1305  return ok;
1306 #endif
1307 }
1308 
1309 
1311 {
1312  //* main tracking routine
1313  fStatNEvents++;
1314 
1315 #ifdef MAIN_DRAW
1316  PndFTSCAPerformance::Instance().SetTracker( this );
1318  PndFTSCADisplay::Instance().SetGB( this );
1320 #endif //MAIN_DRAW
1321 
1322 #ifdef MAIN_DRAW
1323 
1324 #if defined(PANDA_STT) || defined(PANDA_FTS)
1327  //PndFTSCADisplay::Instance().DrawGBPoints();
1328  PndFTSCADisplay::Instance().DrawGBHits( *this, kGreen+2, 0.1, 1 );
1331 #endif
1332 
1333 // // PndFTSCADisplay::Instance().DrawGBHits( *this, kRed, 0.2, 2 );
1334 // // PndFTSCADisplay::Instance().SaveCanvasToFile( "Hits_b.pdf");
1335 // // PndFTSCADisplay::Instance().Ask();
1336 #endif //MAIN_DRAW
1337 
1338  //cout << " NHits = " << fNHits << endl;
1339 
1349 
1350 #ifdef USE_IDEAL_TF
1351  IdealTrackFinder();
1352 #else // USE_IDEAL_TF
1353  CATrackFinder();
1354  FitTracks();
1355 #ifndef USE_CA_FIT // fitted in CATrackFinder
1356  FitTracks();
1357 #endif
1358 
1359 #endif // USE_IDEAL_TF
1360 
1361 #ifdef DRAW_CA
1363  for( int i=0; i<fNTracks; i++ ){
1364  switch (i)
1365  {
1366  case 0: disp.DrawRecoTrack(i, kRed, 2); break;
1367  case 1: disp.DrawRecoTrack(i, kBlue, 2); break;
1368  case 2: disp.DrawRecoTrack(i, kOrange, 2); break;
1369  case 3: disp.DrawRecoTrack(i, kPink, 2); break;
1370  case 4: disp.DrawRecoTrack(i, kBlack, 2); break;
1371  default: disp.DrawRecoTrack(i, kGreen, 2); break;
1372  }
1373  //disp.Ask();
1374  }
1375  disp.Ask();
1376 
1377 #endif
1378 
1379 }
1380 
1381 
1382 void PndFTSCAGBTracker::SetHits( std::vector<PndFTSCAGBHit> &hits)
1383 {
1384  const int NHits2 = hits.size();
1385 
1386  SetNHits(NHits2);
1387  fFStrips.Resize(NHits2); // create a virtual strip for each hit (currently strips position is not used for FTS, so don't have to fill them)
1388  fBStrips.Resize(NHits2); // create a virtual strip for each hit
1389 
1390  fHits.Resize(NHits2);
1391  for (int iH = 0; iH < NHits2; iH++){
1392  fHits[iH] = hits[iH];
1393  fHits[iH].SetFStripP( &fFStrips[iH] );
1394  fHits[iH].SetBStripP( &fBStrips[iH] );
1395  }
1396 }
1397 
1399 {
1400  //* Read settings from the file
1401  in >> fParameters;
1402 }
1403 
1405 {
1406  ifstream ifile((prefix).data());
1407  if ( !ifile.is_open() ) return 0;
1408  ReadSettings(ifile);
1409  return 1;
1410 }
1411 
1412 const int StartStationShift = 1;
1413 
1414 
1415 //BEGIN@@@@!!!!STT===>>>FTS COMBINATORIAL PART!!!!@@@@@
1416 //ATTENTION LAST VERSION OF STT_CA_TRACK_FINDER FROM PANDAROOT_TRUNK
1417 /*
1418 */
1420 {
1421 
1422 #ifdef DRAW_CA
1424  //PndFTSCADisplay::Instance().SetTPCView();
1426 #endif
1427  // prepare memory for tracks
1428  if(fTracks) delete [] fTracks;
1429  if(fTrackHits) delete [] fTrackHits;
1430  fTracks = new PndFTSCAGBTrack[5000]; // TODO
1431  fTrackHits = new int[3000*PndFTSCAParameters::MaxNStations]; // TODO
1432  fNTracks = 0;
1433 
1434  //std::sort( fHits.Data(), fHits.Data() + fNHits, PndFTSCAGBHit::Compare ); to make convertion faster
1435  FTSCAHits hits( NStations(), fHits.Size()/NStations() ); // suppose approximately equal nHits per station
1436 
1437  //convert hits
1438  for( int iH = 0; iH < fNHits; ++iH )
1439  {
1440  hits.Add( FTSCAHit( fHits[iH], iH ) );
1441  }
1442 
1443  hits.Sort();
1444 
1445  //estimate PV
1446  float xT = 0, yT = 0, zT = 0;
1447 
1449  // set parameters; TODO depend on iteration
1450 // const float kCorr = 4.;//1;//.2; // correction on pulls width
1451  const float kCorr = 2.;
1452  const float kCorr2 = kCorr*kCorr;
1453  fPick_m = 3.*kCorr; //3.*kCorr;
1454  fPick_r = 5.*kCorr; //5.*kCorr;
1455  fPickNeighbour = 7.*kCorr;//3.*kCorr; 7*kCorr
1456  TRACK_PROB_CUT = 0.01; //0.01;
1457  TRACK_CHI2_CUT = 10.*kCorr2;//10.*kCorr2;
1458 // TRIPLET_CHI2_CUT = 15.*kCorr2; // TMath::Prob(20,-3+1+6) = TMath::Prob(15,2) = 5e-04
1459  TRIPLET_CHI2_CUT = 20.*kCorr2; // TMath::Prob(20,-3+1+6) = TMath::Prob(15,2) = 5e-04
1460 
1461 
1462  // Set correction in order to take into account overlaping
1463  // 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
1464  fMaxDX0 = 0;
1465 
1466 // fMaxInvMom = 2;
1467  fMaxInvMom = 5;
1468 
1469 // fTarget = FTSCATarget( xT, yT, zT, 10, 10, fMaxInvMom/3.f, GetParameters(), 0 );
1470 fTarget = FTSCATarget( xT, yT, zT, 10, 10, fMaxInvMom, GetParameters(), 0 );
1471 
1472 
1473  //cout<<"MaxCellLength = "<<PndCAParameters::MaxCellLength<<endl;
1474 
1475  // reconstruct
1476  int maxCellLength = PndFTSCAParameters::MaxCellLength;
1477  //maxCellLength = 6;
1478 
1479 #ifdef DRAW_CA
1482  PndFTSCADisplay::Instance().SaveCanvasToFile( "DrawHits.pdf" );
1484 #endif
1485 
1486 
1487  FTSCANPletsV pletsV( NStations(), &hits );
1488 
1489  int iMin = ( maxCellLength < PndFTSCAParameters::LastCellLength ) ? maxCellLength : PndFTSCAParameters::LastCellLength;
1490 
1491  fPick = fPick_r;
1492  FTSCATracks tracks(&hits);
1493 
1494 
1495  for( char iS = 0; iS <= NStations() - iMin; iS+=StartStationShift )
1496 
1497  {
1498  CreateNPlets( fTarget, hits, pletsV.OnStation(iS), iS, maxCellLength-1 );
1499  }
1500 
1501 #ifdef DRAW_CA1
1503  PndFTSCADisplay::Instance().SaveCanvasToFile( "DrawCells.pdf" );
1505 #endif
1506 
1507  FTSCANPlets triplets(pletsV);
1508 
1510  FindNeighbours( triplets );
1511 
1512  CreateTracks( triplets, tracks );
1513 
1514 
1515  Merge( tracks );
1516 
1517 
1518  // save tracks in compact format
1519  int curHit = 0; // counters, used to save tracks in output format
1520  int curTr = 0;
1521 
1522  const int NRTracks = tracks.size();
1523 
1524  for(int iT=0; iT<NRTracks; iT++)
1525  {
1526  const int NTHits = tracks[iT].NHits();
1527  PndFTSCAGBTrack &oT = fTracks[curTr];
1528  oT.SetNHits( NTHits );
1529  //cout<<"NTHits "<<NTHits<<endl;
1530  oT.SetFirstHitRef( curHit );
1531 #ifdef USE_CA_FIT
1532  //oT.SetOuterParam( tracks[iT].Fit( hits, fTarget, GetParameters(), false ) );
1533  //oT.SetInnerParam( tracks[iT].Fit( hits, fTarget, GetParameters(), true ) );
1534  //InnerParam turns out to be full of nan's for long tracks
1535  //oT.SetInnerParam( tracks[iT].Fit2Times( hits, fTarget, GetParameters(), false ) );
1536 #endif
1537  for(int iH=0; iH < NTHits; iH++)
1538  {
1539  fTrackHits[curHit] = tracks.Hit(iH, iT).Id();
1540  curHit++;
1541  }
1542  curTr++;
1543  }
1544  fNTracks += NRTracks;
1545 
1546  hits.Clean(); // remove used hits
1547 }
1548 
1549 
1550 struct TrackHitRecord{
1551  int fPrevHit; // index of previous TrackHitRecord of same track in an array of records
1552  unsigned short fIHit;
1553  char fStation;
1554 };
1555 
1556 vector<TrackHitRecord> gTrackHitRecords;
1557 
1559 {
1560  const FTSCAElementsOnStation<FTSCAHit>& hs = hits.OnStation(iS);
1561 
1562  r.clear();
1563  r.reserve(hs.size()/float_v::Size + 1);
1564 
1565  TrackHitRecord hitRecord;
1566  hitRecord.fPrevHit = -1;
1567  hitRecord.fStation = iS;
1568 
1569  //no vectorization for hits...
1570  for( unsigned int iH = 0; iH < hs.size(); iH += 1 ) //check with 2508
1571  {
1572  const FTSCAHit &hit_t = hs[iH];
1573  int ISta = (int) hit_t.IStation();
1574 
1575  //const PndFTSCAGBHit &hit_1 = fHits[hit_t.Id()];
1576  //float_v Tx_1 = float_v(hit_1.point_Px/hit_1.point_Pz);
1577 
1578  float_m valid = static_cast<float_m>(uint_v::IndexesFromZero() < uint_v(hs.size() - iH) );
1579 
1580  FTSCAHitV hit( &(hs[iH]), valid );
1582  float_m active = hit.IsValid();
1583 
1584  if (ISta<32)
1585  {
1586  // start from target
1587  param.InitByTarget(target);
1588  float_v r0(10.f); float_v r1(10.f); float_v r2(10.f);
1589  r0(active) = hit.X0() - target.X0();
1590  r1(active) = hit.X1() - target.X1();
1591  r2(active) = hit.X2() - target.X2();
1592  param.InitDirection(r0, r1, r2);
1593  //param.InitDirection( hit.X0() - target.X0(), hit.X1() - target.X1(), hit.X2() - target.X2() );
1594 
1595  param.SetAngle( hit.Angle() );
1596  active &= param.Transport( hit, GetParameters(), active /*float_m(true)*/ );
1597 // active &= param.Filter( hit, GetParameters(), active );
1598  }
1599  else
1600  {
1601  param.SetAngle( hit.Angle() );
1602  param.InitByHit( hit, GetParameters(), target.DQMom() );
1603  param.SetTx(0.f);
1604  }
1605 
1606  if( active.isEmpty() ) continue;
1607  uint_v iHit = uint_v::IndexesFromZero() + iH;
1608  r.resize(r.size()+1);
1609  FTSCANPletV &nPlet = r.back();
1610  nPlet = FTSCANPletV(iHit, int_v(hit.IStation()), param, active);
1611 
1612  nPlet.fNHits=1;
1613  //nPlet.fParam=param;
1614  //nPlet.fIsValid = active;
1615  nPlet.fLastHit = -1;
1616  foreach_bit( unsigned int iBit, active )
1617  {
1618  hitRecord.fIHit = iHit[iBit];
1619  nPlet.fLastHit[iBit] = gTrackHitRecords.size();
1620  gTrackHitRecords.push_back(hitRecord);
1621  }
1622  }
1623  //cout<<"singlets on stat "<<iS<<" size "<<r.size()<<endl;
1624 }
1625 
1626 void PndFTSCAGBTracker::CreateNPlets( const FTSCATarget& target, const FTSCAHits& hits,
1627  FTSCAElementsOnStation<FTSCANPletV> &nPlets, int iS,
1628  int cellLength )
1629 {
1632  tmp0.fHitsRef = &hits;
1633  tmp0.fISta = iS;
1634  tmp1.fHitsRef = &hits;
1635  tmp1.fISta = iS;
1636 
1637  FTSCAElementsOnStation<FTSCANPletV> *rCurr = &tmp0;
1638  FTSCAElementsOnStation<FTSCANPletV> *rNext = &tmp1;
1639 
1640  Create1Plets( target, hits, *rCurr, iS );
1641 
1642 //draw singlets
1643 #ifdef MAIN_DRAW1
1646 #endif
1647 
1648  for( int iLen=1; iLen<=cellLength; iLen++)
1649  {
1650  if ( rCurr->size() <= 0 ) break;
1651  if ( (*rCurr)[0].N() >= GetParameters().Station( iS ).CellLength ) break; //track-segment size check
1652  if ((rCurr->HitsRef())->OnStationConst( iS ).size() == 0) continue; //to take into account gapped tracks
1653  rNext->clear();
1654  //cout << " iS+iLen " << (int) (iS+iLen) << endl;
1655  PickUpHits( *rCurr, *rNext, iS+iLen );
1657  rCurr=rNext;
1658 //draw cells
1659 #ifdef MAIN_DRAW1
1662 #endif
1663  rNext = rr;
1664  }
1665  nPlets = *rCurr;
1666 }
1667 
1668 
1670 {
1671  next.SetStation( curr.IStation() );
1672  next.clear();
1673 
1674  if ( curr.size() <= 0 ) return;
1675 
1676  next.reserve(5*curr.size());
1677 
1678  const float_v Pick2 = fPick*fPick;
1679  const FTSCAHits* allHits = curr.HitsRef();
1680  const FTSCAElementsOnStation<FTSCAHit> &hits = allHits->OnStationConst( iS );
1681  //ATTENTION the hit-size is doubled because of lr-division
1682  //therefore twice more than necessary track-segments are created
1683 
1684  for( unsigned int iD1 = 0; iD1 < curr.size(); ++iD1 )
1685  {
1686  FTSCANPletV& D1 = curr[iD1];
1687  float_m valid1G = D1.IsValid();
1688  if( valid1G.isEmpty() ) continue;
1689  //mod:begin
1690  /*PndFTSCATrackParamVector paramTransp;
1691  paramTransp = D1.ParamRef();
1692  float_m activeTransp = valid1G;
1693  activeTransp &= paramTransp.Transport( hits[0], GetParameters(), valid1G );*/
1694  //mod:end
1695  for( unsigned int ih=0; ih<hits.size(); ih++ )
1696  {
1697  const FTSCAHit &hit = hits[ih];
1698  float_m active = valid1G;
1699  //27.09 float_m active = activeTransp;
1701  param = D1.ParamRef();
1702  //27.09 param = paramTransp;
1703  //init by hit
1704  if (param.Tx()[0] == 0.f)
1705  {
1706  param.Tx() = (hit.X1() - param.X())/(hit.X0() - param.Z());
1707  }
1708  //cout<<"D1.param \n"<<param<<"\n ";
1709  //cout<<"adding hit X0 "<<hit.X0()<<" X1 "<<hit.X1()<<endl;
1710 
1711  //TODO get this procedure out of the cycle
1712  active &= param.Transport( hit, GetParameters(), valid1G );
1713 
1714  if (param.Cov(0)[0] < 0.f) param.Cov(0)[0] = 0.2;
1715 
1716  if ( active.isEmpty() ) continue;
1717 
1718  const float_v dx1 = hit.X1() - param.X1();
1719 
1720  const float_v Pick_temp = float_v(10.0*10.0);
1721  int coeff=1;
1722 
1723  float_v OOnne = float_v(1.0*1.0);
1724  float_v Correction2= param.Tx()*param.Tx() + OOnne;
1725 
1726  if (param.Err2X1() > hit.Err2X1()*hit.Err2X1() )
1727  {
1728  active &= dx1*dx1 < Pick_temp*((hit.R()*hit.R() + hit.Err2R())*Correction2 + hit.Err2X1());
1729  }
1730  else
1731  {
1732  active &= dx1*dx1 < coeff*Pick2*(param.Err2X1() + hit.Err2X1() + hit.Err2R()*Correction2);
1733  }
1734 
1735  if ( active.isEmpty() ) continue;
1736 
1737  active &= param.Filter( hit, GetParameters(), active, TRIPLET_CHI2_CUT );
1738 
1739  if ( active.isEmpty() ) continue;
1740 
1741  TrackHitRecord hitRecord;
1742  hitRecord.fStation = iS;
1743  hitRecord.fIHit = ih;
1744  FTSCANPletV nPlet( D1, iS, ih, param, active );
1745  //compare these two constructors and if necessary update the new one with features from the old
1746  //FTSCANPletV( D1, D2, iV, param, active )
1747  nPlet.fLastHit = -1;
1748  foreach_bit( unsigned int iBit, active )
1749  {
1750  nPlet.fLastHit[iBit] = gTrackHitRecords.size();
1751  hitRecord.fPrevHit = D1.fLastHit[iBit];
1752  gTrackHitRecords.push_back(hitRecord);
1753  }
1754 
1755  //if (nPlet.N()>1)
1756  //{ //amount of hits on the segment is manual
1757  //cout<<"beforeRefit N "<<nPlet.N()<<" QP "<<nPlet.Param().QP()<<" tx "<<nPlet.Param().Tx()<<" ty "<<nPlet.Param().Ty()<<" Chi2 "<< nPlet.Param().Chi2()<<" NDF "<< nPlet.Param().NDF()<<endl;
1758  //05.10 if ( (Refit( nPlet, *allHits)).isEmpty() ) continue;
1759  //cout<<"afterRefit N "<<nPlet.N()<<" QP "<<nPlet.Param().QP()<<" tx "<<nPlet.Param().Tx()<<" ty "<<nPlet.Param().Ty()<<" Chi2 "<< nPlet.Param().Chi2()<<" NDF "<< nPlet.Param().NDF()<<endl;
1760  //08.09 if ( (nPlet.Param().Chi2() < TRIPLET_CHI2_CUT).isEmpty() ) continue;
1761  //25.08 if ( nPlet.Param().Chi2()[0] > TRIPLET_CHI2_CUT ) continue;
1762  next.push_back( nPlet );
1763  //}
1764  //else {next.push_back( nPlet );}
1765  //cout<<"nPlet.N() "<<nPlet.N()<<" nPlet.Param().QP() "<<nPlet.Param().QP()<<endl;
1766  }
1767  }
1768 }
1769 
1770 //#include "SQM.h"
1771 
1772 
1773 float_m PndFTSCAGBTracker::Refit( FTSCANPletV& triplet, const FTSCAHits& hits )
1774 {
1775  //* Fitting of the triplet by using Kalman Filter.
1776 
1777  const int N = triplet.N();
1778 
1779  PndFTSCATrackParamVector &param = triplet.Param();
1780 
1781  vector<FTSCAHitV> thits( N );
1782 
1783  float_m active = triplet.IsValid();
1784  for ( int ihit = 0; ihit < N; ihit++ ) {
1785  const TESV& index = triplet.IHit(ihit);
1786 
1787  FTSCAHit hs[float_v::Size];
1788  foreach_bit(unsigned int iV, active) {
1789  hs[iV] = hits[index.s[iV]][index.e[iV]];
1790  }
1791  thits[ihit] = FTSCAHitV( hs, active );
1792  }
1793 
1794  const FTSCAHitV& hit0 = thits[0];
1795 
1796  FTSCATarget target = fTarget;
1797 
1798  //const float_v qp = param.QP();
1799  //param.SetQP(qp);
1800 
1801  /*param.InitByTarget(target);
1802  param.InitDirection( hit0.X0(), hit0.X1(), hit0.X2() );
1803  param.SetAngle( hit0.Angle() );*/
1804 
1805  //param.Transport( hit0, GetParameters(), active );
1806  param.InitByTarget(target);
1807 
1808  //direction initialization (tx,ty) by hit-neighbour
1809 // if (hit0.IsValid() != thits[1].IsValid())
1810 // {
1811 // //FTSCAHitV hit1(); //create from thits[1] such a hit-set that it would work out with all hits from thits[0]
1812 // cout<<"WE'VE GOT A PROBLEM \n";
1813 // }
1814  //param.InitDirection(thits[1].X0() - hit0.X0(), thits[1].X1() - hit0.X1(), thits[1].X2() - hit0.X2());
1815  param.InitDirection( hit0.X0(), hit0.X1(), hit0.X2() );
1816  param.SetAngle( hit0.Angle() );
1817 
1818  //param.InitCovMatrix(target.Err2QMom());
1819  //cout<<"1. fit fwd NDF "<<param.NDF()<<" Chi2 "<<param.Chi2()<<endl;
1820  //fit fwd
1821  for ( int ihit = 0; ihit < N; ihit++ )
1822  {
1823  const FTSCAHitV& hit = thits[ihit];
1824  active &= param.Transport( hit, GetParameters(), active );
1825  active &= param.Filter( hit, GetParameters(), active );
1826  //cout<<"1.after filter NDF "<<param.NDF()<<" Chi2 "<<param.Chi2()<<endl;
1827  }
1828  //param.PrintCovMat();
1829  //param.InitCovMatrix(target.Err2QMom());
1830  int_v ndf;
1831  ndf(static_cast<int_m>(active)) = -4;
1832  param.SetNDF(ndf);
1833  param.SetChi2(0.f);
1834  //cout<<"2. fit bckwrd NDF "<<param.NDF()<<" Chi2 "<<param.Chi2()<<endl;
1835  //fit bckwd
1836  for ( int ihit = N-2; ihit >= 0; ihit-- )
1837  {
1838  const FTSCAHitV& hit = thits[ihit];
1839  active &= param.Transport( hit, GetParameters(), active );
1840  active &= param.Filter( hit, GetParameters(), active );
1841  //cout<<"2.after filter NDF "<<param.NDF()<<" Chi2 "<<param.Chi2()<<endl;
1842  }
1843  //param.PrintCovMat();
1844  //param.InitCovMatrix(target.Err2QMom());
1845 
1846  param.SetNDF(ndf);
1847  param.SetChi2(0.f);
1848  //cout<<"3. fit fwd NDF "<<param.NDF()<<" Chi2 "<<param.Chi2()<<endl;
1849  //fit fwd
1850  for ( int ihit = 1; ihit < N; ihit++ )
1851  {
1852  const FTSCAHitV& hit = thits[ihit];
1853  active &= param.Transport( hit, GetParameters(), active );
1854  active &= param.Filter( hit, GetParameters(), active );
1855  //cout<<"3.after filter NDF "<<param.NDF()<<" Chi2 "<<param.Chi2()<<endl;
1856  }
1857  //param.PrintCovMat();
1858  //cout<<"NDF "<<param.NDF()<<" Chi2 "<<param.Chi2()<<endl;
1859  //cin.get();
1860  return active;
1861 }
1862 
1863 inline bool IsRightNeighbour( const FTSCANPlet& a, const FTSCANPlet& b, float pick, float& chi2 )
1864 {
1865  int start = (a.N() < b.N() ) ? 0 : a.N() - b.N();
1866  for( int i = start; i<a.N()-StartStationShift; i++)
1867  {
1868  if ( a.IHit(i+StartStationShift) != b.IHit(i) )
1869  {
1870  return false;
1871  }
1872  }
1873 
1874  //chi2 = fabs(a.QMomentum() - b.QMomentum())/sqrt(a.QMomentumErr2() + b.QMomentumErr2());
1875 
1876  chi2= fabs(a.Param().Tx() - b.Param().Tx())/sqrt(a.Param().Err2Tx() + b.Param().Err2Tx());
1877  //cout<<"b.ISta(b.N()-1) "<<b.ISta(b.N()-1)<<endl;
1878  if (b.ISta(b.N()-1)==26)
1879  {
1880  chi2 = fabs(a.QMomentum() - b.QMomentum())/sqrt(a.QMomentumErr2() + b.QMomentumErr2());
1881  }
1882  /*
1883  float chi2_qp = fabs(a.QMomentum() - b.QMomentum())/sqrt(a.Param().Err2QMomentum() + b.Param().Err2QMomentum());
1884  float chi2_x = fabs(a.Param().X() - b.Param().X())/sqrt(a.Param().Err2X() + b.Param().Err2X());
1885 
1886  cout<<"a.QP "<<a.QMomentum()<<" b.QP "<<b.QMomentum()<<endl;
1887  cout<<"a.C44 "<<a.Param().Err2QMomentum()<<" b.C44 "<<b.Param().Err2QMomentum()<<endl;
1888  cout<<"a.Tx() "<<a.Param().Tx()<<" b.Tx() "<<b.Param().Tx()<<endl;
1889  cout<<"a.C22 "<<a.Param().Err2Tx()<<" b.C22 "<<b.Param().Err2Tx()<<endl;
1890  cout<<"a.X() "<<a.Param().X()<<" b.X() "<<b.Param().X()<<endl;
1891  cout<<"a.C00 "<<a.Param().Err2X()<<" b.C00 "<<b.Param().Err2X()<<endl;
1892  cout<<"dif qp "<<a.QMomentum()-b.QMomentum()<<" tx "<<a.Param().Tx()-b.Param().Tx()<<" x "<<a.Param().X()-b.Param().X()<<endl;
1893  cout<<"chi2_tx "<<chi2<<" chi2_qp "<<chi2_qp<<" chi2_x "<<chi2_x<<endl;
1894  */
1895  if ( chi2 > pick ) return false; // neighbours must have same qp (or some other criteria)
1896 
1897  chi2 *= chi2;
1898  //cout<<"picked neigh \n";
1899  //cout<<endl;
1900  return true;
1901 }
1902 
1903 // find and store neighbours triplets
1904 // to make recursive search faster saves only neighbours with level = level - 1
1906 {
1907  for( int iS = triplets.NStations() - 1; iS >= 0; --iS )
1908  { // CHECKME
1909  FTSCAElementsOnStation<FTSCANPlet>& ts1 = triplets.OnStation( iS );
1910  for( unsigned int iT1 = 0; iT1 < ts1.size(); ++iT1 )
1911  {
1912  FTSCANPlet& t1 = ts1[iT1];
1913  int neighIStation = t1.ISta(0) + StartStationShift;
1914  //cout<<"neighIStation "<<neighIStation<<endl;
1915  if ( neighIStation >= triplets.NStations() ) continue; // triplets can't start from this (non-existent) station
1916 
1917  FTSCAElementsOnStation<FTSCANPlet>& ts2 = triplets.OnStation( neighIStation );
1918  /*if (ts2.size()==0)
1919  {
1920  int ncalls = 0;
1921  while (triplets.OnStation( neighIStation ).size()==0 && (neighIStation >=0 && neighIStation<47))
1922  {
1923  if (ncalls>5) break;
1924  if (neighIStation==iS) {neighIStation-=1; continue;}
1925  neighIStation-=1;
1926  ncalls++;
1927  }
1928  }
1929  ts2 = triplets.OnStation( neighIStation );*/
1930  char maxLevel = -1; // maxLevel of neighbour triplets
1931  vector< pair<float,unsigned int> > neighCands; // save neighbour candidates
1932  for( unsigned int iT2 = 0; iT2 < ts2.size(); ++iT2 )
1933  {
1934  const FTSCANPlet& t2 = ts2[iT2];
1935  float chi2;
1936  if( !IsRightNeighbour( t1, t2, fPick, chi2 ) ) continue;
1937  if ( maxLevel < t2.Level() ) maxLevel = t2.Level();
1938  if ( maxLevel == t2.Level() ) neighCands.push_back(pair<float,unsigned int>(chi2 + t2.Chi2Level(),iT2));
1939  }
1940  t1.Level() = maxLevel + 1;
1941  //cout<<"neighCands.size() "<<neighCands.size()<<endl;
1942  //save
1943  for( unsigned int iN = 0; iN < neighCands.size(); ++iN )
1944  {
1945  const FTSCANPlet& t2 = ts2[ neighCands[iN].second ];
1946  //cout<<" t2.Level() "<<int(t2.Level())<<" maxLevel "<<int(maxLevel)<<endl;
1947  if ( maxLevel == t2.Level() )
1948  {
1949  //cout<<"Adding this one to Neighbours-list \n";
1950  //cout<<"maxLevel "<<int(maxLevel)<<endl;
1951  t1.Neighbours().push_back( neighCands[iN] );
1952  }
1953  }
1954  sort( t1.Neighbours().begin(), t1.Neighbours().end() );
1955  //cout<<"t1.NNeighbours() "<<t1.NNeighbours()<<endl;
1956  if ( t1.NNeighbours()>0 )
1957  {
1958  t1.Chi2Level() = t1.Chi2Neighbours(0);
1959  const pair<float,unsigned int> tmp = t1.Neighbours()[0]; // leave only one. CHECKME for 1000tracks events
1960  t1.Neighbours().clear();
1961  t1.Neighbours().push_back( tmp );
1962  //cout<<"Got a neighbour! \n";
1963  }
1964  } // iTrip1
1965 
1966  //sort( ts1.begin(), ts1.end(), PndCANPlet::compare );
1967  } //iStation
1968 }
1969 
1971 {
1972  const int Nlast = PndFTSCAParameters::LastCellLength; // N hits in the rightmost triplet
1973 
1974  int min_level = 1; // min level to start triplet. So min track length = min_level+3.
1975 
1976  // collect consequtive: the longest tracks, shorter, more shorter and so on
1977  for (int ilev = NStations()-Nlast; ilev >= min_level; ilev--)
1978  { // choose length
1979  FTSCATracks vtrackcandidate( tracks.HitsRef() );
1980  //how many levels to check
1981 
1982  //lose maximum one hit and find all hits for min_level
1983  //const unsigned char min_best_l = (ilev > min_level) ? ilev-1 : min_level;
1984  //find all hits (slower)
1985  const unsigned char min_best_l = ilev + 3;
1986  //find candidates
1987  for( int istaF = 0; istaF <= NStations()-Nlast-ilev; istaF++ )
1988  {
1989  const FTSCAElementsOnStation<FTSCANPlet>& tsF = triplets.OnStation( istaF );
1990  for( unsigned int iTrip=0; iTrip < tsF.size(); iTrip++ )
1991  {
1992  const FTSCANPlet* tripF = &(tsF[iTrip]);
1993  if (0)
1994  { // ghost supression !!!
1995  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
1996  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
1997  if ( (ilev == 0) && (tripF->ISta(0) != 0) ) continue; // ghost supression // collect only MAPS tracks-triplets
1998  }
1999  if ( tripF->Level() < min_best_l ) continue;
2000 
2001  FTSCATrack curr_tr;
2002 
2003  bool isUsed = false;
2004  for( int i = 0; i < tripF->N(); i++ )
2005  {
2006  if( triplets.OnStation( tripF->ISta(0) ).GetHit( i, iTrip ).IsUsed() )
2007  {
2008  isUsed = true;
2009  break;
2010  }
2011  curr_tr.AddHit( tripF->IHit(i) );
2012  }
2013  if (isUsed) continue;
2014  curr_tr.Level()++;
2015  curr_tr.Chi2() = tripF->Param().Chi2();
2016 
2017  FTSCATrack best_tr = curr_tr;
2018  unsigned int nCalls = 0;
2019  FindBestCandidate(istaF, best_tr, iTrip, curr_tr, min_best_l, triplets, nCalls );
2020 
2021  if ( best_tr.Level() < min_best_l ) continue;
2022  if ( best_tr.NHits() < PndFTSCAParameters::MinimumHitsForRecoTrack ) continue;
2023 
2024 // if ( best_tr.Fit( *tracks.HitsRef(), fTarget, GetParameters(), tripF->QMomentum() ).QPt() > 0.5*fMaxInvMom ) continue; // fit to determine Chi2 and NDF
2025 
2026  vtrackcandidate.push_back(best_tr);
2027  // best_tr.SetHitsAsUsed(*tracks.HitsRef()); TODO
2028  // tracks.push_back(best_tr);
2029  }
2030  } // istaF
2031 
2032  // select and save best candidates
2033  vtrackcandidate.SelectAndSaveTracks( tracks );
2034  } // ilev
2035 
2036 }
2037 
2039  int ista,
2040  FTSCATrack &bT, // best track
2041  int currITrip, // index of current triplet
2042  FTSCATrack &cT, // current track
2043  unsigned char min_best_l,
2044  const FTSCANPlets& triplets,
2045  unsigned int& nCalls)
2046 {
2047 //if (nCalls > 100) return; // avoid long processing in confusing cases
2048  nCalls++;
2049 
2050  const FTSCAElementsOnStation<FTSCANPlet>& trs = triplets.OnStation( ista );
2051  const FTSCANPlet* curr_trip = &(trs[currITrip]);
2052 
2053  if (curr_trip->Level() == 0) // && nCalls>7)
2054  { // the end of the track -> check and store
2055 
2056  // -- finish with current track
2057 
2058 // if( cT.Level() < min_best_l - 1 ) return; // suppose that only one hit can be added by extender
2059 // cT.Fit( *trs.HitsRef(), fTarget, GetParameters() ); // fit to determine Chi2 and NDF // takes 20 times more time then the rest
2060 
2061  // -- select the best
2062  if ( (cT.NDF() > bT.NDF()) || ( (cT.NDF() == bT.NDF()) && (cT.Chi2() < bT.Chi2()) ) )
2063  bT = cT;
2064 
2065  }
2066  else
2067  { // level != 0
2068 
2069  // try to extend. try all possible triplets
2070  int NNeighs = curr_trip->NNeighbours();
2071  for (int in = 0; in < NNeighs; in++)
2072  {
2073  int newITrip = curr_trip->INeighbours(in);
2074  const FTSCANPlet* new_trip = &(triplets.OnStation( curr_trip->ISta(0) + StartStationShift )[newITrip]);
2075 
2076  // check new triplet
2077  bool isUsed = false;
2078  const int newTripLength = new_trip->N();
2079  ASSERT( newTripLength - curr_trip->N() >= -1, newTripLength << " - " << curr_trip->N() );
2080  for( int i = curr_trip->N() - 1; i < newTripLength; i++ )
2081  {
2082  if( triplets.OnStation( new_trip->ISta(0) ).GetHit( i, newITrip ).IsUsed() )
2083  {
2084  isUsed = true;
2085  break;
2086  }
2087  }
2088 
2089  if (isUsed)
2090  {
2091  // cT.Fit( *trs.HitsRef(), fTarget, GetParameters() ); // fit to determine Chi2 and NDF
2092 
2093  // no used hits allowed -> compare and store track
2094  if ( (cT.NDF() > bT.NDF()) || ( (cT.NDF() == bT.NDF()) && (cT.Chi2() < bT.Chi2()) ) )
2095  bT = cT;
2096  }
2097  else
2098  { // add new triplet to the current track
2099 
2100  // restore current track
2101  // save current tracklet
2102  FTSCATrack nT = cT; // new track
2103 
2104  // add new triplet
2105  nT.Level()++;
2106  int start = curr_trip->N() - StartStationShift;
2107  if( start<0 ) start = 0;
2108  for( int i = start; i < newTripLength; i++ )
2109  {
2110  nT.AddHit( new_trip->IHit(i) );
2111  }
2112 
2113  const float qp1 = curr_trip->QMomentum();
2114  const float qp2 = new_trip->QMomentum();
2115  float dqp = fabs(qp1 - qp2);
2116  float Cqp = curr_trip->QMomentumErr();
2117  Cqp += new_trip->QMomentumErr();
2118  dqp = dqp/Cqp;
2119  nT.Chi2() += dqp*dqp;
2120  FindBestCandidate(new_trip->ISta(0), bT, newITrip, nT, min_best_l, triplets, nCalls);
2121  } // add triplet to track
2122  } // for neighbours
2123  } // level != 0
2124 }
2125 
2126 
2128 {
2129  const int NTracksS = tracks.size();
2130  vector< pair<PndFTSCATrackParam,PndFTSCATrackParam> > fittedTracks;
2131  fittedTracks.reserve(NTracksS);
2132  //cout<<"NTracksS "<<NTracksS<<endl;
2133  tracks.SortTracksByZ();
2134  for ( int iT1 = 0; iT1 < NTracksS; iT1++ )
2135  {
2136  FTSCATrack& t1 = tracks[iT1];
2137  PndFTSCATrackParam outerParam = t1.Fit( *tracks.HitsRef(), fTarget, GetParameters(), false );
2138  //PndFTSCATrackParam outerBufParam = outerParam;
2139  PndFTSCATrackParam innerParam = t1.Fit( *tracks.HitsRef(), fTarget, GetParameters(), true); //, true, outerParam); //we use the obtained outerParam as seed to avoid numerical divergencies
2140  if (abs(innerParam.Err2X())>20. || isnan(innerParam.Err2X()))
2141  {
2142  //innerParam = t1.Fit( *tracks.HitsRef(), fTarget, GetParameters(), true, true, outerParam );
2143  innerParam = outerParam;
2144  innerParam.SetX((*tracks.HitsRef())[t1.IHits()[0]].X1());
2145  innerParam.SetY((*tracks.HitsRef())[t1.IHits()[0]].X2());
2146  innerParam.SetZ((*tracks.HitsRef())[t1.IHits()[0]].X0());
2147  innerParam.SetTX(innerParam.X()/innerParam.Z());
2148  innerParam.SetTY(innerParam.Y()/innerParam.Z());
2149  }
2150  if (abs(outerParam.Err2X())>20. || isnan(outerParam.Err2X()))
2151  {
2152  outerParam = innerParam;
2153  outerParam.SetX((*tracks.HitsRef())[t1.IHits()[t1.NHits()-1]].X1());
2154  outerParam.SetY((*tracks.HitsRef())[t1.IHits()[t1.NHits()-1]].X2());
2155  outerParam.SetZ((*tracks.HitsRef())[t1.IHits()[t1.NHits()-1]].X0());
2156  outerParam.SetTX(outerParam.X()/outerParam.Z());
2157  outerParam.SetTY(outerParam.Y()/outerParam.Z());
2158  }
2159  fittedTracks.push_back(pair<PndFTSCATrackParam,PndFTSCATrackParam>(innerParam,outerParam));
2160  //float X0_back = (*tracks.HitsRef())[t1.IHits()[0]].X0();
2161  //float X0_front = (*tracks.HitsRef())[t1.IHits()[t1.NHits()-1]].X0();
2162  //cout<<"Z_first "<<X0_back<<" Z_last "<<X0_front<<endl;
2163  //cout<<"InnerParam.X() "<<innerParam.X()<<" OuterParam.X() "<<outerParam.X()<<endl;
2164  }
2165  //PndFTSCATrackParam recursiveParam;
2166 
2167  for ( int iT_middle = 0; iT_middle < NTracksS; iT_middle++ )
2168  {
2169  FTSCATrack& t_middle = tracks[iT_middle];
2170  //cout<<"t_middle.NHits() "<<t_middle.NHits()<<endl;
2171  if ( t_middle.NHits() <= 0 ) continue;
2172  PndFTSCATrackParam t_middleOuter;
2173  t_middleOuter = fittedTracks[iT_middle].second;
2174  //try to extend forward (from the last hit in middle-track to the first hit in end-track)
2175  for ( int iT_end = 0; iT_end < NTracksS; iT_end++ )
2176  {
2177  FTSCATrack& t_end = tracks[iT_end];
2178  //cout<<"t_end.NHits() "<<t_end.NHits()<<endl;
2179  if (( t_end.NHits() <= 0 ) || (iT_middle==iT_end)) continue;
2180  const float xDiff1 = (*tracks.HitsRef())[t_end.IHits().front()].X0() - (*tracks.HitsRef())[t_middle.IHits().back()].X0();
2181  if (xDiff1<=0) continue;
2182 
2183  PndFTSCATrackParam t_endInner = fittedTracks[iT_end].first;
2184  //cout<<"t_endInner.Z() "<<t_endInner.Z()<<" t_middleOuter.Z() "<<t_middleOuter.Z()<<endl;
2185  //cout<<"before transp t2Outer.X() "<<(fittedTracks[iT2].second).X()<<" t1Inner.X() "<<(fittedTracks[iT1].first).X()<<endl;
2186  float Xt_endInnerBuf = t_endInner.X();
2187  float Xt_middleOuterBuf = t_middleOuter.X();
2188 
2189  //PndFTSCATrackParam buf_t_end = t_endInner;
2190  PndFTSCATrackParam buf_t_middle = t_middleOuter;
2191 
2192  t_endInner.Transport( (*tracks.HitsRef())[t_middle.IHits().back()], GetParameters() );
2193  t_middleOuter.Transport( (*tracks.HitsRef())[t_end.IHits().front()], GetParameters() );//HINT because sometimes backward fit fails
2194 
2195  if (abs(t_middleOuter.Err2X())>20. || isnan(t_middleOuter.Err2X()))
2196  {
2197  float coefQP = 10.;
2198  int counterX = 0;
2199  while ((abs(t_middleOuter.Err2X())>20. || isnan(t_middleOuter.Err2X())) && (counterX<5))
2200  {
2201  t_middleOuter = buf_t_middle;
2202  t_middleOuter.SetQP(buf_t_middle.QP()/coefQP);
2203  t_middleOuter.Transport( (*tracks.HitsRef())[t_end.IHits().front()], GetParameters() );
2204  counterX+=1;
2205  coefQP/=2.;
2206  }
2207  }
2208  //cout<<"1. after transp t_endInner.X() "<<t_endInner.X()<<" t_middleOuterBufX "<<Xt_middleOuterBuf<<endl;
2209  //cout<<"2. after transp t_middleOuter.X() "<<t_middleOuter.X()<<" t_endInnerBufX "<<Xt_endInnerBuf<<endl;
2210  float coef1=1.;
2211  float deltaX1=0;
2212  if (xDiff1<1)
2213  deltaX1=2.5;
2214  if (xDiff1>=1 && xDiff1<6)
2215  deltaX1=5.0;
2216  if (xDiff1>=6 && xDiff1<10)
2217  deltaX1=7.5;
2218  if (xDiff1>=10 && xDiff1<20)
2219  deltaX1=10.0;
2220  if (xDiff1>=20 && xDiff1<30)
2221  deltaX1=11.0;
2222  if (xDiff1>=30)
2223  deltaX1=12.0;
2224  if (xDiff1>=120)
2225  deltaX1=25.0;
2226 
2227  if ((fabs(t_endInner.X()-Xt_middleOuterBuf)<deltaX1*coef1) || (fabs(t_middleOuter.X()-Xt_endInnerBuf)<deltaX1*coef1))
2228  {
2229  //merge t_middle & t_end
2230  //cout<<"MERGED t_middle & t_end \n";
2231  for ( int ih = 0; ih < t_end.NHits(); ih++ )
2232  {
2233  t_middle.AddHit( t_end.IHits()[ih] );
2234  }
2235  t_end.IHits().clear(); //marking this track as used
2236  }
2237  //recursiveParam = fittedTracks[iT_middle].first;
2238  //try to extend backward (from the first hit in middle-track to the last hit in start-track)
2239 
2240 /*
2241  for ( int iT_start = 0; iT_start < NTracksS; iT_start++ )
2242  {
2243  FTSCATrack& t_start = tracks[iT_start];
2244  //cout<<"t_start.NHits() "<<t_start.NHits()<<endl;
2245  if (( t_start.NHits() <= 0 ) || (iT_middle==iT_start) ) continue;
2246  const float xDiff2 = (*tracks.HitsRef())[t_start.IHits().front()].X0() - (*tracks.HitsRef())[t_middle.IHits().back()].X0();
2247  if (xDiff2>=0) continue;
2248 
2249  PndFTSCATrackParam t_startOuter = fittedTracks[iT_start].second;
2250  //recursiveParam=t_middleInner
2251  cout<<"t_startOuter.Z() "<<t_startOuter.Z()<<" t_middleInner.Z() "<<recursiveParam.Z()<<endl;
2252  //cout<<"before transp t2Outer.X() "<<(fittedTracks[iT2].second).X()<<" t1Inner.X() "<<(fittedTracks[iT1].first).X()<<endl;
2253  float Xt_startOuterBuf = t_startOuter.X();
2254  float Xt_middleInnerBuf = recursiveParam.X();
2255 
2256  t_startOuter.Transport( (*tracks.HitsRef())[t_middle.IHits().front()], GetParameters() );
2257  recursiveParam.Transport( (*tracks.HitsRef())[t_start.IHits().back()], GetParameters() );//HINT because sometimes backward fit fails
2258 
2259  cout<<"1. after transp t_startOuter.X() "<<t_startOuter.X()<<" Xt_middleInnerBuf "<<Xt_middleInnerBuf<<endl;
2260  cout<<"2. after transp t_middleInner.X() "<<recursiveParam.X()<<" Xt_startOuterBuf "<<Xt_startOuterBuf<<endl;
2261 
2262  float coef2=1.;
2263  float deltaX2=0;
2264  if (xDiff2>-1)
2265  deltaX2=2.5;
2266  if (xDiff2<=-1 && xDiff2>-6)
2267  deltaX2=5.0;
2268  if (xDiff2<=-6 && xDiff2>-10)
2269  deltaX2=7.5;
2270  if (xDiff2<=-10 && xDiff2>-20)
2271  deltaX2=10.0;
2272  if (xDiff2<=-20 && xDiff2>-30)
2273  deltaX2=12.5;
2274  if (xDiff2<=-30)
2275  deltaX2=15.0;
2276  if ((fabs(t_endInner.X()-Xt_middleOuterBuf)<deltaX2*coef2) || (fabs(t_middleOuter.X()-Xt_endInnerBuf)<deltaX2*coef2))
2277  {
2278  //merge t_middle & t_start
2279  cout<<"MERGED t_middle & t_start \n";
2280  t_middle.AddHitsToTheBeginning(t_start.IHits());
2281  t_start.IHits().clear(); //marking this track as used
2282  }
2283  }//iT_start
2284 */
2285  }//iT_end
2286  }//iT_middle
2287 
2288  //remove tracks, which were atached to other tracks
2289  //remove clones if any
2290  FTSCATracks tracks_saved = tracks;
2291  tracks.clear();
2292  //bool addTrack = true;
2293  for ( int iT1 = 0; iT1 < NTracksS; iT1++ )
2294  {
2295  FTSCATrack& t1 = tracks_saved[iT1];
2296  if (t1.NHits() != 0)
2297  tracks.push_back(t1);
2298 
2299  }
2300  /*tracks_saved = tracks;
2301  tracks.clear();
2302  tracks_saved.SelectAndSaveTracks(tracks);*/
2303 }
2304 
2305 //END@@@@!!!!STT===>>>FTS COMBINATORIAL PART!!!!@@@@@
2306 
2308 {
2309  //* Estimate coordinates of the primary vertex.
2310 
2311  int iS = 0;
2312  const float maxZ = GetParameters().MaxZ();
2313  const float maxPVR = 0.1; // max distance between PV and beam line
2314  const unsigned int N = 2*maxZ/0.01; // n bins in histo
2315 
2316  vector<float> pvHist(N,0);
2317  const FTSCAElementsOnStation<FTSCAHitV>& s = all.OnStation( iS );
2318  const FTSCAElementsOnStation<FTSCAHitV>& s2 = all.OnStation( iS+1 );
2319  for( unsigned int i = 0; i < s.size(); ++i ) {
2320  const FTSCAHitV &h = s[i];
2321  foreach_bit( int iV, h.IsValid() ) {
2322  float gx, gy, gz;
2323  h.GetGlobalCoor( iV, gx, gy, gz );
2324  PndFTSCAParameters::CALocalToGlobal(float(h.X0()[iV]), float(h.X1()[iV]), float(h.X2()[iV]), float(h.Angle()[iV]), gx, gy, gz);
2325  float r = sqrt(gx*gx+gy*gy);
2326 
2327  for( unsigned int i2 = 0; i2 < s2.size(); ++i2 ) {
2328  const FTSCAHitV &h2 = s2[i2];
2329  foreach_bit( int iV2, h2.IsValid() ) {
2330  float gx2, gy2, gz2;
2331  h2.GetGlobalCoor( iV2, gx2, gy2, gz2 );
2332  float r2 = sqrt(gx2*gx2+gy2*gy2);
2333 
2334  float gz0 = -(gz2-gz)/(r2-r)*r + gz;
2335  float gx0 = -(gx2-gx)/(r2-r)*r + gx;
2336  float gy0 = -(gy2-gy)/(r2-r)*r + gy;
2337  if ( abs(gz0) < maxZ && abs(gx0) < maxPVR && abs(gy0) < maxPVR )
2338  pvHist[(gz0/maxZ+1)*N/2]++;
2339  }
2340  }
2341  }
2342 
2343  }
2344 
2345 #ifdef DRAW_CA
2346  const double *pv = PndFTSCAPerformance::Instance().PV(); // dbg
2349  PndFTSCADisplay::Instance().DrawGBPoint(pv[0],pv[1],pv[2],2,0.5);
2350  PndFTSCADisplay::Instance().SaveCanvasToFile( "DrawPVHisto.pdf" );
2352 #endif
2353 
2354  float max = -1;
2355  int maxI = -1;
2356  for( unsigned int i = 0; i < pvHist.size(); ++i ) {
2357  if ( max < pvHist[i] ) {
2358  max = pvHist[i];
2359  maxI = i;
2360  }
2361  }
2362 
2363  zPV = (2.f*maxI/N-1)*maxZ;
2364 }
2365 
2366 
2368 {
2369  float d[5], uud, u[5][5];
2370  for(int i=0; i<5; i++)
2371  {
2372  d[i]=0.f;
2373  for(int j=0; j<5; j++)
2374  u[i][j]=0.;
2375  }
2376 
2377  for(int i=0; i<5; i++)
2378  {
2379  uud=0.;
2380  for(int j=0; j<i; j++)
2381  uud += u[j][i]*u[j][i]*d[j];
2382  uud = a[i*(i+3)/2] - uud;
2383 
2384  if(fabs(uud)<1.e-12) uud = 1.e-12;
2385  d[i] = uud/fabs(uud);
2386  u[i][i] = sqrt(fabs(uud));
2387 
2388  for(int j=i+1; j<5; j++)
2389  {
2390  uud = 0.;
2391  for(int k=0; k<i; k++)
2392  uud += u[k][i]*u[k][j]*d[k];
2393  uud = a[j*(j+1)/2+i] - uud;
2394  u[i][j] = d[i]/u[i][i]*uud;
2395  }
2396  }
2397 
2398  float u1[5];
2399 
2400  for(int i=0; i<5; i++)
2401  {
2402  u1[i] = u[i][i];
2403  u[i][i] = 1.f/u[i][i];
2404  }
2405  for(int i=0; i<4; i++)
2406  {
2407  u[i][i+1] = - u[i][i+1]*u[i][i]*u[i+1][i+1];
2408  }
2409  for(int i=0; i<3; i++)
2410  {
2411  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];
2412  }
2413  for(int i=0; i<2; i++)
2414  {
2415  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];
2416  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]);
2417  }
2418  u[0][4] = u[0][2]*u1[2]*u[2][4] - u[0][4]*u[0][0]*u[4][4];
2419  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]);
2420  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]));
2421 
2422  for(int i=0; i<5; i++)
2423  a[i+10] = u[i][4]*d[4]*u[4][4];
2424  for(int i=0; i<4; i++)
2425  a[i+6] = u[i][3]*u[3][3]*d[3] + u[i][4]*u[3][4]*d[4];
2426  for(int i=0; i<3; i++)
2427  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];
2428  for(int i=0; i<2; i++)
2429  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];
2430  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];
2431 }
2432 
2433 void PndFTSCAGBTracker::MultiplySS(float const C[15], float const V[15], float K[5][5]) const
2434 {
2435 //*multiply 2 symmetric matricies
2436  K[0][0] = C[0]*V[ 0] + C[1]*V[ 1] + C[3]*V[ 3] + C[6]*V[ 6] + C[10]*V[10];
2437  K[0][1] = C[0]*V[ 1] + C[1]*V[ 2] + C[3]*V[ 4] + C[6]*V[ 7] + C[10]*V[11];
2438  K[0][2] = C[0]*V[ 3] + C[1]*V[ 4] + C[3]*V[ 5] + C[6]*V[ 8] + C[10]*V[12];
2439  K[0][3] = C[0]*V[ 6] + C[1]*V[ 7] + C[3]*V[ 8] + C[6]*V[ 9] + C[10]*V[13];
2440  K[0][4] = C[0]*V[10] + C[1]*V[11] + C[3]*V[12] + C[6]*V[13] + C[10]*V[14];
2441 
2442  K[1][0] = C[1]*V[ 0] + C[2]*V[ 1] + C[4]*V[ 3] + C[7]*V[ 6] + C[11]*V[10];
2443  K[1][1] = C[1]*V[ 1] + C[2]*V[ 2] + C[4]*V[ 4] + C[7]*V[ 7] + C[11]*V[11];
2444  K[1][2] = C[1]*V[ 3] + C[2]*V[ 4] + C[4]*V[ 5] + C[7]*V[ 8] + C[11]*V[12];
2445  K[1][3] = C[1]*V[ 6] + C[2]*V[ 7] + C[4]*V[ 8] + C[7]*V[ 9] + C[11]*V[13];
2446  K[1][4] = C[1]*V[10] + C[2]*V[11] + C[4]*V[12] + C[7]*V[13] + C[11]*V[14];
2447 
2448  K[2][0] = C[3]*V[ 0] + C[4]*V[ 1] + C[5]*V[ 3] + C[8]*V[ 6] + C[12]*V[10];
2449  K[2][1] = C[3]*V[ 1] + C[4]*V[ 2] + C[5]*V[ 4] + C[8]*V[ 7] + C[12]*V[11];
2450  K[2][2] = C[3]*V[ 3] + C[4]*V[ 4] + C[5]*V[ 5] + C[8]*V[ 8] + C[12]*V[12];
2451  K[2][3] = C[3]*V[ 6] + C[4]*V[ 7] + C[5]*V[ 8] + C[8]*V[ 9] + C[12]*V[13];
2452  K[2][4] = C[3]*V[10] + C[4]*V[11] + C[5]*V[12] + C[8]*V[13] + C[12]*V[14];
2453 
2454  K[3][0] = C[6]*V[ 0] + C[7]*V[ 1] + C[8]*V[ 3] + C[9]*V[ 6] + C[13]*V[10];
2455  K[3][1] = C[6]*V[ 1] + C[7]*V[ 2] + C[8]*V[ 4] + C[9]*V[ 7] + C[13]*V[11];
2456  K[3][2] = C[6]*V[ 3] + C[7]*V[ 4] + C[8]*V[ 5] + C[9]*V[ 8] + C[13]*V[12];
2457  K[3][3] = C[6]*V[ 6] + C[7]*V[ 7] + C[8]*V[ 8] + C[9]*V[ 9] + C[13]*V[13];
2458  K[3][4] = C[6]*V[10] + C[7]*V[11] + C[8]*V[12] + C[9]*V[13] + C[13]*V[14];
2459 
2460  K[4][0] = C[10]*V[ 0] + C[11]*V[ 1] + C[12]*V[ 3] + C[13]*V[ 6] + C[14]*V[10];
2461  K[4][1] = C[10]*V[ 1] + C[11]*V[ 2] + C[12]*V[ 4] + C[13]*V[ 7] + C[14]*V[11];
2462  K[4][2] = C[10]*V[ 3] + C[11]*V[ 4] + C[12]*V[ 5] + C[13]*V[ 8] + C[14]*V[12];
2463  K[4][3] = C[10]*V[ 6] + C[11]*V[ 7] + C[12]*V[ 8] + C[13]*V[ 9] + C[14]*V[13];
2464  K[4][4] = C[10]*V[10] + C[11]*V[11] + C[12]*V[12] + C[13]*V[13] + C[14]*V[14];
2465 }
2466 
2467 void PndFTSCAGBTracker::MultiplyMS(float const C[5][5], float const V[15], float K[15]) const
2468 {
2469 //*multiply symmetric and nonsymmetric matricies
2470  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];
2471 
2472  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];
2473  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];
2474 
2475  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];
2476  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];
2477  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];
2478 
2479  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];
2480  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];
2481  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];
2482  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];
2483 
2484  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];
2485  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];
2486  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];
2487  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];
2488  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];
2489 }
2490 
2491 void PndFTSCAGBTracker::MultiplySR(float const C[15], float const r_in[5], float r_out[5]) const
2492 {
2493 //*multiply vector and symmetric matrix
2494  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];
2495  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];
2496  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];
2497  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];
2498  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];
2499 }
2500 
2501 void PndFTSCAGBTracker::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
2502 {
2503  //* Track filtering is realized with the Kalman Filter,
2504  //* which allows one to obtain optimal estimate of track's parameters.
2505 
2506  float S[15];
2507  for(int i=0; i<15; i++)
2508  {
2509  W[i] = C[i];
2510  S[i] = C[i] + V[i];
2511  }
2512  for(int i=0; i<5; i++)
2513  R[i] = r[i];
2514 
2515  InvertCholetsky(S);
2516 
2517  float K[5][5];
2518  MultiplySS(C,S,K);
2519  float dzeta[5];
2520  for(int i=0; i<5; i++) dzeta[i] = m[i] - r[i];
2521  float KC[15];
2522  MultiplyMS(K,C,KC);
2523  for(int i=0; i< 15; i++)
2524  W[i] -= KC[i];
2525 
2526  float kd;
2527  for(int i=0; i<5; i++)
2528  {
2529  kd = 0.f;
2530  for(int j=0; j<5; j++)
2531  kd += K[i][j]*dzeta[j];
2532  R[i] += kd;
2533  }
2534  float S_dzeta[5];
2535  MultiplySR(S, dzeta, S_dzeta);
2536  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];
2537 }
static T ASin(const T &x)
void Merge(FTSCATracks &tracks)
bool ReadSettingsFromFile(string prefix)
Double_t x0
Definition: checkhelixhit.C:70
float QMomentumErr() const
Definition: FTSCANPlets.h:42
float_v X2() const
Definition: FTSCAHitsV.h:51
Int_t t1
Definition: hist-t7.C:106
PndFTSCAParam fParameters
int ISta(int IH) const
Definition: FTSCANPlets.h:36
PndFTSCAGBTrack * fTracks
float_v Err2X1() const
Definition: FTSCAHitsV.h:56
static bool Compare(const PndFTSCAGBHit &a, const PndFTSCAGBHit &b)
Hits reordering in accordance with the geometry and the track-finder needs: Hits are sorted by sector...
L1CATFTimerInfo fTi
int_v s
Definition: FTSCATES.h:42
void SetCov(int i, const float_v &v)
const TESV & IHit(int IH) const
Definition: FTSCANPletsV.h:53
L1CATFTimerInfo fStatTi
void SetTPC(const PndFTSCAParam &tpcParam)
double r
Definition: RiemannTest.C:14
TObjArray * d
unsigned short fIHit
bool Transport(const FTSCAHit &hit, const PndFTSCAParam &param)
const float & Chi2Neighbours(int i) const
Definition: FTSCANPlets.h:52
const int StartStationShift
void DrawRecoTrack(int itr, int color=-1, int width=-1)
const FTSCAStation & Station(short i) const
Definition: PndFTSCAParam.h:45
void DrawPVHisto(const vector< float > &pvHist, const PndFTSCAParam &param)
void InitByHit(const FTSCAHitV &hit, const PndFTSCAParam &param, const float_v &dQMom)
Int_t i
Definition: run_full.C:25
__m128 m
Definition: P4_F32vec4.h:28
TTree * b
float QMomentumErr2() const
Definition: FTSCANPlets.h:43
void SetNIter(int n)
Definition: L1Timer.h:83
int NMCPoints() const
void InitialTrackApproximation(PndFTSCATrackParamVector &t, uint_v &firstHits, uint_v::Memory &NTrackHits, int &nTracksV, float_m active0)
float_m FitTrackCA(PndFTSCATrackParamVector &t, uint_v &firstHits, uint_v::Memory &NTrackHits, int &nTracksV, float_m active0, bool dir, bool init=false)
char IStation() const
Definition: FTSCAHits.h:33
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
PndFTSResizableArray< FTSCAStrip > fBStrips
float X1() const
Definition: FTSCATarget.h:39
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:29
float & Chi2Level()
Definition: FTSCANPlets.h:48
PndRiemannTrack track
Definition: RiemannTest.C:33
void MultiplyMS(float const C[5][5], float const V[15], float K[15]) const
FTSCAHits * HitsRef()
Definition: FTSCATracks.h:135
const unsigned int & INeighbours(int i) const
Definition: FTSCANPlets.h:51
static T Sqrt(const T &x)
Definition: PndCAMath.h:37
float_m IsValid() const
Definition: FTSCANPletsV.h:59
void SetSignCosPhi(const float_v &v)
void SetFirstHitRef(int v)
char IStation() const
Definition: FTSCAHitsV.h:40
bool SINGLE_THREADED
void DrawGBPoint(float x, float y, float z, int Start=1, Size_t width=1)
TLorentzVector s
Definition: Pnd2DStar.C:50
static T Sin(const T &x)
Definition: PndCAMath.h:42
void PickUpHits(FTSCAElementsOnStation< FTSCANPletV > &a, FTSCAElementsOnStation< FTSCANPletV > &r, int iS)
Definition: FTSCATES.h:28
void InvertCholetsky(float a[15]) const
void SetNHits(int v)
void ReadSettings(std::istream &in)
float GetX0(short iSt) const
Definition: PndFTSCAParam.h:61
float Z() const
Definition: PndFTSCAGBHit.h:43
float_m IsValid() const
Definition: FTSCAHitsV.h:38
int FirstHitRef() const
static PndFTSCADisplay & Instance()
friend F32vec4 max(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:26
float GetXOverX0(short iSt) const
Definition: PndFTSCAParam.h:65
double r1
static const fvec Zero
float_v X1() const
Definition: FTSCAHitsV.h:50
double Y
Definition: anaLmdDigi.C:68
double fStatTime[fNTimers]
static T Cos(const T &x)
Definition: PndCAMath.h:43
float_v Angle() const
Definition: FTSCAHitsV.h:73
const FTSCAElementsOnStation< T > & OnStationConst(char i) const
Definition: FTSCAHits.h:134
void SetInnerParam(const PndFTSCATrackParam &v)
float_m Rotate(const float_v &alpha, PndFTSCATrackLinearisationVector &t0, const float maxSinPhi=.999f, const float_m &mask=float_m(true))
void SetOuterParam(const PndFTSCATrackParam &v)
float_m Refit(FTSCANPletV &triplet, const FTSCAHits &hits)
float X0() const
Definition: FTSCAHits.h:41
int NStations() const
float_m AddTarget(const FTSCATarget &target, const float_m &mask=float_m(true))
float X1() const
Definition: FTSCAHits.h:42
float_m FitTrack(PndFTSCATrackParamVector &t, uint_v &firstHits, uint_v::Memory &NTrackHits, int &nTracksV, float_m active0, bool dir)
L1CATFIterTimerInfo fStatGTi
static int init
Definition: ranlxd.cxx:374
float Y() const
Definition: PndFTSCAGBHit.h:42
int N() const
Definition: FTSCANPletsV.h:51
int_v IStations() const
Definition: FTSCAHitsV.h:45
PndFTSResizableArray< FTSCAStrip > fFStrips
PndFTSResizableArray< PndFTSCAGBHit > fHits
int Pic_FED Eff_lEE C()
static T Abs(const T &x)
Definition: PndCAMath.h:39
void EstimatePV(const FTSCAHitsV &hits, float &zPV)
void FindBestCandidate(int ista, FTSCATrack &best_tr, int currITrip, FTSCATrack &curr_tr, unsigned char min_best_l, const FTSCANPlets &triplets, unsigned int &nCalls)
const PndFTSCATrackParam Fit(const FTSCAHits &hits, const FTSCATarget &target, const PndFTSCAParam &caParam, bool dir=true, bool usePar=false, PndFTSCATrackParam outerParam=PndFTSCATrackParam())
Definition: FTSCATracks.h:199
int NHits() const
void Add(string name)
Definition: L1Timer.h:54
FTSCAElementsOnStation< T > & OnStation(char i)
Definition: FTSCAHits.h:135
Int_t a
Definition: anaLmdDigi.C:126
const FTSCAHits * fHitsRef
char NStations() const
#define W
Definition: createSTT.C:76
void SetGB(const PndFTSCAGBTracker *GBTracker)
float_m Transport(const int_v &ista, const PndFTSCAParam &param, const float_m &mask=float_m(true))
Double_t lx
static void GlobalToCALocal(T x, T y, T angle, T &x0, T &x1)
float DQMom() const
Definition: FTSCATarget.h:45
char & Level()
Definition: FTSCATracks.h:67
friend class PndFTSCAPerformance
Try to group close hits in row formed by one track. After sort hits.
int nHits
Definition: RiemannTest.C:16
void InitDirection(float_v r0, float_v r1, float_v r2)
static T Min(const T &x, const T &y)
Definition: PndCAMath.h:35
float X2() const
Definition: FTSCATarget.h:40
float Angle() const
void SetHits(std::vector< PndFTSCAGBHit > &hits)
float QMomentum() const
Definition: FTSCANPlets.h:41
const PndFTSCAParam & GetParameters() const
float_m ok
int_v fLastHit
Definition: FTSCANPletsV.h:80
Double_t y0
Definition: checkhelixhit.C:71
static T ATan2(const T &y, const T &x)
void AddHit(char iS, int iH)
Definition: FTSCATracks.h:36
vector< TES > & IHits()
Definition: FTSCATracks.h:24
FTSCAElementsOnStation< T > & OnStation(char i)
Definition: FTSCAHitsV.h:128
int Size() const
Definition: PndFTSArray.h:374
TFile * f
Definition: bump_analys.C:12
void SaveCanvasToFile(TString fileName)
char & NDF()
Definition: FTSCATracks.h:65
FTSCAElementsOnStation< T > & OnStation(char i)
void CalculateFitParameters(PndFTSCATrackFitParam &par, const float_v &mass=0.13957f)
vector< pair< float, unsigned int > > & Neighbours()
Definition: FTSCANPlets.h:54
int ID() const
Definition: PndFTSCAGBHit.h:57
void SetNHits(int nHits)
friend F32vec4 fabs(const F32vec4 &a)
Definition: P4_F32vec4.h:47
void MultiplySS(float const C[15], float const V[15], float K[5][5]) const
float X() const
Definition: PndFTSCAGBHit.h:41
void SetDeDx(float v)
float X0() const
Definition: FTSCATarget.h:38
void DrawGBNPlets(const FTSCANPletsV &all)
const TES & IHit(int IH) const
Definition: FTSCANPlets.h:35
float_m TransportToX0WithMaterial(const float_v &x, const float_v &XOverX0, const float_v &XThimesRho, const float_v &Bz, const float maxSinPhi=.999f)
const PndFTSCATrackParam & InnerParam() const
void Create1Plets(const FTSCATarget &target, const FTSCAHits &hits, FTSCAElementsOnStation< FTSCANPletV > &singlets, int iStation)
uint_v e
Definition: FTSCATES.h:43
void CreateTracks(const FTSCANPlets &triplets, FTSCATracks &tracks)
double dx
void MultiplySR(float const C[15], float const r_in[5], float r_out[5]) const
float_m FilterWithMaterial(const float_v &y, const float_v &z, float_v err2Y, float_v errYZ, float_v err2Z, float maxSinPhi=0.999f, const float_m &mask=float_m(true), const int_v &hitNDF=int_v(2), const float_v &chi2Cut=10e10f)
Double_t ly
double X
Definition: anaLmdDigi.C:68
unsigned int NNeighbours() const
Definition: FTSCANPlets.h:53
const PndFTSCATrackParam & Param() const
Definition: FTSCANPlets.h:38
float GetXTimesRho(short iSt) const
Definition: PndFTSCAParam.h:66
static T Max(const T &x, const T &y)
Definition: PndCAMath.h:36
void SortTracksByZ()
Definition: FTSCATracks.h:141
vector< TrackHitRecord > gTrackHitRecords
int hit(Int_t nEvents=0, TString inFile="sim.root", TString parFile="par.root", TString inDigi="digi.root", TString outFile="hit.root", Int_t timeBased=0)
Definition: hit.C:1
Int_t t2
Definition: hist-t7.C:106
float & Chi2()
Definition: FTSCATracks.h:63
double mcZ
Definition: anaLmdCluster.C:53
Double_t x
const FTSCAHits * HitsRef() const
void GetGlobalCoor(int iV, float &x, float &y, float &z) const
Definition: FTSCAHitsV.h:75
#define ASSERT(v, msg)
Definition: PndCADef.h:56
double Z
Definition: anaLmdDigi.C:68
static void CALocalToGlobal(T x0, T x1, T angle, T &x, T &y)
bool IsRightNeighbour(const FTSCANPlet &a, const FTSCANPlet &b, float pick, float &chi2)
const float_v & Cov(int i) const
void DrawArc(float x, float y, float r, int Start=1, Size_t width=1)
TTree * t
Definition: bump_analys.C:13
const float_v & Par(int i) const
void FindNeighbours(FTSCANPlets &triplets)
float_v X0() const
Definition: FTSCAHitsV.h:49
int Id() const
Definition: FTSCAHits.h:35
void InitByTarget(const FTSCATarget &target)
void CreateNPlets(const FTSCATarget &target, const FTSCAHitsV &hits, FTSCANPletsV &singlets)
static FiniteReturnTypeHelper< T >::R Finite(const T &x)
CbmHit * hits[nHits]
Definition: RiemannTest.C:19
L1CATFIterTimerInfo fGTi
Double_t y
float_v Err2X2() const
Definition: FTSCAHitsV.h:58
TClonesArray * hh
float_v ErrX12() const
Definition: FTSCAHitsV.h:57
void SetTrackParam(const PndFTSCATrackParamVector &param, const float_m &m=float_m(true))
static int next[96]
Definition: ranlxd.cxx:374
float Err2X1() const
Definition: FTSCAHits.h:50
PndFTSCATrackParamVector & ParamRef()
Definition: FTSCANPletsV.h:57
float MaxZ() const
void Resize(int x)
Definition: PndFTSArray.h:703
const FTSCAHit & Hit(int iH, int iT) const
Definition: FTSCATracks.h:123
const PndFTSCATrackParamVector & Param() const
Definition: FTSCANPletsV.h:55
static const fvec One
Double_t R
Definition: checkhelixhit.C:61
void ConvertTrackParamToVector(PndFTSCATrackParam t0[float_v::Size], int nTracksV)
double r2
char & Level()
Definition: FTSCANPlets.h:45
void DrawGBHits(const FTSCAHitsV &all)
int FirstMCPointID() const
float_m Filter(const FTSCAHitV &hit, const PndFTSCAParam &param, const float_m &mask=float_m(true), const float_v &chi2Cut=10e10f)
int N() const
Definition: FTSCANPlets.h:33
const char & IStation() const
int NHits() const
Definition: FTSCATracks.h:22
void Add(string name)
Definition: L1Timer.h:91