79 std::vector<const xAOD::TruthParticle*>& fat_inparts,
80 std::vector<const xAOD::TruthParticle*>& fat_internal,
81 std::vector<const xAOD::TruthParticle*>& fat_outparts,
83 const float truthVertexMergeDistance,
84 const std::vector<const xAOD::TruthParticle*>& additional_in_parts
86 if ( !vertex )
return;
87 std::vector<const xAOD::TruthParticle*> out_particles = vertex->particles_out();
88 std::vector<const xAOD::TruthParticle*> in_particles = vertex->particles_in();
90 for(
auto part : additional_in_parts){
92 if (std::find(in_particles.begin(), in_particles.end(), part) == in_particles.end()){
93 in_particles.push_back(part);
96 if(part->hasDecayVtx() && part->decayVtx()){
97 for(
auto child : part->decayVtx()->particles_out()){
98 if(child && std::find(out_particles.begin(), out_particles.end(), child) == out_particles.end()){
99 out_particles.push_back(child);
105 for (
auto part : in_particles ) {
106 if ( !part )
continue;
108 if ( std::find(fat_inparts.begin(), fat_inparts.end(), part) == fat_inparts.end()
109 && std::find(fat_internal.begin(), fat_internal.end(), part) == fat_internal.end()
110 && std::find(fat_outparts.begin(), fat_outparts.end(), part) == fat_outparts.end() ) {
112 if ( internal ) fat_internal.push_back(part);
113 else fat_inparts.push_back(part);
116 for (
auto part : out_particles ) {
117 if ( !part )
continue;
119 std::find(fat_inparts.begin(), fat_inparts.end(), part) != fat_inparts.end() ||
120 std::find(fat_internal.begin(), fat_internal.end(), part) != fat_internal.end() ||
121 std::find(fat_outparts.begin(), fat_outparts.end(), part) != fat_outparts.end()
127 if (!(part->status() == 1 || part->status() == 2)){
128 if (!part->hasDecayVtx() || !part->decayVtx() || !
has_valid_child(part)) {
129 fat_outparts.push_back(part);
136 if ( !
has_valid_child(part) || !(part->hasDecayVtx() && part->decayVtx()) ) {
137 fat_outparts.push_back(part);
142 !fat_inparts.empty() &&
143 part->hasDecayVtx() && part->decayVtx() &&
144 fat_inparts[0]->hasDecayVtx() && fat_inparts[0]->decayVtx() &&
145 vertex_distance(part->decayVtx(), fat_inparts[0]->decayVtx()) < truthVertexMergeDistance
148 part->decayVtx(), fat_inparts, fat_internal, fat_outparts,
true, truthVertexMergeDistance
158 if ( valid_children.size() == 1 &&
159 valid_children[0]->pdgId() == part->pdgId() ) {
161 part->decayVtx(), fat_inparts, fat_internal, fat_outparts,
true,
162 truthVertexMergeDistance
170 if ( valid_children.size() >= 2 &&
171 valid_children[0]->pdgId() == part->pdgId() ) {
173 part->decayVtx(), fat_inparts, fat_internal, fat_outparts,
true,
174 truthVertexMergeDistance
180 if ( valid_children.size() == 1 &&
181 part->isStrangeHadron() && valid_children[0]->isStrangeHadron() ) {
183 part->decayVtx(), fat_inparts, fat_internal, fat_outparts,
true,
184 truthVertexMergeDistance
188 fat_outparts.push_back(part);
194 const float truthVertexMergeDistance,
195 const std::vector<const xAOD::TruthParticle*>& truth_particles
197 std::vector<FatVertex> fat_vertices;
198 std::vector<const xAOD::TruthParticle*> searched;
199 std::vector<const xAOD::TruthParticle*> to_search;
201 to_search.push_back(pv->incomingParticle(0));
204 while ( !to_search.empty() ) {
207 to_search.pop_back();
208 searched.push_back(part);
209 if (!part || !part->hasDecayVtx() )
continue;
214 std::vector<const xAOD::TruthParticle*> inparts, internal, outparts;
216 part->decayVtx(), inparts, internal, outparts,
217 false, truthVertexMergeDistance,
218 is_pv ? truth_particles : std::vector<const xAOD::TruthParticle*>(0,
nullptr)
224 bool is_real_vertex = outparts.size() > 1;
225 if (!is_real_vertex && !inparts.empty() && inparts[0] && inparts[0]->nChildren() >= 2) {
226 is_real_vertex =
true;
228 if ( is_real_vertex ){
229 fat_vertices.push_back(
FatVertex(inparts, internal, outparts, is_pv));
235 for (
auto inp : inparts ) {
236 if ( std::find(searched.begin(), searched.end(), inp) == searched.end() ) {
237 searched.push_back(inp);
239 if(std::find(to_search.begin(), to_search.end(), inp) != to_search.end()){
241 std::remove(to_search.begin(), to_search.end(), inp),
245 for (
auto intern : internal ) {
246 if ( std::find(searched.begin(), searched.end(), intern) == searched.end() ) {
247 searched.push_back(intern);
249 if(std::find(to_search.begin(), to_search.end(), intern) != to_search.end()){
251 std::remove(to_search.begin(), to_search.end(), intern),
255 for (
auto outp : outparts ) {
256 if ( std::find(searched.begin(), searched.end(),
outp) == searched.end()
257 && std::find(to_search.begin(), to_search.end(),
outp) == to_search.end() ) {
258 to_search.push_back(
outp);
267 fat_vertices.begin(),
270 return fv.outparts.empty();
311 for (
auto child :
inparts[0]->decayVtx()->particles_out()) {
312 if (child) { input_child = child;
break; }
316 bool has_parent =
parent !=
nullptr;
318 ?
parent->getType(uid_accessor).detailedType
335 size_t truth_out_parts =
inparts[0]->nChildren();
337 std::vector<const xAOD::TruthParticle*> truth_children;
338 for (
auto child :
inparts[0]->decayVtx()->particles_out() ) {
339 if ( child ) truth_children.push_back(child);
341 TLorentzVector in4 =
inparts[0]->p4();
342 TLorentzVector out4 =
sum_4vec(
inparts[0]->decayVtx()->particles_out());
343 float deltaE = std::abs(in4.E() - out4.E());
346 if ( truth_out_parts == truth_valid_out_parts && truth_valid_out_parts > 1 ) {
354 if ( truth_valid_out_parts > 1 ) {
355 double children_mass_sum = 0.0;
356 for (
const auto& child : truth_children) {
357 children_mass_sum += child->p4().M();
359 if ( children_mass_sum > in4.M() + 1.0 ) {
371 if (
auto t =
classifyPhotonVertex(truth_out_parts, truth_valid_out_parts, truth_children))
return *t;
376 if (
auto t =
classifyLeptonVertex(uid_accessor, truth_out_parts, truth_valid_out_parts, truth_children))
return *t;
383 if ( std::abs(
inparts[0]->pdgId()) == 111 ) {
386 if ( std::abs(
inparts[0]->pdgId()) == 211 ) {
387 bool has_muon =
false, has_neutrino =
false;
388 for (
auto c : truth_children) {
389 if (std::abs(c->pdgId()) == 13) has_muon =
true;
390 if (std::abs(c->pdgId()) == 14) has_neutrino =
true;
397 if ( truth_out_parts > truth_valid_out_parts && truth_out_parts > 1 &&
403 if ( truth_out_parts == 1 && truth_valid_out_parts == 1 ) {
void generateFatVertex(const xAOD::TruthVertex *vertex, std::vector< const xAOD::TruthParticle * > &fat_inparts, std::vector< const xAOD::TruthParticle * > &fat_internal, std::vector< const xAOD::TruthParticle * > &fat_outparts, bool internal, const float truthVertexMergeDistance, const std::vector< const xAOD::TruthParticle * > &additional_in_parts=std::vector< const xAOD::TruthParticle * >())
Generates a fat vertex by recursively searching children of the provided truth vertex and adding them...