12 #include "HepPDT/ParticleDataTable.hh"
14 #include "HepMC/IO_HEPEVT.h"
24 #include <Math/VectorUtil.h>
48 generatorMode_(cfg.getParameter<std::
string>(
"generatorMode")),
49 beamEnergy_(cfg.getParameter<double>(
"beamEnergy")),
51 applyMuonRadiationCorrection_(
false),
52 muonRadiationAlgo_(0),
83 if ( cfg.
exists(
"minVisibleTransverseMomentum") ) {
85 const char* startptr = minVisibleTransverseMomentumLine.c_str();
87 double d = strtod(startptr, &endptr);
88 if ( *endptr ==
'\0' && endptr != startptr ) {
100 minVisPtCut.
cut_string_ = minVisibleTransverseMomentumLine;
101 minVisPtCut.
cuts_.push_back(cutLeg1);
102 minVisPtCut.
cuts_.push_back(cutLeg2);
107 for (
std::string::size_type prev = 0, pos = 0; prev < minVisibleTransverseMomentumLine.length(); prev = pos + 1) {
108 pos = minVisibleTransverseMomentumLine.find(
';', prev);
109 if ( pos == std::string::npos ) pos = minVisibleTransverseMomentumLine.length();
111 std::string sub = minVisibleTransverseMomentumLine.substr(prev, pos - prev);
113 minVisPtCut.
cut_string_ = minVisibleTransverseMomentumLine;
114 const char* sub_c = sub.c_str();
115 while (*sub_c !=
'\0' ) {
116 const char* sep = std::strchr(sub_c,
'_');
118 <<
"Minimum transverse parameter string must contain an underscore to separate type from Pt threshold !!\n";
131 <<
"'" << type <<
"' is not a valid type. Allowed values are { elec1, mu1, had1, tau1, elec2, mu2, had2, tau2 } !!\n";
136 <<
"No Pt threshold given !!\n";
139 minVisPtCut.
cuts_.push_back(cut);
152 <<
"The RandomNumberProducer module requires the RandomNumberGeneratorService\n"
153 <<
"which appears to be absent. Please add that service to your configuration\n"
154 <<
"or remove the modules that require it.\n";
160 if ( applyMuonRadiationCorrection_string !=
"" ) {
200 if ( genParticle1->pdg_id() == genParticle2->pdg_id() &&
201 TMath::Abs(genParticle1->momentum().e() - genParticle2->momentum().e()) < (1.
e-3*(genParticle1->momentum().e() + genParticle2->momentum().e())) &&
202 reco::deltaR(genParticle1->momentum(), genParticle2->momentum()) < 1.
e-3 )
208 bool matchesGenVertex(
const HepMC::GenVertex* genVertex1,
const HepMC::GenVertex* genVertex2,
bool checkIncomingParticles,
bool checkOutgoingParticles)
211 if ( !(TMath::Abs(genVertex1->position().x() - genVertex2->position().x()) < 1.
e-3 &&
212 TMath::Abs(genVertex1->position().y() - genVertex2->position().y()) < 1.
e-3 &&
213 TMath::Abs(genVertex1->position().z() - genVertex2->position().z()) < 1.
e-3) )
return false;
216 if ( checkIncomingParticles ) {
217 for ( HepMC::GenVertex::particles_in_const_iterator genParticle1 = genVertex1->particles_in_const_begin();
218 genParticle1 != genVertex1->particles_in_const_end(); ++genParticle1 ) {
220 for ( HepMC::GenVertex::particles_in_const_iterator genParticle2 = genVertex2->particles_in_const_begin();
221 genParticle2 != genVertex2->particles_in_const_end() && !
isMatched; ++genParticle2 ) {
222 isMatched |= matchesGenParticle(*genParticle1, *genParticle2);
224 if ( !isMatched )
return false;
229 if ( checkOutgoingParticles ) {
230 for ( HepMC::GenVertex::particles_out_const_iterator genParticle1 = genVertex1->particles_out_const_begin();
231 genParticle1 != genVertex1->particles_out_const_end(); ++genParticle1 ) {
232 bool isMatched =
false;
233 for ( HepMC::GenVertex::particles_out_const_iterator genParticle2 = genVertex2->particles_out_const_begin();
234 genParticle2 != genVertex2->particles_out_const_end() && !
isMatched; ++genParticle2 ) {
235 isMatched |= matchesGenParticle(*genParticle1, *genParticle2);
237 if ( !isMatched )
return false;
248 <<
"ParticleReplacerZtautau does NOT support using primary vertex as the origin for taus !!\n";
254 std::vector<reco::Particle> embedParticles;
257 if ( muons.size() != 2 ) {
259 <<
"The decay mode Z->ll requires exactly two muons --> returning empty HepMC event !!" << std::endl;
260 return std::auto_ptr<HepMC::GenEvent>(0);
289 embedParticles.push_back(embedLepton1);
290 embedParticles.push_back(embedLepton2);
293 if ( muons.size() != 2 ) {
295 <<
"The decay mode W->taunu requires exactly two muons --> returning empty HepMC event !!" << std::endl;
296 return std::auto_ptr<HepMC::GenEvent>(0);
309 embedParticles.push_back(embedTau);
310 embedParticles.push_back(embedNu);
313 if ( muons.size() != 2 ) {
315 <<
"The decay mode W->taunu requires exactly two gen. leptons --> returning empty HepMC event !!" << std::endl;
316 return std::auto_ptr<HepMC::GenEvent>(0);
328 embedTau.setStatus(1);
329 embedParticles.push_back(embedTau);
333 embedParticles.push_back(embedNu);
336 if ( embedParticles.size() != 2 ){
338 <<
"The creation of gen. particles failed somehow --> returning empty HepMC event !!" << std::endl;
339 return std::auto_ptr<HepMC::GenEvent>(0);
342 HepMC::GenEvent* genEvt_output = 0;
344 HepMC::GenVertex* genVtx_output =
new HepMC::GenVertex();
346 HepMC::GenVertex* ppCollisionVtx = 0;
348 std::vector<reco::Candidate::LorentzVector> auxPhotonP4s;
352 genEvt_output =
new HepMC::GenEvent(*genEvt);
355 genVtx != genEvt_output->vertices_end(); ++genVtx ) {
357 if ( (*genVtx)->particles_out_size() <= 0 || (*genVtx)->particles_in_size() <= 0 )
continue;
359 bool foundMuon1 =
false;
360 bool foundMuon2 =
false;
362 for ( HepMC::GenVertex::particles_out_const_iterator genParticle = (*genVtx)->particles_out_const_begin();
363 genParticle != (*genVtx)->particles_out_const_end(); ++genParticle ) {
364 if ( (*genParticle)->pdg_id() == 13 ) foundMuon1 =
true;
365 if ( (*genParticle)->pdg_id() == -13 ) foundMuon2 =
true;
366 if ( (*genParticle)->pdg_id() == 23 ) foundZ =
true;
369 int motherPdgId = (*(*genVtx)->particles_in_const_begin())->pdg_id();
371 if ( ((*genVtx)->particles_out_size() == 2 &&
372 (*genVtx)->particles_in_size() > 0 &&
376 ((*genVtx)->particles_out_size() > 2 &&
377 (*genVtx)->particles_in_size() > 0 &&
382 genVtx_output = (*genVtx);
390 for ( HepMC::GenEvent::particle_iterator genParticle = genEvt_output->particles_begin();
391 genParticle != genEvt_output->particles_end(); ++genParticle ) {
392 (*genParticle)->set_status(0);
395 for ( std::vector<reco::Particle>::const_iterator embedParticle = embedParticles.begin();
396 embedParticle != embedParticles.end(); ++embedParticle ) {
399 for ( std::vector<reco::Particle>::const_iterator otherParticle = embedParticles.begin();
400 otherParticle != embedParticles.end(); ++otherParticle ) {
401 if (
deltaR(otherParticle->p4(), embedParticle->p4()) > 1.
e-3 ) sumOtherParticlesP4 += otherParticle->p4();
405 double embedParticlePx_corrected = embedParticle->px() + muonFSR.px();
406 double embedParticlePy_corrected = embedParticle->py() + muonFSR.py();
407 double embedParticlePz_corrected = embedParticle->pz() + muonFSR.pz();
408 double embedParticleEn_corrected =
sqrt(
square(embedParticlePx_corrected) +
square(embedParticlePy_corrected) +
square(embedParticlePz_corrected) +
square(embedParticle->mass()));
409 reco::Candidate::LorentzVector embedParticleP4_corrected(embedParticlePx_corrected, embedParticlePy_corrected, embedParticlePz_corrected, embedParticleEn_corrected);
410 genVtx_output->add_particle_out(
new HepMC::GenParticle((HepMC::FourVector)embedParticleP4_corrected, embedParticle->pdgId(), 1, HepMC::Flow(), HepMC::Polarization(0,0)));
416 ppCollisionVtx = (*genEvt_output->vertices_begin());
417 assert(ppCollisionVtx);
419 muonsBeforeRad->push_back(
reco::Particle(embedParticle->charge(), embedParticle->p4(), embedParticle->vertex(), embedParticle->pdgId()));
420 muonsAfterRad->push_back(
reco::Particle(embedParticle->charge(), embedParticleP4_corrected, embedParticle->vertex(), embedParticle->pdgId()));
422 genVtx_output->add_particle_out(
new HepMC::GenParticle((HepMC::FourVector)embedParticle->p4(), embedParticle->pdgId(), 1, HepMC::Flow(), HepMC::Polarization(0,0)));
427 double ppCollisionPosX = 0.;
428 double ppCollisionPosY = 0.;
429 double ppCollisionPosZ = 0.;
431 for ( std::vector<reco::Particle>::const_iterator embedParticle = embedParticles.begin();
432 embedParticle != embedParticles.end(); ++embedParticle ) {
436 genMotherP4 += embedParticle->p4();
438 ppCollisionPosX += embedParticleVertex.x();
439 ppCollisionPosY += embedParticleVertex.y();
440 ppCollisionPosZ += embedParticleVertex.z();
444 int numEmbedParticles = embedParticles.size();
445 if ( numEmbedParticles > 0 ) {
446 ppCollisionPosX /= numEmbedParticles;
447 ppCollisionPosY /= numEmbedParticles;
448 ppCollisionPosZ /= numEmbedParticles;
451 ppCollisionVtx =
new HepMC::GenVertex(HepMC::FourVector(ppCollisionPosX*10., ppCollisionPosY*10., ppCollisionPosZ*10., 0.));
454 ppCollisionVtx->add_particle_in(
new HepMC::GenParticle(HepMC::FourVector(0., 0., +protonPz, protonEn), 2212, 3));
455 ppCollisionVtx->add_particle_in(
new HepMC::GenParticle(HepMC::FourVector(0., 0., -protonPz, protonEn), 2212, 3));
457 HepMC::GenVertex* genMotherDecayVtx =
new HepMC::GenVertex(HepMC::FourVector(ppCollisionPosX*10., ppCollisionPosY*10., ppCollisionPosZ*10., 0.));
460 int chargedLepPdgId = embedParticles.begin()->pdgId();
461 int motherPdgId = -24*chargedLepPdgId/
std::abs(chargedLepPdgId);
462 genMother->set_pdg_id(motherPdgId);
465 ppCollisionVtx->add_particle_out(genMother);
467 genMotherDecayVtx->add_particle_in(genMother);
468 for ( std::vector<reco::Particle>::const_iterator embedParticle = embedParticles.begin();
469 embedParticle != embedParticles.end(); ++embedParticle ) {
472 for ( std::vector<reco::Particle>::const_iterator otherParticle = embedParticles.begin();
473 otherParticle != embedParticles.end(); ++otherParticle ) {
474 if (
deltaR(otherParticle->p4(), embedParticle->p4()) > 1.
e-3 ) sumOtherParticlesP4 += otherParticle->p4();
488 double embedParticlePx_corrected = embedParticle->px() + muonFSR.px();
489 double embedParticlePy_corrected = embedParticle->py() + muonFSR.py();
490 double embedParticlePz_corrected = embedParticle->pz() + muonFSR.pz();
491 double embedParticleEn_corrected =
sqrt(
square(embedParticlePx_corrected) +
square(embedParticlePy_corrected) +
square(embedParticlePz_corrected) +
square(embedParticle->mass()));
492 reco::Candidate::LorentzVector embedParticleP4_corrected(embedParticlePx_corrected, embedParticlePy_corrected, embedParticlePz_corrected, embedParticleEn_corrected);
498 genMotherDecayVtx->add_particle_out(
new HepMC::GenParticle((HepMC::FourVector)embedParticleP4_corrected, embedParticle->pdgId(), 1, HepMC::Flow(), HepMC::Polarization(0,0)));
503 muonsBeforeRad->push_back(
reco::Particle(embedParticle->charge(), embedParticleP4_corrected, embedParticle->vertex(), embedParticle->pdgId()));
504 muonsAfterRad->push_back(
reco::Particle(embedParticle->charge(), embedParticle->p4(), embedParticle->vertex(), embedParticle->pdgId()));
506 genMotherDecayVtx->add_particle_out(
new HepMC::GenParticle((HepMC::FourVector)embedParticle->p4(), embedParticle->pdgId(), 1, HepMC::Flow(), HepMC::Polarization(0,0)));
510 genEvt_output =
new HepMC::GenEvent();
511 genEvt_output->add_vertex(ppCollisionVtx);
512 genEvt_output->add_vertex(genMotherDecayVtx);
518 HepMC::GenEvent* passedEvt_output = 0;
520 unsigned int numEvents_tried = 0;
521 unsigned int numEvents_passed = 0;
525 HepMC::IO_HEPEVT
conv;
527 HepMC::GenEvent* tempEvt =
new HepMC::GenEvent(*genEvt_output);
531 <<
"Pythia is currently not supported !!\n";
533 conv.write_event(tempEvt);
539 assert(decayEvt == tempEvt);
542 bool passesVisPtCuts =
testEvent(tempEvt);
543 if ( passesVisPtCuts ) {
544 if ( !passedEvt_output ) passedEvt_output = tempEvt;
557 if ( !passedEvt_output ) {
559 <<
"Failed to create an event which satisfies the visible Pt cuts !!" << std::endl;
561 for ( std::vector<reco::Particle>::const_iterator
muon = muons.begin();
563 std::cout <<
" muon #" << idx <<
" (charge = " <<
muon->charge() <<
"): Pt = " <<
muon->pt() <<
", eta = " <<
muon->eta() <<
", phi = " <<
muon->phi() << std::endl;
566 return std::auto_ptr<HepMC::GenEvent>(0);
573 conv.write_event(passedEvt_output);
586 HepMC::GenEvent* passedEvt_pythia = conv.read_next_event();
594 for ( HepMC::GenEvent::vertex_const_iterator genVertex_pythia = passedEvt_pythia->vertices_begin();
595 genVertex_pythia != passedEvt_pythia->vertices_end(); ++genVertex_pythia ) {
596 bool isDecayVertex = ((*genVertex_pythia)->particles_in_size() >= 1 && (*genVertex_pythia)->particles_out_size() >= 2);
597 for ( HepMC::GenEvent::vertex_const_iterator genVertex_output = passedEvt_output->vertices_begin();
598 genVertex_output != passedEvt_output->vertices_end(); ++genVertex_output ) {
599 if ( matchesGenVertex(*genVertex_output, *genVertex_pythia,
true,
false) ) isDecayVertex =
false;
601 if ( !isDecayVertex )
continue;
605 HepMC::GenVertex* genVertex_output =
new HepMC::GenVertex((*genVertex_pythia)->position());
608 for ( HepMC::GenVertex::particles_in_const_iterator genParticle_pythia = (*genVertex_pythia)->particles_in_const_begin();
609 genParticle_pythia != (*genVertex_pythia)->particles_in_const_end(); ++genParticle_pythia ) {
610 for ( HepMC::GenEvent::particle_iterator genParticle_output = passedEvt_output->particles_begin();
611 genParticle_output != passedEvt_output->particles_end(); ++genParticle_output ) {
612 if ( matchesGenParticle(*genParticle_output, *genParticle_pythia) ) {
614 genVertex_output->add_particle_in(*genParticle_output);
616 (*genParticle_output)->set_status(2);
622 for ( HepMC::GenVertex::particles_out_const_iterator genParticle_pythia = (*genVertex_pythia)->particles_out_const_begin();
623 genParticle_pythia != (*genVertex_pythia)->particles_out_const_end(); ++genParticle_pythia ) {
625 (*genParticle_pythia)->momentum(),
626 (*genParticle_pythia)->pdg_id(),
627 (*genParticle_pythia)->status(),
628 (*genParticle_pythia)->flow(),
629 (*genParticle_pythia)->polarization());
630 genParticle_output->suggest_barcode((*genParticle_pythia)->barcode());
632 genVertex_output->add_particle_out(genParticle_output);
636 passedEvt_output->add_vertex(genVertex_output);
642 for ( std::vector<reco::Candidate::LorentzVector>::const_iterator auxPhotonP4 = auxPhotonP4s.begin();
643 auxPhotonP4 != auxPhotonP4s.end(); ++auxPhotonP4 ) {
644 ppCollisionVtx->add_particle_out(
new HepMC::GenParticle((HepMC::FourVector)*auxPhotonP4, 22, 1, HepMC::Flow(), HepMC::Polarization(0,0)));
648 delete passedEvt_pythia;
656 for ( HepMC::GenEvent::particle_iterator genParticle = passedEvt_output->particles_begin();
657 genParticle != passedEvt_output->particles_end(); ++genParticle ) {
658 if ( (*genParticle)->end_vertex() ) (*genParticle)->set_status(2);
659 else (*genParticle)->set_status(1);
666 for ( std::vector<reco::Particle>::const_iterator
muon = muons.begin();
668 sumMuonP4_replaced +=
muon->p4();
672 for ( HepMC::GenEvent::particle_iterator genParticle = passedEvt_output->particles_begin();
673 genParticle != passedEvt_output->particles_end(); ++genParticle ) {
674 if ( (*genParticle)->status() != 1 )
continue;
675 if (
abs((*genParticle)->pdg_id()) == 12 ||
abs((*genParticle)->pdg_id()) == 14 ||
abs((*genParticle)->pdg_id()) == 16 )
continue;
676 sumMuonP4_embedded +=
reco::Candidate::LorentzVector((*genParticle)->momentum().px(), (*genParticle)->momentum().py(), (*genParticle)->momentum().pz(), (*genParticle)->momentum().e());
679 if ( (sumMuonP4_embedded.pt() - sumMuonP4_replaced.pt()) > (1.
e-3*sumMuonP4_replaced.pt()) ) {
681 <<
"Transverse momentum of embedded tau leptons = " << sumMuonP4_embedded.pt()
682 <<
" differs from transverse momentum of replaced muons = " << sumMuonP4_replaced.pt() <<
" !!" << std::endl;
685 std::auto_ptr<HepMC::GenEvent> passedEvt_output_ptr(passedEvt_output);
688 std::cout <<
" numEvents: tried = " << numEvents_tried <<
", passed = " << numEvents_passed << std::endl;
691 delete genVtx_output;
692 delete genEvt_output;
694 producer->
call_put(muonsBeforeRad,
"muonsBeforeRad");
695 producer->
call_put(muonsAfterRad,
"muonsAfterRad");
697 return passedEvt_output_ptr;
703 std::cout <<
"<ParticleReplacerZtautau::beginRun>: Initializing TAUOLA interface." << std::endl;
720 std::vector<double> muonPts;
721 std::vector<double> electronPts;
722 std::vector<double> tauJetPts;
723 std::vector<double> tauPts;
725 int genParticleIdx = 0;
726 for ( HepMC::GenEvent::particle_iterator genParticle = genEvt->particles_begin();
727 genParticle != genEvt->particles_end(); ++genParticle ) {
728 if (
abs((*genParticle)->pdg_id()) == 15 && (*genParticle)->end_vertex() ) {
730 std::queue<const HepMC::GenParticle*> decayProducts;
731 decayProducts.push(*genParticle);
732 enum { kELEC, kMU, kHAD };
734 int decayProductIdx = 0;
735 while ( !decayProducts.empty() && decayProductIdx < 100 ) {
738 std::cout <<
"decayProduct #" << (decayProductIdx + 1) <<
" (pdgId = " << decayProduct->pdg_id() <<
"):"
739 <<
" Pt = " << decayProduct->momentum().perp() <<
", eta = " << decayProduct->momentum().eta() <<
", phi = " << decayProduct->momentum().phi()
743 if ( !decayProduct->end_vertex() ) {
744 int absPdgId =
abs(decayProduct->pdg_id());
746 if ( absPdgId == 11 ) type = kELEC;
747 if ( absPdgId == 13 ) type = kMU;
749 HepMC::GenVertex* decayVtx = decayProduct->end_vertex();
750 for ( HepMC::GenVertex::particles_out_const_iterator daughter = decayVtx->particles_out_const_begin();
751 daughter != decayVtx->particles_out_const_end(); ++daughter ) {
752 decayProducts.push(*daughter);
758 double visPt = visP4.pt();
759 tauPts.push_back(visPt);
760 if ( type == kMU ) muonPts.push_back(visPt);
761 else if ( type == kELEC ) electronPts.push_back(visPt);
762 else if ( type == kHAD ) tauJetPts.push_back(visPt);
765 if ( type == kMU ) type_string =
"mu";
766 else if ( type == kELEC ) type_string =
"elec";
767 else if ( type == kHAD ) type_string =
"had";
768 std::cout <<
"visLeg #" << (genParticleIdx + 1) <<
" (type = " << type_string <<
"):"
769 <<
" Pt = " << visP4.pt() <<
", eta = " << visP4.eta() <<
", phi = " << visP4.phi()
770 <<
" (X = " << (visP4.energy()/(*genParticle)->momentum().e()) <<
")" << std::endl;
776 std::sort(tauPts.begin(), tauPts.end(), std::greater<double>());
777 std::sort(electronPts.begin(), electronPts.end(), std::greater<double>());
778 std::sort(muonPts.begin(), muonPts.end(), std::greater<double>());
779 std::sort(tauJetPts.begin(), tauJetPts.end(), std::greater<double>());
786 for ( std::vector<MinVisPtCutCombination>::const_iterator minVisPtCut =
minVisPtCuts_.begin();
790 bool passesMinVisCut =
true;
792 for ( std::vector<MinVisPtCut>::const_iterator
cut = minVisPtCut->cuts_.begin();
793 cut != minVisPtCut->cuts_.end(); ++
cut ) {
795 switch (
cut->type_ ) {
797 collection = &electronPts;
800 collection = &muonPts;
803 collection = &tauJetPts;
806 collection = &tauPts;
812 if (
cut->index_ >= collection->size() || (*collection)[
cut->index_] <
cut->threshold_ ) {
813 passesMinVisCut =
false;
820 if ( passesMinVisCut )
return true;
829 std::stack<HepMC::GenParticle*> genParticles_to_delete;
831 std::stack<HepMC::GenVertex*> genVertices_to_process;
832 std::stack<HepMC::GenVertex*> genVertices_to_delete;
834 for ( HepMC::GenVertex::particles_out_const_iterator genParticle = genVtx->particles_out_const_begin();
835 genParticle != genVtx->particles_out_const_end(); ++genParticle ) {
836 genParticles_to_delete.push(*genParticle);
837 if ( (*genParticle)->end_vertex() ) genVertices_to_process.push((*genParticle)->end_vertex());
840 while ( !genVertices_to_process.empty() ) {
841 HepMC::GenVertex* tempVtx = genVertices_to_process.top();
842 if ( tempVtx->particles_out_size() > 0 ) {
843 for ( HepMC::GenVertex::particles_out_const_iterator genParticle = tempVtx->particles_out_const_begin();
844 genParticle != tempVtx->particles_out_const_end(); ++genParticle ) {
845 if ( (*genParticle)->end_vertex() ) genVertices_to_process.push((*genParticle)->end_vertex());
849 genVertices_to_delete.push(tempVtx);
850 genVertices_to_process.pop();
853 while ( !genVertices_to_delete.empty() ) {
854 genEvt->remove_vertex(genVertices_to_delete.top());
855 genVertices_to_delete.pop();
858 while ( !genParticles_to_delete.empty() ) {
859 delete genVtx->remove_particle(genParticles_to_delete.top());
860 genParticles_to_delete.pop();
870 TVector3
p3(p4.px(), p4.py(), p4.pz());
871 p3.Rotate(angle, TVector3(axis.x(), axis.y(), axis.z()).Unit());
873 assert(TMath::Abs(
p3.Mag() - p4.P()) < (1.
e-3*p4.P()));
879 std::cout << label <<
": En = " << p4.E() <<
", Pt = " << p4.pt() <<
" (Px = " << p4.px() <<
", Py = " << p4.py() <<
"),"
880 <<
" theta = " << p4.theta() <<
" (eta = " << p4.eta() <<
"), phi = " << p4.phi() <<
", mass = " << p4.mass();
882 double angle = TMath::ACos((p4.px()*p4_ref->px() + p4.py()*p4_ref->py() + p4.pz()*p4_ref->pz())/(p4.P()*p4_ref->P()));
883 std::cout <<
" (angle wrt. ref = " << angle <<
")";
898 ROOT::Math::Boost boost_to_rf(zP4_lab.BoostToCM());
899 ROOT::Math::Boost boost_to_lab(boost_to_rf.Inverse());
907 std::cout <<
"before rotation:" << std::endl;
908 print(
"muon1(lab)", muon1P4_lab, &zP4_lab);
909 print(
"muon2(lab)", muon2P4_lab, &zP4_lab);
910 print(
"Z(lab)", zP4_lab);
911 print(
"muon1(rf)", muon1P4_rf, &zP4_lab);
912 print(
"muon2(rf)", muon2P4_rf, &zP4_lab);
913 print(
"Z(rf)", zP4_rf);
920 rfRotationAngle_value = 2.*
TMath::Pi()*u;
923 muon1P4_rf =
rotate(muon1P4_rf, zP4_lab, rfRotationAngle_value);
924 muon2P4_rf =
rotate(muon2P4_rf, zP4_lab, rfRotationAngle_value);
927 double muon1P_rf2 =
square(muon1P4_rf.px()) +
square(muon1P4_rf.py()) +
square(muon1P4_rf.pz());
929 double lep1En_rf = 0.5*zP4_rf.E();
930 double lep1P_rf2 =
square(lep1En_rf) - lep1Mass2;
931 if ( lep1P_rf2 < 0. ) lep1P_rf2 = 0.;
932 float scaleFactor1 =
sqrt(lep1P_rf2/muon1P_rf2);
934 scaleFactor1*muon1P4_rf.px(), scaleFactor1*muon1P4_rf.py(), scaleFactor1*muon1P4_rf.pz(), lep1En_rf);
936 double muon2P_rf2 =
square(muon2P4_rf.px()) +
square(muon2P4_rf.py()) +
square(muon2P4_rf.pz());
938 double lep2En_rf = 0.5*zP4_rf.E();
939 double lep2P_rf2 =
square(lep2En_rf) - lep2Mass2;
940 if ( lep2P_rf2 < 0. ) lep2P_rf2 = 0.;
941 float scaleFactor2 =
sqrt(lep2P_rf2/muon2P_rf2);
943 scaleFactor2*muon2P4_rf.px(), scaleFactor2*muon2P4_rf.py(), scaleFactor2*muon2P4_rf.pz(), lep2En_rf);
949 std::cout <<
"after rotation:" << std::endl;
950 print(
"lep1(rf)", muon1P4_rf, &zP4_lab);
951 print(
"lep2(rf)", muon2P4_rf, &zP4_lab);
953 print(
"lep1(lab)", lep1P4_lab, &zP4_lab);
954 print(
"lep2(lab)", lep2P4_lab, &zP4_lab);
955 print(
"lep1+2(lab)", lep1p2_lab);
963 if ( !(fabs(zP4_lab.mass() - (lep1P4_lab + lep2P4_lab).mass()) < (1.
e-3*zP4_lab.mass()) &&
964 fabs(zP4_lab.pt() - (lep1P4_lab + lep2P4_lab).
pt()) < (1.
e-3*zP4_lab.pt())) )
966 <<
"The kinematics of muons and embedded electrons/taus differ by more than 0.1%:" << std::endl
967 <<
" mass(muon1 + muon2) = " << zP4_lab.mass() <<
", mass(lep1 + lep2) = " << (lep1P4_lab + lep2P4_lab).mass() << std::endl
968 <<
" Pt(muon1 + muon2) = " << zP4_lab.pt() <<
", Pt(lep1 + lep2) = " << (lep1P4_lab + lep2P4_lab).
pt() <<
" --> please CHECK !!" << std::endl;
970 muon1->
setP4(lep1P4_lab);
971 muon2->
setP4(lep2P4_lab);
990 ROOT::Math::Boost boost_to_rf(zP4_lab.BoostToCM());
991 ROOT::Math::Boost boost_to_lab(boost_to_rf.Inverse());
1000 double muon1P_rf2 =
square(muon1P4_rf.px()) +
square(muon1P4_rf.py()) +
square(muon1P4_rf.pz());
1002 double tauEn_rf = 0.5*zP4_rf.E();
1003 double tauP_rf2 =
square(tauEn_rf) - tauMass2;
1004 if ( tauP_rf2 < 0. ) tauP_rf2 = 0.;
1005 float scaleFactor1 =
sqrt(tauP_rf2/muon1P_rf2)*(wMass/zP4_rf.mass());
1007 scaleFactor1*muon1P4_rf.px(), scaleFactor1*muon1P4_rf.py(), scaleFactor1*muon1P4_rf.pz(), tauEn_rf);
1009 double muon2P_rf2 =
square(muon2P4_rf.px()) +
square(muon2P4_rf.py()) +
square(muon2P4_rf.pz());
1011 assert(nuMass2 < 1.
e-4);
1012 double nuEn_rf = 0.5*zP4_rf.E();
1013 double nuP_rf2 =
square(nuEn_rf) - nuMass2;
1014 if ( nuP_rf2 < 0. ) nuP_rf2 = 0.;
1015 float scaleFactor2 =
sqrt(nuP_rf2/muon2P_rf2)*(wMass/zP4_rf.mass());
1017 scaleFactor2*muon2P4_rf.px(), scaleFactor2*muon2P4_rf.py(), scaleFactor2*muon2P4_rf.pz(), nuEn_rf);
1027 if ( !(
std::abs(zP4_lab.theta() - (tauP4_lab + nuP4_lab).
theta())/zP4_lab.theta() < 1.e-3 &&
1028 std::abs(zP4_lab.phi() - (tauP4_lab + nuP4_lab).
phi())/zP4_lab.phi() < 1.e-3) )
1030 <<
"The kinematics of muons and embedded tau/neutrino differ by more than 0.1%:" << std::endl
1031 <<
" mass(muon1 + muon2) = " << zP4_lab.mass() <<
", mass(lep1 + lep2) = " << (tauP4_lab + nuP4_lab).mass() << std::endl
1032 <<
" Pt(muon1 + muon2) = " << zP4_lab.pt() <<
", Pt(lep1 + lep2) = " << (tauP4_lab + nuP4_lab).
pt() <<
" --> please CHECK !!" << std::endl;
1034 muon1->
setP4(tauP4_lab);
1035 muon2->
setP4(nuP4_lab);
double px() const
x coordinate of momentum vector
int targetParticle1AbsPdgID_
T getParameter(std::string const &) const
virtual void beginRun(edm::Run &, const edm::EventSetup &)
std::vector< MinVisPtCutCombination > minVisPtCuts_
void setP4(const LorentzVector &p4)
set 4-momentum
std::string generatorMode_
~ParticleReplacerZtautau()
HepMC::GenEvent * decay(HepMC::GenEvent *)
static HepMC::IO_HEPEVT conv
double targetParticle1Mass_
std::vector< MinVisPtCut > cuts_
virtual std::auto_ptr< HepMC::GenEvent > produce(const std::vector< reco::Particle > &, const reco::Vertex *=0, const HepMC::GenEvent *=0, MCParticleReplacer *=0)
virtual void declareExtraProducts(MCParticleReplacer *)
std::string print(const Track &, edm::Verbosity=edm::Concise)
Track print utility.
void setPSet(const edm::ParameterSet &)
Geom::Theta< T > theta() const
bool exists(std::string const ¶meterName) const
checks if a parameter exists
const LorentzVector & p4() const
four-momentum Lorentz vector
double targetParticle2Mass_
void cleanEvent(HepMC::GenEvent *, HepMC::GenVertex *)
bool applyMuonRadiationCorrection_
void transformMuMu2TauNu(reco::Particle *, reco::Particle *)
void call_put(T &product, const std::string &instanceName)
bool testEvent(HepMC::GenEvent *)
void addParameter(std::string const &name, T const &value)
static bool tauola_isInitialized_
math::XYZPoint Point
point in the space
Abs< T >::type abs(const T &t)
auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
bool isMatched(TrackingRecHit const &hit)
const Point & vertex() const
vertex position
virtual CLHEP::HepRandomEngine & getEngine() const =0
Use this to get the random number engine, this is the only function most users should call...
void call_produces(const std::string &instanceName)
const double breitWignerWidthW
double deltaR(double eta1, double eta2, double phi1, double phi2)
ParticleReplacerZtautau(const edm::ParameterSet &)
reco::Candidate::LorentzVector compFSR(const reco::Candidate::LorentzVector &, int, const reco::Candidate::LorentzVector &, int &)
tuple idx
DEBUGGING if hasattr(process,"trackMonIterativeTracking2012"): print "trackMonIterativeTracking2012 D...
double pz() const
z coordinate of momentum vector
int pdgId() const
PDG identifier.
gen::Pythia6Service pythia_
const double electronMass
math::XYZTLorentzVector LorentzVector
Lorentz vector.
void repairBarcodes(HepMC::GenEvent *)
void transformMuMu2LepLep(reco::Particle *, reco::Particle *)
int targetParticle2AbsPdgID_
gen::TauolaInterface * tauola_
unsigned int transformationMode_
void tauola_(int *, int *)
double square(const double a)
void init(const edm::EventSetup &)
#define DEFINE_EDM_PLUGIN(factory, type, name)
VertexRefVector::iterator vertex_iterator
iterator over a vector of references to Vertex objects in the same collection
volatile std::atomic< bool > shutdown_flag false
CLHEP::HepRandomEngine * decayRandomEngine
double py() const
y coordinate of momentum vector
void setStatus(int status)
set status word
int charge() const
electric charge
math::XYZTLorentzVector LorentzVector
Lorentz vector.
const double breitWignerWidthZ
GenMuonRadiationAlgorithm * muonRadiationAlgo_
std::vector< reco::Particle > ParticleCollection
T angle(T x1, T y1, T z1, T x2, T y2, T z2)