116 const bool doDebug =
false;
117 const bool doExtra =
false;
125 return StatusCode::FAILURE;
128 if (mcEvts->
empty()) {
130 return StatusCode::SUCCESS;
137 delete thinnedMcEvts;
138 thinnedMcEvts =
nullptr;
139 return StatusCode::FAILURE;
145 const auto &wtCont = mcEvt->weights();
146 if (!wtCont.empty()) {
150 int inEvent = mcEvt->event_number();
158 int nEvent = thinEvt->event_number();
162 std::cout <<
"========== BEGIN EVENT BEFORE THINNING ==========" << std::endl;
163 HepMC::Print::line(std::cout, *thinEvt);
164 std::cout <<
"========== END EVENT BEFORE THINNING ==========" << std::endl;
184 typedef std::pair<HepMC::GenVertexPtr, HepMC::GenParticlePtr> vpPair;
185 std::vector<vpPair> removePV;
186 std::vector<vpPair> addinPV;
187 std::vector<vpPair> addoutPV;
188 std::vector<HepMC::GenVertexPtr> removeV;
191 std::list<HepMC::GenParticlePtr> deleteP;
192 std::list<HepMC::GenVertexPtr> deleteV;
193 std::list<HepMC::GenParticlePtr>::iterator dpItr;
194 std::list<HepMC::GenParticlePtr>::iterator dpItrE;
195 std::list<HepMC::GenVertexPtr>::iterator dvItr;
196 std::list<HepMC::GenVertexPtr>::iterator dvItrE;
204 std::vector<HepMC::GenVertexPtr> hadVertices;
206 for (
auto& hadv: thinEvt->vertices()) {
208 if (hadv->particles_in().size() < 2)
continue;
209 if (hadv->particles_out().size() < 1)
continue;
213 bool isHadVtx =
true;
214 bool isHadOut =
false;
215 for (
const auto& inp: hadv->particles_in() ) {
218 for (
const auto& vp: hadv->particles_out()) {
222 isHadVtx = isHadVtx && isHadOut;
223 if (isHadVtx) hadVertices.push_back(hadv);
224 if (doDebug && isHadVtx)
ATH_MSG_VERBOSE(
"Hadronization vertex " << hadv);
227 if (hadVertices.empty()) {
231 return StatusCode::SUCCESS;
239 for (
unsigned int iv = 0; iv < hadVertices.size(); ++iv) {
241 if (doDebug)
ATH_MSG_DEBUG(
"Removing partons from hadVertex " << ivtx);
242 for (
auto pin: ivtx->particles_in()) {
243 removePV.push_back(vpPair(ivtx, pin));
248 for (
unsigned int iv = 0; iv < hadVertices.size(); ++iv) {
250 auto descendants = HepMC::descendant_particles(ivtx);
251 for (
auto pout: descendants) {
253 if (vpar) removePV.push_back(vpPair(vpar, pout));
255 if (vend) removePV.push_back(vpPair(vend, pout));
256 deleteP.push_back(std::move(pout));
265 for (
auto hadv:thinEvt->vertices()) {
267 if (hadv->particles_in().size() == 0 && hadv->particles_out().size() == 0) {
268 removeV.push_back(hadv);
269 deleteV.push_back(hadv);
273 for (
auto pin: hadv->particles_in()) {
274 removePV.push_back(vpPair(hadv, pin));
277 for (
auto pout: hadv->particles_out()) {
278 removePV.push_back(vpPair(hadv, pout));
281 removeV.push_back(hadv);
282 deleteV.push_back(std::move(hadv));
287 for (
unsigned int i = 0; i < removePV.size(); ++i) {
290 v->remove_particle_in(p);
291 v->remove_particle_out(std::move(p));
294 for (
unsigned int i = 0; i < addoutPV.size(); ++i) {
297 v->add_particle_out(std::move(p));
299 for (
unsigned int iv = 1; iv < hadVertices.size(); ++iv) {
301 if (v->particles_in().size() != 0 || v->particles_out().size() != 0) {
303 <<
" with in/out particles " << v->particles_in().size() <<
" " << v->particles_out().size());
305 thinEvt->remove_vertex(hadVertices[iv]);
312 if (doDebug && doExtra) {
313 std::cout <<
"========== BEGIN EVENT BEFORE CLUSTER ==========" << std::endl;
314 HepMC::Print::line(std::cout, *thinEvt);
315 std::cout <<
"========== END EVENT BEFORE CLUSTER ==========" << std::endl;
330 using vpPair = std::pair<HepMC::GenVertexPtr, HepMC::GenParticlePtr>;
338 using pkPair = std::pair<HepMC::GenParticlePtr, HepMC::FourVector>;
339 std::vector<pkPair> changePK;
343 if (doDebug)
ATH_MSG_DEBUG(
"New parton pass " << inEvent <<
" " << thinEvt->particles_size() <<
" " << thinEvt->vertices_size());
352 for (
auto fp: thinEvt->particles() ) {
362 if (doDebug)
ATH_MSG_DEBUG(
"Final parton " << pvtx <<
" " << fp);
368 if (pvtx->particles_in().size() == 1 && pvtx->particles_out().size() == 1) {
371 if (!pp || pp->parent_event() ==
nullptr) {
378 if (!ppvtx || ppvtx->parent_event() ==
nullptr) {
385 removePV.push_back(vpPair(ppvtx, pp));
386 removePV.push_back(vpPair(pvtx, pp));
387 deleteP.push_back(pp);
388 removeV.push_back(pvtx);
389 deleteV.push_back(pvtx);
390 addoutPV.push_back(vpPair(ppvtx, fp));
391 if (doDebug) {
ATH_MSG_DEBUG(
"1->1: ppvtx,pp,pvtx,fp,evtx " << ppvtx <<
" " << pp <<
" " << pvtx <<
" " << fp); }
400 if (pvtx->particles_in().size() == 2 && pvtx->particles_out().size() == 1) {
406 if (std::abs(pp1->momentum().perp()) < 1.e-3)
continue;
407 if (std::abs(pp2->momentum().perp()) < 1.e-3)
continue;
411 if (!ppvtx1 || ppvtx1->parent_event() ==
nullptr) {
416 if (!ppvtx2 || ppvtx2->parent_event() ==
nullptr) {
423 removePV.push_back(vpPair(pvtx, fp));
424 removePV.push_back(vpPair(pvtx, pp1));
425 removePV.push_back(vpPair(pvtx, pp2));
426 deleteP.push_back(fp);
427 removeV.push_back(pvtx);
428 deleteV.push_back(pvtx);
430 ATH_MSG_DEBUG(
"2->1: ppvtx1,pp1,ppvtx2,pp2,pvtx,fp " << ppvtx1 <<
" " << pp1
431 <<
" " << ppvtx2 <<
" " << pp2 <<
" " << pvtx <<
" "<< fp);
440 if (pvtx->particles_in().size() == 1 && pvtx->particles_out().size() == 2) {
449 }
else if (fp == pout2) {
455 ATH_MSG_WARNING(
"1->2: No match found for branching " << fp <<
" " << pvtx <<
" " << pout1 <<
" " << pout2);
458 if (fp != pout1)
continue;
462 if (pout1->momentum().m() < -1.0 || pout1->momentum().perp() < 1.0)
continue;
463 if (pout2->momentum().m() < -1.0 || pout2->momentum().perp() < 1.0)
continue;
466 double m12 = p12.m();
468 if (std::abs(m12) > 10. + 1.0e-5 * p12.e()) {
469 ATH_MSG_WARNING(
"Spacelike mass^2 for parton sum " << m12 <<
" " << pp <<
" " << pvtx <<
" " << pout1 <<
" " << pout2);
473 if (doDebug)
ATH_MSG_DEBUG(
"1->2: parton pair mass " << m12);
476 if (doDebug)
ATH_MSG_DEBUG(
"Keeping 1->2: parton mass " << m12);
481 if (!ppvtx || ppvtx->parent_event() ==
nullptr) {
489 if (doDebug)
ATH_MSG_DEBUG(
"Merging 1->2: mass " << p12.m());
490 changePK.push_back(pkPair(pp, p12));
491 removePV.push_back(vpPair(pvtx, pp));
492 removePV.push_back(vpPair(pvtx, pout1));
493 removePV.push_back(vpPair(pvtx, pout2));
494 deleteP.push_back(pout1);
495 deleteP.push_back(pout2);
496 removeV.push_back(pvtx);
497 deleteV.push_back(pvtx);
499 ATH_MSG_DEBUG(
"Merge 1->2: ppvtx,pp,pvtx,pout1,pout2,evtx " << ppvtx <<
" " << pp <<
" " << pvtx <<
" " << pout1 <<
" "
501 ATH_MSG_DEBUG(
"Merge 1->2: id " << pp->pdg_id() <<
" " << pout1->pdg_id() <<
" " << pout2->pdg_id());
508 if (pvtx->particles_in().size() == 1) {
511 if (std::abs(pp->pdg_id()) ==
MC::PROTON) iCase = -1;
516 if (doDebug)
ATH_MSG_DEBUG(
"Case not found " << pvtx <<
" " << fp <<
" " << pvtx->particles_in().size() <<
" " << pvtx->particles_out().size());
522 if (doDebug)
ATH_MSG_DEBUG(
"Actually removing particles " << removePV.size());
524 for (
unsigned int i = 0; i < removePV.size(); ++i) {
528 v->remove_particle_in(p);
529 v->remove_particle_out(std::move(p));
533 if (doDebug)
ATH_MSG_DEBUG(
"Actually add particles in/out " << addinPV.size() <<
" " << addoutPV.size());
534 for (
unsigned int i = 0; i < addoutPV.size(); ++i) {
538 v->add_particle_out(std::move(p));
542 for (
unsigned int i = 0; i < changePK.size(); ++i) {
545 pp->set_momentum(changePK[i].second);
549 if (doDebug)
ATH_MSG_DEBUG(
"Actually remove vertices " << removeV.size());
550 for (
unsigned int i = 0; i < removeV.size(); ++i) {
551 int nv = thinEvt->vertices().size();
552 if (doDebug) {
ATH_MSG_VERBOSE(
"Removing vertex " << removeV[i] <<
" " << nv <<
" " << thinEvt->vertices().size()); }
553 thinEvt->remove_vertex(removeV[i]);
555 if (doDebug)
ATH_MSG_DEBUG(
"End while(moreP) pass " << moreP);
563 if (doDebug && doExtra) {
564 std::cout <<
"========== BEGIN EVENT BEFORE SOFT ==========" << std::endl;
565 HepMC::Print::line(std::cout, *thinEvt);
566 std::cout <<
"========== END EVENT BEFORE SOFT ==========" << std::endl;
571 std::list<HepMC::GenParticlePtr> pNotHad;
572 std::list<HepMC::GenParticlePtr> pHard;
573 std::vector<HepMC::GenParticlePtr> beams=thinEvt->beams();
574 for (
auto fp: thinEvt->particles()) {
578 double ep = fp->momentum().e();
579 double pzp = fp->momentum().pz();
580 double mtmax = (ep + pzp) * (ep - pzp);
581 auto ancestors = HepMC::ancestor_particles(fp);
583 for (
auto gpar: ancestors) {
584 double e = gpar->momentum().e();
585 double pz = gpar->momentum().pz();
586 mtmax = std::max((e+pz)*(e-pz), mtmax);
590 pNotHad.push_back(fp);
591 int ida = std::abs(fp->pdg_id());
592 bool keepid = (ida > 10 && ida < 20) || (ida > 1000000 && ida < 9000000);
595 pHard.insert(pHard.end(),ancestors.begin(),ancestors.end());
602 bool keepid2 = ( ida == 6) || (ida >= 11 && ida <= 16) || (ida >= 23 && ida <= 37) || (ida > 1000000 && ida < 9000000);
603 if (keepid2 && fp->end_vertex()) {
604 auto descendants = HepMC::descendant_particles(fp);
605 pHard.insert(pHard.end(),descendants.begin(),descendants.end());
618 for (
auto ph: pHard) {
622 if (doDebug)
ATH_MSG_DEBUG(
"Hard GenParticles total " << nhard);
628 for (
auto p: pNotHad) {
631 for (
auto h: pHard) {
637 if (doDebug)
ATH_MSG_DEBUG(
"Particle bc/isHard " << p <<
" " << isHard);
638 if (isHard)
continue;
640 if (pvtx) pvtx->remove_particle_out(p);
642 if (evtx) evtx->remove_particle_in(std::move(p));
652 for (
auto vtx: thinEvt->vertices()) {
653 if (vtx->particles_in().size() != 0)
continue;
654 if (vtx->particles_out().size() != 0)
continue;
655 removeV.push_back(vtx);
656 deleteV.push_back(std::move(vtx));
658 if (doDebug)
ATH_MSG_DEBUG(
"Removing/deleting 0-particle vertices " << removeV.size() <<
" " << deleteV.size());
659 for (
unsigned int i = 0; i < removeV.size(); ++i) {
661 thinEvt->remove_vertex(removeV[i]);
668 if (doDebug && doExtra) {
669 std::cout <<
"========== BEGIN EVENT BEFORE 1-BODY ==========" << std::endl;
670 HepMC::Print::line(std::cout, *thinEvt);
671 std::cout <<
"========== END EVENT BEFORE 1-BODY ==========" << std::endl;
686 for (
auto v: thinEvt->vertices()) {
687 if (v->particles_in().size() != 1)
continue;
688 if (v->particles_out().size() != 1)
continue;
689 pin = *(v->particles_in().begin());
690 pout = *(v->particles_out().begin());
691 if (pin->pdg_id() != pout->pdg_id())
continue;
693 if (pin == beams[0] || pin == beams[1])
continue;
695 if (!pvtx || pvtx->parent_event() ==
nullptr) {
701 vtx11 = std::move(v);
702 if (doDebug)
ATH_MSG_DEBUG(
"One-body " << pin <<
" " << vtx11 <<
" " << pout);
707 pvtx->remove_particle_in(pin);
708 pvtx->remove_particle_out(pin);
709 pvtx->add_particle_out(pout);
710 vtx11->remove_particle_in(pin);
711 vtx11->remove_particle_out(pin);
712 vtx11->remove_particle_in(pout);
713 vtx11->remove_particle_out(pout);
714 thinEvt->remove_vertex(vtx11);
715 if (doDebug)
ATH_MSG_DEBUG(
"One-body new pvtx " << pvtx <<
" " << pvtx->particles_in().size() <<
" " << pvtx->particles_out().size());
733 for (
auto badv: thinEvt->vertices()) {
735 if (badv->particles_in().size() != 1 || badv->particles_out().size() != 0)
continue;
736 auto pitr = badv->particles_in().begin();
738 if (pp->production_vertex())
continue;
739 double pt = pp->momentum().perp();
743 if (doDebug)
ATH_MSG_DEBUG(
"1->0: removing pp,badv,pt " << pp <<
" " << badv <<
" " << pt);
744 removePV.push_back(vpPair(badv, pp));
745 deleteP.push_back(std::move(pp));
746 removeV.push_back(badv);
747 deleteV.push_back(std::move(badv));
751 for (
unsigned int i = 0; i < removePV.size(); ++i) {
754 v->remove_particle_in(p);
755 v->remove_particle_out(std::move(p));
758 for (
unsigned int i = 0; i < removeV.size(); ++i) {
759 thinEvt->remove_vertex(removeV[i]);
768 std::cout <<
"========== BEGIN EVENT AFTER THINNING ==========" << std::endl;
769 HepMC::Print::line(std::cout, *thinEvt);
770 std::cout <<
"========== END EVENT AFTER THINNING ==========" << std::endl;
781 return StatusCode::SUCCESS;