9 #include "HepPDT/ParticleDataTable.hh"
11 #include "HepMC/IO_HEPEVT.h"
21 #include <Math/VectorUtil.h>
45 generatorMode_(cfg.getParameter<std::
string>(
"generatorMode")),
46 beamEnergy_(cfg.getParameter<double>(
"beamEnergy")),
47 applyMuonRadiationCorrection_(
false),
48 muonRadiationAlgo_(0),
81 if ( cfg.
exists(
"minVisibleTransverseMomentum") ) {
83 const char* startptr = minVisibleTransverseMomentumLine.c_str();
85 double d = strtod(startptr, &endptr);
86 if ( *endptr ==
'\0' && endptr != startptr ) {
98 minVisPtCut.
cut_string_ = minVisibleTransverseMomentumLine;
99 minVisPtCut.
cuts_.push_back(cutLeg1);
100 minVisPtCut.
cuts_.push_back(cutLeg2);
105 for (
std::string::size_type prev = 0, pos = 0; prev < minVisibleTransverseMomentumLine.length(); prev = pos + 1) {
106 pos = minVisibleTransverseMomentumLine.find(
';', prev);
107 if ( pos == std::string::npos ) pos = minVisibleTransverseMomentumLine.length();
109 std::string sub = minVisibleTransverseMomentumLine.substr(prev, pos - prev);
111 minVisPtCut.
cut_string_ = minVisibleTransverseMomentumLine;
112 const char* sub_c = sub.c_str();
113 while (*sub_c !=
'\0' ) {
114 const char*
sep = std::strchr(sub_c,
'_');
116 <<
"Minimum transverse parameter string must contain an underscore to separate type from Pt threshold !!\n";
129 <<
"'" << type <<
"' is not a valid type. Allowed values are { elec1, mu1, had1, tau1, elec2, mu2, had2, tau2 } !!\n";
134 <<
"No Pt threshold given !!\n";
137 minVisPtCut.
cuts_.push_back(cut);
148 if ( applyMuonRadiationCorrection_string !=
"" ) {
188 if ( genParticle1->pdg_id() == genParticle2->pdg_id() &&
189 TMath::Abs(genParticle1->momentum().e() - genParticle2->momentum().e()) < (1.
e-3*(genParticle1->momentum().e() + genParticle2->momentum().e())) &&
190 reco::deltaR(genParticle1->momentum(), genParticle2->momentum()) < 1.
e-3 )
196 bool matchesGenVertex(
const HepMC::GenVertex* genVertex1,
const HepMC::GenVertex* genVertex2,
bool checkIncomingParticles,
bool checkOutgoingParticles)
199 if ( !(
TMath::Abs(genVertex1->position().x() - genVertex2->position().x()) < 1.
e-3 &&
200 TMath::Abs(genVertex1->position().y() - genVertex2->position().y()) < 1.
e-3 &&
201 TMath::Abs(genVertex1->position().z() - genVertex2->position().z()) < 1.
e-3) )
return false;
204 if ( checkIncomingParticles ) {
205 for ( HepMC::GenVertex::particles_in_const_iterator genParticle1 = genVertex1->particles_in_const_begin();
206 genParticle1 != genVertex1->particles_in_const_end(); ++genParticle1 ) {
208 for ( HepMC::GenVertex::particles_in_const_iterator genParticle2 = genVertex2->particles_in_const_begin();
209 genParticle2 != genVertex2->particles_in_const_end() && !
isMatched; ++genParticle2 ) {
210 isMatched |= matchesGenParticle(*genParticle1, *genParticle2);
212 if ( !isMatched )
return false;
217 if ( checkOutgoingParticles ) {
218 for ( HepMC::GenVertex::particles_out_const_iterator genParticle1 = genVertex1->particles_out_const_begin();
219 genParticle1 != genVertex1->particles_out_const_end(); ++genParticle1 ) {
220 bool isMatched =
false;
221 for ( HepMC::GenVertex::particles_out_const_iterator genParticle2 = genVertex2->particles_out_const_begin();
222 genParticle2 != genVertex2->particles_out_const_end() && !
isMatched; ++genParticle2 ) {
223 isMatched |= matchesGenParticle(*genParticle1, *genParticle2);
225 if ( !isMatched )
return false;
238 <<
"The RandomNumberProducer module requires the RandomNumberGeneratorService\n"
239 <<
"which appears to be absent. Please add that service to your configuration\n"
240 <<
"or remove the modules that require it.\n";
246 <<
"ParticleReplacerZtautau does NOT support using primary vertex as the origin for taus !!\n";
252 std::vector<reco::Particle> embedParticles;
255 if ( muons.size() != 2 ) {
257 <<
"The decay mode Z->ll requires exactly two muons --> returning empty HepMC event !!" << std::endl;
258 return std::auto_ptr<HepMC::GenEvent>(0);
287 embedParticles.push_back(embedLepton1);
288 embedParticles.push_back(embedLepton2);
291 if ( muons.size() != 2 ) {
293 <<
"The decay mode W->taunu requires exactly two muons --> returning empty HepMC event !!" << std::endl;
294 return std::auto_ptr<HepMC::GenEvent>(0);
307 embedParticles.push_back(embedTau);
308 embedParticles.push_back(embedNu);
311 if ( muons.size() != 2 ) {
313 <<
"The decay mode W->taunu requires exactly two gen. leptons --> returning empty HepMC event !!" << std::endl;
314 return std::auto_ptr<HepMC::GenEvent>(0);
326 embedTau.setStatus(1);
327 embedParticles.push_back(embedTau);
331 embedParticles.push_back(embedNu);
334 if ( embedParticles.size() != 2 ){
336 <<
"The creation of gen. particles failed somehow --> returning empty HepMC event !!" << std::endl;
337 return std::auto_ptr<HepMC::GenEvent>(0);
340 HepMC::GenEvent* genEvt_output = 0;
342 HepMC::GenVertex* genVtx_output =
new HepMC::GenVertex();
344 HepMC::GenVertex* ppCollisionVtx = 0;
346 std::vector<reco::Candidate::LorentzVector> auxPhotonP4s;
350 genEvt_output =
new HepMC::GenEvent(*genEvt);
353 genVtx != genEvt_output->vertices_end(); ++genVtx ) {
355 if ( (*genVtx)->particles_out_size() <= 0 || (*genVtx)->particles_in_size() <= 0 )
continue;
357 bool foundMuon1 =
false;
358 bool foundMuon2 =
false;
360 for ( HepMC::GenVertex::particles_out_const_iterator genParticle = (*genVtx)->particles_out_const_begin();
361 genParticle != (*genVtx)->particles_out_const_end(); ++genParticle ) {
362 if ( (*genParticle)->pdg_id() == 13 ) foundMuon1 =
true;
363 if ( (*genParticle)->pdg_id() == -13 ) foundMuon2 =
true;
364 if ( (*genParticle)->pdg_id() == 23 ) foundZ =
true;
367 int motherPdgId = (*(*genVtx)->particles_in_const_begin())->pdg_id();
369 if ( ((*genVtx)->particles_out_size() == 2 &&
370 (*genVtx)->particles_in_size() > 0 &&
374 ((*genVtx)->particles_out_size() > 2 &&
375 (*genVtx)->particles_in_size() > 0 &&
380 genVtx_output = (*genVtx);
388 for ( HepMC::GenEvent::particle_iterator genParticle = genEvt_output->particles_begin();
389 genParticle != genEvt_output->particles_end(); ++genParticle ) {
390 (*genParticle)->set_status(0);
393 for ( std::vector<reco::Particle>::const_iterator embedParticle = embedParticles.begin();
394 embedParticle != embedParticles.end(); ++embedParticle ) {
397 for ( std::vector<reco::Particle>::const_iterator otherParticle = embedParticles.begin();
398 otherParticle != embedParticles.end(); ++otherParticle ) {
399 if (
deltaR(otherParticle->p4(), embedParticle->p4()) > 1.
e-3 ) sumOtherParticlesP4 += otherParticle->p4();
403 double embedParticlePx_corrected = embedParticle->px() + muonFSR.px();
404 double embedParticlePy_corrected = embedParticle->py() + muonFSR.py();
405 double embedParticlePz_corrected = embedParticle->pz() + muonFSR.pz();
406 double embedParticleEn_corrected =
sqrt(
square(embedParticlePx_corrected) +
square(embedParticlePy_corrected) +
square(embedParticlePz_corrected) +
square(embedParticle->mass()));
407 reco::Candidate::LorentzVector embedParticleP4_corrected(embedParticlePx_corrected, embedParticlePy_corrected, embedParticlePz_corrected, embedParticleEn_corrected);
408 genVtx_output->add_particle_out(
new HepMC::GenParticle((HepMC::FourVector)embedParticleP4_corrected, embedParticle->pdgId(), 1, HepMC::Flow(), HepMC::Polarization(0,0)));
414 ppCollisionVtx = (*genEvt_output->vertices_begin());
415 assert(ppCollisionVtx);
417 muonsBeforeRad->push_back(
reco::Particle(embedParticle->charge(), embedParticle->p4(), embedParticle->vertex(), embedParticle->pdgId()));
418 muonsAfterRad->push_back(
reco::Particle(embedParticle->charge(), embedParticleP4_corrected, embedParticle->vertex(), embedParticle->pdgId()));
420 genVtx_output->add_particle_out(
new HepMC::GenParticle((HepMC::FourVector)embedParticle->p4(), embedParticle->pdgId(), 1, HepMC::Flow(), HepMC::Polarization(0,0)));
425 double ppCollisionPosX = 0.;
426 double ppCollisionPosY = 0.;
427 double ppCollisionPosZ = 0.;
429 for ( std::vector<reco::Particle>::const_iterator embedParticle = embedParticles.begin();
430 embedParticle != embedParticles.end(); ++embedParticle ) {
434 genMotherP4 += embedParticle->p4();
436 ppCollisionPosX += embedParticleVertex.x();
437 ppCollisionPosY += embedParticleVertex.y();
438 ppCollisionPosZ += embedParticleVertex.z();
442 int numEmbedParticles = embedParticles.size();
443 if ( numEmbedParticles > 0 ) {
444 ppCollisionPosX /= numEmbedParticles;
445 ppCollisionPosY /= numEmbedParticles;
446 ppCollisionPosZ /= numEmbedParticles;
449 ppCollisionVtx =
new HepMC::GenVertex(HepMC::FourVector(ppCollisionPosX*10., ppCollisionPosY*10., ppCollisionPosZ*10., 0.));
452 ppCollisionVtx->add_particle_in(
new HepMC::GenParticle(HepMC::FourVector(0., 0., +protonPz, protonEn), 2212, 3));
453 ppCollisionVtx->add_particle_in(
new HepMC::GenParticle(HepMC::FourVector(0., 0., -protonPz, protonEn), 2212, 3));
455 HepMC::GenVertex* genMotherDecayVtx =
new HepMC::GenVertex(HepMC::FourVector(ppCollisionPosX*10., ppCollisionPosY*10., ppCollisionPosZ*10., 0.));
458 int chargedLepPdgId = embedParticles.begin()->pdgId();
459 int motherPdgId = -24*chargedLepPdgId/
std::abs(chargedLepPdgId);
460 genMother->set_pdg_id(motherPdgId);
463 ppCollisionVtx->add_particle_out(genMother);
465 genMotherDecayVtx->add_particle_in(genMother);
466 for ( std::vector<reco::Particle>::const_iterator embedParticle = embedParticles.begin();
467 embedParticle != embedParticles.end(); ++embedParticle ) {
470 for ( std::vector<reco::Particle>::const_iterator otherParticle = embedParticles.begin();
471 otherParticle != embedParticles.end(); ++otherParticle ) {
472 if (
deltaR(otherParticle->p4(), embedParticle->p4()) > 1.
e-3 ) sumOtherParticlesP4 += otherParticle->p4();
486 double embedParticlePx_corrected = embedParticle->px() + muonFSR.px();
487 double embedParticlePy_corrected = embedParticle->py() + muonFSR.py();
488 double embedParticlePz_corrected = embedParticle->pz() + muonFSR.pz();
489 double embedParticleEn_corrected =
sqrt(
square(embedParticlePx_corrected) +
square(embedParticlePy_corrected) +
square(embedParticlePz_corrected) +
square(embedParticle->mass()));
490 reco::Candidate::LorentzVector embedParticleP4_corrected(embedParticlePx_corrected, embedParticlePy_corrected, embedParticlePz_corrected, embedParticleEn_corrected);
496 genMotherDecayVtx->add_particle_out(
new HepMC::GenParticle((HepMC::FourVector)embedParticleP4_corrected, embedParticle->pdgId(), 1, HepMC::Flow(), HepMC::Polarization(0,0)));
501 muonsBeforeRad->push_back(
reco::Particle(embedParticle->charge(), embedParticleP4_corrected, embedParticle->vertex(), embedParticle->pdgId()));
502 muonsAfterRad->push_back(
reco::Particle(embedParticle->charge(), embedParticle->p4(), embedParticle->vertex(), embedParticle->pdgId()));
504 genMotherDecayVtx->add_particle_out(
new HepMC::GenParticle((HepMC::FourVector)embedParticle->p4(), embedParticle->pdgId(), 1, HepMC::Flow(), HepMC::Polarization(0,0)));
508 genEvt_output =
new HepMC::GenEvent();
509 genEvt_output->add_vertex(ppCollisionVtx);
510 genEvt_output->add_vertex(genMotherDecayVtx);
516 HepMC::GenEvent* passedEvt_output = 0;
518 unsigned int numEvents_tried = 0;
519 unsigned int numEvents_passed = 0;
523 HepMC::IO_HEPEVT
conv;
525 HepMC::GenEvent* tempEvt =
new HepMC::GenEvent(*genEvt_output);
529 <<
"Pythia is currently not supported !!\n";
531 conv.write_event(tempEvt);
537 assert(decayEvt == tempEvt);
540 bool passesVisPtCuts =
testEvent(tempEvt);
541 if ( passesVisPtCuts ) {
542 if ( !passedEvt_output ) passedEvt_output = tempEvt;
555 if ( !passedEvt_output ) {
557 <<
"Failed to create an event which satisfies the visible Pt cuts !!" << std::endl;
559 for ( std::vector<reco::Particle>::const_iterator
muon = muons.begin();
561 std::cout <<
" muon #" << idx <<
" (charge = " <<
muon->charge() <<
"): Pt = " <<
muon->pt() <<
", eta = " <<
muon->eta() <<
", phi = " <<
muon->phi() << std::endl;
564 return std::auto_ptr<HepMC::GenEvent>(0);
571 conv.write_event(passedEvt_output);
584 HepMC::GenEvent* passedEvt_pythia = conv.read_next_event();
592 for ( HepMC::GenEvent::vertex_const_iterator genVertex_pythia = passedEvt_pythia->vertices_begin();
593 genVertex_pythia != passedEvt_pythia->vertices_end(); ++genVertex_pythia ) {
594 bool isDecayVertex = ((*genVertex_pythia)->particles_in_size() >= 1 && (*genVertex_pythia)->particles_out_size() >= 2);
595 for ( HepMC::GenEvent::vertex_const_iterator genVertex_output = passedEvt_output->vertices_begin();
596 genVertex_output != passedEvt_output->vertices_end(); ++genVertex_output ) {
597 if ( matchesGenVertex(*genVertex_output, *genVertex_pythia,
true,
false) ) isDecayVertex =
false;
599 if ( !isDecayVertex )
continue;
603 HepMC::GenVertex* genVertex_output =
new HepMC::GenVertex((*genVertex_pythia)->position());
606 for ( HepMC::GenVertex::particles_in_const_iterator genParticle_pythia = (*genVertex_pythia)->particles_in_const_begin();
607 genParticle_pythia != (*genVertex_pythia)->particles_in_const_end(); ++genParticle_pythia ) {
608 for ( HepMC::GenEvent::particle_iterator genParticle_output = passedEvt_output->particles_begin();
609 genParticle_output != passedEvt_output->particles_end(); ++genParticle_output ) {
610 if ( matchesGenParticle(*genParticle_output, *genParticle_pythia) ) {
612 genVertex_output->add_particle_in(*genParticle_output);
614 (*genParticle_output)->set_status(2);
620 for ( HepMC::GenVertex::particles_out_const_iterator genParticle_pythia = (*genVertex_pythia)->particles_out_const_begin();
621 genParticle_pythia != (*genVertex_pythia)->particles_out_const_end(); ++genParticle_pythia ) {
623 (*genParticle_pythia)->momentum(),
624 (*genParticle_pythia)->pdg_id(),
625 (*genParticle_pythia)->status(),
626 (*genParticle_pythia)->flow(),
627 (*genParticle_pythia)->polarization());
628 genParticle_output->suggest_barcode((*genParticle_pythia)->barcode());
630 genVertex_output->add_particle_out(genParticle_output);
634 passedEvt_output->add_vertex(genVertex_output);
640 for ( std::vector<reco::Candidate::LorentzVector>::const_iterator auxPhotonP4 = auxPhotonP4s.begin();
641 auxPhotonP4 != auxPhotonP4s.end(); ++auxPhotonP4 ) {
642 ppCollisionVtx->add_particle_out(
new HepMC::GenParticle((HepMC::FourVector)*auxPhotonP4, 22, 1, HepMC::Flow(), HepMC::Polarization(0,0)));
646 delete passedEvt_pythia;
654 for ( HepMC::GenEvent::particle_iterator genParticle = passedEvt_output->particles_begin();
655 genParticle != passedEvt_output->particles_end(); ++genParticle ) {
656 if ( (*genParticle)->end_vertex() ) (*genParticle)->set_status(2);
657 else (*genParticle)->set_status(1);
664 for ( std::vector<reco::Particle>::const_iterator
muon = muons.begin();
666 sumMuonP4_replaced +=
muon->p4();
670 for ( HepMC::GenEvent::particle_iterator genParticle = passedEvt_output->particles_begin();
671 genParticle != passedEvt_output->particles_end(); ++genParticle ) {
672 if ( (*genParticle)->status() != 1 )
continue;
673 if (
abs((*genParticle)->pdg_id()) == 12 ||
abs((*genParticle)->pdg_id()) == 14 ||
abs((*genParticle)->pdg_id()) == 16 )
continue;
674 sumMuonP4_embedded +=
reco::Candidate::LorentzVector((*genParticle)->momentum().px(), (*genParticle)->momentum().py(), (*genParticle)->momentum().pz(), (*genParticle)->momentum().e());
677 if ( (sumMuonP4_embedded.pt() - sumMuonP4_replaced.pt()) > (1.
e-3*sumMuonP4_replaced.pt()) ) {
679 <<
"Transverse momentum of embedded tau leptons = " << sumMuonP4_embedded.pt()
680 <<
" differs from transverse momentum of replaced muons = " << sumMuonP4_replaced.pt() <<
" !!" << std::endl;
683 std::auto_ptr<HepMC::GenEvent> passedEvt_output_ptr(passedEvt_output);
686 std::cout <<
" numEvents: tried = " << numEvents_tried <<
", passed = " << numEvents_passed << std::endl;
689 delete genVtx_output;
690 delete genEvt_output;
692 producer->
call_put(muonsBeforeRad,
"muonsBeforeRad");
693 producer->
call_put(muonsAfterRad,
"muonsAfterRad");
695 return passedEvt_output_ptr;
701 std::cout <<
"<ParticleReplacerZtautau::beginRun>: Initializing TAUOLA interface." << std::endl;
718 std::vector<double> muonPts;
719 std::vector<double> electronPts;
720 std::vector<double> tauJetPts;
721 std::vector<double> tauPts;
723 int genParticleIdx = 0;
724 for ( HepMC::GenEvent::particle_iterator genParticle = genEvt->particles_begin();
725 genParticle != genEvt->particles_end(); ++genParticle ) {
726 if (
abs((*genParticle)->pdg_id()) == 15 && (*genParticle)->end_vertex() ) {
728 std::queue<const HepMC::GenParticle*> decayProducts;
729 decayProducts.push(*genParticle);
730 enum { kELEC, kMU, kHAD };
732 int decayProductIdx = 0;
733 while ( !decayProducts.empty() && decayProductIdx < 100 ) {
736 std::cout <<
"decayProduct #" << (decayProductIdx + 1) <<
" (pdgId = " << decayProduct->pdg_id() <<
"):"
737 <<
" Pt = " << decayProduct->momentum().perp() <<
", eta = " << decayProduct->momentum().eta() <<
", phi = " << decayProduct->momentum().phi()
741 if ( !decayProduct->end_vertex() ) {
742 int absPdgId =
abs(decayProduct->pdg_id());
744 if ( absPdgId == 11 ) type = kELEC;
745 if ( absPdgId == 13 ) type = kMU;
747 HepMC::GenVertex* decayVtx = decayProduct->end_vertex();
748 for ( HepMC::GenVertex::particles_out_const_iterator daughter = decayVtx->particles_out_const_begin();
749 daughter != decayVtx->particles_out_const_end(); ++daughter ) {
750 decayProducts.push(*daughter);
756 double visPt = visP4.pt();
757 tauPts.push_back(visPt);
758 if ( type == kMU ) muonPts.push_back(visPt);
759 else if ( type == kELEC ) electronPts.push_back(visPt);
760 else if ( type == kHAD ) tauJetPts.push_back(visPt);
763 if ( type == kMU ) type_string =
"mu";
764 else if ( type == kELEC ) type_string =
"elec";
765 else if ( type == kHAD ) type_string =
"had";
766 std::cout <<
"visLeg #" << (genParticleIdx + 1) <<
" (type = " << type_string <<
"):"
767 <<
" Pt = " << visP4.pt() <<
", eta = " << visP4.eta() <<
", phi = " << visP4.phi()
768 <<
" (X = " << (visP4.energy()/(*genParticle)->momentum().e()) <<
")" << std::endl;
774 std::sort(tauPts.begin(), tauPts.end(), std::greater<double>());
775 std::sort(electronPts.begin(), electronPts.end(), std::greater<double>());
776 std::sort(muonPts.begin(), muonPts.end(), std::greater<double>());
777 std::sort(tauJetPts.begin(), tauJetPts.end(), std::greater<double>());
784 for ( std::vector<MinVisPtCutCombination>::const_iterator minVisPtCut =
minVisPtCuts_.begin();
788 bool passesMinVisCut =
true;
790 for ( std::vector<MinVisPtCut>::const_iterator
cut = minVisPtCut->cuts_.begin();
791 cut != minVisPtCut->cuts_.end(); ++
cut ) {
793 switch (
cut->type_ ) {
795 collection = &electronPts;
798 collection = &muonPts;
801 collection = &tauJetPts;
804 collection = &tauPts;
810 if (
cut->index_ >= collection->size() || (*collection)[
cut->index_] <
cut->threshold_ ) {
811 passesMinVisCut =
false;
818 if ( passesMinVisCut )
return true;
827 std::stack<HepMC::GenParticle*> genParticles_to_delete;
829 std::stack<HepMC::GenVertex*> genVertices_to_process;
830 std::stack<HepMC::GenVertex*> genVertices_to_delete;
832 for ( HepMC::GenVertex::particles_out_const_iterator genParticle = genVtx->particles_out_const_begin();
833 genParticle != genVtx->particles_out_const_end(); ++genParticle ) {
834 genParticles_to_delete.push(*genParticle);
835 if ( (*genParticle)->end_vertex() ) genVertices_to_process.push((*genParticle)->end_vertex());
838 while ( !genVertices_to_process.empty() ) {
839 HepMC::GenVertex* tempVtx = genVertices_to_process.top();
840 if ( tempVtx->particles_out_size() > 0 ) {
841 for ( HepMC::GenVertex::particles_out_const_iterator genParticle = tempVtx->particles_out_const_begin();
842 genParticle != tempVtx->particles_out_const_end(); ++genParticle ) {
843 if ( (*genParticle)->end_vertex() ) genVertices_to_process.push((*genParticle)->end_vertex());
847 genVertices_to_delete.push(tempVtx);
848 genVertices_to_process.pop();
851 while ( !genVertices_to_delete.empty() ) {
852 genEvt->remove_vertex(genVertices_to_delete.top());
853 genVertices_to_delete.pop();
856 while ( !genParticles_to_delete.empty() ) {
857 delete genVtx->remove_particle(genParticles_to_delete.top());
858 genParticles_to_delete.pop();
868 TVector3
p3(p4.px(), p4.py(), p4.pz());
869 p3.Rotate(angle, TVector3(axis.x(), axis.y(), axis.z()).Unit());
877 std::cout << label <<
": En = " << p4.E() <<
", Pt = " << p4.pt() <<
" (Px = " << p4.px() <<
", Py = " << p4.py() <<
"),"
878 <<
" theta = " << p4.theta() <<
" (eta = " << p4.eta() <<
"), phi = " << p4.phi() <<
", mass = " << p4.mass();
880 double angle = TMath::ACos((p4.px()*p4_ref->px() + p4.py()*p4_ref->py() + p4.pz()*p4_ref->pz())/(p4.P()*p4_ref->P()));
881 std::cout <<
" (angle wrt. ref = " << angle <<
")";
896 ROOT::Math::Boost boost_to_rf(zP4_lab.BoostToCM());
897 ROOT::Math::Boost boost_to_lab(boost_to_rf.Inverse());
905 std::cout <<
"before rotation:" << std::endl;
906 print(
"muon1(lab)", muon1P4_lab, &zP4_lab);
907 print(
"muon2(lab)", muon2P4_lab, &zP4_lab);
908 print(
"Z(lab)", zP4_lab);
909 print(
"muon1(rf)", muon1P4_rf, &zP4_lab);
910 print(
"muon2(rf)", muon2P4_rf, &zP4_lab);
911 print(
"Z(rf)", zP4_rf);
917 double u = randomEngine.flat();
918 rfRotationAngle_value = 2.*
TMath::Pi()*u;
921 muon1P4_rf =
rotate(muon1P4_rf, zP4_lab, rfRotationAngle_value);
922 muon2P4_rf =
rotate(muon2P4_rf, zP4_lab, rfRotationAngle_value);
925 double muon1P_rf2 =
square(muon1P4_rf.px()) +
square(muon1P4_rf.py()) +
square(muon1P4_rf.pz());
927 double lep1En_rf = 0.5*zP4_rf.E();
928 double lep1P_rf2 =
square(lep1En_rf) - lep1Mass2;
929 if ( lep1P_rf2 < 0. ) lep1P_rf2 = 0.;
930 float scaleFactor1 =
sqrt(lep1P_rf2/muon1P_rf2);
932 scaleFactor1*muon1P4_rf.px(), scaleFactor1*muon1P4_rf.py(), scaleFactor1*muon1P4_rf.pz(), lep1En_rf);
934 double muon2P_rf2 =
square(muon2P4_rf.px()) +
square(muon2P4_rf.py()) +
square(muon2P4_rf.pz());
936 double lep2En_rf = 0.5*zP4_rf.E();
937 double lep2P_rf2 =
square(lep2En_rf) - lep2Mass2;
938 if ( lep2P_rf2 < 0. ) lep2P_rf2 = 0.;
939 float scaleFactor2 =
sqrt(lep2P_rf2/muon2P_rf2);
941 scaleFactor2*muon2P4_rf.px(), scaleFactor2*muon2P4_rf.py(), scaleFactor2*muon2P4_rf.pz(), lep2En_rf);
947 std::cout <<
"after rotation:" << std::endl;
948 print(
"lep1(rf)", muon1P4_rf, &zP4_lab);
949 print(
"lep2(rf)", muon2P4_rf, &zP4_lab);
951 print(
"lep1(lab)", lep1P4_lab, &zP4_lab);
952 print(
"lep2(lab)", lep2P4_lab, &zP4_lab);
953 print(
"lep1+2(lab)", lep1p2_lab);
961 if ( !(fabs(zP4_lab.mass() - (lep1P4_lab + lep2P4_lab).mass()) < (1.
e-3*zP4_lab.mass()) &&
962 fabs(zP4_lab.pt() - (lep1P4_lab + lep2P4_lab).
pt()) < (1.
e-3*zP4_lab.pt())) )
964 <<
"The kinematics of muons and embedded electrons/taus differ by more than 0.1%:" << std::endl
965 <<
" mass(muon1 + muon2) = " << zP4_lab.mass() <<
", mass(lep1 + lep2) = " << (lep1P4_lab + lep2P4_lab).mass() << std::endl
966 <<
" Pt(muon1 + muon2) = " << zP4_lab.pt() <<
", Pt(lep1 + lep2) = " << (lep1P4_lab + lep2P4_lab).
pt() <<
" --> please CHECK !!" << std::endl;
968 muon1->
setP4(lep1P4_lab);
969 muon2->
setP4(lep2P4_lab);
988 ROOT::Math::Boost boost_to_rf(zP4_lab.BoostToCM());
989 ROOT::Math::Boost boost_to_lab(boost_to_rf.Inverse());
998 double muon1P_rf2 =
square(muon1P4_rf.px()) +
square(muon1P4_rf.py()) +
square(muon1P4_rf.pz());
1000 double tauEn_rf = 0.5*zP4_rf.E();
1001 double tauP_rf2 =
square(tauEn_rf) - tauMass2;
1002 if ( tauP_rf2 < 0. ) tauP_rf2 = 0.;
1003 float scaleFactor1 =
sqrt(tauP_rf2/muon1P_rf2)*(wMass/zP4_rf.mass());
1005 scaleFactor1*muon1P4_rf.px(), scaleFactor1*muon1P4_rf.py(), scaleFactor1*muon1P4_rf.pz(), tauEn_rf);
1007 double muon2P_rf2 =
square(muon2P4_rf.px()) +
square(muon2P4_rf.py()) +
square(muon2P4_rf.pz());
1009 assert(nuMass2 < 1.
e-4);
1010 double nuEn_rf = 0.5*zP4_rf.E();
1011 double nuP_rf2 =
square(nuEn_rf) - nuMass2;
1012 if ( nuP_rf2 < 0. ) nuP_rf2 = 0.;
1013 float scaleFactor2 =
sqrt(nuP_rf2/muon2P_rf2)*(wMass/zP4_rf.mass());
1015 scaleFactor2*muon2P4_rf.px(), scaleFactor2*muon2P4_rf.py(), scaleFactor2*muon2P4_rf.pz(), nuEn_rf);
1025 if ( !(
std::abs(zP4_lab.theta() - (tauP4_lab + nuP4_lab).
theta())/zP4_lab.theta() < 1.e-3 &&
1026 std::abs(zP4_lab.phi() - (tauP4_lab + nuP4_lab).
phi())/zP4_lab.phi() < 1.e-3) )
1028 <<
"The kinematics of muons and embedded tau/neutrino differ by more than 0.1%:" << std::endl
1029 <<
" mass(muon1 + muon2) = " << zP4_lab.mass() <<
", mass(lep1 + lep2) = " << (tauP4_lab + nuP4_lab).mass() << std::endl
1030 <<
" Pt(muon1 + muon2) = " << zP4_lab.pt() <<
", Pt(lep1 + lep2) = " << (tauP4_lab + nuP4_lab).
pt() <<
" --> please CHECK !!" << std::endl;
1032 muon1->
setP4(tauP4_lab);
1033 muon2->
setP4(nuP4_lab);
CLHEP::HepRandomEngine * randomEngine
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
CLHEP::HepRandomEngine * decayRandomEngine
std::string generatorMode_
~ParticleReplacerZtautau()
virtual void init(const edm::EventSetup &)
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 transformMuMu2LepLep(CLHEP::HepRandomEngine &randomEngine, reco::Particle *, reco::Particle *)
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_
edm::StreamID getStreamID() const
double deltaR(const T1 &t1, const T2 &t2)
void cleanEvent(HepMC::GenEvent *, HepMC::GenVertex *)
bool applyMuonRadiationCorrection_
virtual void statistics()
void transformMuMu2TauNu(reco::Particle *, reco::Particle *)
void call_put(T &product, const std::string &instanceName)
gen::TauolaInterfaceBase * tauola_
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)
bool isMatched(TrackingRecHit const &hit)
const Point & vertex() const
vertex position
void call_produces(const std::string &instanceName)
const double breitWignerWidthW
reco::Candidate::LorentzVector compFSR(const edm::StreamID &streamID, const reco::Candidate::LorentzVector &, int, const reco::Candidate::LorentzVector &, int &)
double deltaR(double eta1, double eta2, double phi1, double phi2)
ParticleReplacerZtautau(const edm::ParameterSet &)
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_
virtual HepMC::GenEvent * decay(HepMC::GenEvent *evt)
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &) const =0
Use this engine in event methods.
const double electronMass
math::XYZTLorentzVector LorentzVector
Lorentz vector.
void repairBarcodes(HepMC::GenEvent *)
int targetParticle2AbsPdgID_
unsigned int transformationMode_
double square(const double a)
#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
double py() const
y coordinate of momentum vector
void setStatus(int status)
set status word
virtual void setRandomEngine(CLHEP::HepRandomEngine *v)=0
int charge() const
electric charge
math::XYZTLorentzVector LorentzVector
Lorentz vector.
const double breitWignerWidthZ
GenMuonRadiationAlgorithm * muonRadiationAlgo_
T get(const Candidate &c)
std::vector< reco::Particle > ParticleCollection
T angle(T x1, T y1, T z1, T x2, T y2, T z2)