BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
KFParticleFinder.cxx
Go to the documentation of this file.
1#include "KFParticleFinder.h"
2
3#define cnst static const fvec
4
5// for particle finding
6#include "CbmKFTrack.h"
7#include "CbmL1Track.h"
8#include "CbmStsTrack.h"
9
10#include <map>
11using std::map;
12
13const float KFParticleFinder::DefaultCuts[2][3] = {{3., 3., -100.}, {3., 3., -100.}};
14
16
17void KFParticleFinder::FindParticles(vector<CbmKFTrack>& vRTracks,
18 vector<float>& ChiToPrimVtx,
19 vector<L1FieldRegion>& vField,
20 vector<KFParticle>& Particles,
21 KFParticleSIMD& PrimVtx,
22 const vector<int>& vTrackPDG,
23 const float cuts[2][3])
24{
25 //* The function find the full set of particles at once.
26 //* As an input it takes a set of tracks (vector<CbmKFTrack> &vRTracks),
27 //* chi to the primary vertex for each track (vector<float>& ChiToPrimVtx) - a distance between the
28 //* track and the PV in the plane of the target normalized to the total error of track an PV
29 //* ChiToPrimVtx = srqt( (x_pv - x_track)^2 + (y_pv - y_track)^2 )/ (error_pv + error_track),
30 //* field for particle extrapolation (vector<L1FieldRegion>& vField),
31 //* an output set of found particles (vector<KFParticle>& Particles),
32 //* a primary vertex (CbmKFVertex& PrimVtx),
33 //* PDG hypothesis for the tracks (const vector<int>& vTrackPDG),
34 //* set of cuts (const float cuts[2][3]).
35
36 //* At first all particles are divided into 2 sets: positive and negative
37 //* Each set in its turn is divided into 8 groups according to the provided PDG hypothesis:
38 //* e, mu, pi, K, p, pi+unidentified particles, K+unidentified, p+unidentified
39
40 //* Then mother particles are combined from tracks or already reconstructed particles
41 //* according to the particle hypothesis and a decay channel under consideration
42
43 static const int NTrackTypes = 8;
44
45 int pdgPos[NTrackTypes] = {-11, -13, 211, 321, 2212, 211, 321, 2212};
46 int pdgNeg[NTrackTypes] = {11, 13, -211, -321, -2212, -211, -321, -2212};
47
48 vector<short> idPosSec[NTrackTypes];
49 vector<short> idNegSec[NTrackTypes];
50
51 vector<short> idPosPrim[NTrackTypes];
52 vector<short> idNegPrim[NTrackTypes];
53
54 for (unsigned short iTr = 0; iTr < vRTracks.size(); iTr++) {
55 CbmKFTrack& kfTrack = vRTracks[iTr];
56 bool ok = 1;
57 for (unsigned short iT = 0; iT < 5; iT++)
58 ok = ok && finite(kfTrack.GetTrack()[iT]);
59 for (unsigned short iC = 0; iC < 15; iC++)
60 ok = ok && finite(kfTrack.GetCovMatrix()[iC]);
61 ok = ok && (kfTrack.GetCovMatrix()[0] < 1. && kfTrack.GetCovMatrix()[0] > 0.)
62 && (kfTrack.GetCovMatrix()[2] < 1. && kfTrack.GetCovMatrix()[2] > 0.)
63 && (kfTrack.GetCovMatrix()[5] < 1. && kfTrack.GetCovMatrix()[5] > 0.)
64 && (kfTrack.GetCovMatrix()[9] < 1. && kfTrack.GetCovMatrix()[9] > 0.)
65 && (kfTrack.GetCovMatrix()[14] < 1. && kfTrack.GetCovMatrix()[14] > 0.);
66 ok = ok && kfTrack.GetRefChi2() < 10 * kfTrack.GetRefNDF();
67 if (!ok)
68 continue;
69
70 const int pdg = abs(vTrackPDG[iTr]);
71
72 short pdgIndex = -1;
73 switch (pdg) {
74 case 11:
75 pdgIndex = 0;
76 break;
77 case 13:
78 pdgIndex = 1;
79 break;
80 case 211:
81 pdgIndex = 2;
82 break;
83 case 321:
84 pdgIndex = 3;
85 break;
86 case 2212:
87 pdgIndex = 4;
88 break;
89 }
90
91 short incr = 3;
92 short pdgIndexMax = pdgIndex + incr;
93
94 if (pdgIndex < 2) {
95 incr = 1;
96 pdgIndexMax = pdgIndex;
97 }
98
99 if (pdgIndex < 0) {
100 pdgIndex = 5;
101 pdgIndexMax = 7;
102 incr = 1;
103 }
104
105 if (ChiToPrimVtx[iTr] < cuts[0][0]) {
106 if (kfTrack.GetTrack()[4] >= 0.) {
107 for (int ipdg = pdgIndex; ipdg <= pdgIndexMax; ipdg += incr)
108 idPosPrim[ipdg].push_back(iTr);
109 }
110 if (kfTrack.GetTrack()[4] < 0.)
111 for (int ipdg = pdgIndex; ipdg <= pdgIndexMax; ipdg += incr)
112 idNegPrim[ipdg].push_back(iTr);
113 } else {
114 if (kfTrack.GetTrack()[4] >= 0.)
115 for (int ipdg = pdgIndex; ipdg <= pdgIndexMax; ipdg += incr)
116 idPosSec[ipdg].push_back(iTr);
117 if (kfTrack.GetTrack()[4] < 0.)
118 for (int ipdg = pdgIndex; ipdg <= pdgIndexMax; ipdg += incr)
119 idNegSec[ipdg].push_back(iTr);
120 }
121 }
122
123 const int nPart = idPosSec[5].size() * idNegSec[5].size() + idPosSec[5].size() * idNegSec[7].size()
124 + idPosSec[7].size() * idNegSec[5].size() + idPosPrim[2].size() * idNegPrim[3].size()
125 + idPosPrim[3].size() * idNegPrim[2].size() + idPosPrim[3].size() * idNegPrim[3].size()
126 + idPosPrim[4].size() * idNegPrim[3].size() + idPosPrim[3].size() * idNegPrim[4].size()
127 + idPosPrim[0].size() * idNegPrim[0].size() + idPosPrim[1].size() * idNegPrim[1].size();
128
129 // std::cout << "NPart estim " << nPart << std::endl;
130 Particles.reserve(vRTracks.size() + nPart);
131
132 const float massLambdaPDG = 1.115683;
133 const float massK0sPDG = 0.497614;
134 const float massKsiPDG = 1.32171;
135
136 for (unsigned short iTr = 0; iTr < vRTracks.size(); iTr++) {
137 CbmKFTrack& kfTrack = vRTracks[iTr];
138 kfTrack.SetId(iTr);
139 KFParticle tmp(&kfTrack);
140 tmp.SetPDG(211); // vTrackPDG[iTr]);
141 tmp.SetId(Particles.size());
142 tmp.SetNDaughters(1);
143 tmp.AddDaughterId(iTr);
144 Particles.push_back(tmp);
145 }
146
147 vector<float> vLambdaTopoChi2Ndf;
148 vector<KFParticle> vLambdaSec;
149 vector<KFParticle> vLambdaPrim;
150
151 vector<float> vLambdaBarTopoChi2Ndf;
152 vector<KFParticle> vLambdaBarSec;
153 vector<KFParticle> vLambdaBarPrim;
154
155 vector<float> vK0sTopoChi2Ndf;
156 vector<KFParticle> vK0sPrim;
157
158 vector<float> vGammaTopoChi2Ndf;
159 vector<KFParticle> vGammaPrim;
160 vector<KFParticle> vGammaSec;
161
162 vector<KFParticle> vPi0Prim;
163 vector<KFParticle> vPi0Sec;
164
165 vector<KFParticle> vXiPrim;
166 vector<KFParticle> vXiSec;
167 vector<KFParticle> vXiBarPrim;
168
169 vector<KFParticle> vXiStarPrim;
170 vector<KFParticle> vXiStarBarPrim;
171
172 const float SecCuts[3] = {3.f, 5.f, 10.f};
173 // const float SecCuts[3] = {3.f,5.f,4.f};
174
175 // K0s -> pi+ pi-
176 Find2DaughterDecay(vRTracks, vField, Particles, pdgNeg[5], pdgPos[5], 310, idNegSec[5], idPosSec[5], PrimVtx,
177 cuts[0], 0, &vK0sTopoChi2Ndf, SecCuts, massK0sPDG, 0.0022, &vK0sPrim, 0);
178 // Lambda -> p pi-
179 Find2DaughterDecay(vRTracks, vField, Particles, pdgNeg[5], pdgPos[7], 3122, idNegSec[5], idPosSec[7], PrimVtx,
180 cuts[1], 0, &vLambdaTopoChi2Ndf, SecCuts, massLambdaPDG, 0.0012, &vLambdaPrim, &vLambdaSec);
181 // Lambda_bar -> pi+ p-
182 Find2DaughterDecay(vRTracks, vField, Particles, pdgPos[5], pdgNeg[4], -3122, idPosSec[5], idNegSec[4], PrimVtx,
183 cuts[1], 0, &vLambdaBarTopoChi2Ndf, SecCuts, massLambdaPDG, 0.0012, &vLambdaBarPrim,
184 &vLambdaBarSec);
185 // K*0 -> K+ pi-
186 Find2DaughterDecay(vRTracks, vField, Particles, pdgPos[3], pdgNeg[2], 313, idPosPrim[3], idNegPrim[2], PrimVtx,
187 cuts[1], 1);
188 // K*0_bar -> pi+ K-
189 Find2DaughterDecay(vRTracks, vField, Particles, pdgNeg[3], pdgPos[2], -313, idNegPrim[3], idPosPrim[2], PrimVtx,
190 cuts[1], 1);
191 // Lambda* -> p K-
192 Find2DaughterDecay(vRTracks, vField, Particles, pdgNeg[3], pdgPos[4], 3124, idNegPrim[3], idPosPrim[4], PrimVtx,
193 cuts[1], 1);
194 // Lambda*_bar -> K+ p-
195 Find2DaughterDecay(vRTracks, vField, Particles, pdgNeg[4], pdgPos[3], -3124, idNegPrim[4], idPosPrim[3], PrimVtx,
196 cuts[1], 1);
197 // phi -> K+ K-
198 Find2DaughterDecay(vRTracks, vField, Particles, pdgNeg[3], pdgPos[3], 333, idNegPrim[3], idPosPrim[3], PrimVtx,
199 cuts[1], 1);
200 // //rho -> pi+ pi-
201 // Find2DaughterDecay(vRTracks, vField, Particles, pdgNeg[2], pdgPos[2], 113,
202 // idNegPrim[2], idPosPrim[2],
203 // PrimVtx, cuts[1]);
204 // gamma -> e+ e-
205
206 float SecCutsGamma[3] = {3, 3, -100};
207 float gammaCuts[3] = {3, 100000, -100};
208 Find2DaughterDecay(vRTracks, vField, Particles, pdgNeg[0], pdgPos[0], 22, idNegPrim[0], idPosPrim[0], PrimVtx,
209 gammaCuts, 1, &vGammaTopoChi2Ndf, SecCutsGamma, 0, 0.006, &vGammaPrim, &vGammaSec);
210 Find2DaughterDecay(vRTracks, vField, Particles, pdgNeg[0], pdgPos[0], 22, idNegSec[0], idPosSec[0], PrimVtx,
211 gammaCuts, 0, &vGammaTopoChi2Ndf, SecCutsGamma, 0, 0.006, &vGammaPrim, &vGammaSec);
212 Find2DaughterDecay(vRTracks, vField, Particles, pdgNeg[0], pdgPos[0], 22, idNegSec[0], idPosPrim[0], PrimVtx,
213 gammaCuts, 0, &vGammaTopoChi2Ndf, SecCutsGamma, 0, 0.006, &vGammaPrim, &vGammaSec);
214 Find2DaughterDecay(vRTracks, vField, Particles, pdgNeg[0], pdgPos[0], 22, idNegPrim[0], idPosSec[0], PrimVtx,
215 gammaCuts, 0, &vGammaTopoChi2Ndf, SecCutsGamma, 0, 0.006, &vGammaPrim, &vGammaSec);
216 // JPsi-> e+ e-
217 Find2DaughterDecay(vRTracks, vField, Particles, pdgNeg[0], pdgPos[0], 443, idNegPrim[0], idPosPrim[0], PrimVtx,
218 cuts[1], 1, 1.f);
219 // JPsi-> mu+ mu-
220 Find2DaughterDecay(vRTracks, vField, Particles, pdgNeg[1], pdgPos[1], 100443, idNegPrim[1], idPosPrim[1], PrimVtx,
221 cuts[1], 1, 1.f);
222 // rho, omega, phi -> e+ e-
223 Find2DaughterDecay(vRTracks, vField, Particles, pdgNeg[0], pdgPos[0], 100113, idNegPrim[0], idPosPrim[0], PrimVtx,
224 cuts[1], 1, 0.2f);
225 // rho, omega, phi -> mu+ mu-
226 const float PCut = 1.f;
227 Find2DaughterDecay(vRTracks, vField, Particles, pdgNeg[1], pdgPos[1], 200113, idNegPrim[1], idPosPrim[1], PrimVtx,
228 cuts[1], 1, 0.2f, -100, 0, &PCut);
229
230 ExtrapolateToPV(vLambdaPrim, PrimVtx);
231 ExtrapolateToPV(vLambdaBarPrim, PrimVtx);
232 ExtrapolateToPV(vK0sPrim, PrimVtx);
233 ExtrapolateToPV(vGammaPrim, PrimVtx);
234
235 float cutSigma0[3] = {-100, 3, 3};
236 // Sigma0 -> Lambda Gamma
237 CombinePartPart(vGammaPrim, vLambdaPrim, Particles, PrimVtx, cutSigma0, 1, 3212, 0);
238
239 // Sigma0_bar -> Lambda_bar Gamma
240 CombinePartPart(vGammaPrim, vLambdaBarPrim, Particles, PrimVtx, cutSigma0, 1, -3212, 0);
241
242 // pi0 -> gamma gamma
243 float cutPi0[3] = {-100, 1000000, 3};
244 float cutPi0Sec[2] = {3, 3};
245 CombinePartPart(vGammaPrim, vGammaPrim, Particles, PrimVtx, cutPi0, 1, 111, 1, &vPi0Prim, &vPi0Sec, cutPi0Sec,
246 0.13498, 0.006);
247 CombinePartPart(vGammaPrim, vGammaSec, Particles, PrimVtx, cutPi0, 0, 111, 0, &vPi0Prim, &vPi0Sec, cutPi0Sec,
248 0.13498, 0.006);
249 CombinePartPart(vGammaSec, vGammaPrim, Particles, PrimVtx, cutPi0, 0, 111, 0, &vPi0Prim, &vPi0Sec, cutPi0Sec,
250 0.13498, 0.006);
251 CombinePartPart(vGammaSec, vGammaSec, Particles, PrimVtx, cutPi0, 0, 111, 1, &vPi0Prim, &vPi0Sec, cutPi0Sec,
252 0.13498, 0.006);
253
254 // Find Sigma+ -> p pi0
255 float cutSigmaPlus[3] = {-100., 3., 3.};
256 FindTrackV0Decay(3222, Particles, vPi0Sec, vRTracks, vField, pdgPos[4], idPosSec[4], PrimVtx, cutSigmaPlus, 0, 0);
257 // Find Sigma+ -> p pi0
258 float cutSigmaPlusBar[3] = {-100., 3., 3.};
259 FindTrackV0Decay(-3222, Particles, vPi0Sec, vRTracks, vField, pdgNeg[4], idNegSec[4], PrimVtx, cutSigmaPlusBar, 0,
260 0);
261 // Sigma*0 -> Lambda pi0
262 CombinePartPart(vPi0Prim, vLambdaPrim, Particles, PrimVtx, cutSigma0, 1, 3214, 0);
263 // Sigma*0_bar -> Lambda_bar pi0
264 CombinePartPart(vPi0Prim, vLambdaBarPrim, Particles, PrimVtx, cutSigma0, 1, -3214, 0);
265 // Xi0 -> Lambda pi0
266 CombinePartPart(vPi0Sec, vLambdaSec, Particles, PrimVtx, cutSigma0, 0, 3322, 0);
267 // Xi0_bar -> Lambda_bar pi0
268 CombinePartPart(vPi0Sec, vLambdaBarSec, Particles, PrimVtx, cutSigma0, 0, -3322, 0);
269
270 // Find Xi-
271 float cutXi[3] = {10., 5., 6.};
272 // float cutXi[3] = {-300.,10.,10.};
273 FindTrackV0Decay(3312, Particles, vLambdaSec, vRTracks, vField, pdgNeg[5], idNegSec[5], PrimVtx, cutXi, 0, 0,
274 &vXiPrim, massKsiPDG, 0.002);
275
276 float cutLL[3] = {10., 10000000., 3.};
277 float cutLL2[3] = {10., 3., 3.};
278 vector<KFParticle> vLL;
279 FindTrackV0Decay(3002, vLL, vLambdaSec, vRTracks, vField, pdgNeg[5], idNegSec[5], PrimVtx, cutLL, 0, &ChiToPrimVtx);
280 // Find H0->Lambda p pi-
281 // Find Omega*-
282 FindTrackV0Decay(3001, Particles, vLL, vRTracks, vField, pdgPos[4], idPosSec[4], PrimVtx, cutLL2, 0, &ChiToPrimVtx);
283 // Find Xi+
284 float cutXiPlus[3] = {10., 5., 6.};
285 FindTrackV0Decay(-3312, Particles, vLambdaBarSec, vRTracks, vField, pdgPos[5], idPosSec[5], PrimVtx, cutXiPlus, 0,
286 0, &vXiBarPrim, massKsiPDG, 0.002);
287 // Find Omega-
288 float cutOmega[3] = {10., 3., 3.};
289 FindTrackV0Decay(3334, Particles, vLambdaSec, vRTracks, vField, pdgNeg[6], idNegSec[6], PrimVtx, cutOmega, 0,
290 &ChiToPrimVtx);
291 // Find Omega+
292 float cutOmegaPlus[3] = {10., 3., 3.};
293 FindTrackV0Decay(-3334, Particles, vLambdaBarSec, vRTracks, vField, pdgPos[6], idPosSec[6], PrimVtx, cutOmegaPlus,
294 0, &ChiToPrimVtx);
295 // Find Xi*-
296 float cutXiStarMinus[3] = {-100., 3., 3.};
297 FindTrackV0Decay(1003314, Particles, vLambdaPrim, vRTracks, vField, pdgNeg[3], idNegPrim[3], PrimVtx,
298 cutXiStarMinus, 1);
299 // Find Xi*+
300 float cutXiStarPlus[3] = {-100., 3., 3.};
301 FindTrackV0Decay(-1003314, Particles, vLambdaBarPrim, vRTracks, vField, pdgPos[3], idPosPrim[3], PrimVtx,
302 cutXiStarPlus, 1);
303
304 ExtrapolateToPV(vXiPrim, PrimVtx);
305 ExtrapolateToPV(vXiBarPrim, PrimVtx);
306
307 // Find Xi*0
308 float cutXiStar0[3] = {-100., 3., 3.};
309 FindTrackV0Decay(3324, Particles, vXiPrim, vRTracks, vField, pdgPos[5], idPosPrim[5], PrimVtx, cutXiStar0, 1, 0,
310 &vXiStarPrim);
311 // Find Xi*0 bar
312 float cutXiBarStar0[3] = {-100., 3., 3.};
313 FindTrackV0Decay(-3324, Particles, vXiBarPrim, vRTracks, vField, pdgNeg[5], idNegPrim[5], PrimVtx, cutXiBarStar0, 1,
314 0, &vXiStarBarPrim);
315
316 // Xi*- -> Xi- pi0
317 float cutXiStarMinusXiPi[3] = {-100., 3., 3.};
318 CombinePartPart(vPi0Prim, vXiPrim, Particles, PrimVtx, cutXiStarMinusXiPi, 1, 3314, 0);
319 // Xi*+ -> Xi+ pi0
320 float cutXiStarPlusXiPi[3] = {-100., 3., 3.};
321 CombinePartPart(vPi0Prim, vXiBarPrim, Particles, PrimVtx, cutXiStarPlusXiPi, 1, -3314, 0);
322
323 // Find Omega*-
324 const float cutOmegaStar[2] = {-100., 3.};
325 for (unsigned int iPart = 0; iPart < vXiStarPrim.size(); iPart++)
326 CombineTrackPart(vRTracks, vField, Particles, vXiStarPrim[iPart], pdgNeg[3], 1003334, idNegPrim[3],
327 cutOmegaStar, 0);
328 // Find Omega*+
329 for (unsigned int iPart = 0; iPart < vXiStarBarPrim.size(); iPart++)
330 CombineTrackPart(vRTracks, vField, Particles, vXiStarBarPrim[iPart], pdgPos[3], -1003334, idPosPrim[3],
331 cutOmegaStar, 0);
332 // Find K*+
333 float cutKStarPlus[3] = {-100., 3., 3.};
334 FindTrackV0Decay(323, Particles, vK0sPrim, vRTracks, vField, pdgPos[5], idPosPrim[5], PrimVtx, cutKStarPlus, 1, 0);
335 // Find K*-
336 float cutKStarMinus[3] = {-100., 3., 3.};
337 FindTrackV0Decay(-323, Particles, vK0sPrim, vRTracks, vField, pdgNeg[5], idNegPrim[5], PrimVtx, cutKStarMinus, 1,
338 0);
339 // Find Sigma*+
340 float cutSigmaStarPlus[3] = {-100., 3., 3.};
341 FindTrackV0Decay(3224, Particles, vLambdaPrim, vRTracks, vField, pdgPos[5], idPosPrim[5], PrimVtx, cutSigmaStarPlus,
342 1, 0);
343 // Find Sigma*+ bar
344 float cutSigmaStarPlusBar[3] = {-100., 3., 3.};
345 FindTrackV0Decay(-3114, Particles, vLambdaBarPrim, vRTracks, vField, pdgPos[5], idPosPrim[5], PrimVtx,
346 cutSigmaStarPlusBar, 1, 0);
347 // Find Sigma*-
348 float cutSigmaStarMinus[3] = {-100., 3., 3.};
349 FindTrackV0Decay(3114, Particles, vLambdaPrim, vRTracks, vField, pdgNeg[5], idNegPrim[5], PrimVtx,
350 cutSigmaStarMinus, 1, 0);
351 // Find Sigma*- bar
352 float cutSigmaStarMinusBar[3] = {-100., 3., 3.};
353 FindTrackV0Decay(-3224, Particles, vLambdaBarPrim, vRTracks, vField, pdgNeg[5], idNegPrim[5], PrimVtx,
354 cutSigmaStarMinusBar, 1, 0);
355 // Find H-dibarion
356 vector<KFParticle> vHdibarion;
357 float cutHdb[3] = {3., 3., 3.};
358 for (unsigned short iL = 0; iL < vLambdaSec.size(); iL++) {
359 KFParticleSIMD vDaughters[2] = {KFParticleSIMD(), KFParticleSIMD(vLambdaSec[iL])};
360
361 vector<int> daughterIds;
362 for (unsigned int iD = 0; iD < vLambdaSec[iL].DaughterIds().size(); iD++)
363 daughterIds.push_back(vLambdaSec[iL].DaughterIds()[iD]);
364 FindHyperons(3000, vDaughters, daughterIds, vLambdaSec, vHdibarion, PrimVtx, cutHdb, iL + 1);
365 }
366
367 for (unsigned int iH = 0; iH < vHdibarion.size(); iH++) {
368 vHdibarion[iH].SetId(Particles.size());
369 Particles.push_back(vHdibarion[iH]);
370 }
371 // chi2_prim chi2_geo z pt chi2_topo
372 const float cutsD[8][8] = {{6., 3., 0.04, 0.3, 3.}, // D0 -> pi+ K-
373 {6., 3., 0.04, 0.3, 3.}, // D+ -> K- pi+ pi+
374 {6., 3., 0.04, 0.3, 3.}, // D0 -> pi+ pi+ pi- K-
375 {6., 3., 0.04, 0.3, 3.}, // Ds+ -> K- K+ pi+
376 {6., 3., 0.04, 0.3, 3.}, // Lambdac -> pi+ K- p
377 {6., 3., -100., 0.3, -100.}, // D*0 -> D+ pi-
378 {6., 3., -100., 0.3, -100.}, // D*+ -> D0 pi+
379 {6., 3., -100., 0.3, -100.}}; // D*+4 -> D04 pi+
380
381 const int DMesLambdcDaughterPDG[5] = {211, -321, -211, 321, 2212};
382 const int DMesLambdcMotherPDG[8] = {421, 411, 100421, 431, 4122, 10421, 10411, 20411};
383 vector<short>* DMesLambdcIdTrack[5] = {&idPosSec[5], &idNegSec[3], &idNegSec[5], &idPosSec[3], &idPosSec[4]};
384 FindDMesLambdac(vRTracks, vField, Particles, DMesLambdcDaughterPDG, DMesLambdcMotherPDG, DMesLambdcIdTrack, PrimVtx,
385 cutsD, ChiToPrimVtx);
386
387 const int DMesLambdcBarDaughterPDG[5] = {-211, 321, 211, -321, -2212};
388 const int DMesLambdcBarMotherPDG[8] = {-421, -411, -100421, -431, -4122, -10421, -10411, -20411};
389 vector<short>* DMesLambdcBarIdTrack[5] = {&idNegSec[5], &idPosSec[3], &idPosSec[5], &idNegSec[3], &idNegSec[4]};
390 FindDMesLambdac(vRTracks, vField, Particles, DMesLambdcBarDaughterPDG, DMesLambdcBarMotherPDG, DMesLambdcBarIdTrack,
391 PrimVtx, cutsD, ChiToPrimVtx);
392 // std::cout << "NPart " << Particles.size() << std::endl;
393}
394
395void KFParticleFinder::ExtrapolateToPV(vector<KFParticle>& vParticles, KFParticleSIMD& PrimVtx)
396{
397 for (unsigned int iL = 0; iL < vParticles.size(); iL += fvecLen) {
398 KFParticle* parts[fvecLen];
399 unsigned int nPart = vParticles.size();
400
401 unsigned int nEntries = (iL + fvecLen < nPart) ? fvecLen : (nPart - iL);
402
403 for (unsigned short iv = 0; iv < nEntries; iv++)
404 parts[iv] = &vParticles[iL + iv];
405
406 KFParticleSIMD tmp(parts, nEntries);
407 tmp.TransportToPoint(PrimVtx.Parameters());
408
409 for (unsigned int iv = 0; iv < nEntries; iv++) {
410 tmp.GetKFParticle(vParticles[iL + iv], iv);
411 }
412 }
413}
414
416{
417 const fvec& x1 = p1.GetX();
418 const fvec& y1 = p1.GetY();
419 const fvec& z1 = p1.GetZ();
420
421 const fvec& x2 = p2.GetX();
422 const fvec& y2 = p2.GetY();
423 const fvec& z2 = p2.GetZ();
424
425 const fvec dx = x1 - x2;
426 const fvec dy = y1 - y2;
427 const fvec dz = z1 - z2;
428
429 const fvec& c0 = p1.GetCovariance(0) + p2.GetCovariance(0);
430 const fvec& c1 = p1.GetCovariance(1) + p2.GetCovariance(1);
431 const fvec& c2 = p1.GetCovariance(2) + p2.GetCovariance(2);
432 const fvec& c3 = p1.GetCovariance(3) + p2.GetCovariance(3);
433 const fvec& c4 = p1.GetCovariance(4) + p2.GetCovariance(4);
434 const fvec& c5 = p1.GetCovariance(5) + p2.GetCovariance(5);
435
436 const fvec r2 = dx * dx + dy * dy + dz * dz;
437 const fvec err2 = c0 * dx * dx + c2 * dy * dy + c5 * dz * dz + 2 * (c1 * dx * dy + c3 * dx * dz + c4 * dy * dz);
438
439 return (r2 * r2 / err2);
440}
441
442void KFParticleFinder::Find2DaughterDecay(vector<CbmKFTrack>& vTracks,
443 const vector<L1FieldRegion>& vField,
444 vector<KFParticle>& Particles,
445 const int DaughterNegPDG,
446 const int DaughterPosPDG,
447 const int MotherPDG,
448 vector<short>& idNeg,
449 vector<short>& idPos,
450 KFParticleSIMD& PrimVtx,
451 const float* cuts,
452 bool isPrimary,
453 vector<float>* vMotherTopoChi2Ndf,
454 const float* secCuts,
455 const float massMotherPDG,
456 const float massMotherPDGSigma,
457 vector<KFParticle>* vMotherPrim,
458 vector<KFParticle>* vMotherSec)
459{
460 //* The function combines 2 tracks into a mother particle
461 //* parameters: array of input tracks (vTracks), array with field approximation for the input tracks
462 //* (vField), array of output particles (Particles), PDG hypothesis for tracks (DaughterNegPDG and DaughterPosPDG),
463 //* PDG hypothesis of mother particles (MotherPDG), indexes of the first and second group of tracks (idNeg and
464 // idPos),
465 //* a primary vertex (PrimVtx),
466 //* a set of cuts (cuts): 0 - doesn't used, 1 - cut on reconstructed Chi2/NDF, 2 - cut on l/dl;
467 //* a flag (isPrimary), which indicates, that the moter particles decay in the primary vertex region,
468 //* if 1 - daughter tracks should be already transported to the primary vertex,
469 //* an array (vMotherTopoChi2Ndf) to store the chi2/ndf of the particles with a production point constraint,
470 //* a set of cuts (secCuts) for primary and secondary particles separation: 0 - cut on mass of the reconstructed
471 // particles:
472 //* mass should be within secCuts[0] sigmas with respect to the PDG mass, 1 - cut on topo chi2/ndf, if chi2ndf_topo<
473 // secCuts[1]
474 //* particle is considered as primary, if not - secondary, 2 - cut on l/dl of the reconstructed particle,
475 //* pdg value of mass of the reconstructed particle (massMotherPDG) and expected width of the peak
476 //(massMotherPDGSigma),
477 //* arrays to store selected according to secCuts primary (vMotherPrim) and secondary (vMotherSec) particles, if the
478 // pointers
479 //* sre equal to 0, corresponding set of particles is not stored.
480
481 //* examples of usage:
482 //* 1) reconstruction of K0s from secondary tracks with selection and storage of primary K0s:
483 //* Find2DaughterDecay(vRTracks, vField, Particles, pdgNeg[5], pdgPos[5], 310,
484 //* idNegSec[5], idPosSec[5], PrimVtx, cuts[0], 0, &vK0sTopoChi2Ndf,
485 //* SecCuts, massK0sPDG, 0.0022, &vK0sPrim, 0);
486 //* 2) reconstruction of Lambda from secondary tracks with selection and storage of primary and secondary Lambdas:
487 //* Find2DaughterDecay(vRTracks, vField, Particles, pdgNeg[5], pdgPos[5], 310,
488 //* idNegSec[5], idPosSec[5], PrimVtx, cuts[0], 0, &vK0sTopoChi2Ndf,
489 //* SecCuts, massK0sPDG, 0.0022, &vK0sPrim, 0);
490 //* 3) reconstruction of K*0 from primary tracks with no selection and storage of primary and secondary particles:
491 //* Find2DaughterDecay(vRTracks, vField, Particles, pdgPos[3], pdgNeg[2], 313,
492 //* idPosPrim[3], idNegPrim[2], PrimVtx, cuts[1], 1);
493
494 const int NPositive = idPos.size();
495 KFParticle mother_temp;
496
497 KFParticleSIMD mother;
498 mother.SetPDG(MotherPDG);
499 KFParticleSIMD motherTopo;
500
501 const short NPosVect = NPositive % fvecLen == 0 ? NPositive / fvecLen : NPositive / fvecLen + 1;
502 vector<KFParticleSIMD> posPart(NPosVect);
503
504 // create particles from tracks
506
507 int iPosVect = 0;
508 for (unsigned short iTrP = 0; iTrP < NPositive; iTrP += fvecLen) {
509 const unsigned short NTracks = (iTrP + fvecLen < NPositive) ? fvecLen : (NPositive - iTrP);
510
511 L1FieldRegion posField;
512 for (unsigned short iv = 0; iv < NTracks; iv++) {
513 vvPos[iv] = &vTracks[idPos[iTrP + iv]];
514
515 int entrSIMDPos = idPos[iTrP + iv] % fvecLen;
516 int entrVecPos = idPos[iTrP + iv] / fvecLen;
517 posField.SetOneEntry(iv, vField[entrVecPos], entrSIMDPos);
518 }
519
520 posPart[iPosVect].Create(vvPos, NTracks, 0, &DaughterPosPDG);
521 posPart[iPosVect].SetField(posField);
522 fvec posId;
523 for (int iv = 0; iv < NTracks; iv++)
524 posId[iv] = idPos[iTrP + iv];
525 posPart[iPosVect].SetId(posId);
526 iPosVect++;
527 }
528
529 for (unsigned short iTrN = 0; iTrN < idNeg.size(); iTrN++) {
530 CbmKFTrack& kfTrackNeg = vTracks[idNeg[iTrN]];
531 KFParticleSIMD vDaughters[2] = {KFParticleSIMD(kfTrackNeg, 0, &DaughterNegPDG), KFParticleSIMD()};
532 int entrSIMD = idNeg[iTrN] % fvecLen;
533 int entrVec = idNeg[iTrN] / fvecLen;
534 vDaughters[0].SetField(vField[entrVec], 1, entrSIMD);
535 vDaughters[0].SetId(idNeg[iTrN]);
536
537 for (unsigned short iTrP = 0; iTrP < NPositive; iTrP += fvecLen) {
538 const unsigned short NTracks = (iTrP + fvecLen < NPositive) ? fvecLen : (NPositive - iTrP);
539
540 vDaughters[1] = posPart[iTrP / fvecLen];
541
542 if (isPrimary) {
543 fvec errGuess[3] = {100 * sqrt(PrimVtx.CovarianceMatrix()[0]),
544 100 * sqrt(PrimVtx.CovarianceMatrix()[2]),
545 100 * sqrt(PrimVtx.CovarianceMatrix()[5])};
546 mother.SetVtxGuess(PrimVtx.X(), PrimVtx.Y(), PrimVtx.Z());
547 mother.SetVtxErrGuess(errGuess[0], errGuess[1], errGuess[2]);
548 const KFParticleSIMD* vDaughtersPointer[2] = {&vDaughters[0], &vDaughters[1]};
549 mother.Construct(vDaughtersPointer, 2, 0, -1, 0, 0);
550 } else {
551 const KFParticleSIMD* vDaughtersPointer[2] = {&vDaughters[0], &vDaughters[1]};
552 mother.Construct(vDaughtersPointer, 2, 0);
553 }
554
555 if (vMotherTopoChi2Ndf) {
556 motherTopo = mother;
557 motherTopo.SetProductionVertex(PrimVtx);
558 }
559
560 for (int iv = 0; iv < NTracks; iv++) {
561 if (!finite(mother.GetChi2()[iv]))
562 continue;
563 if (!(mother.GetChi2()[iv] > 0.0f))
564 continue;
565 if (!(mother.GetChi2()[iv] == mother.GetChi2()[iv]))
566 continue;
567 fvec l, dl, isParticleFromVertex;
568 mother.GetDistanceToVertexLine(PrimVtx, l, dl, &isParticleFromVertex);
569 if ((l / dl)[iv] < cuts[2])
570 continue;
571 if (isPrimary && ((l / dl)[iv] > 3))
572 continue;
573 if ((!isPrimary) && !(isParticleFromVertex[iv]))
574 continue;
575 if (mother.GetChi2()[iv] / mother.GetNDF()[iv] < cuts[1]) {
576 mother.GetKFParticle(mother_temp, iv);
577 mother_temp.SetId(Particles.size());
578 Particles.push_back(mother_temp);
579 float motherTopoChi2Ndf(0);
580 if (vMotherTopoChi2Ndf)
581 motherTopoChi2Ndf = motherTopo.GetChi2()[iv] / motherTopo.GetNDF()[iv];
582
583 if (vMotherPrim) {
584 Double_t mass, errMass;
585
586 mother_temp.GetMass(mass, errMass);
587 if ((fabs(mass - massMotherPDG) / massMotherPDGSigma) > secCuts[0])
588 continue;
589 if ((l / dl)[iv] < secCuts[2])
590 continue;
591
592 mother_temp.SetNonlinearMassConstraint(massMotherPDG);
593
594 if (motherTopoChi2Ndf < secCuts[1]) {
595 vMotherPrim->push_back(mother_temp);
596 } else if (vMotherSec) {
597 // if((l/dl)[iv] < secCuts[2]) continue;
598 vMotherSec->push_back(mother_temp);
599 }
600 }
601 }
602 }
603 }
604 }
605}
606
607void KFParticleFinder::Find2DaughterDecay(vector<CbmKFTrack>& vTracks,
608 const vector<L1FieldRegion>& vField,
609 vector<KFParticle>& Particles,
610 const int DaughterNegPDG,
611 const int DaughterPosPDG,
612 const int MotherPDG,
613 vector<short>& idNeg,
614 vector<short>& idPos,
615 KFParticleSIMD& PrimVtx,
616 const float* cuts,
617 bool isPrimary,
618 const float PtCut,
619 const float Chi2PrimCut,
620 vector<float>* ChiToPrimVtx,
621 const float* PCut)
622{
623 vector<short> idPosPt;
624 vector<short> idNegPt;
625
626 for (unsigned int iEl = 0; iEl < idPos.size(); iEl++) {
627 CbmKFTrack& kfTrack = vTracks[idPos[iEl]];
628 const float tx = kfTrack.GetTrack()[2];
629 const float ty = kfTrack.GetTrack()[3];
630 const float p = fabs(1 / kfTrack.GetTrack()[4]);
631 const float t2 = tx * tx + ty * ty;
632 float pt = p * (sqrt(t2 / (1 + t2)));
633 if (PCut)
634 if (p < *PCut)
635 continue;
636 if (pt < PtCut)
637 continue;
638 if (Chi2PrimCut > -1)
639 if (ChiToPrimVtx->at(idPos[iEl]) < Chi2PrimCut)
640 continue;
641 idPosPt.push_back(idPos[iEl]);
642 }
643
644 for (unsigned int iEl = 0; iEl < idNeg.size(); iEl++) {
645 CbmKFTrack& kfTrack = vTracks[idNeg[iEl]];
646 const float tx = kfTrack.GetTrack()[2];
647 const float ty = kfTrack.GetTrack()[3];
648 const float p = fabs(1 / kfTrack.GetTrack()[4]);
649 const float t2 = tx * tx + ty * ty;
650 float pt = p * (sqrt(t2 / (1 + t2)));
651 if (PCut)
652 if (p < *PCut)
653 continue;
654 if (pt < PtCut)
655 continue;
656 if (Chi2PrimCut > -1)
657 if (ChiToPrimVtx->at(idNeg[iEl]) < Chi2PrimCut)
658 continue;
659 idNegPt.push_back(idNeg[iEl]);
660 }
661
662 Find2DaughterDecay(vTracks, vField, Particles, DaughterNegPDG, DaughterPosPDG, MotherPDG, idNegPt, idPosPt, PrimVtx,
663 cuts, isPrimary);
664}
665
666void KFParticleFinder::FindTrackV0Decay(const int MotherPDG,
667 vector<KFParticle>& Particles,
668 vector<KFParticle>& vV0,
669 vector<CbmKFTrack>& vTracks,
670 const vector<L1FieldRegion>& vField,
671 const int DaughterPDG,
672 vector<short>& idTrack,
673 KFParticleSIMD& PrimVtx,
674 const float* cuts,
675 bool isPrimary,
676 vector<float>* ChiToPrimVtx,
677 vector<KFParticle>* vHyperonPrim,
678 float hyperonPrimMass,
679 float hyperonPrimMassErr,
680 vector<KFParticle>* vHyperonSec)
681{
682 KFParticle hyperon_temp;
683 KFParticleSIMD hyperon;
684 hyperon.SetPDG(MotherPDG);
685
686 for (unsigned short iV0 = 0; iV0 < vV0.size(); iV0++) {
687 unsigned short nElements = 0;
688 KFParticleSIMD vDaughters[2] = {KFParticleSIMD(vV0[iV0]), KFParticleSIMD()};
689
691 L1FieldRegion field;
692 fvec trId;
693
694 for (unsigned short iTr = 0; iTr < idTrack.size(); iTr++) {
695 bool ok = 1;
696 if (ChiToPrimVtx)
697 if ((ChiToPrimVtx->at(idTrack[iTr]) < 7))
698 ok = 0; // TODO 7 for Omega
699
700 if (ok) {
701 trId[nElements] = idTrack[iTr];
702 vvTr[nElements] = &vTracks[idTrack[iTr]];
703
704 int entrSIMD = idTrack[iTr] % fvecLen;
705 int entrVec = idTrack[iTr] / fvecLen;
706 field.SetOneEntry(nElements, vField[entrVec], entrSIMD);
707
708 nElements++;
709 } else if ((iTr != idTrack.size() - 1))
710 continue;
711
712 if ((nElements == fvecLen) || ((iTr == idTrack.size() - 1) && (nElements > 0))) {
713 vDaughters[1].Create(vvTr, nElements, 0, &DaughterPDG);
714 vDaughters[1].SetField(field);
715 vDaughters[1].SetId(trId);
716
717 if (isPrimary) {
718 fvec errGuess[3] = {100 * sqrt(PrimVtx.CovarianceMatrix()[0]),
719 100 * sqrt(PrimVtx.CovarianceMatrix()[2]),
720 100 * sqrt(PrimVtx.CovarianceMatrix()[5])};
721 hyperon.SetVtxGuess(PrimVtx.X(), PrimVtx.Y(), PrimVtx.Z());
722 hyperon.SetVtxErrGuess(errGuess[0], errGuess[1], errGuess[2]);
723 const KFParticleSIMD* vDaughtersPointer[2] = {&vDaughters[0], &vDaughters[1]};
724 hyperon.Construct(vDaughtersPointer, 2, 0, -1, 0, 0);
725 } else {
726 const KFParticleSIMD* vDaughtersPointer[2] = {&vDaughters[0], &vDaughters[1]};
727 hyperon.Construct(vDaughtersPointer, 2, 0);
728 }
729
730 KFParticleSIMD hyperonTopo(hyperon);
731 hyperonTopo.SetProductionVertex(PrimVtx);
732
733 for (unsigned int iv = 0; iv < nElements; iv++) {
734 bool isSameTrack = 0;
735 for (unsigned short iD = 0; iD < vV0[iV0].DaughterIds().size(); iD++)
736 if (vV0[iV0].DaughterIds()[iD] == trId[iv])
737 isSameTrack = 1;
738
739 if (isSameTrack)
740 continue;
741 if (!finite(hyperon.GetChi2()[iv]))
742 continue;
743 if (!(hyperon.GetChi2()[iv] > 0.0f))
744 continue;
745 if (!(hyperon.GetChi2()[iv] == hyperon.GetChi2()[iv]))
746 continue;
747
748 fvec l, dl, isParticleFromVertex;
749 hyperon.GetDistanceToVertexLine(PrimVtx, l, dl, &isParticleFromVertex);
750 if (!(isParticleFromVertex[iv]))
751 continue;
752
753 if (((l / dl)[iv] < cuts[0]))
754 continue;
755 if (!isPrimary) {
756 fvec l1, dl1;
757 vDaughters[0].GetDistanceToVertexLine(hyperon, l1, dl1, &isParticleFromVertex);
758 if (!(isParticleFromVertex[iv]))
759 continue;
760 }
761
762 if (hyperonTopo.GetChi2()[iv] / hyperonTopo.GetNDF()[iv] > cuts[1])
763 continue;
764
765 if (hyperon.GetChi2()[iv] / hyperon.GetNDF()[iv] > cuts[2])
766 continue;
767 hyperon.GetKFParticle(hyperon_temp, iv);
768
769 hyperon_temp.SetId(Particles.size());
770 Particles.push_back(hyperon_temp);
771
772 if (vHyperonPrim) {
773 Double_t mass, errMass;
774
775 hyperon_temp.GetMass(mass, errMass);
776 hyperon_temp.SetNonlinearMassConstraint(hyperonPrimMass);
777
778 if ((fabs(mass - hyperonPrimMass) / hyperonPrimMassErr) <= 3)
779 vHyperonPrim->push_back(hyperon_temp);
780 else if (vHyperonSec)
781 vHyperonSec->push_back(hyperon_temp);
782 }
783 }
784 nElements = 0;
785 }
786 }
787 }
788}
789
791 KFParticleSIMD vDaughters[2],
792 vector<int>& daughterIds,
793 vector<KFParticle>& vLambdaSec,
794 vector<KFParticle>& vHyperon,
795 KFParticleSIMD& PrimVtx,
796 const float* cuts,
797 int startIndex)
798{
799 KFParticle* lambdas[fvecLen];
800 int nLambdasSec = vLambdaSec.size();
801
802 for (unsigned short iL = startIndex; iL < vLambdaSec.size(); iL += fvecLen) {
803 unsigned int nEntries = (iL + fvecLen < nLambdasSec) ? fvecLen : (nLambdasSec - iL);
804
805 for (unsigned short iv = 0; iv < nEntries; iv++)
806 lambdas[iv] = &vLambdaSec[iL + iv];
807
808 vDaughters[0] = KFParticleSIMD(lambdas, nEntries);
809
810 KFParticleSIMD hyperon;
811
812 hyperon.SetPDG(PDG);
813 const KFParticleSIMD* vDaughtersPointer[2] = {&vDaughters[0], &vDaughters[1]};
814 hyperon.Construct(vDaughtersPointer, 2, 0);
815
816 KFParticleSIMD hyperonTopo(hyperon);
817 hyperonTopo.SetProductionVertex(PrimVtx);
818
819 for (unsigned int iv = 0; iv < nEntries; iv++) {
820 bool isSameTrack = 0;
821 for (unsigned short iD = 0; iD < lambdas[iv]->DaughterIds().size(); iD++)
822 for (unsigned short iD0 = 0; iD0 < daughterIds.size(); iD0++)
823 if (lambdas[iv]->DaughterIds()[iD] == daughterIds[iD0])
824 isSameTrack = 1;
825
826 if (isSameTrack)
827 continue;
828 if (!finite(hyperon.GetChi2()[iv]))
829 continue;
830 if (!(hyperon.GetChi2()[iv] > 0.0f))
831 continue;
832 if (!(hyperon.GetChi2()[iv] == hyperon.GetChi2()[iv]))
833 continue;
834
835 fvec l, dl, isParticleFromVertex;
836 fvec l1, dl1, l2, dl2;
837 hyperon.GetDistanceToVertexLine(PrimVtx, l, dl, &isParticleFromVertex);
838 vDaughters[0].GetDistanceToVertexLine(hyperon, l1, dl1);
839 vDaughters[1].GetDistanceToVertexLine(hyperon, l2, dl2);
840 if (!(isParticleFromVertex[iv]))
841 continue;
842
843 if (((l / dl)[iv] < cuts[0]))
844 continue;
845 if (((l1 - l)[iv] < 0) || ((l2 - l)[iv] < 0))
846 continue;
847
848 if (hyperonTopo.GetChi2()[iv] / hyperonTopo.GetNDF()[iv] > cuts[1])
849 continue;
850
851 if (hyperon.GetChi2()[iv] / hyperon.GetNDF()[iv] > cuts[2])
852 continue;
853 KFParticle hyperon_temp;
854 hyperon.GetKFParticle(hyperon_temp, iv);
855 vHyperon.push_back(hyperon_temp);
856 }
857 }
858}
859
860void KFParticleFinder::FindDMesLambdac(vector<CbmKFTrack>& vTracks,
861 const vector<L1FieldRegion>& vField,
862 vector<KFParticle>& Particles,
863 const int DaughterPDG[5], // pi, K_b, pi_b, K, p
864 const int MotherPDG[8], // D0, D+, D0_4, Ds+, Lc
865 vector<short>* idTrack[5], // pi, K_b, pi_b, K, p
866 KFParticleSIMD& PrimVtx,
867 const float cuts[8][8],
868 vector<float> ChiToPrimVtx)
869{
870 vector<short> id[5]; // pi, K_b, pi_b, K, p
871 for (int iId = 0; iId < 5; iId++) {
872 for (unsigned int iTr = 0; iTr < idTrack[iId]->size(); iTr++) {
873 CbmKFTrack& kfTrack = vTracks[idTrack[iId]->at(iTr)];
874 const float tx = kfTrack.GetTrack()[2];
875 const float ty = kfTrack.GetTrack()[3];
876 const float p = fabs(1 / kfTrack.GetTrack()[4]);
877 const float t2 = tx * tx + ty * ty;
878 float pt = p * (sqrt(t2 / (1 + t2)));
879 if (pt < cuts[0][3])
880 continue;
881 if (ChiToPrimVtx[idTrack[iId]->at(iTr)] < cuts[0][0])
882 continue;
883 id[iId].push_back(idTrack[iId]->at(iTr));
884 }
885 }
886
887 vector<KFParticle> kpi;
888 vector<KFParticle> kpipi;
889 vector<KFParticle> kpipipi;
890 vector<KFParticle> kpik;
891 vector<KFParticle> kpip;
892
893 const float cutskpi[3] = {3., 3., -100.};
894 Find2DaughterDecay(vTracks, vField, kpi, DaughterPDG[0], DaughterPDG[1], MotherPDG[0], id[0], id[1], PrimVtx,
895 cutskpi, 0);
896
897 for (unsigned int iKPi = 0; iKPi < kpi.size(); iKPi++) {
898 unsigned short startPiIndex = kpi[iKPi].DaughterIds()[0] + 1;
899
900 CombineTrackPart(vTracks, vField, kpipi, kpi[iKPi], DaughterPDG[0], MotherPDG[1], id[0], cuts[1], startPiIndex,
901 1);
902 CombineTrackPart(vTracks, vField, kpik, kpi[iKPi], DaughterPDG[3], MotherPDG[3], id[3], cuts[3], 0, 1);
903 CombineTrackPart(vTracks, vField, kpip, kpi[iKPi], DaughterPDG[4], MotherPDG[4], id[4], cuts[4], 0, 1);
904 }
905 for (unsigned int iKPiPi = 0; iKPiPi < kpipi.size(); iKPiPi++)
906 CombineTrackPart(vTracks, vField, kpipipi, kpipi[iKPiPi], DaughterPDG[2], MotherPDG[2], id[2], cuts[2], 0, 1);
907
908 SelectParticleCandidates(Particles, kpi, PrimVtx, cuts[0]);
909 SelectParticleCandidates(Particles, kpipi, PrimVtx, cuts[1]);
910 SelectParticleCandidates(Particles, kpipipi, PrimVtx, cuts[2]);
911 SelectParticleCandidates(Particles, kpik, PrimVtx, cuts[3]);
912 SelectParticleCandidates(Particles, kpip, PrimVtx, cuts[4]);
913
914 vector<KFParticle> d0pi;
915 vector<KFParticle> d2pi;
916 vector<KFParticle> d4pi;
917
918 for (unsigned int iKPiPi = 0; iKPiPi < kpipi.size(); iKPiPi++)
919 CombineTrackPart(vTracks, vField, d0pi, kpipi[iKPiPi], DaughterPDG[2], MotherPDG[5], id[2], cuts[5], 0, 0);
920
921 for (unsigned int iKPi = 0; iKPi < kpi.size(); iKPi++)
922 CombineTrackPart(vTracks, vField, d2pi, kpi[iKPi], DaughterPDG[0], MotherPDG[6], id[0], cuts[6], 0, 0);
923
924 for (unsigned int iKPiPiPi = 0; iKPiPiPi < kpipipi.size(); iKPiPiPi++)
925 CombineTrackPart(vTracks, vField, d4pi, kpipipi[iKPiPiPi], DaughterPDG[0], MotherPDG[7], id[0], cuts[7], 0, 0);
926
927 SelectParticleCandidates(Particles, d0pi, PrimVtx, cuts[5]);
928 SelectParticleCandidates(Particles, d2pi, PrimVtx, cuts[6]);
929 SelectParticleCandidates(Particles, d4pi, PrimVtx, cuts[7]);
930}
931
932void KFParticleFinder::CombineTrackPart(vector<CbmKFTrack>& vTracks,
933 const vector<L1FieldRegion>& vField,
934 vector<KFParticle>& Particles,
935 KFParticle& part,
936 const int DaughterPDG,
937 const int MotherPDG,
938 vector<short>& id,
939 const float* cuts,
940 const unsigned short startIndex,
941 const bool IsSamePart)
942{
943 KFParticleSIMD vDaughters[2] = {KFParticleSIMD(part), KFParticleSIMD()};
944
946
947 fvec vtxGuess[3] = {part.GetX(), part.GetY(), part.GetZ()};
948 fvec errGuess[3] = {fvec(10.f * sqrt(part.CovarianceMatrix()[0])), fvec(10.f * sqrt(part.CovarianceMatrix()[2])),
949 fvec(10.f * sqrt(part.CovarianceMatrix()[5]))};
950
951 const unsigned short NTr = id.size();
952 for (unsigned short iTr = startIndex; iTr < NTr; iTr += fvecLen) {
953 const unsigned short NTracks = (iTr + fvecLen < NTr) ? fvecLen : (NTr - iTr);
954
955 L1FieldRegion trField;
956 for (unsigned short iv = 0; iv < NTracks; iv++) {
957 vTr[iv] = &vTracks[id[iTr + iv]];
958
959 int entrSIMDPos = id[iTr + iv] % fvecLen;
960 int entrVecPos = id[iTr + iv] / fvecLen;
961 trField.SetOneEntry(iv, vField[entrVecPos], entrSIMDPos);
962 }
963
964 vDaughters[1].Create(vTr, NTracks, 0, &DaughterPDG);
965 vDaughters[1].SetField(trField);
966 fvec trId;
967 for (int iv = 0; iv < NTracks; iv++)
968 trId[iv] = id[iTr + iv];
969 vDaughters[1].SetId(trId);
970
971 KFParticleSIMD mother;
972 mother.SetPDG(MotherPDG);
973 if (IsSamePart) {
974 mother.SetVtxGuess(vtxGuess[0], vtxGuess[1], vtxGuess[2]);
975 mother.SetVtxErrGuess(errGuess[0], errGuess[1], errGuess[2]);
976 }
977 const KFParticleSIMD* vDaughtersPointer[2] = {&vDaughters[0], &vDaughters[1]};
978 mother.Construct(vDaughtersPointer, 2, 0);
979
980 for (int iv = 0; iv < NTracks; iv++) {
981 if (!finite(mother.GetChi2()[iv]))
982 continue;
983 if (!(mother.GetChi2()[iv] > 0.0f))
984 continue;
985 if (!(mother.GetChi2()[iv] == mother.GetChi2()[iv]))
986 continue;
987
988 if (mother.GetChi2()[iv] / mother.GetNDF()[iv] > cuts[1])
989 continue;
990
991 bool isSameTrack = 0;
992 for (unsigned short iD = 0; iD < part.DaughterIds().size(); iD++)
993 if (part.DaughterIds()[iD] == id[iTr + iv])
994 isSameTrack = 1;
995 if (isSameTrack)
996 continue;
997
998 KFParticle mother_temp;
999 mother.GetKFParticle(mother_temp, iv);
1000 mother_temp.CleanDaughtersId();
1001 mother_temp.AddDaughter(id[iTr + iv]);
1002 for (unsigned short iD = 0; iD < part.DaughterIds().size(); iD++)
1003 mother_temp.AddDaughter(part.DaughterIds()[iD]);
1004 Particles.push_back(mother_temp);
1005 }
1006 }
1007}
1008
1009void KFParticleFinder::CombinePartPart(vector<KFParticle>& particles1,
1010 vector<KFParticle>& particles2,
1011 vector<KFParticle>& Particles,
1012 KFParticleSIMD& PrimVtx,
1013 const float* cuts,
1014 bool isPrimary,
1015 const int MotherPDG,
1016 bool isSameInputPart,
1017 vector<KFParticle>* vMotherPrim,
1018 vector<KFParticle>* vMotherSec,
1019 float* secCuts,
1020 float massMotherPDG,
1021 float massMotherPDGSigma)
1022{
1023 KFParticle mother_temp;
1024 KFParticleSIMD mother;
1025 KFParticleSIMD motherTopo;
1026 mother.SetPDG(MotherPDG);
1027
1028 KFParticle* tmpPart2[fvecLen];
1029 int nPart2 = particles2.size();
1030
1031 for (unsigned short iP1 = 0; iP1 < particles1.size(); iP1++) {
1032 KFParticleSIMD vDaughters[2] = {KFParticleSIMD(particles1[iP1]), KFParticleSIMD()};
1033
1034 unsigned short startIndex = 0;
1035 if (isSameInputPart)
1036 startIndex = iP1 + 1;
1037 for (unsigned short iP2 = startIndex; iP2 < nPart2; iP2 += fvecLen) {
1038 unsigned int nEntries = (iP2 + fvecLen < nPart2) ? fvecLen : (nPart2 - iP2);
1039
1040 for (unsigned short iv = 0; iv < nEntries; iv++)
1041 tmpPart2[iv] = &particles2[iP2 + iv];
1042
1043 vDaughters[1] = KFParticleSIMD(tmpPart2, nEntries);
1044
1045 if (isPrimary) {
1046 fvec errGuess[3] = {100 * sqrt(PrimVtx.CovarianceMatrix()[0]),
1047 100 * sqrt(PrimVtx.CovarianceMatrix()[2]),
1048 100 * sqrt(PrimVtx.CovarianceMatrix()[5])};
1049 mother.SetVtxGuess(PrimVtx.X(), PrimVtx.Y(), PrimVtx.Z());
1050 mother.SetVtxErrGuess(errGuess[0], errGuess[1], errGuess[2]);
1051 const KFParticleSIMD* vDaughtersPointer[2] = {&vDaughters[0], &vDaughters[1]};
1052 mother.Construct(vDaughtersPointer, 2, 0, -1, 0, 0);
1053 } else {
1054 const KFParticleSIMD* vDaughtersPointer[2] = {&vDaughters[0], &vDaughters[1]};
1055 mother.Construct(vDaughtersPointer, 2, 0);
1056 }
1057
1058 motherTopo = mother;
1059 motherTopo.SetProductionVertex(PrimVtx);
1060
1061 for (unsigned short iv = 0; iv < nEntries; iv++) {
1062 bool isSameTrack = 0;
1063 for (unsigned short iD = 0; iD < tmpPart2[iv]->DaughterIds().size(); iD++)
1064 for (unsigned short iD0 = 0; iD0 < particles1[iP1].DaughterIds().size(); iD0++)
1065 if (tmpPart2[iv]->DaughterIds()[iD] == particles1[iP1].DaughterIds()[iD0])
1066 isSameTrack = 1;
1067
1068 if (isSameTrack)
1069 continue;
1070 if (!finite(mother.GetChi2()[iv]))
1071 continue;
1072 if (!(mother.GetChi2()[iv] > 0.0f))
1073 continue;
1074 if (!(mother.GetChi2()[iv] == mother.GetChi2()[iv]))
1075 continue;
1076
1077 fvec l, dl, isParticleFromVertex;
1078 mother.GetDistanceToVertexLine(PrimVtx, l, dl, &isParticleFromVertex);
1079 if (!(isParticleFromVertex[iv]))
1080 continue;
1081
1082 if (((l / dl)[iv] < cuts[0]))
1083 continue;
1084 if (!isPrimary) {
1085 fvec l1, dl1;
1086 vDaughters[0].GetDistanceToVertexLine(mother, l1, dl1, &isParticleFromVertex);
1087 if (!(isParticleFromVertex[iv]))
1088 continue;
1089 }
1090
1091 float motherTopoChi2Ndf = motherTopo.GetChi2()[iv] / motherTopo.GetNDF()[iv];
1092 if (motherTopo.GetChi2()[iv] / motherTopo.GetNDF()[iv] > cuts[1])
1093 continue;
1094
1095 if (mother.GetChi2()[iv] / mother.GetNDF()[iv] > cuts[2])
1096 continue;
1097 mother.GetKFParticle(mother_temp, iv);
1098
1099 mother_temp.SetId(Particles.size());
1100 Particles.push_back(mother_temp);
1101
1102 if (vMotherPrim) {
1103 Double_t mass, errMass;
1104
1105 mother_temp.GetMass(mass, errMass);
1106 if ((fabs(mass - massMotherPDG) / massMotherPDGSigma) > secCuts[0])
1107 continue;
1108
1109 mother_temp.SetNonlinearMassConstraint(massMotherPDG);
1110
1111 if (motherTopoChi2Ndf < secCuts[1]) {
1112 vMotherPrim->push_back(mother_temp);
1113 } else if (vMotherSec) {
1114 vMotherSec->push_back(mother_temp);
1115 }
1116 }
1117 }
1118 }
1119 }
1120}
1121
1122void KFParticleFinder::SelectParticleCandidates(vector<KFParticle>& Particles,
1123 vector<KFParticle>& vCandidates,
1124 KFParticleSIMD& PrimVtx,
1125 const float cuts[5])
1126{
1127 KFParticle* cand[fvecLen];
1128 int nCand = vCandidates.size();
1129
1130 for (unsigned short iC = 0; iC < nCand; iC += fvecLen) {
1131 unsigned int nEntries = (iC + fvecLen < nCand) ? fvecLen : (nCand - iC);
1132
1133 for (unsigned short iv = 0; iv < nEntries; iv++)
1134 cand[iv] = &vCandidates[iC + iv];
1135
1136 KFParticleSIMD candTopo(cand, nEntries);
1137
1138 candTopo.SetProductionVertex(PrimVtx);
1139
1140 for (unsigned int iv = 0; iv < nEntries; iv++) {
1141 if (!finite(candTopo.GetChi2()[iv]))
1142 continue;
1143 if (!(candTopo.GetChi2()[iv] > 0.0f))
1144 continue;
1145 if (!(candTopo.GetChi2()[iv] == candTopo.GetChi2()[iv]))
1146 continue;
1147
1148 fvec l, dl, isParticleFromVertex;
1149 candTopo.GetDistanceToVertexLine(PrimVtx, l, dl, &isParticleFromVertex);
1150 if (!(isParticleFromVertex[iv]))
1151 continue;
1152 if (((l / dl)[iv] < cuts[2]))
1153 continue;
1154
1155 if (candTopo.GetChi2()[iv] / candTopo.GetNDF()[iv] > cuts[4])
1156 continue;
1157
1158 Particles.push_back(vCandidates[iC + iv]);
1159 }
1160 }
1161}
1162
1163void KFParticleFinder::ConstructPVT(vector<CbmKFTrack>& vRTracks) {}
1164
1165#undef cnst
friend F32vec4 fabs(const F32vec4 &a)
Definition P4_F32vec4.h:52
const int fvecLen
Definition P4_F32vec4.h:233
F32vec4 fvec
Definition P4_F32vec4.h:231
double Double_t
Double_t * GetTrack()
Is it electron.
Definition CbmKFTrack.h:74
Double_t & GetRefChi2()
array[15] of covariance matrix
Definition CbmKFTrack.h:76
Int_t & GetRefNDF()
Chi^2 after fit.
Definition CbmKFTrack.h:77
Double_t * GetCovMatrix()
array[6] of track parameters(x,y,tx,ty,qp,z)
Definition CbmKFTrack.h:75
void GetDistanceToVertexLine(const KFParticleBaseSIMD &Vertex, fvec &l, fvec &dl, fvec *isParticleFromVertex=0) const
void SetVtxErrGuess(fvec &x, fvec &y, fvec &z)
void SetNonlinearMassConstraint(Double_t Mass)
void SetPDG(int pdg)
const std::vector< int > & DaughterIds() const
void AddDaughterId(int id)
void SetId(int id)
void ConstructPVT(std::vector< CbmKFTrack > &vRTracks)
static void SelectParticleCandidates(std::vector< KFParticle > &Particles, std::vector< KFParticle > &vCandidates, KFParticleSIMD &PrimVtx, const float cuts[5])
static fvec GetChi2BetweenParticles(KFParticleSIMD &p1, KFParticleSIMD &p2)
static void ExtrapolateToPV(std::vector< KFParticle > &vParticles, KFParticleSIMD &PrimVtx)
static void FindTrackV0Decay(const int MotherPDG, std::vector< KFParticle > &Particles, std::vector< KFParticle > &vV0, std::vector< CbmKFTrack > &vTracks, const std::vector< L1FieldRegion > &field, const int DaughterPDG, std::vector< short > &idTrack, KFParticleSIMD &PrimVtx, const float *cuts=0, bool isPrimary=0, std::vector< float > *ChiToPrimVtx=0, std::vector< KFParticle > *vHyperonPrim=0, float hyperonPrimMass=0, float hyperonPrimMassErr=0, std::vector< KFParticle > *vHyperonSec=0)
static void CombineTrackPart(std::vector< CbmKFTrack > &vTracks, const std::vector< L1FieldRegion > &vField, std::vector< KFParticle > &Particles, KFParticle &part, const int DaughterPDG, const int MotherPDG, std::vector< short > &id, const float *cuts, const unsigned short startIndex=0, const bool IsSamePart=0)
static void CombinePartPart(std::vector< KFParticle > &particles1, std::vector< KFParticle > &particles2, std::vector< KFParticle > &Particles, KFParticleSIMD &PrimVtx, const float *cuts=0, bool isPrimary=0, const int MotherPDG=0, bool isSameInputPart=0, std::vector< KFParticle > *vMotherPrim=0, std::vector< KFParticle > *vMotherSec=0, float *SecCuts=0, float massMotherPdg=0, float massMotherPdgSigma=0)
static void FindParticles(std::vector< CbmKFTrack > &vRTracks, std::vector< float > &ChiToPrimVtx, std::vector< L1FieldRegion > &vField, std::vector< KFParticle > &Particles, KFParticleSIMD &PrimVtx, const std::vector< int > &vTrackPDG, const float cuts[2][3]=DefaultCuts)
Find particles with 2-body decay channel from input tracks vRTracks with primary vertex PrimVtx:
static void Find2DaughterDecay(std::vector< CbmKFTrack > &vTracks, const std::vector< L1FieldRegion > &vField, std::vector< KFParticle > &Particles, const int DaughterNegPDG, const int DaughterPosPDG, const int MotherPDG, std::vector< short > &idNeg, std::vector< short > &idPos, KFParticleSIMD &PrimVtx, const float *cuts=0, bool isPrimary=0, std::vector< float > *vMotherTopoChi2Ndf=0, const float *secCuts=0, const float massMotherPDG=0, const float massMotherPDGSigma=0, std::vector< KFParticle > *vMotherPrim=0, std::vector< KFParticle > *vMotherSec=0)
static void FindHyperons(int PDG, KFParticleSIMD vDaughters[2], std::vector< int > &daughterIds, std::vector< KFParticle > &vLambdaSec, std::vector< KFParticle > &vHyperon, KFParticleSIMD &PrimVtx, const float *cuts=0, int startIndex=0)
static const float DefaultCuts[2][3]
static void FindDMesLambdac(std::vector< CbmKFTrack > &vTracks, const std::vector< L1FieldRegion > &vField, std::vector< KFParticle > &Particles, const int DaughterPDG[5], const int MotherPDG[8], std::vector< short > *idTrack[5], KFParticleSIMD &PrimVtx, const float cuts[8][8], std::vector< float > ChiToPrimVtx)
fvec GetCovariance(int i) const
fvec GetNDF() const
fvec GetZ() const
fvec GetChi2() const
void Construct(const KFParticleSIMD *vDaughters[], int nDaughters, const KFParticleSIMD *ProdVtx=0, Float_t Mass=-1, Bool_t IsConstrained=0, Bool_t isAtVtxGuess=0)
void Create(const fvec Param[], const fvec Cov[], Int_t Charge, fvec mass)
void SetProductionVertex(const KFParticleSIMD &Vtx)
const fvec & Y() const
const fvec & Z() const
fvec GetX() const
const fvec & X() const
void SetVtxGuess(fvec x, fvec y, fvec z)
void TransportToPoint(const fvec xyz[])
fvec * CovarianceMatrix()
void GetKFParticle(KFParticle &Part, int iPart=0)
fvec GetY() const
void SetField(const L1FieldRegion &field, bool isOneEntry=0, const int iVec=0)
Double_t GetY() const
Definition KFParticle.h:437
Double_t GetZ() const
Definition KFParticle.h:442
Double_t * CovarianceMatrix()
Definition KFParticle.h:847
void CleanDaughtersId()
Definition KFParticle.h:90
Double_t GetMass() const
Definition KFParticle.h:547
void AddDaughter(int id)
Definition KFParticle.h:92
void SetNDaughters(int n)
Definition KFParticle.h:91
Double_t GetX() const
Definition KFParticle.h:432
void SetOneEntry(const int i0, const L1FieldRegion &f1, const int i1)
Definition L1Field.h:193
RVec< PromoteType< T > > abs(const RVec< T > &v)
RVec< PromoteType< T > > sqrt(const RVec< T > &v)