Execute method.
104 {
105
107
109
110
111
112
113
114
116 const bool doDebug = false;
117 const bool doExtra = false;
118
119
120
121
125 return StatusCode::FAILURE;
126 }
127
128 if (mcEvts->
empty()) {
130 return StatusCode::SUCCESS;
131 }
132
133
137 delete thinnedMcEvts;
138 thinnedMcEvts = nullptr;
139 return StatusCode::FAILURE;
140 }
142
143
145 const auto &wtCont = mcEvt->weights();
146 if (!wtCont.empty()) {
147 } else {
149 }
150 int inEvent = mcEvt->event_number();
152
154
156
158 int nEvent = thinEvt->event_number();
160
161 if (doPrint) {
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;
165 }
166
168
170
171
172
173
174
175
176
177
178
179
180
181
182
183
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;
189
190
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;
197
199
201
203
204 std::vector<HepMC::GenVertexPtr> hadVertices;
205
206 for (auto& hadv: thinEvt->vertices()) {
207 if (!hadv) continue;
208 if (hadv->particles_in().size() < 2) continue;
209 if (hadv->particles_out().size() < 1) continue;
210
211
212
213 bool isHadVtx = true;
214 bool isHadOut = false;
215 for (const auto& inp: hadv->particles_in() ) {
217 }
218 for (const auto& vp: hadv->particles_out()) {
221 }
222 isHadVtx = isHadVtx && isHadOut;
223 if (isHadVtx) hadVertices.push_back(hadv);
224 if (doDebug && isHadVtx)
ATH_MSG_VERBOSE(
"Hadronization vertex " << hadv);
225 }
226
227 if (hadVertices.empty()) {
231 return StatusCode::SUCCESS;
232 }
233
235
236
238
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));
244 }
245 }
246
247
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));
257 }
258 }
259
260
261
262
263
264
265 for (auto hadv:thinEvt->vertices()) {
266
267 if (hadv->particles_in().size() == 0 && hadv->particles_out().size() == 0) {
268 removeV.push_back(hadv);
269 deleteV.push_back(hadv);
270 }
271
273 for (auto pin: hadv->particles_in()) {
274 removePV.push_back(vpPair(hadv, pin));
276 }
277 for (auto pout: hadv->particles_out()) {
278 removePV.push_back(vpPair(hadv, pout));
280 }
281 removeV.push_back(hadv);
282 deleteV.push_back(std::move(hadv));
283 }
284
285
286
287 for (
unsigned int i = 0;
i < removePV.size(); ++
i) {
290 v->remove_particle_in(p);
291 v->remove_particle_out(std::move(p));
292 }
293
294 for (
unsigned int i = 0;
i < addoutPV.size(); ++
i) {
297 v->add_particle_out(std::move(p));
298 }
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());
304 }
305 thinEvt->remove_vertex(hadVertices[iv]);
306 }
307
309
311
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;
316 }
317
318
319
320
321
322
323
324
325
326
327
328
329 bool moreP = true;
330 using vpPair = std::pair<HepMC::GenVertexPtr, HepMC::GenParticlePtr>;
331 removePV.clear();
332 addinPV.clear();
333 addoutPV.clear();
334 removeV.clear();
335 deleteP.clear();
336 deleteV.clear();
337
338 using pkPair = std::pair<HepMC::GenParticlePtr, HepMC::FourVector>;
339 std::vector<pkPair> changePK;
340
342 while (moreP) {
343 if (doDebug)
ATH_MSG_DEBUG(
"New parton pass " << inEvent <<
" " << thinEvt->particles_size() <<
" " << thinEvt->vertices_size());
344
345 moreP = false;
346 removePV.clear();
347 addinPV.clear();
348 addoutPV.clear();
349 removeV.clear();
350 changePK.clear();
351
352 for (auto fp: thinEvt->particles() ) {
353 int iCase = 0;
356
358 if (!pvtx) {
360 continue;
361 }
362 if (doDebug)
ATH_MSG_DEBUG(
"Final parton " << pvtx <<
" " << fp);
364
366
367
368 if (pvtx->particles_in().size() == 1 && pvtx->particles_out().size() == 1) {
369
371 if (!pp || pp->parent_event() == nullptr) {
374 continue;
375 }
376
378 if (!ppvtx || ppvtx->parent_event() == nullptr) {
381 continue;
382 }
383 moreP = true;
384 iCase = 1;
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); }
392 }
394
396
397
398
399
400 if (pvtx->particles_in().size() == 2 && pvtx->particles_out().size() == 1) {
401
404
405
406 if (std::abs(pp1->momentum().perp()) < 1.e-3) continue;
407 if (std::abs(pp2->momentum().perp()) < 1.e-3) continue;
408
411 if (!ppvtx1 || ppvtx1->parent_event() == nullptr) {
414 continue;
415 }
416 if (!ppvtx2 || ppvtx2->parent_event() == nullptr) {
419 continue;
420 }
421 moreP = true;
422 iCase = 2;
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);
429 if (doDebug) {
430 ATH_MSG_DEBUG(
"2->1: ppvtx1,pp1,ppvtx2,pp2,pvtx,fp " << ppvtx1 <<
" " << pp1
431 << " " << ppvtx2 << " " << pp2 << " " << pvtx << " "<< fp);
432 }
433 }
435
437
438
439
440 if (pvtx->particles_in().size() == 1 && pvtx->particles_out().size() == 2) {
443
444 if (fp == pout1) {
447 continue;
448 }
449 } else if (fp == pout2) {
452 continue;
453 }
454 } else {
455 ATH_MSG_WARNING(
"1->2: No match found for branching " << fp <<
" " << pvtx <<
" " << pout1 <<
" " << pout2);
456 continue;
457 }
458 if (fp != pout1) continue;
459
461
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;
464
466 double m12 = p12.m();
467 if (m12 < 0) {
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);
470 }
471 m12 = 0;
472 }
473 if (doDebug)
ATH_MSG_DEBUG(
"1->2: parton pair mass " << m12);
474
476 if (doDebug)
ATH_MSG_DEBUG(
"Keeping 1->2: parton mass " << m12);
477 continue;
478 }
479
481 if (!ppvtx || ppvtx->parent_event() == nullptr) {
484 continue;
485 }
486
487 moreP = true;
488 iCase = 3;
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);
498 if (doDebug) {
499 ATH_MSG_DEBUG(
"Merge 1->2: ppvtx,pp,pvtx,pout1,pout2,evtx " << ppvtx <<
" " << pp <<
" " << pvtx <<
" " << pout1 <<
" "
500 << pout2);
501 ATH_MSG_DEBUG(
"Merge 1->2: id " << pp->pdg_id() <<
" " << pout1->pdg_id() <<
" " << pout2->pdg_id());
502 }
503 }
505
507
508 if (pvtx->particles_in().size() == 1) {
509
511 if (std::abs(pp->pdg_id()) ==
MC::PROTON) iCase = -1;
512 }
513
514
515 if (iCase == 0) {
516 if (doDebug)
ATH_MSG_DEBUG(
"Case not found " << pvtx <<
" " << fp <<
" " << pvtx->particles_in().size() <<
" " << pvtx->particles_out().size());
517 }
518 }
519
520
521
522 if (doDebug)
ATH_MSG_DEBUG(
"Actually removing particles " << removePV.size());
523
524 for (
unsigned int i = 0;
i < removePV.size(); ++
i) {
528 v->remove_particle_in(p);
529 v->remove_particle_out(std::move(p));
530 }
531
532
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));
539 }
540
541
542 for (
unsigned int i = 0;
i < changePK.size(); ++
i) {
545 pp->set_momentum(changePK[i].second);
546 }
547
548
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]);
554 }
555 if (doDebug)
ATH_MSG_DEBUG(
"End while(moreP) pass " << moreP);
556
557 }
558
560
562
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;
567 }
568
569
570
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()) {
576 if (!pvtx) continue;
577
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);
582
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);
587 }
588
589
590 pNotHad.push_back(fp);
591 int ida = std::abs(
fp->pdg_id());
592 bool keepid = (ida > 10 && ida < 20) || (ida > 1000000 && ida < 9000000);
594 pHard.push_back(fp);
596 }
597
598
599
600
601
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);
606 }
607 }
608
609
610 pNotHad.sort();
611 pNotHad.unique();
612 pHard.sort();
613 pHard.unique();
614
615
616 if (doDebug) {
617 int nhard = 0;
618 for (auto ph: pHard) {
619 ++nhard;
621 }
622 if (doDebug)
ATH_MSG_DEBUG(
"Hard GenParticles total " << nhard);
623 }
624
625
626
627
628 for (auto p: pNotHad) {
629
630 bool isHard = false;
631 for (auto h: pHard) {
632 if (p == h) {
633 isHard = true;
634 break;
635 }
636 }
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));
643 }
644
646
648
649 removeV.clear();
650 deleteV.clear();
651
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));
657 }
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]);
662 }
663
665
667
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;
672 }
673
674
675
676
677
678 bool moreV1 = true;
682
683 while (moreV1) {
684 moreV1 = false;
685
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());
691 if (pin->pdg_id() !=
pout->pdg_id())
continue;
692
693 if (pin == beams[0] || pin == beams[1]) continue;
695 if (!pvtx || pvtx->parent_event() == nullptr) {
698 continue;
699 }
700 moreV1 = true;
701 vtx11 = std::move(v);
702 if (doDebug)
ATH_MSG_DEBUG(
"One-body " << pin <<
" " << vtx11 <<
" " << pout);
703 break;
704 }
705 if (moreV1) {
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());
716 }
717 }
719
721
722
723
724
725
727
728 removePV.clear();
729 removeV.clear();
730 deleteP.clear();
731 deleteV.clear();
732
733 for (auto badv: thinEvt->vertices()) {
734 if (!badv) continue;
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));
749 }
750
751 for (
unsigned int i = 0;
i < removePV.size(); ++
i) {
754 v->remove_particle_in(p);
755 v->remove_particle_out(std::move(p));
756 }
757
758 for (
unsigned int i = 0;
i < removeV.size(); ++
i) {
759 thinEvt->remove_vertex(removeV[i]);
760 }
761 }
762
764
766
767 if (doPrint) {
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;
771 }
772
775
777
779
781 return StatusCode::SUCCESS;
782}
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
ServiceHandle< StoreGateSvc > & evtStore()
value_type push_back(value_type pElem)
Add an element to the end of the collection.
const T * front() const
Access the first element in the collection as an rvalue.
bool empty() const noexcept
Returns true if the collection is empty.
virtual HepMC::FourVector vtxOutMom(HepMC::ConstGenVertexPtr)
void setConst()
Set the const flag for this expression.
bool is_simulation_vertex(const T &v)
Method to establish if the vertex was created during simulation (TODO migrate to be based on status).
HepMC3::FourVector FourVector
HepMC3::GenParticlePtr GenParticlePtr
HepMC3::GenVertexPtr GenVertexPtr
bool is_simulation_particle(const T &p)
Method to establish if a particle (or barcode) was created during the simulation (TODO update to be s...
HepMC3::GenEvent GenEvent
bool isParton(const T &p)
bool isDiquark(const T &p)
PDG rule 4 Diquarks have 4-digit numbers with nq1 >= nq2 and nq3 = 0 APID: states with top quarks are...
bool isHadron(const T &p)