274 bool filter_pass =
true;
282 double nonG4_energy = 0;
283 std::vector<HepMC::ConstGenParticlePtr> negEnPart;
284 std::vector<HepMC::ConstGenParticlePtr> tachyons;
285 std::vector<HepMC::ConstGenParticlePtr> unstNoEnd;
286 std::vector<HepMC::ConstGenParticlePtr> unDecPi0;
287 std::vector<HepMC::ConstGenParticlePtr> undisplaceds;
290 if (!
m_looper.loop_particles().empty() || !
m_looper.loop_vertices().empty()) {
293 ATH_MSG_DEBUG(
"Please use MC::Loops::findLoops for this event to obtain all particles and vertices in the loops");
297 const auto xsec = evt->cross_section();
299 ATH_MSG_WARNING(
"WATCH OUT: event is missing the generator cross-section!");
302 ATH_MSG_WARNING(
"-> Adding a dummy cross-section for debugging purposes.");
304 std::shared_ptr<HepMC3::GenCrossSection> dummy_xsec = std::make_shared<HepMC3::GenCrossSection>();
305 dummy_xsec->set_cross_section(1.0,0.0);
307 evt_nonconst->set_cross_section(std::move(dummy_xsec));
315 std::vector<std::shared_ptr<const HepMC3::GenParticle>> beams_t;
316 for (
auto p : evt->beams()) {
if (p->status() == 4) beams_t.push_back(std::move(p)); }
317 std::pair<std::shared_ptr<const HepMC3::GenParticle>,std::shared_ptr<const HepMC3::GenParticle>> beams;
318 if (beams_t.size() == 2) {
319 beams.first=beams_t.at(0);
320 beams.second=beams_t.at(1);
322 ATH_MSG_WARNING(
"Invalid number of beam particles " << beams_t.size() <<
" this generator interface should be fixed");
324 for (
const auto& part: beams_t) HepMC3::Print::line(part);
328 ATH_MSG_WARNING(
"Invalid beam particle pointers -- this generator interface should be fixed");
329 if (cmenergy < 0)
ATH_MSG_WARNING(
"Invalid expected beam energy: " << cmenergy <<
" MeV");
333 ATH_MSG_WARNING(
"Beam particles have incorrectly set status -- this generator interface should be fixed");
336 const double sumE = beams.first->momentum().e() + beams.second->momentum().e();
337 const double sumP = beams.first->momentum().pz() + beams.second->momentum().pz();
338 cmenergy = std::sqrt(sumE*sumE - sumP*sumP);
343 if(beams.first->pdg_id() ==
MC::LEAD && beams.second->pdg_id() ==
MC::LEAD){
366 ATH_MSG_FATAL(
"Beam particles have incorrect energy: " <<
m_cm_energy/Gaudi::Units::GeV <<
" GeV expected, vs. " << cmenergy/Gaudi::Units::GeV <<
" GeV found");
375 return StatusCode::FAILURE;
380 int vtxDisplacedstatuscode12CheckRateCnt=0;
381 int vtxDisplacedstatuscodenot12CheckRateCnt=0;
382 int vtxDisplacedMoreThan_1m_CheckRateCnt=0;
383 for (
const auto& vtx: evt->vertices()) {
387 if ( std::isnan(pos.x()) || std::isinf(pos.x()) ||
388 std::isnan(pos.y()) || std::isinf(pos.y()) ||
389 std::isnan(pos.z()) || std::isinf(pos.z()) ) {
390 ATH_MSG_WARNING(
"NaN (Not A Number) or inf found in the event record vertex positions");
393 if (
m_dumpEvent) HepMC::Print::content(std::cout,*evt);
401 const double dist_trans2 = pos.x()*pos.x() + pos.y()*pos.y();
402 const double dist2 = dist_trans2 + pos.z()*pos.z();
403 const double dist_trans = std::sqrt(dist_trans2);
404 const double dist = std::sqrt(dist2);
407 ++vtxDisplacedMoreThan_1m_CheckRateCnt;
415 <<
"mm in transverse distance: " << dist_trans <<
"mm");
417 for (
const auto& part: vtx->particles_in()) {
420 HepMC::Print::line(
msg( MSG::WARNING ).stream(), part);
432 for (
const auto& part: vtx->particles_in()) {
435 HepMC::Print::line(
msg( MSG::WARNING ).stream(),part);
437 ATH_MSG_WARNING(
"production vertex = " << part->production_vertex()->position().x() <<
", " << part->production_vertex()->position().y() <<
", " << part->production_vertex()->position().z());
438 ATH_MSG_WARNING(
"end vertex = " << part->end_vertex()->position().x() <<
", " << part->end_vertex()->position().y() <<
", " << part->end_vertex()->position().z());
440 if (part->production_vertex()) {
441 for(
const auto& p_parents: part->production_vertex()->particles_in()) {
443 msg(MSG::WARNING) <<
"\t";
444 HepMC::Print::line(
msg( MSG::WARNING ).stream() , p_parents );
449 if (part->status() == 1 || part->status() == 2){
450 vtxDisplacedstatuscode12CheckRateCnt += 1;
452 vtxDisplacedstatuscodenot12CheckRateCnt += 1;
457 if (part->momentum().e()/Gaudi::Units::GeV < 10.) {
471 double endvx = part->end_vertex()->position().x();
472 double endvy = part->end_vertex()->position().y();
473 double endvz = part->end_vertex()->position().z();
474 double prodvx = part->production_vertex()->position().x();
475 double prodvy = part->production_vertex()->position().y();
476 double prodvz = part->production_vertex()->position().z();
477 double enddis = std::sqrt(endvx*endvx + endvy*endvy + endvz*endvz);
478 double proddis = std::sqrt(prodvx*prodvx + prodvy*prodvy + prodvz*prodvz);
490 for (
auto pitr: *evt) {
494 const int pstatus = pitr->status();
495 const int ppdgid = pitr->pdg_id();
497 if ( std::isnan(pmom.px()) || std::isinf(pmom.px()) ||
498 std::isnan(pmom.py()) || std::isinf(pmom.py()) ||
499 std::isnan(pmom.pz()) || std::isinf(pmom.pz()) ||
500 std::isnan(pmom.e()) || std::isinf(pmom.e()) ) {
501 ATH_MSG_WARNING(
"NaN (Not A Number) or inf found in the event record momenta");
504 if (
m_dumpEvent) HepMC::Print::line(std::cout,pitr);
512 if (ppdgid == 111 && !pitr->end_vertex() ) {
513 unDecPi0.push_back( pitr);
520 const auto plifetime =
m_gendata->particleLifetime(ppdgid);
522 double lifetime = plifetime.value()*1e+12;
523 if (lifetime != 0 && lifetime <
m_min_tau) {
524 ATH_MSG_WARNING(
"Stable particle found with lifetime = " << lifetime <<
"~ns!!");
525 if (
m_dumpEvent) HepMC::Print::line(std::cout,pitr);
536 std::vector<int>::size_type
count = 0;
545 ATH_MSG_WARNING(
"Stable particle not found in PDT, no lifetime check done");
546 if (
m_dumpEvent) HepMC::Print::line(std::cout,pitr);
553 const int first_dig = decodedPID(0);
558 std::vector<int>::size_type
count =0;
565 nonG4_energy += pmom.e();
566 ATH_MSG_WARNING(
"Interacting particle not known by Geant4 with ID " << ppdgid);
582 unstNoEnd.push_back(pitr);
589 totalPx += pmom.px();
590 totalPy += pmom.py();
591 totalPz += pmom.pz();
594 negEnPart.push_back(pitr);
597 const double aener = std::abs(pmom.e());
599 tachyons.push_back(pitr);
609 auto vtx = pitr->end_vertex();
612 for (
auto desc: HepMC::descendant_particles(vtx)) {
613 if (std::abs(desc->pdg_id()) ==
m_pdg) tau_child = 1;
614 if (
MC::isStable(desc) ) p_energy += desc->momentum().e();
616 if (std::abs( p_energy - pmom.e()) >
m_energy_diff && !tau_child) {
618 <<
"Energy (original particle) > " <<
m_energy_diff <<
" MeV, "
619 <<
"Event #" << evt->event_number() <<
", "
620 <<
"The original particle = " << pitr);
622 if (
m_dumpEvent) HepMC::Print::content(std::cout,*evt);
626 const double tau_displacement = tau_decaypos.x()*tau_decaypos.x() + tau_decaypos.y()*tau_decaypos.y() + tau_decaypos.z()*tau_decaypos.z();
632 if (
m_dumpEvent) HepMC::Print::content(std::cout,*evt);
637 if (pitr->end_vertex()) {
638 auto decayvtx = pitr->end_vertex();
640 const double displacement = decaypos.x()*decaypos.x() + decaypos.y()*decaypos.y() + decaypos.z()*decaypos.z();
641 if (displacement > 1e-6) {
642 for (
auto ip: *decayvtx) {
644 const double displacement2 = pos2.x()*pos2.x() + pos2.y()*pos2.y() + pos2.z()*pos2.z();
645 if (displacement2 < 1e-6) {
647 <<
" has undisplaced vertex (" << ip->production_vertex()
648 <<
" @ " << displacement2 <<
"mm) "
649 <<
" but parent vertex is displaced (" << decayvtx
650 <<
" @ " << displacement <<
"mm)");
651 undisplaceds.push_back(std::move(ip));
661 const double mass = pitr->generated_mass();
662 if (std::abs(mass) > 1.0) {
663 ATH_MSG_WARNING(
"Photon with non-zero mass found! Mass: " << mass <<
" MeV" << pitr);
672 ATH_MSG_WARNING(
"The energy of interacting particles not known by Geant4 is = " << nonG4_energy <<
" MeV");
680 double lostE = std::abs(totalE - cmenergy);
682 ATH_MSG_WARNING(
"ENERGY BALANCE FAILED : E-difference = " << lostE <<
" MeV");
684 ATH_MSG_WARNING(
"balance " << totalPx <<
" " << totalPy <<
" " << totalPz <<
" " << totalE);
689 if (
m_dumpEvent) HepMC::Print::content(std::cout,*evt);
698 ATH_MSG_WARNING(
"MOMENTUM BALANCE FAILED : SumPx = " << totalPx <<
" SumPy = " << totalPy <<
" SumPz = " << totalPz <<
" MeV");
704 if (
m_dumpEvent) HepMC::Print::content(std::cout,*evt);
712 if (!negEnPart.empty()) {
713 std::stringstream
ss;
714 ss <<
"NEGATIVE ENERGY PARTICLES FOUND :";
715 for (
const auto &b: negEnPart){
719 if (
m_dumpEvent) HepMC::Print::content(std::cout,*evt);
727 if (!tachyons.empty()) {
728 std::stringstream
ss;
729 ss <<
"PARTICLES WITH |E| < |Pi| (i=x,y,z) FOUND :";
730 for (
auto b: tachyons){
734 if (
m_dumpEvent) HepMC::Print::content(std::cout,*evt);
742 if (!unstNoEnd.empty()) {
743 std::stringstream
ss;
744 ss <<
"Unstable particle with no decay vertex found: ";
745 for (
auto b: unstNoEnd){
749 if (
m_dumpEvent) HepMC::Print::content(std::cout,*evt);
757 if (!unDecPi0.empty()) {
758 std::stringstream
ss;
759 ss <<
"pi0 with no decay vertex found:";
760 for (
auto b: unDecPi0){
764 if (
m_dumpEvent) HepMC::Print::content(std::cout,*evt);
772 if (!undisplaceds.empty()) {
773 std::stringstream
ss{
"Undisplaced decay vertices from displaced particle: "};
779 if (
m_dumpEvent) HepMC::Print::content(std::cout,*evt);
801 return StatusCode::FAILURE;
804 return StatusCode::SUCCESS;