32 #include <KFParticle.h>
33 #include <KFParticleDatabase.h>
49 : m_constrain_to_vertex(
true)
50 , m_constrain_int_mass(
false)
51 , m_use_fake_pv(
false)
56 std::vector<std::vector<KFParticle>>& selectedDaughters,
57 std::vector<std::vector<KFParticle>>& selectedIntermediates,
58 int& nPVs,
int& multiplicity)
61 KFParticle::SetField(-1.4e0);
63 std::vector<KFParticle> primaryVertices;
69 nPVs = primaryVertices.size();
70 multiplicity = daughterParticles.size();
72 std::vector<int> goodTrackIndex =
findAllGoodTracks(daughterParticles, primaryVertices);
75 buildBasicChain(selectedMother, selectedVertex, selectedDaughters, daughterParticles, goodTrackIndex, primaryVertices);
77 buildChain(selectedMother, selectedVertex, selectedDaughters, selectedIntermediates, daughterParticles, goodTrackIndex, primaryVertices);
84 std::vector<KFParticle>& selectedVertexBasic,
85 std::vector<std::vector<KFParticle>>& selectedDaughtersBasic,
86 const std::vector<KFParticle>& daughterParticlesBasic,
87 const std::vector<int>& goodTrackIndexBasic,
88 const std::vector<KFParticle>& primaryVerticesBasic)
90 std::vector<std::vector<int>> goodTracksThatMeet =
findTwoProngs(daughterParticlesBasic, goodTrackIndexBasic,
m_num_tracks);
91 for (
int p = 3;
p <
m_num_tracks + 1; ++
p) goodTracksThatMeet =
findNProngs(daughterParticlesBasic, goodTrackIndexBasic, goodTracksThatMeet, m_num_tracks,
p);
93 getCandidateDecay(selectedMotherBasic, selectedVertexBasic, selectedDaughtersBasic, daughterParticlesBasic,
94 goodTracksThatMeet, primaryVerticesBasic, 0, m_num_tracks,
false, 0,
true);
101 std::vector<KFParticle>& selectedVertexAdv,
102 std::vector<std::vector<KFParticle>>& selectedDaughtersAdv,
103 std::vector<std::vector<KFParticle>>& selectedIntermediatesAdv,
104 const std::vector<KFParticle>& daughterParticlesAdv,
105 const std::vector<int>& goodTrackIndexAdv,
106 const std::vector<KFParticle>& primaryVerticesAdv)
111 std::vector<KFParticle> goodCandidates;
112 std::vector<KFParticle> goodVertex;
120 std::vector<KFParticle> vertices;
128 getCandidateDecay(potentialIntermediates[i], vertices, potentialDaughters[i], daughterParticlesAdv,
129 goodTracksThatMeet, primaryVerticesAdv, track_start, track_stop,
true, i,
m_constrain_int_mass);
131 track_start += track_stop;
135 int num_tracks_used_by_intermediates = 0;
138 int num_remaining_tracks =
m_num_tracks - num_tracks_used_by_intermediates;
139 unsigned int num_pot_inter_a, num_pot_inter_b, num_pot_inter_c, num_pot_inter_d;
140 num_pot_inter_a = potentialIntermediates[0].size();
141 num_pot_inter_b = m_num_intermediate_states < 2 ? 1 : potentialIntermediates[1].size();
142 num_pot_inter_c = m_num_intermediate_states < 3 ? 1 : potentialIntermediates[2].size();
143 num_pot_inter_d = m_num_intermediate_states < 4 ? 1 : potentialIntermediates[3].size();
145 for (
unsigned int a = 0; a < num_pot_inter_a; ++a)
147 for (
unsigned int b = 0; b < num_pot_inter_b; ++b)
149 for (
unsigned int c = 0;
c < num_pot_inter_c; ++
c)
151 for (
unsigned int d = 0;
d < num_pot_inter_d; ++
d)
153 KFParticle candidate;
155 unsigned int matchIterators[4] = {a, b,
c,
d};
157 int num_mother_decay_products = m_num_intermediate_states + num_remaining_tracks;
158 assert(num_mother_decay_products > 0);
159 KFParticle motherDecayProducts[num_mother_decay_products];
160 std::vector<KFParticle> finalTracks = potentialDaughters[0][a];
162 for (
int i = 0; i <
m_num_intermediate_states; ++i) motherDecayProducts[i] = potentialIntermediates[i][matchIterators[i]];
165 finalTracks.insert(finalTracks.end(), potentialDaughters[j][matchIterators[j]].begin(), potentialDaughters[j][matchIterators[j]].end());
169 std::vector<int> goodTrackIndexAdv_withoutIntermediates = goodTrackIndexAdv;
170 for (
int m = 0;
m < num_tracks_used_by_intermediates; ++
m)
172 int trackID_to_remove = finalTracks[
m].Id();
173 int trackElement_to_remove = -1;
175 auto it = std::find_if(daughterParticlesAdv.begin(), daughterParticlesAdv.end(),
176 [&trackID_to_remove](
const KFParticle& obj)
177 {
return obj.Id() == trackID_to_remove;});
179 if (
it != daughterParticlesAdv.end())
181 trackElement_to_remove = std::distance(daughterParticlesAdv.begin(),
it);
184 goodTrackIndexAdv_withoutIntermediates.erase(
remove(goodTrackIndexAdv_withoutIntermediates.begin(),
185 goodTrackIndexAdv_withoutIntermediates.end(), trackElement_to_remove),
186 goodTrackIndexAdv_withoutIntermediates.end());
189 float required_unique_vertexID = 0;
193 std::vector<std::vector<std::string>> uniqueCombinations;
194 std::vector<std::vector<int>> listOfTracksToAppend;
196 if (num_remaining_tracks != 0)
198 for (
int i = num_tracks_used_by_intermediates; i <
m_num_tracks; ++i)
205 listOfTracksToAppend =
appendTracksToIntermediates(motherDecayProducts, daughterParticlesAdv, goodTrackIndexAdv_withoutIntermediates, num_remaining_tracks);
207 for (
unsigned int n_names = 0; n_names < uniqueCombinations.size(); ++n_names)
215 listOfTracksToAppend.push_back({0});
218 for (
unsigned int n_tracks = 0; n_tracks < listOfTracksToAppend.size(); ++n_tracks)
220 for (
int n_trackID = 0; n_trackID < num_remaining_tracks; ++n_trackID)
222 int mDP_trackElem = m_num_intermediate_states + n_trackID;
223 int dP_trackElem = listOfTracksToAppend[n_tracks][n_trackID];
224 motherDecayProducts[mDP_trackElem] = daughterParticlesAdv[dP_trackElem];
227 for (
unsigned int n_names = 0; n_names < uniqueCombinations.size(); ++n_names)
229 for (
unsigned int i_pv = 0; i_pv < primaryVerticesAdv.size(); ++i_pv)
231 std::tie(candidate, isGood) =
getCombination(motherDecayProducts, &uniqueCombinations[n_names][0], primaryVerticesAdv[i_pv],
235 goodCandidates.push_back(candidate);
238 for (
int k = 0; k < num_tracks_used_by_intermediates; ++
k) goodDaughters[k].push_back(finalTracks[k]);
239 for (
int k = 0; k < num_remaining_tracks; ++
k)
242 KFParticle slowTrack;
243 slowTrack.Create(motherDecayProducts[trackArrayID].
Parameters(),
244 motherDecayProducts[trackArrayID].CovarianceMatrix(),
245 (Int_t) motherDecayProducts[trackArrayID].GetQ(),
246 particleMasses_evtReco.find(uniqueCombinations[n_names][trackArrayID].c_str())->second.second);
247 slowTrack.NDF() = motherDecayProducts[trackArrayID].GetNDF();
248 slowTrack.Chi2() = motherDecayProducts[trackArrayID].GetChi2();
249 slowTrack.SetId(motherDecayProducts[trackArrayID].Id());
250 slowTrack.SetPDG(motherDecayProducts[trackArrayID].GetQ() * particleMasses_evtReco.find(uniqueCombinations[n_names][trackArrayID].c_str())->second.first);
251 goodDaughters[k + num_tracks_used_by_intermediates].push_back(slowTrack);
257 if (goodCandidates.size() != 0)
261 selectedMotherAdv.push_back(goodCandidates[bestCombinationIndex]);
263 std::vector<KFParticle> intermediates;
265 selectedIntermediatesAdv.push_back(intermediates);
266 std::vector<KFParticle> particles;
267 for (
int i = 0; i <
m_num_tracks; ++i) particles.push_back(goodDaughters[i][bestCombinationIndex]);
268 selectedDaughtersAdv.push_back(particles);
270 goodCandidates.clear();
273 for (
int j = 0; j <
m_num_tracks; ++j) goodDaughters[j].clear();
282 std::vector<KFParticle>& selectedVertexCand,
283 std::vector<std::vector<KFParticle>>& selectedDaughtersCand,
284 std::vector<KFParticle> daughterParticlesCand,
285 std::vector<std::vector<int>> goodTracksThatMeetCand,
286 std::vector<KFParticle> primaryVerticesCand,
287 int n_track_start,
int n_track_stop,
288 bool isIntermediate,
int intermediateNumber,
bool constrainMass)
290 int nTracks = n_track_stop - n_track_start;
292 std::vector<KFParticle> goodCandidates, goodVertex, goodDaughters[nTracks];
293 KFParticle candidate;
297 float required_unique_vertexID = 0;
298 for (
int i = n_track_start; i < n_track_stop; ++i) required_unique_vertexID +=
m_daughter_charge[i] * particleMasses_evtReco.find(
m_daughter_name[i].c_str())->second.second;
300 for (
unsigned int i_comb = 0; i_comb < goodTracksThatMeetCand.size(); ++i_comb)
302 KFParticle daughterTracks[nTracks];
304 for (
int i_track = 0; i_track < nTracks; ++i_track)
306 daughterTracks[i_track] = daughterParticlesCand[goodTracksThatMeetCand[i_comb][i_track]];
309 for (
unsigned int i_uc = 0; i_uc < uniqueCombinations.size(); ++i_uc)
311 for (
unsigned int i_pv = 0; i_pv < primaryVerticesCand.size(); ++i_pv)
313 std::string*
names = &uniqueCombinations[i_uc][0];
315 isIntermediate, intermediateNumber, nTracks, constrainMass, required_unique_vertexID);
318 float min_ipchi2 = 0;
319 if (isIntermediate && isGood)
321 calcMinIP(candidate, primaryVerticesCand, min_ip, min_ipchi2);
329 goodCandidates.push_back(candidate);
330 goodVertex.push_back(primaryVerticesCand[i_pv]);
331 for (
int i = 0; i < nTracks; ++i)
333 KFParticle intParticle;
334 intParticle.Create(daughterTracks[i].
Parameters(),
335 daughterTracks[i].CovarianceMatrix(),
336 (Int_t) daughterTracks[i].GetQ(),
337 particleMasses_evtReco.find(names[i].c_str())->second.second);
338 intParticle.NDF() = daughterTracks[i].GetNDF();
339 intParticle.Chi2() = daughterTracks[i].GetChi2();
340 intParticle.SetId(daughterTracks[i].Id());
341 intParticle.SetPDG(daughterTracks[i].GetQ() * particleMasses_evtReco.find(names[i].c_str())->second.first);
342 goodDaughters[i].push_back(intParticle);
348 if (goodCandidates.size() != 0)
350 int bestCombinationIndex =
selectBestCombination(fixToPV, isIntermediate, goodCandidates, goodVertex);
352 selectedMotherCand.push_back(goodCandidates[bestCombinationIndex]);
353 if (fixToPV) selectedVertexCand.push_back(goodVertex[bestCombinationIndex]);
354 std::vector<KFParticle> particles;
355 for (
int i = 0; i < nTracks; ++i) particles.push_back(goodDaughters[i][bestCombinationIndex]);
356 selectedDaughtersCand.push_back(particles);
358 goodCandidates.clear();
360 for (
int j = 0; j < nTracks; ++j) goodDaughters[j].clear();
366 std::vector<KFParticle> possibleCandidates,
367 std::vector<KFParticle> possibleVertex)
369 KFParticle smallestMassError = possibleCandidates[0];
370 int bestCombinationIndex = 0;
371 for (
unsigned int i = 1; i < possibleCandidates.size(); ++i)
373 if (PVconstraint && !isAnInterMother)
375 if (possibleCandidates[i].GetDeviationFromVertex(possibleVertex[i]) <
376 smallestMassError.GetDeviationFromVertex(possibleVertex[bestCombinationIndex]))
378 smallestMassError = possibleCandidates[i];
379 bestCombinationIndex = i;
384 if (possibleCandidates[i].GetErrMass() < smallestMassError.GetErrMass())
386 smallestMassError = possibleCandidates[i];
387 bestCombinationIndex = i;
392 return bestCombinationIndex;
397 float f_vertexParameters[6] = {0};
399 float f_vertexCovariance[21] = {0};
401 KFParticle kfp_vertex;
402 kfp_vertex.Create(f_vertexParameters, f_vertexCovariance, 0, -1);
403 kfp_vertex.NDF() = 0;
404 kfp_vertex.Chi2() = 0;