Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
KFParticlePVReconstructor.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file KFParticlePVReconstructor.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 
23 #include "KFPTrackVector.h"
24 #include "KFParticle.h"
25 
26 using std::vector;
27 
29 {
49  fNParticles = nParticles;
50  fParticles.resize(fNParticles);
51  fWeight.resize(fNParticles);
52 
53  float C[3] = {0,0,0};
54  int nC[3] = {0,0,0};
55 
56  KFPTrack track;
57  for ( int iTr = 0; iTr < fNParticles; iTr++ ) {
58  tracks->GetTrack(track,iTr);
59  fParticles[iTr] = KFParticle( track, 211 );
60  fParticles[iTr].AddDaughterId(track.Id());
61  float zeroPoint[3]{0,0,0};
62  fParticles[iTr].TransportToPoint(zeroPoint);
63 
64  for(int iC=0; iC<3; iC++)
65  {
66  if(!(fParticles[0].Covariance(iC,iC)==fParticles[0].Covariance(iC,iC))) continue;
67  if(fParticles[0].Covariance(iC,iC) < 10.f && fParticles[0].Covariance(iC,iC) > 0.f )
68  {
69  C[iC] += fParticles[0].Covariance(iC,iC);
70  nC[iC]++;
71  }
72  }
73  }
74 
75  fPrimVertices.clear();
76  fClusters.clear();
77 
78  float pvEstimation[3] = {0.};
79  float pvEstimationTr[3] = {0.};
80 
81  float parTmp[8] = {0.};
82  float covTmp[36] = {0.};
83 
84  for(int iC=0; iC<3; iC++)
85  {
86  if(nC[iC] >0)
87  C[iC] /= nC[iC];
88  else
89  C[iC] = 1.e-2;
90  }
91 
92  for(int iIter=0; iIter<3; iIter++)
93  {
94  C[0]*=100.f; C[1]*=100.f; C[2]*=100.f;
95  for ( int iTr = 0; iTr < fNParticles; iTr++ ) {
96  float ds = 0.f;
97  float dsdr[6] = {0.f};
98  if(iIter>0)
99  ds = fParticles[iTr].GetDStoPoint(pvEstimationTr, dsdr);
100  fParticles[iTr].Transport( ds, dsdr, parTmp, covTmp);
101 
102  float r2 = parTmp[0]*parTmp[0] + parTmp[1]*parTmp[1];
103  if(!(r2==r2)) continue;
104  if(r2 > 25 ) continue;
105 
106  const float V[3] = {covTmp[0], covTmp[2], covTmp[5]};
107 
108  for(int iComp=0; iComp<3; iComp++)
109  {
110  float K = C[iComp]/(C[iComp]+V[iComp]);
111  if (fabs(V[iComp]) < 1.e-8) continue;
112  if(C[iComp] > 16*V[iComp])
113  K = 1.f - V[iComp]/C[iComp];
114  const float dzeta = parTmp[iComp]-pvEstimation[iComp];
115  if(K!=K) continue;
116  if(K<0. || K>0.999) continue;
117  pvEstimation[iComp] += K*dzeta;
118  C[iComp] -= K*C[iComp];
119  }
120  }
121  pvEstimationTr[0] = pvEstimation[0];
122  pvEstimationTr[1] = pvEstimation[1];
123  pvEstimationTr[2] = pvEstimation[2];
124  }
125 
126  for(int iP=0; iP<fNParticles; iP++)
127  {
128  fParticles[iP].TransportToPoint(pvEstimation);
129 
130  fWeight[iP] = fParticles[iP].CovarianceMatrix()[0]
131  + fParticles[iP].CovarianceMatrix()[2] + fParticles[iP].CovarianceMatrix()[5];
132 
133  if(fWeight[iP] > 0.f)
134  fWeight[iP] = 1.f/sqrt(fWeight[iP]);
135  else
136  fWeight[iP] = -100;
137 
138  if( (fParticles[iP].X()*fParticles[iP].X() + fParticles[iP].Y()*fParticles[iP].Y()) > 100.f ) fWeight[iP] = -100.f;
139  }
140 } // void KFParticlePVReconstructor::Init
141 
143 {
163  if( IsBeamLine() )
164  cutNDF += 2;
165 
166  vector<unsigned short int> notUsedTracks(fNParticles);
167  vector<unsigned short int> *notUsedTracksPtr = &notUsedTracks;
168  int nNotUsedTracks = fNParticles;
169 
170  vector<unsigned short int> notUsedTracksNew(fNParticles);
171  vector<unsigned short int> *notUsedTracksNewPtr = &notUsedTracksNew;
172  int nNotUsedTracksNew = 0;
173 
174  for(int iTr=0; iTr<fNParticles; iTr++)
175  (*notUsedTracksPtr)[iTr] = iTr;
176 
177  while(nNotUsedTracks>0)
178  {
179  short int bestTrack = 0;
180  float bestWeight = -1.f;
181 
182  for(unsigned short int iTr = 0; iTr < nNotUsedTracks; iTr++)
183  {
184  unsigned short int &curTrack = (*notUsedTracksPtr)[iTr];
185 
186  if (fWeight[curTrack] > bestWeight)
187  {
188  bestWeight = fWeight[curTrack];
189  bestTrack = curTrack;
190  }
191  }
192 
193  if(bestWeight < 0.f) break;
194 
195  KFParticleCluster cluster;
196  cluster.fTracks.reserve(nNotUsedTracks);
197 
198  const float *rBest = fParticles[bestTrack].Parameters();
199  const float *covBest = fParticles[bestTrack].CovarianceMatrix();
200 
201  float rVertex[3] = {0.f};
202  float covVertex[6] = {0.f};
203  float weightVertex = 0.f;
204 
205  for(unsigned short int iTr = 0; iTr < nNotUsedTracks; iTr++)
206  {
207  unsigned short int &curTrack = (*notUsedTracksPtr)[iTr];
208  float chi2deviation = fParticles[curTrack].GetDeviationFromVertex(rBest, covBest);
209  if( ( chi2deviation < fChi2CutPreparation && chi2deviation >= 0 && fWeight[curTrack] > -1.f) || curTrack == bestTrack)
210  {
211  for(int iP=0; iP<3; iP++)
212  rVertex[iP] += fWeight[curTrack] * fParticles[curTrack].Parameters()[iP];
213 
214  float weight2 = fWeight[curTrack] * fWeight[curTrack];
215  for(int iC=0; iC<6; iC++)
216  covVertex[iC] += weight2 *fParticles[curTrack].CovarianceMatrix()[iC];
217 
218  weightVertex += fWeight[curTrack];
219  cluster.fTracks.push_back(curTrack);
220  }
221  else
222  {
223  (*notUsedTracksNewPtr)[nNotUsedTracksNew] = curTrack;
224  nNotUsedTracksNew++;
225  }
226  }
227 
228  vector<unsigned short int> *notUsedTracksPtrSave = notUsedTracksPtr;
229  notUsedTracksPtr = notUsedTracksNewPtr;
230  notUsedTracksNewPtr = notUsedTracksPtrSave;
231 
232  nNotUsedTracks = nNotUsedTracksNew;
233  nNotUsedTracksNew = 0;
234 
235  if(cluster.fTracks.size() < 2) continue;
236  if((cluster.fTracks.size() < 3) && (fNParticles>3)) continue;
237 
238  for(int iP=0; iP<3; iP++)
239  cluster.fP[iP] = rVertex[iP]/weightVertex;
240 
241  for(int iC=0; iC<6; iC++)
242  cluster.fC[iC] = covVertex[iC]/(weightVertex*weightVertex);
243 
244 
245  int nPrimCand = cluster.fTracks.size(); // 1 is reserved for a beam line
246  int nTracks = cluster.fTracks.size();
247 
248  const KFParticle **pParticles = new const KFParticle*[nPrimCand+1]; // tmp array
249 
250  for ( int iP = 0; iP < nPrimCand; iP++ )
251  pParticles[iP] = &fParticles[ cluster.fTracks[iP] ];
252 
253  if( IsBeamLine() )
254  {
255  pParticles[nPrimCand] = &fBeamLine;
256  nPrimCand++;
257  }
258 
259 
260  // find prim vertex
261  KFVertex primVtx;
262 
263  if(fNParticles>1)
264  {
265  // construct PV candidate from a cluster
266  bool *vFlags = new bool[nPrimCand]; // flags returned by the vertex finder
267  for(int iFl=0; iFl<nPrimCand; iFl++)
268  vFlags[iFl] = true;
269 // primVtx.SetVtxGuess(cluster.fP[0], cluster.fP[1], cluster.fP[2]);
270  primVtx.SetConstructMethod(0);
271  primVtx.ConstructPrimaryVertex( pParticles, nPrimCand, vFlags, fChi2Cut );
272 
273  // clean cluster
274  vector<int> clearClusterInd;
275  clearClusterInd.reserve(cluster.fTracks.size());
276  for ( int iP = 0; iP < nTracks; iP++ ){
277  if(cluster.fTracks[iP] == bestTrack) {
278  clearClusterInd.push_back(cluster.fTracks[iP]);
279  continue;
280  }
281  if(vFlags[iP])
282  clearClusterInd.push_back(cluster.fTracks[iP]);
283  else
284  {
285  (*notUsedTracksPtr)[nNotUsedTracks] = cluster.fTracks[iP];
286  nNotUsedTracks++;
287  }
288  }
289 
290  for(unsigned short int iTr = 0; iTr < nNotUsedTracks; iTr++)
291  {
292  unsigned short int &curTrack = (*notUsedTracksPtr)[iTr];
293  if( fParticles[curTrack].GetDeviationFromVertex(primVtx)<fChi2Cut )
294  {
295  primVtx += fParticles[curTrack];
296  clearClusterInd.push_back(curTrack);
297  }
298  else
299  {
300  (*notUsedTracksNewPtr)[nNotUsedTracksNew] = curTrack;
301  nNotUsedTracksNew++;
302  }
303  }
304  cluster.fTracks = clearClusterInd;
305 
306  notUsedTracksPtrSave = notUsedTracksPtr;
307  notUsedTracksPtr = notUsedTracksNewPtr;
308  notUsedTracksNewPtr = notUsedTracksPtrSave;
309 
310  nNotUsedTracks = nNotUsedTracksNew;
311  nNotUsedTracksNew = 0;
312 
313  // save PV
314 #ifdef CBM
315  if( primVtx.GetNDF() >= cutNDF && ((cluster.fTracks.size()>0.1f*fNParticles && fNParticles > 30) || fNParticles<=30 ) ) //at least 2 particles
316 #else
317  if( primVtx.GetNDF() >= cutNDF)
318 #endif
319  {
320  fPrimVertices.push_back(primVtx);
321  fClusters.push_back(cluster);
322  }
323 
324  if(vFlags) delete [] vFlags;
325  }
326  if(pParticles) delete [] pParticles;
327  }
328 }
329 
331 {
338 
339  if ( fPrimVertices.size() == 0 )
340  {
341  float X=0,Y=0,Z=0;
342 
343  KFPVertex primVtx_tmp;
344  primVtx_tmp.SetXYZ(X, Y, Z);
345  primVtx_tmp.SetCovarianceMatrix( 0, 0, 0, 0, 0, 0 );
346  primVtx_tmp.SetNContributors(0);
347  primVtx_tmp.SetChi2(-100);
348 
349  fPrimVertices.push_back(primVtx_tmp);
350 
351  KFParticleCluster cluster;
352  fClusters.push_back(cluster);
353  }
354 }
355 
356 void KFParticlePVReconstructor::AddPV(const KFVertex &pv, const vector<int> &tracks)
357 {
358  fPrimVertices.push_back(pv);
359  KFParticleCluster cluster;
360  cluster.fTracks = tracks;
361  fClusters.push_back(cluster);
362 }
363 
365 {
366  fPrimVertices.push_back(pv);
367  KFParticleCluster cluster;
368  fClusters.push_back(cluster);
369 }