Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
KFParticleTopoReconstructor.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file KFParticleTopoReconstructor.cxx
1 /*
2  * This file is part of KFParticle package
3  * Copyright (C) 2007-2019 FIAS Frankfurt Institute for Advanced Studies
4  * 2007-2019 Goethe University of Frankfurt
5  * 2007-2019 Ivan Kisel <I.Kisel@compeng.uni-frankfurt.de>
6  * 2007-2019 Maksym Zyzak
7  *
8  * KFParticle is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * KFParticle is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 
24 
25 #ifdef KFPWITHTRACKER
26 #include "AliHLTTPCCAGBTracker.h"
27 #endif
28 
29 #include "KFParticleSIMD.h"
30 #include "KFParticleDatabase.h"
31 
32 #include <fstream>
33 #include <iostream>
34 #include "string"
35 using std::string;
36 using std::ofstream;
37 using std::vector;
38 
39 #include "KFPInputData.h"
40 
42 {
46  if(fTracks) delete [] fTracks;
47 }
48 
49 #ifdef HomogeneousField
50 void KFParticleTopoReconstructor::SetField(double b)
51 {
53  KFParticle::SetField(b);
54  KFParticleSIMD::SetField(float(b));
55 }
56 #endif
57 
58 #ifdef KFPWITHTRACKER
59 void KFParticleTopoReconstructor::Init(AliHLTTPCCAGBTracker* tracker, vector<int>* pdg)
60 {
61  if(!fTracks)
63 
64  fTracks[0].Resize(0);
65  fTracks[1].Resize(0);
66  fTracks[2].Resize(0);
67  fTracks[3].Resize(0);
68  fTracks[4].Resize(0);
69  fTracks[5].Resize(0);
70  fTracks[6].Resize(0);
71  fTracks[7].Resize(0);
72 
73 #ifdef USE_TIMERS
74  timer.Start();
75 #endif // USE_TIMERS
76 
77  KFParticle::SetField( tracker->Slice(0).Param().Bz() );
78  KFParticleSIMD::SetField( tracker->Slice(0).Param().Bz() );
79 
80  // create and fill array of tracks to init KFParticleTopoReconstructor
81  const int nTracks = tracker->NTracks();
82  fTracks[1].Resize( int(nTracks/float_vLen+1)*float_vLen );
83  fTracks[5].Resize( int(nTracks/float_vLen+1)*float_vLen );
84  fParticles.clear();
85  int iOTr = 0; // index in out array
86 
87  float_v alpha(Vc::Zero);
88  int nElements=0;
89 
90  for ( int iTr = 0; iTr < nTracks; iTr++ ) {
91  // get track params in local CS
92 
93  bool ok = true;
94  const int q = -(tracker->Tracks()[ iTr ].InnerParam().QPt()>=0 ? 1 : -1);
95 
96  for(int iParamSet=0; iParamSet<2; iParamSet++)
97  {
98  AliHLTTPCCATrackParam trParam;
99  int arrayIndex = -1;
100  if(iParamSet==0)
101  {
102  arrayIndex = 1;
103  trParam = tracker->Tracks()[ iTr ].InnerParam();
104  }
105  if(iParamSet==1)
106  {
107  arrayIndex = 5;
108  trParam = tracker->Tracks()[ iTr ].OuterParam();
109  }
110 
111  const float x0 = 0;
112  trParam.TransportToXWithMaterial( x0, tracker->Slice(0).Param().cBz( ) );
113 
114  // -- convert parameters
115  fTracks[arrayIndex].SetParameter(trParam.X(), 0, iOTr); // X
116  fTracks[arrayIndex].SetParameter(trParam.Y(), 1, iOTr); // Y
117  fTracks[arrayIndex].SetParameter(trParam.Z(), 2, iOTr); // Z
118 
119  const float pt = CAMath::Abs( 1.f / trParam.QPt() );
120 // const int q = -(trParam.QPt()>=0 ? 1 : -1);
121  // if ( pt < 1 ) continue; // dbg
122  ok = ok && !( trParam.NDF() < 10+5); //if ( trParam.NDF() < 10+5 ) continue; // at least 15 hits in track
123  ok = ok && !( trParam.Chi2() > 10*trParam.NDF() ); //if ( trParam.Chi2() > 10*trParam.NDF() ) continue; // dbg
124  // if ( iOTr >= 4 ) continue; // dbg
125 
126  const float cosL = trParam.DzDs();
127  fTracks[arrayIndex].SetParameter(pt * trParam.GetCosPhi(), 3, iOTr); // Px
128  fTracks[arrayIndex].SetParameter(pt * trParam.SinPhi() , 4, iOTr); // Py
129  fTracks[arrayIndex].SetParameter(pt * cosL , 5, iOTr); // Pz
130 
131  // -- convert cov matrix
132  // get jacobian
133  float J[6][6];
134  for (int i = 0; i < 6; i++)
135  for (int j = 0; j < 6; j++)
136  J[i][j] = 0;
137  J[0][0] = 1; // x -> x
138  J[1][1] = 1; // y -> y
139  J[2][2] = 1; // z -> z
140  J[3][3] = -pt * trParam.SinPhi() / trParam.GetCosPhi();
141  J[3][5] = -q * pt * pt * trParam.GetCosPhi(); // q/pt -> px
142  J[4][3] = pt; // sinPhi -> py
143  J[4][5] = -q* pt * pt * trParam.SinPhi(); // q/pt -> py
144  J[5][4] = pt; // dz/ds -> pz
145  J[5][5] = -q* pt * pt * cosL; // q/pt -> pz
146 
147  float CovIn[6][6]; // triangular -> symmetric matrix
148  {
149  CovIn[0][0] = .001f*.001f; // dx. From nowhere. TODO
150  for (int i = 1; i < 6; i++) {
151  CovIn[i][0] = 0;
152  CovIn[0][i] = 0;
153  }
154  int k = 0;
155  for (int i = 1; i < 6; i++) {
156  for (int j = 1; j <= i; j++, k++) {
157  CovIn[i][j] = trParam.Cov()[k];
158  CovIn[j][i] = trParam.Cov()[k];
159  }
160  }
161  }
162 
163  float CovInJ[6][6]; // CovInJ = CovIn * J^t
164  for (int i = 0; i < 6; i++)
165  for (int j = 0; j < 6; j++) {
166  CovInJ[i][j] = 0;
167  for (int k = 0; k < 6; k++) {
168  CovInJ[i][j] += CovIn[i][k] * J[j][k];
169  }
170  }
171 
172  float CovOut[6][6]; // CovOut = J * CovInJ
173  for (int i = 0; i < 6; i++)
174  for (int j = 0; j < 6; j++) {
175  CovOut[i][j] = 0;
176  for (int k = 0; k < 6; k++) {
177  CovOut[i][j] += J[i][k] * CovInJ[k][j];
178  }
179  }
180 
181  float KFPCov[21]; // symmetric matrix -> triangular
182  {
183  int k = 0;
184  for (int i = 0; i < 6; i++) {
185  for (int j = 0; j <= i; j++, k++) {
186  KFPCov[k] = CovOut[i][j];
187  ASSERT( !CAMath::Finite(CovOut[i][j]) || CovOut[i][j] == 0 || fabs( 1. - CovOut[j][i]/CovOut[i][j] ) <= 0.05,
188  "CovOut[" << i << "][" << j << "] == CovOut[" << j << "][" << i << "] : " << CovOut[i][j] << " == " << CovOut[j][i]);
189  }
190  }
191  }
192 
193  if(iParamSet == 0)
194  { // check cov matrix
195  int k = 0;
196  for (int i = 0; i < 6; i++) {
197  for (int j = 0; j <= i; j++, k++) {
198  ok &= CAMath::Finite( KFPCov[k] );
199  }
200  ok &= ( KFPCov[k-1] > 0 );
201  }
202  }
203 
204  if(ok)
205  {
206  int trackPDG = -1;
207  if(pdg)
208  trackPDG = (*pdg)[iTr];
209 
210  for(int iC=0; iC<21; iC++)
211  fTracks[arrayIndex].SetCovariance( KFPCov[iC], iC, iOTr);
212  fTracks[arrayIndex].SetId(iTr, iOTr);
213  fTracks[arrayIndex].SetPDG(trackPDG, iOTr);
214  fTracks[arrayIndex].SetQ(q, iOTr);
215  fTracks[arrayIndex].SetPVIndex(-1, iOTr);
216  }
217  }
218  if (!ok) continue;
219 
220  iOTr++;
221 
222  // convert into Global CS. Can't be done erlier because in tracker X hasn't correspondent covMatrix elements.
223  alpha[nElements] = tracker->Tracks()[ iTr ].Alpha();
224  nElements++;
225  if(nElements == float_vLen)
226  {
227  fTracks[1].RotateXY( alpha, iOTr-nElements);
228  fTracks[5].RotateXY( alpha, iOTr-nElements);
229  nElements=0;
230  }
231  }
232  if(nElements>0)
233  {
234  fTracks[1].RotateXY( alpha, iOTr-nElements);
235  fTracks[5].RotateXY( alpha, iOTr-nElements);
236  }
237 
238  fTracks[0].Resize(iOTr);
239  fTracks[0].Set(fTracks[1],iOTr,0);
240 
241  fTracks[4].Resize(iOTr);
242  fTracks[4].Set(fTracks[5],iOTr,0);
243 
245 #ifdef USE_TIMERS
246  timer.Stop();
247  fStatTime[0] = timer.RealTime();
248 #endif // USE_TIMERS
249 } // void KFParticleTopoReconstructor::Init(AliHLTTPCCAGBTracker* tracker)
250 #endif
251 
252 void KFParticleTopoReconstructor::Init(vector<KFParticle> &particles, vector<int>* pdg, vector<int>* nPixelHits)
253 {
254 #ifdef USE_TIMERS
255  timer.Start();
256 #endif // USE_TIMERS
257 
258  if(!fTracks)
260 
261  fParticles.clear();
262  fPV.clear();
263 
264  int nTracks = particles.size();
265  fTracks[0].Resize(nTracks);
266  fTracks[1].Resize(0);
267  fTracks[2].Resize(0);
268  fTracks[3].Resize(0);
269  fTracks[4].Resize(0);
270  fTracks[5].Resize(0);
271  fTracks[6].Resize(0);
272  fTracks[7].Resize(0);
273 
274  for(int iTr=0; iTr<nTracks; iTr++)
275  {
276  int trackPDG = -1;
277  if(pdg)
278  trackPDG = (*pdg)[iTr];
279 
280  int npixelhits = 0;
281  if(nPixelHits)
282  npixelhits = nPixelHits->at(iTr);
283 
284  for(int iP=0; iP<6; iP++)
285  fTracks[0].SetParameter(particles[iTr].Parameters()[iP], iP, iTr);
286  for(int iC=0; iC<21; iC++)
287  fTracks[0].SetCovariance(particles[iTr].CovarianceMatrix()[iC], iC, iTr);
288 // fTracks[0].SetId(iTr, iTr);
289  fTracks[0].SetId(particles[iTr].Id(), iTr);
290  fTracks[0].SetPDG(trackPDG, iTr);
291  fTracks[0].SetQ(particles[iTr].Q(), iTr);
292  fTracks[0].SetPVIndex(-1, iTr);
293  fTracks[0].SetNPixelHits(npixelhits,iTr);
294  }
295 
296  fKFParticlePVReconstructor->Init( &fTracks[0], nTracks );
297 
298 #ifdef USE_TIMERS
299  timer.Stop();
300  fStatTime[0] = timer.RealTime();
301 #endif // USE_TIMERS
302 }
303 
305 {
306 #ifdef USE_TIMERS
307  timer.Start();
308 #endif // USE_TIMERS
309 
310  if(!fTracks)
312 
313  fParticles.clear();
314  fPV.clear();
315 
316  int nTracks = tracks.Size();
317  fTracks[0].Resize(nTracks);
318  fTracks[0].Set(tracks, nTracks, 0);
319  fTracks[1].Resize(0);
320  fTracks[2].Resize(0);
321  fTracks[3].Resize(0);
322  fTracks[4].Resize(tracksAtLastPoint.Size());
323  fTracks[4].Set(tracksAtLastPoint, tracksAtLastPoint.Size(), 0);
324  fTracks[5].Resize(0);
325  fTracks[6].Resize(0);
326  fTracks[7].Resize(0);
327  fKFParticlePVReconstructor->Init( &fTracks[0], nTracks );
328 
329 #ifdef USE_TIMERS
330  timer.Stop();
331  fStatTime[0] = timer.RealTime();
332 #endif // USE_TIMERS
333 }
334 
335 void KFParticleTopoReconstructor::Init(const KFPTrackVector *particles, const vector<KFParticle>& pv)
336 {
337 #ifdef USE_TIMERS
338  timer.Start();
339 #endif // USE_TIMERS
340  fParticles.clear();
341  fPV.clear();
342 
343  fTracks = const_cast< KFPTrackVector* >(particles);
344  fChiToPrimVtx[0].resize(fTracks[0].Size());
345  fChiToPrimVtx[1].resize(fTracks[1].Size());
346  fPV.resize(pv.size());
347 
348  for(unsigned int iPV=0; iPV<fPV.size(); iPV++)
349  fPV[iPV] = KFParticleSIMD(const_cast<KFParticle&>(pv[iPV]));
350 
351 #ifdef USE_TIMERS
352  timer.Stop();
353  fStatTime[0] = timer.RealTime();
354 #endif // USE_TIMERS
355 }
356 
358 {
362 #ifdef USE_TIMERS
363  timer.Start();
364 #endif // USE_TIMERS
366 
367  fPV.clear();
368 
369  int nPrimVtx = NPrimaryVertices();
370  int nPV = 0;
371  if(isHeavySystem)
372  {
373  if(NPrimaryVertices() > 1)
374  {
375  unsigned int nMax = GetPVTrackIndexArray(0).size();
376  for(int i=1; i<NPrimaryVertices(); i++)
377  if(GetPVTrackIndexArray(i).size() > nMax)
378  {
379  nMax = GetPVTrackIndexArray(i).size();
380  nPV = i;
381  }
382  }
383 
384  nPrimVtx = 1;
385  fPV.resize(nPrimVtx);
386  fPV[0] = GetPrimVertex(nPV);
387  }
388  else
389  {
390  fPV.resize(nPrimVtx);
391  for(int iPV=0; iPV<nPrimVtx; iPV++)
392  fPV[iPV] = GetPrimVertex(iPV);
393  }
394 
395  for(int iPV=0; iPV<NPrimaryVertices(); iPV++)
396  {
397  int pvI = iPV;
398 
399  if( isHeavySystem )
400  {
401  if(iPV != nPV) continue;
402  pvI = 0; //save only one PV
403  }
404 
405  vector<int>& tracks = GetPVTrackIndexArray(iPV);
406  for(unsigned int iTr=0; iTr<tracks.size(); iTr++)
407  fTracks[0].SetPVIndex(pvI, tracks[iTr]);
408  }
409 
410  if(isHeavySystem)
411  {
412  vector<int> pvTracks = fKFParticlePVReconstructor->GetPVTrackIndexArray(nPV);
415  fKFParticlePVReconstructor->AddPV(pv, pvTracks);
416  }
417 
418 #ifdef USE_TIMERS
419  timer.Stop();
420  fStatTime[1] = timer.RealTime();
421 #endif // USE_TIMERS
422 } // void KFParticleTopoReconstructor::ReconstructPrimVertex
423 
425 {
440 #ifdef USE_TIMERS
441  timer.Start();
442 #endif // USE_TIMERS
443 
444  int offset[2] = {0, 4};
445  int nSets = 2;
446 
447  if(fTracks[4].Size() == 0)
448  nSets = 1;
449 
450  for(int iSet=nSets-1; iSet>=0; iSet--)
451  {
452  int Size = fTracks[0].Size();
453 
454  vector<KFPTrackIndex> sortedTracks(Size);
455  kfvector_uint trackIndex[4];
456  for(int iTV=0; iTV<4; iTV++)
457  trackIndex[iTV].resize(Size);
458  int nTracks[4] = {0,0,0,0};
459 
460  for(int iTr=0; iTr<Size; iTr++)
461  {
462  sortedTracks[iTr].fIndex = iTr;
463  sortedTracks[iTr].fPdg = fTracks[0].PDG()[iTr];
464  }
465 
466  std::sort(sortedTracks.begin(), sortedTracks.end(), KFPTrackIndex::Compare);
467 
468  for(int iTr=0; iTr<Size; iTr++)
469  {
470  int iTrSorted = sortedTracks[iTr].fIndex;
471 
472  //int q = fTracks[offset[iSet]].Q()[iTrSorted];
473  int q = fTracks[0].Q()[iTrSorted]; //take the charge at the first point to avoid ambiguities in array size
474  if(fTracks[0].PVIndex()[iTrSorted] < 0) //secondary track
475  {
476 
477  if(q<0) //secondary negative track
478  {
479  trackIndex[1][nTracks[1]] = iTrSorted;
480  nTracks[1]++;
481  }
482  else //secondary positive track
483  {
484  trackIndex[0][nTracks[0]] = iTrSorted;
485  nTracks[0]++;
486  }
487  }
488  else //primary track
489  {
490  if(q<0) //primary negative track
491  {
492  trackIndex[3][nTracks[3]] = iTrSorted;
493  nTracks[3]++;
494  }
495  else //primary positive track
496  {
497  trackIndex[2][nTracks[2]] = iTrSorted;
498  nTracks[2]++;
499  }
500  }
501  }
502 
503  for(int iTV=1; iTV<4; iTV++)
504  fTracks[iTV+offset[iSet]].SetTracks(fTracks[offset[iSet]], trackIndex[iTV], nTracks[iTV]);
505 
506  KFPTrackVector positive;
507  positive.SetTracks(fTracks[offset[iSet]], trackIndex[0], nTracks[0]);
508  fTracks[offset[iSet]].Resize(nTracks[0]);
509  fTracks[offset[iSet]].Set(positive,nTracks[0],0);
510 
511  for(int iTV=0; iTV<4; iTV++)
512  fTracks[iTV+offset[iSet]].RecalculateLastIndex();
513 
514  //correct index of tracks in primary clusters with respect to the sorted array
515  if(iSet == 0)
516  {
517  vector<int> newIndex(Size);
518  int iCurrentTrack=0;
519  for(int iTC=0; iTC<4; iTC++)
520  {
521  for(int iTrackIndex=0; iTrackIndex<fTracks[iTC].Size(); iTrackIndex++)
522  {
523  newIndex[trackIndex[iTC][iTrackIndex]] = iCurrentTrack;
524  iCurrentTrack++;
525  }
526  }
527 
528  for(int iPV=0; iPV<NPrimaryVertices(); iPV++)
529  for(unsigned int iTrack=0; iTrack<GetPVTrackIndexArray(iPV).size(); iTrack++)
530  fKFParticlePVReconstructor->GetPVTrackIndexArray(iPV)[iTrack] = newIndex[GetPVTrackIndexArray(iPV)[iTrack]];
531  }
532  }
533 
534  fChiToPrimVtx[0].resize(fTracks[0].Size(), -1);
535  fChiToPrimVtx[1].resize(fTracks[1].Size(), -1);
536 
537 #ifdef USE_TIMERS
538  timer.Stop();
539  fStatTime[2] = timer.RealTime();
540 #endif // USE_TIMERS
541 }
542 
544 {
549  float_v point[3];
550  KFParticleSIMD tmpPart;
551 
552  for(int iTV=2; iTV<4; iTV++)
553  {
554  unsigned int NTr = fTracks[iTV].Size();
555  for(unsigned int iTr=0; iTr < NTr; iTr += float_vLen)
556  {
557  const int_v& pdg = reinterpret_cast<const int_v&>(fTracks[iTV].PDG()[iTr]);
558  const int_v& pvIndex = reinterpret_cast<const int_v&>(fTracks[iTV].PVIndex()[iTr]);
559 
560  tmpPart.Load(fTracks[iTV], iTr, pdg);
561 
562  for(unsigned int iV=0; iV < (unsigned int)float_vLen; iV++)
563  {
564  if(iV+iTr >= NTr) continue;
565 
566  int iPV = pvIndex[iV];
567  point[0][iV] = fPV[iPV].X()[0];
568  point[1][iV] = fPV[iPV].Y()[0];
569  point[2][iV] = fPV[iPV].Z()[0];
570  }
571 
572  tmpPart.TransportToPoint(point);
573 
574  for(int iP=0; iP<6; iP++)
575  fTracks[iTV].SetParameter( tmpPart.GetParameter(iP), iP, iTr );
576  for(int iC=0; iC<21; iC++)
577  fTracks[iTV].SetCovariance( tmpPart.GetCovariance(iC), iC, iTr );
578  }
579  }
580 }
581 
583 {
589  KFParticleSIMD tmpPart;
590 
591  for(int iTV=0; iTV<2; iTV++)
592  {
593  unsigned int NTr = fTracks[iTV].Size();
594  for(unsigned int iTr=0; iTr < NTr; iTr += float_vLen)
595  {
596  uint_v trackIndex = iTr + uint_v::IndexesFromZero();
597  const int_v& pdg = reinterpret_cast<const int_v&>(fTracks[iTV].PDG()[iTr]);
598  tmpPart.Create(fTracks[iTV],trackIndex, pdg);
599 
600  float_v& chi2 = reinterpret_cast<float_v&>(fChiToPrimVtx[iTV][iTr]);
601  chi2(simd_cast<float_m>(trackIndex<NTr)) = 10000.f;
602 
603  for(int iPV=0; iPV<nPV; iPV++)
604  {
605  const float_v point[3] = {pv[iPV].X(), pv[iPV].Y(), pv[iPV].Z()};
606  tmpPart.TransportToPoint(point);
607  const float_v& chiVec = tmpPart.GetDeviationFromVertex(pv[iPV]);
608  chi2( (chi2>chiVec) && simd_cast<float_m>(trackIndex<NTr) ) = chiVec;
609  }
610  }
611  }
612 }
613 
625 struct ParticleInfo
626 {
629  ParticleInfo(int index, float massDistance):fParticleIndex(index),fMassDistance(massDistance) {};
630 
632  static bool compare(const ParticleInfo& a, const ParticleInfo& b) { return (a.fMassDistance < b.fMassDistance); }
633 
636 };
637 
639 {
643  bool use = (PDG == 310) || //K0
644  (PDG == 22) || //gamma
645  (PDG == 111) || //pi0
646  (abs(PDG) == 3122) || //Lambda
647  (abs(PDG) == 3312) || //Xi
648  (abs(PDG) == 3334) || //Omega
649  (abs(PDG) == 3003) || //LambdaN
650  (abs(PDG) == 3103) || //LambdaNN
651  (abs(PDG) == 3004) || //H3L
652  (abs(PDG) == 3005) || //H4L
653  (abs(PDG) == 3006) || //He4L
654  (abs(PDG) == 3007) || //He5L
655  (abs(PDG) == 3203) || //LLn
656  (abs(PDG) == 3008) || //H4LL
657  (abs(PDG) == 3009) || //H4LL
658  (abs(PDG) == 3010) || //H5LL
659  (abs(PDG) == 3011); //He6LL
660  return use;
661 }
662 
664 {
674  std::vector<ParticleInfo> particleInfo;
675  std::vector<bool> isUsed(fParticles.size());
676  std::vector<bool> deleteCandidate(fParticles.size());
677  std::vector<int> bestMother(fParticles.size());
678 
679  for(unsigned int iParticle=0; iParticle<fParticles.size(); iParticle++)
680  {
681  isUsed[iParticle] = false;
682  deleteCandidate[iParticle] = false;
683  bestMother[iParticle] = -1;
684  }
685 
686  for(unsigned int iParticle=0; iParticle<fParticles.size(); iParticle++)
687  {
688  if(!UseParticleInCompetition(fParticles[iParticle].GetPDG())) continue;
689 
690  bool isSecondary = 1;
691  for(int iPV=0; iPV<NPrimaryVertices(); iPV++)
692  {
693  KFParticle tmp = fParticles[iParticle];
695  if(tmp.Chi2()/tmp.NDF()<5)
696  isSecondary=0;
697  }
698  if(isSecondary)
699  deleteCandidate[iParticle] = true;
700  }
701 
702 // for(unsigned int iParticle=0; iParticle<fParticles.size(); iParticle++)
703 // {
704 // if(abs(fParticles[iParticle].GetPDG()) == 431 || abs(fParticles[iParticle].GetPDG()) == 4122)
705 // {
706 // vector<int> daughterIds(fParticles[iParticle].NDaughters());
707 // for(int iDaughter=0; iDaughter<fParticles[iParticle].NDaughters(); iDaughter++)
708 // daughterIds[iDaughter] = fParticles[fParticles[iParticle].DaughterIds()[iDaughter]].DaughterIds()[0];
709 // std::sort(daughterIds.begin(), daughterIds.end());
710 //
711 // for(unsigned int jParticle=0; jParticle<fParticles.size(); jParticle++)
712 // {
713 // if(abs(fParticles[jParticle].GetPDG()) == 411)
714 // {
715 // vector<int> daughterIdsDPlus(fParticles[jParticle].NDaughters());
716 // for(int iDaughter=0; iDaughter<fParticles[jParticle].NDaughters(); iDaughter++)
717 // daughterIdsDPlus[iDaughter] = fParticles[fParticles[jParticle].DaughterIds()[iDaughter]].DaughterIds()[0];
718 // std::sort(daughterIdsDPlus.begin(), daughterIdsDPlus.end());
719 //
720 // if(daughterIdsDPlus.size() != daughterIds.size()) continue;
721 //
722 // bool isSameParticle=1;
723 // for(unsigned int iDaughter=0; iDaughter<daughterIds.size(); iDaughter++)
724 // isSameParticle &= daughterIds[iDaughter] == daughterIdsDPlus[iDaughter];
725 // if(!isSameParticle) continue;
726 //
727 // float mass, massSigma;
728 // fParticles[jParticle].GetMass(mass, massSigma);
729 //
730 // if(fabs(mass - KFParticleDatabase::Instance()->GetDPlusMass()) < 3*KFParticleDatabase::Instance()->GetDPlusMassSigma())
731 // {
732 // deleteCandidate[iParticle] = true;
733 // break;
734 // }
735 // }
736 // }
737 // }
738 // }
739 
740 
741  //clean K0 and Lambda
742  for(unsigned int iParticle=0; iParticle<fParticles.size(); iParticle++)
743  {
744  if(deleteCandidate[iParticle]) continue;
745  if(!UseParticleInCompetition(fParticles[iParticle].GetPDG())) continue;
746 
747  float mass, massSigma;
748  fParticles[iParticle].GetMass(mass, massSigma);
749 
750  float massPDG, massPDGSigma;
751  KFParticleDatabase::Instance()->GetMotherMass(fParticles[iParticle].GetPDG(), massPDG, massPDGSigma);
752 
753  float dm1 = fabs(mass - massPDG)/massPDGSigma;
754 // if(dm1 > 3.f) continue;
755 
756  for(unsigned int jParticle=iParticle+1; jParticle<fParticles.size(); jParticle++)
757  {
758  if(deleteCandidate[jParticle]) continue;
759  if(!UseParticleInCompetition(fParticles[jParticle].GetPDG())) continue;
760 
761  fParticles[jParticle].GetMass(mass, massSigma);
762  KFParticleDatabase::Instance()->GetMotherMass(fParticles[jParticle].GetPDG(), massPDG, massPDGSigma);
763 
764  float dm2 = fabs(mass - massPDG)/massPDGSigma;
765 // if(dm2 > 3.f) continue;
766 
767  if(! (fParticles[iParticle].DaughterIds()[0] == fParticles[jParticle].DaughterIds()[0] &&
768  fParticles[iParticle].DaughterIds()[1] == fParticles[jParticle].DaughterIds()[1]) ) continue;
769 
770  if(dm1 < 3.f || dm2 < 3.f)
771  {
772 // if(dm1 < 3.f && dm2<3.f)
773 // {
774 // KFParticle part1 = fParticles[iParticle];
775 // KFParticle part2 = fParticles[jParticle];
776 //
777 // if(fParticles[iParticle].GetPDG() == 310)
778 // {
779 // deleteCandidate[iParticle] = true;
780 // break;
781 // }
782 // else
783 // {
784 // deleteCandidate[jParticle] = true;
785 // }
786 // }
787 
788  if(dm1 < dm2)
789  {
790  deleteCandidate[jParticle] = true;
791  bestMother[fParticles[iParticle].DaughterIds()[0]] = iParticle;
792  bestMother[fParticles[iParticle].DaughterIds()[1]] = iParticle;
793  }
794  else
795  {
796  deleteCandidate[iParticle] = true;
797  bestMother[fParticles[iParticle].DaughterIds()[0]] = jParticle;
798  bestMother[fParticles[iParticle].DaughterIds()[1]] = jParticle;
799  break;
800  }
801  }
802  }
803  }
804 
805 // for(unsigned int iParticle=0; iParticle<fParticles.size(); iParticle++)
806 // {
807 // if(!(abs(fParticles[iParticle].GetPDG()) == 22)) continue;
808 //
809 // bool bothDaughtersElectrons = 1;
810 // for(int iDaughter=0; iDaughter<fParticles[iParticle].NDaughters(); iDaughter++)
811 // {
812 // const int daughterIndex = fParticles[iParticle].DaughterIds()[iDaughter];
813 // bothDaughtersElectrons &= abs(fParticles[daughterIndex].GetPDG()) == 11;
814 // }
815 // if(!bothDaughtersElectrons)
816 // {
817 // deleteCandidate[iParticle] = true;
818 // continue;
819 // }
820 // }
821  //clean dielectron spectrum
822  //at first - both electrons are identified
823  for(unsigned int iParticle=0; iParticle<fParticles.size(); iParticle++)
824  {
825  if(deleteCandidate[iParticle]) continue;
826  if(!(abs(fParticles[iParticle].GetPDG()) == 22)) continue;
827 
828 // bool bothDaughtersElectrons = 1;
829 // for(int iDaughter=0; iDaughter<fParticles[iParticle].NDaughters(); iDaughter++)
830 // {
831 // const int daughterIndex = fParticles[iParticle].DaughterIds()[iDaughter];
832 // bothDaughtersElectrons &= abs(fParticles[daughterIndex].GetPDG()) == 11;
833 // }
834 // if(!bothDaughtersElectrons) continue;
835 
836  float mass, massSigma;
837  fParticles[iParticle].GetMass(mass, massSigma);
838  float massPDG, massPDGSigma;
839  KFParticleDatabase::Instance()->GetMotherMass(fParticles[iParticle].GetPDG(), massPDG, massPDGSigma);
840  float dm = fabs(mass - massPDG)/massPDGSigma;
841 
842  if(dm < 3.f)
843  particleInfo.push_back(ParticleInfo(iParticle, dm));
844  }
845 
846  std::sort(particleInfo.begin(), particleInfo.end(), ParticleInfo::compare);
847 
848  for(unsigned int iPI=0; iPI<particleInfo.size(); iPI++)
849  {
850  const int index = particleInfo[iPI].fParticleIndex;
851  if(deleteCandidate[index]) continue;
852 
853  bool isStore = true;
854  for(int iDaughter=0; iDaughter<fParticles[index].NDaughters(); iDaughter++)
855  isStore &= !(isUsed[ fParticles[index].DaughterIds()[iDaughter] ]);
856 
857  if(isStore)
858  {
859  for(int iDaughter=0; iDaughter<fParticles[index].NDaughters(); iDaughter++)
860  isUsed[ fParticles[index].DaughterIds()[iDaughter] ] = true;
861  }
862  else
863  deleteCandidate[index] = true;
864  }
865 
866  for(unsigned int iParticle=0; iParticle<fParticles.size(); iParticle++)
867  {
868  if(deleteCandidate[iParticle]) continue;
869  if(!(abs(fParticles[iParticle].GetPDG()) == 22)) continue;
870 
871  bool bothDaughtersElectrons = 1;
872  for(int iDaughter=0; iDaughter<fParticles[iParticle].NDaughters(); iDaughter++)
873  {
874  const int daughterIndex = fParticles[iParticle].DaughterIds()[iDaughter];
875  bothDaughtersElectrons &= abs(fParticles[daughterIndex].GetPDG()) == 11;
876  }
877 
878  float mass, massSigma;
879  fParticles[iParticle].GetMass(mass, massSigma);
880  float massPDG, massPDGSigma;
881  KFParticleDatabase::Instance()->GetMotherMass(fParticles[iParticle].GetPDG(), massPDG, massPDGSigma);
882  float dm = fabs(mass - massPDG)/massPDGSigma;
883 
884 // if( (bothDaughtersElectrons && dm > 3.f) || !bothDaughtersElectrons)
885  if( dm > 3.f )
886  {
887  bool isStore = true;
888  for(int iDaughter=0; iDaughter<fParticles[iParticle].NDaughters(); iDaughter++)
889  isStore &= !(isUsed[ fParticles[iParticle].DaughterIds()[iDaughter] ]);
890  if(!isStore)
891  {
892  deleteCandidate[iParticle] = true;
893  }
894  }
895  }
896 
897  // clean LMVM spectrum
898  for(unsigned int iParticle=0; iParticle<fParticles.size(); iParticle++)
899  {
900  if(!(abs(fParticles[iParticle].GetPDG()) == 100113 || abs(fParticles[iParticle].GetPDG()) == 443)) continue;
901 
902  bool bothDaughtersElectrons = 1;
903  for(int iDaughter=0; iDaughter<fParticles[iParticle].NDaughters(); iDaughter++)
904  {
905  const int daughterIndex = fParticles[iParticle].DaughterIds()[iDaughter];
906  bothDaughtersElectrons &= abs(fParticles[daughterIndex].GetPDG()) == 11;
907  }
908  if(!bothDaughtersElectrons)
909  {
910  deleteCandidate[iParticle] = true;
911  continue;
912  }
913 
914  bool isStore = true;
915  for(int iDaughter=0; iDaughter<fParticles[iParticle].NDaughters(); iDaughter++)
916  isStore &= !(isUsed[ fParticles[iParticle].DaughterIds()[iDaughter] ]);
917  if(!isStore)
918  {
919  deleteCandidate[iParticle] = true;
920  }
921  }
922 // for(unsigned int iParticle=0; iParticle<fParticles.size(); iParticle++)
923 // {
924 // if(deleteCandidate[iParticle]) continue;
925 // if(abs(fParticles[iParticle].GetPDG()) == 310 || abs(fParticles[iParticle].GetPDG()) == 3122)
926 // {
927 // // float mass, massSigma;
928 // // fParticles[iParticle].GetMass(mass, massSigma);
929 // //
930 // float massPDG, massPDGSigma;
931 // KFParticleDatabase::Instance()->GetMotherMass(fParticles[iParticle].GetPDG(), massPDG, massPDGSigma);
932 // //
933 // // float dm = fabs(mass - massPDG)/massPDGSigma;
934 //
935 // KFParticle tmp = fParticles[iParticle];
936 // // tmp.SetNonlinearMassConstraint(massPDG);
937 //
938 // particleInfo.push_back(ParticleInfo(iParticle, tmp.Chi2()));
939 // }
940 // }
941 //
942 // std::sort(particleInfo.begin(), particleInfo.end(), ParticleInfo::compare);
943 //
944 // for(unsigned int iPI=0; iPI<particleInfo.size(); iPI++)
945 // {
946 // const int index = particleInfo[iPI].fParticleIndex;
947 // if(deleteCandidate[index]) continue;
948 //
949 // bool isStore = true;
950 // for(int iDaughter=0; iDaughter<fParticles[index].NDaughters(); iDaughter++)
951 // isStore &= !(isUsed[ fParticles[index].DaughterIds()[iDaughter] ]);
952 //
953 // if(isStore)
954 // {
955 // for(int iDaughter=0; iDaughter<fParticles[index].NDaughters(); iDaughter++)
956 // isUsed[ fParticles[index].DaughterIds()[iDaughter] ] = true;
957 // }
958 // else
959 // deleteCandidate[index] = true;
960 // }
961 
962  for(int iParticle=0; iParticle<int(fParticles.size()); iParticle++)
963  {
964  if(deleteCandidate[iParticle]) continue;
965 
966  for(int iDaughter=0; iDaughter<fParticles[iParticle].NDaughters(); iDaughter++)
967  if(bestMother[fParticles[iParticle].DaughterIds()[iDaughter]] != iParticle && bestMother[fParticles[iParticle].DaughterIds()[iDaughter]] > -1)
968  {
969  deleteCandidate[iParticle] = true;
970  break;
971  }
972  }
973 
974  for(unsigned int iParticle=0; iParticle<fParticles.size(); iParticle++)
975  if(deleteCandidate[iParticle])
976  fParticles[iParticle].SetPDG(-1);
977 }
978 
980 {
985  if(particle.NDaughters() < 2) return 0;
986 
987  vector<int> daughters;
988  GetListOfDaughterTracks(particle, daughters);
989  std::sort(daughters.begin(), daughters.end());
990  bool sameDaughter=0;
991  for(unsigned int iDaughter=1; iDaughter<daughters.size(); iDaughter++)
992  {
993  if(daughters[iDaughter] == daughters[iDaughter-1])
994  {
995  sameDaughter = 1;
996  break;
997  }
998  }
999  return sameDaughter;
1000 }
1001 
1003 {
1009  if(particle.NDaughters() == 1)
1010  daughters.push_back( particle.DaughterIds()[0] );
1011  else
1012  for(int iDaughter=0; iDaughter<particle.NDaughters(); iDaughter++)
1013  GetListOfDaughterTracks( fParticles[ particle.DaughterIds()[iDaughter] ], daughters);
1014 }
1015 
1017 {
1025 #ifdef USE_TIMERS
1026  timer.Start();
1027 #endif // USE_TIMERS
1028 
1029  fParticles.clear();
1030 
1031  if(fPV.size() < 1) return;
1032 
1034  //calculate chi to primary vertex, chi = sqrt(dr C-1 dr)
1035  GetChiToPrimVertex(&(fPV[0]), fPV.size());
1036 
1038 // #pragma omp critical
1039 // std::cout << "NPart " << fParticles.size() << " " << fTracks[0].Size() << " "<< fTracks[1].Size() << " " << fTracks[2].Size() << " " << fTracks[3].Size()<< std::endl;
1040 
1041 // for(unsigned int iParticle=0; iParticle<fParticles.size(); iParticle++)
1042 // if(ParticleHasRepeatingDaughters(fParticles[iParticle]))
1043 // fParticles[iParticle].SetPDG(-1);
1044 //
1045 // SelectParticleCandidates();
1046 
1047 #ifdef USE_TIMERS
1048  timer.Stop();
1049  fStatTime[3] = timer.RealTime();
1050 #endif // USE_TIMERS
1051 } // void KFParticleTopoReconstructor::ReconstructPrimVertex
1052 
1053 #ifdef WITHSCIF
1054 void KFParticleTopoReconstructor::SendDataToXeonPhi( int iHLT, scif_epd_t& endpoint, void* buffer, off_t& offsetServer, off_t& offsetSender, float Bz)
1055 {
1056  //pack the input data
1057  int* data = reinterpret_cast<int*>(buffer);
1058  int dataSize = NInputSets + 1 + 1; //sizes of the track vectors and pv vector, and field
1059  for(int iSet=0; iSet<NInputSets; iSet++)
1060  dataSize += fTracks[iSet].DataSize();
1061  dataSize += fPV.size() * 9;
1062 
1063  for(int iSet=0; iSet<NInputSets; iSet++)
1064  data[iSet] = fTracks[iSet].Size();
1065  data[NInputSets] = fPV.size();
1066 
1067  float& field = reinterpret_cast<float&>(data[NInputSets+1]);
1068  field = Bz;
1069 
1070  int offset = NInputSets+2;
1071 
1072  for(int iSet=0; iSet<NInputSets; iSet++)
1073  fTracks[iSet].SetDataToVector(data, offset);
1074 
1075  for(int iP=0; iP<3; iP++)
1076  {
1077  for(unsigned int iPV=0; iPV<fPV.size(); iPV++)
1078  {
1079  float& tmpFloat = reinterpret_cast<float&>(data[offset + iPV]);
1080  tmpFloat = fPV[iPV].Parameter(iP)[0];
1081  }
1082  offset += fPV.size();
1083  }
1084 
1085  for(int iC=0; iC<6; iC++)
1086  {
1087  for(unsigned int iPV=0; iPV<fPV.size(); iPV++)
1088  {
1089  float& tmpFloat = reinterpret_cast<float&>(data[offset + iPV]);
1090  tmpFloat = fPV[iPV].Covariance(iC)[0];
1091  }
1092  offset += fPV.size();
1093  }
1094 
1095  //send the input data to Xeon Phi
1096  int msgSize = sizeof(int) * dataSize;//1000 * sizeof(int);
1097 
1098  const uint16_t portSenderId = 2000 + iHLT;
1099 
1100  int controlSignal = portSenderId;
1101  scif_send(endpoint, &msgSize, sizeof(int), SCIF_SEND_BLOCK);
1102  scif_recv(endpoint, &controlSignal, sizeof(controlSignal), 1);
1103  if(controlSignal != portSenderId) { std::cout << controlSignal << " " << portSenderId << std::endl; return; }
1104 
1105  int ret = scif_writeto(endpoint, offsetServer, msgSize, offsetSender, 0);
1106  if ( ret == -1 ) std::cout << "Fail sending array to the server. Error: " << errno << std::endl;
1107 
1108  scif_send(endpoint, &controlSignal, sizeof(int), SCIF_SEND_BLOCK); // synchronization
1109 }
1110 #endif
1111 
1112 void KFParticleTopoReconstructor::SaveInputParticles(const string prefix, bool onlySecondary)
1113 {
1122  static int nEvents = 0;
1123  string outFileName = "/event";
1124  char Result[16]; // string which will contain the number
1125  sprintf ( Result, "%d", nEvents );
1126  outFileName += string(Result);
1127  outFileName += "_KFPTracks.data";
1128 
1129  ofstream out((prefix+outFileName).data());
1130 
1131  //save tracks. tracks are already propagated to the beam
1132 
1133  int nSets = NInputSets;
1134  if(onlySecondary)
1135  nSets = 2;
1136 
1137  float B[3] = {0.f}, r[3] = {0.f};
1138  KFParticle kfpTmp;
1139  kfpTmp.GetFieldValue(r, B);
1140  out << B[2] << std::endl;
1141  out << nSets << std::endl;
1142  for(int iSet=0; iSet<nSets; iSet++)
1143  {
1144  out << fTracks[iSet].Size() << std::endl;
1145  for(int iP=0; iP<6; iP++)
1146  {
1147  for(int iTr=0; iTr<fTracks[iSet].Size(); iTr++)
1148  out << fTracks[iSet].Parameter(iP)[iTr]<< " ";
1149  out << std::endl;
1150  }
1151 
1152  for(int iC=0; iC<21; iC++)
1153  {
1154  for(int iTr=0; iTr<fTracks[iSet].Size(); iTr++)
1155  out << fTracks[iSet].Covariance(iC)[iTr]<< " ";
1156  out << std::endl;
1157  }
1158 
1159  for(int iTr=0; iTr<fTracks[iSet].Size(); iTr++)
1160  out << fTracks[iSet].Id()[iTr] << " ";
1161  out << std::endl;
1162 
1163  for(int iTr=0; iTr<fTracks[iSet].Size(); iTr++)
1164  out << fTracks[iSet].PDG()[iTr] << " ";
1165  out << std::endl;
1166 
1167  for(int iTr=0; iTr<fTracks[iSet].Size(); iTr++)
1168  out << fTracks[iSet].Q()[iTr] << " ";
1169  out << std::endl;
1170 
1171  for(int iTr=0; iTr<fTracks[iSet].Size(); iTr++)
1172  out << fTracks[iSet].PVIndex()[iTr] << " ";
1173  out << std::endl;
1174 
1175  out << fTracks[iSet].LastElectron() << " "
1176  << fTracks[iSet].LastMuon() << " "
1177  << fTracks[iSet].LastPion() << " "
1178  << fTracks[iSet].LastKaon() << " "
1179  << fTracks[iSet].LastProton() << std::endl;
1180  }
1181 
1182  //Save PVs
1183  out << fPV.size() << std::endl;
1184  for(unsigned int iPV=0; iPV < fPV.size(); iPV++)
1185  {
1186  out << fPV[iPV].X()[0] << " " << fPV[iPV].Y()[0] << " " << fPV[iPV].Z()[0] << " " << std::endl;
1187 
1188  for(int iC=0; iC<6; iC++)
1189  out << fPV[iPV].GetCovariance(iC)[0] << " ";
1190  out << std::endl;
1191  }
1192  out.close();
1193 
1194  nEvents++;
1195 }
1196