48 : m_constrain_to_vertex(
true)
49 , m_constrain_int_mass(
false)
50 , m_use_fake_pv(
false)
55 std::vector<std::vector<KFParticle>>& selectedDaughters,
56 std::vector<std::vector<KFParticle>>& selectedIntermediates,
59 std::vector<KFParticle> primaryVertices;
71 nPVs = primaryVertices.size();
72 multiplicity = daughterParticles.size();
74 std::vector<int> goodTrackIndex =
findAllGoodTracks(daughterParticles, primaryVertices);
78 buildBasicChain(selectedMother, selectedVertex, selectedDaughters, daughterParticles, goodTrackIndex, primaryVertices);
82 buildChain(selectedMother, selectedVertex, selectedDaughters, selectedIntermediates, daughterParticles, goodTrackIndex, primaryVertices);
90 std::vector<KFParticle>& selectedVertexBasic,
91 std::vector<std::vector<KFParticle>>& selectedDaughtersBasic,
92 const std::vector<KFParticle>& daughterParticlesBasic,
93 const std::vector<int>& goodTrackIndexBasic,
94 const std::vector<KFParticle>& primaryVerticesBasic)
96 std::vector<std::vector<int>> goodTracksThatMeet =
findTwoProngs(daughterParticlesBasic, goodTrackIndexBasic,
m_num_tracks);
99 goodTracksThatMeet =
findNProngs(daughterParticlesBasic, goodTrackIndexBasic, goodTracksThatMeet, m_num_tracks,
p);
102 getCandidateDecay(selectedMotherBasic, selectedVertexBasic, selectedDaughtersBasic, daughterParticlesBasic,
103 goodTracksThatMeet, primaryVerticesBasic, 0, m_num_tracks,
false, 0,
true);
110 std::vector<KFParticle>& selectedVertexAdv,
111 std::vector<std::vector<KFParticle>>& selectedDaughtersAdv,
112 std::vector<std::vector<KFParticle>>& selectedIntermediatesAdv,
113 const std::vector<KFParticle>& daughterParticlesAdv,
114 const std::vector<int>& goodTrackIndexAdv,
115 const std::vector<KFParticle>& primaryVerticesAdv)
120 std::vector<KFParticle> goodCandidates;
121 std::vector<KFParticle> goodVertex;
134 goodTracksThatMeet =
findNProngs(daughterParticlesAdv,
140 getCandidateDecay(potentialIntermediates[i], vertices, potentialDaughters[i], daughterParticlesAdv,
141 goodTracksThatMeet, primaryVerticesAdv, track_start, track_stop,
true, i,
m_constrain_int_mass);
143 track_start += track_stop;
147 int num_tracks_used_by_intermediates = 0;
153 int num_remaining_tracks =
m_num_tracks - num_tracks_used_by_intermediates;
154 unsigned int num_pot_inter_a, num_pot_inter_b, num_pot_inter_c, num_pot_inter_d;
155 num_pot_inter_a = potentialIntermediates[0].size();
156 num_pot_inter_b = m_num_intermediate_states < 2 ? 1 : potentialIntermediates[1].size();
157 num_pot_inter_c = m_num_intermediate_states < 3 ? 1 : potentialIntermediates[2].size();
158 num_pot_inter_d = m_num_intermediate_states < 4 ? 1 : potentialIntermediates[3].size();
160 for (
unsigned int a = 0;
a < num_pot_inter_a; ++
a)
162 for (
unsigned int b = 0;
b < num_pot_inter_b; ++
b)
164 for (
unsigned int c = 0;
c < num_pot_inter_c; ++
c)
166 for (
unsigned int d = 0; d < num_pot_inter_d; ++d)
170 const unsigned int matchIterators[4] = {
a,
b,
c, d};
172 int num_mother_decay_products = m_num_intermediate_states + num_remaining_tracks;
173 assert(num_mother_decay_products > 0);
174 KFParticle motherDecayProducts[num_mother_decay_products];
175 std::vector<KFParticle> finalTracks = potentialDaughters[0][
a];
179 motherDecayProducts[
i] = potentialIntermediates[
i][matchIterators[
i]];
183 finalTracks.insert(finalTracks.end(), potentialDaughters[
j][matchIterators[
j]].begin(), potentialDaughters[
j][matchIterators[
j]].end());
187 std::vector<int> goodTrackIndexAdv_withoutIntermediates = goodTrackIndexAdv;
188 for (
int m = 0;
m < num_tracks_used_by_intermediates; ++
m)
190 int trackID_to_remove = finalTracks[
m].Id();
191 int trackElement_to_remove = -1;
193 auto it = std::find_if(daughterParticlesAdv.begin(), daughterParticlesAdv.end(),
195 {
return obj.Id() == trackID_to_remove; });
197 if (
it != daughterParticlesAdv.end())
199 trackElement_to_remove =
std::distance(daughterParticlesAdv.begin(),
it);
202 goodTrackIndexAdv_withoutIntermediates.erase(
remove(goodTrackIndexAdv_withoutIntermediates.begin(),
203 goodTrackIndexAdv_withoutIntermediates.end(), trackElement_to_remove),
204 goodTrackIndexAdv_withoutIntermediates.end());
207 float required_unique_vertexID = 0;
213 std::vector<std::vector<std::string>> uniqueCombinations;
214 std::vector<std::vector<int>> listOfTracksToAppend;
216 if (num_remaining_tracks != 0)
225 listOfTracksToAppend =
appendTracksToIntermediates(motherDecayProducts, daughterParticlesAdv, goodTrackIndexAdv_withoutIntermediates, num_remaining_tracks);
227 for (
auto& uniqueCombination : uniqueCombinations)
235 listOfTracksToAppend.push_back({0});
238 for (
auto& n_tracks : listOfTracksToAppend)
240 for (
int n_trackID = 0; n_trackID < num_remaining_tracks; ++n_trackID)
242 int mDP_trackElem = m_num_intermediate_states + n_trackID;
243 int dP_trackElem = n_tracks[n_trackID];
244 motherDecayProducts[mDP_trackElem] = daughterParticlesAdv[dP_trackElem];
247 for (
auto& uniqueCombination : uniqueCombinations)
249 for (
const auto& i_pv : primaryVerticesAdv)
251 std::tie(candidate, isGood) =
getCombination(motherDecayProducts, &uniqueCombination[0], i_pv,
255 goodCandidates.push_back(candidate);
258 goodVertex.push_back(i_pv);
262 goodIntermediates[
k].push_back(motherDecayProducts[
k]);
264 for (
int k = 0;
k < num_tracks_used_by_intermediates; ++
k)
266 goodDaughters[
k].push_back(finalTracks[
k]);
268 for (
int k = 0;
k < num_remaining_tracks; ++
k)
272 slowTrack.
Create(motherDecayProducts[trackArrayID].Parameters(),
273 motherDecayProducts[trackArrayID].CovarianceMatrix(),
274 (Int_t) motherDecayProducts[trackArrayID].
GetQ(),
275 kfp_Tools_evtReco.
getParticleMass(uniqueCombination[trackArrayID].c_str()));
276 slowTrack.
NDF() = motherDecayProducts[trackArrayID].
GetNDF();
277 slowTrack.
Chi2() = motherDecayProducts[trackArrayID].
GetChi2();
278 slowTrack.
SetId(motherDecayProducts[trackArrayID].
Id());
279 slowTrack.
SetPDG(motherDecayProducts[trackArrayID].
GetQ() * kfp_Tools_evtReco.
getParticleID(uniqueCombination[trackArrayID].c_str()));
280 goodDaughters[
k + num_tracks_used_by_intermediates].push_back(slowTrack);
286 if (goodCandidates.size() != 0)
290 selectedMotherAdv.push_back(goodCandidates[bestCombinationIndex]);
293 selectedVertexAdv.push_back(goodVertex[bestCombinationIndex]);
295 std::vector<KFParticle> intermediates;
296 intermediates.reserve(m_num_intermediate_states);
299 intermediates.push_back(goodIntermediates[
i][bestCombinationIndex]);
301 selectedIntermediatesAdv.push_back(intermediates);
306 particles.push_back(goodDaughters[
i][bestCombinationIndex]);
308 selectedDaughtersAdv.push_back(particles);
310 goodCandidates.clear();
314 goodIntermediates[
j].clear();
318 goodDaughters[
j].clear();
328 std::vector<KFParticle>& selectedVertexCand,
329 std::vector<std::vector<KFParticle>>& selectedDaughtersCand,
330 std::vector<KFParticle> daughterParticlesCand,
331 std::vector<std::vector<int>> goodTracksThatMeetCand,
332 std::vector<KFParticle> primaryVerticesCand,
333 int n_track_start,
int n_track_stop,
334 bool isIntermediate,
int intermediateNumber,
bool constrainMass)
336 int nTracks = n_track_stop - n_track_start;
338 std::vector<KFParticle> goodCandidates, goodVertex, goodDaughters[nTracks];
343 float required_unique_vertexID = 0;
344 for (
int i = n_track_start;
i < n_track_stop; ++
i)
349 for (
auto& i_comb : goodTracksThatMeetCand)
353 for (
int i_track = 0; i_track < nTracks; ++i_track)
355 daughterTracks[i_track] = daughterParticlesCand[i_comb[i_track]];
358 for (
auto& uniqueCombination : uniqueCombinations)
360 for (
unsigned int i_pv = 0; i_pv < primaryVerticesCand.size(); ++i_pv)
364 isIntermediate, intermediateNumber, nTracks, constrainMass, required_unique_vertexID);
366 if (isIntermediate && isGood)
369 float min_ipchi2 = 0;
370 calcMinIP(candidate, primaryVerticesCand, min_ip, min_ipchi2);
379 goodCandidates.push_back(candidate);
380 goodVertex.push_back(primaryVerticesCand[i_pv]);
381 for (
int i = 0;
i < nTracks; ++
i)
384 intParticle.
Create(daughterTracks[
i].Parameters(),
385 daughterTracks[
i].CovarianceMatrix(),
386 (Int_t) daughterTracks[
i].
GetQ(),
388 intParticle.
NDF() = daughterTracks[
i].
GetNDF();
390 intParticle.
SetId(daughterTracks[i].
Id());
392 goodDaughters[
i].push_back(intParticle);
398 if (goodCandidates.size() != 0)
400 int bestCombinationIndex =
selectBestCombination(fixToPV, isIntermediate, goodCandidates, goodVertex);
402 selectedMotherCand.push_back(goodCandidates[bestCombinationIndex]);
405 selectedVertexCand.push_back(goodVertex[bestCombinationIndex]);
408 particles.reserve(nTracks);
409 for (
int i = 0;
i < nTracks; ++
i)
411 particles.push_back(goodDaughters[
i][bestCombinationIndex]);
413 selectedDaughtersCand.push_back(particles);
415 goodCandidates.clear();
417 for (
int j = 0;
j < nTracks; ++
j)
419 goodDaughters[
j].clear();
426 std::vector<KFParticle> possibleCandidates,
427 std::vector<KFParticle> possibleVertex)
429 KFParticle smallestMassError = possibleCandidates[0];
430 int bestCombinationIndex = 0;
431 for (
unsigned int i = 1;
i < possibleCandidates.size(); ++
i)
433 if (PVconstraint && !isAnInterMother)
438 smallestMassError = possibleCandidates[
i];
439 bestCombinationIndex =
i;
444 if (possibleCandidates[
i].GetErrMass() < smallestMassError.
GetErrMass())
446 smallestMassError = possibleCandidates[
i];
447 bestCombinationIndex =
i;
452 return bestCombinationIndex;
457 float f_vertexParameters[6] = {0};
459 float f_vertexCovariance[21] = {0};
462 kfp_vertex.
Create(f_vertexParameters, f_vertexCovariance, 0, -1);
463 kfp_vertex.
NDF() = 0;
464 kfp_vertex.
Chi2() = 0;