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);
149 if ( applyMuonRadiationCorrection_string !=
"" ) {
189 if ( genParticle1->pdg_id() == genParticle2->pdg_id() &&
190 TMath::Abs(genParticle1->momentum().e() - genParticle2->momentum().e()) < (1.
e-3*(genParticle1->momentum().e() + genParticle2->momentum().e())) &&
191 reco::deltaR(genParticle1->momentum(), genParticle2->momentum()) < 1.
e-3 )
197 bool matchesGenVertex(
const HepMC::GenVertex* genVertex1,
const HepMC::GenVertex* genVertex2,
bool checkIncomingParticles,
bool checkOutgoingParticles)
200 if ( !(
TMath::Abs(genVertex1->position().x() - genVertex2->position().x()) < 1.
e-3 &&
201 TMath::Abs(genVertex1->position().y() - genVertex2->position().y()) < 1.
e-3 &&
202 TMath::Abs(genVertex1->position().z() - genVertex2->position().z()) < 1.
e-3) )
return false;
205 if ( checkIncomingParticles ) {
206 for ( HepMC::GenVertex::particles_in_const_iterator genParticle1 = genVertex1->particles_in_const_begin();
207 genParticle1 != genVertex1->particles_in_const_end(); ++genParticle1 ) {
209 for ( HepMC::GenVertex::particles_in_const_iterator genParticle2 = genVertex2->particles_in_const_begin();
210 genParticle2 != genVertex2->particles_in_const_end() && !
isMatched; ++genParticle2 ) {
211 isMatched |= matchesGenParticle(*genParticle1, *genParticle2);
213 if ( !isMatched )
return false;
218 if ( checkOutgoingParticles ) {
219 for ( HepMC::GenVertex::particles_out_const_iterator genParticle1 = genVertex1->particles_out_const_begin();
220 genParticle1 != genVertex1->particles_out_const_end(); ++genParticle1 ) {
221 bool isMatched =
false;
222 for ( HepMC::GenVertex::particles_out_const_iterator genParticle2 = genVertex2->particles_out_const_begin();
223 genParticle2 != genVertex2->particles_out_const_end() && !
isMatched; ++genParticle2 ) {
224 isMatched |= matchesGenParticle(*genParticle1, *genParticle2);
226 if ( !isMatched )
return false;
239 <<
"The RandomNumberProducer module requires the RandomNumberGeneratorService\n"
240 <<
"which appears to be absent. Please add that service to your configuration\n"
241 <<
"or remove the modules that require it.\n";
247 <<
"ParticleReplacerZtautau does NOT support using primary vertex as the origin for taus !!\n";
253 std::vector<reco::Particle> embedParticles;
256 if ( muons.size() != 2 ) {
258 <<
"The decay mode Z->ll requires exactly two muons --> returning empty HepMC event !!" << std::endl;
259 return std::auto_ptr<HepMC::GenEvent>(0);
288 embedParticles.push_back(embedLepton1);
289 embedParticles.push_back(embedLepton2);
292 if ( muons.size() != 2 ) {
294 <<
"The decay mode W->taunu requires exactly two muons --> returning empty HepMC event !!" << std::endl;
295 return std::auto_ptr<HepMC::GenEvent>(0);
308 embedParticles.push_back(embedTau);
309 embedParticles.push_back(embedNu);
312 if ( muons.size() != 2 ) {
314 <<
"The decay mode W->taunu requires exactly two gen. leptons --> returning empty HepMC event !!" << std::endl;
315 return std::auto_ptr<HepMC::GenEvent>(0);
327 embedTau.setStatus(1);
328 embedParticles.push_back(embedTau);
332 embedParticles.push_back(embedNu);
335 if ( embedParticles.size() != 2 ){
337 <<
"The creation of gen. particles failed somehow --> returning empty HepMC event !!" << std::endl;
338 return std::auto_ptr<HepMC::GenEvent>(0);
341 HepMC::GenEvent* genEvt_output = 0;
343 HepMC::GenVertex* genVtx_output =
new HepMC::GenVertex();
345 HepMC::GenVertex* ppCollisionVtx = 0;
347 std::vector<reco::Candidate::LorentzVector> auxPhotonP4s;
351 genEvt_output =
new HepMC::GenEvent(*genEvt);
354 genVtx != genEvt_output->vertices_end(); ++genVtx ) {
356 if ( (*genVtx)->particles_out_size() <= 0 || (*genVtx)->particles_in_size() <= 0 )
continue;
358 bool foundMuon1 =
false;
359 bool foundMuon2 =
false;
361 for ( HepMC::GenVertex::particles_out_const_iterator genParticle = (*genVtx)->particles_out_const_begin();
362 genParticle != (*genVtx)->particles_out_const_end(); ++genParticle ) {
363 if ( (*genParticle)->pdg_id() == 13 ) foundMuon1 =
true;
364 if ( (*genParticle)->pdg_id() == -13 ) foundMuon2 =
true;
365 if ( (*genParticle)->pdg_id() == 23 ) foundZ =
true;
368 int motherPdgId = (*(*genVtx)->particles_in_const_begin())->pdg_id();
370 if ( ((*genVtx)->particles_out_size() == 2 &&
371 (*genVtx)->particles_in_size() > 0 &&
375 ((*genVtx)->particles_out_size() > 2 &&
376 (*genVtx)->particles_in_size() > 0 &&
381 genVtx_output = (*genVtx);
389 for ( HepMC::GenEvent::particle_iterator genParticle = genEvt_output->particles_begin();
390 genParticle != genEvt_output->particles_end(); ++genParticle ) {
391 (*genParticle)->set_status(0);
394 for ( std::vector<reco::Particle>::const_iterator embedParticle = embedParticles.begin();
395 embedParticle != embedParticles.end(); ++embedParticle ) {
398 for ( std::vector<reco::Particle>::const_iterator otherParticle = embedParticles.begin();
399 otherParticle != embedParticles.end(); ++otherParticle ) {
400 if (
deltaR(otherParticle->p4(), embedParticle->p4()) > 1.
e-3 ) sumOtherParticlesP4 += otherParticle->p4();
404 double embedParticlePx_corrected = embedParticle->px() + muonFSR.px();
405 double embedParticlePy_corrected = embedParticle->py() + muonFSR.py();
406 double embedParticlePz_corrected = embedParticle->pz() + muonFSR.pz();
407 double embedParticleEn_corrected =
sqrt(
square(embedParticlePx_corrected) +
square(embedParticlePy_corrected) +
square(embedParticlePz_corrected) +
square(embedParticle->mass()));
408 reco::Candidate::LorentzVector embedParticleP4_corrected(embedParticlePx_corrected, embedParticlePy_corrected, embedParticlePz_corrected, embedParticleEn_corrected);
409 genVtx_output->add_particle_out(
new HepMC::GenParticle((HepMC::FourVector)embedParticleP4_corrected, embedParticle->pdgId(), 1, HepMC::Flow(), HepMC::Polarization(0,0)));
415 ppCollisionVtx = (*genEvt_output->vertices_begin());
418 muonsBeforeRad->push_back(
reco::Particle(embedParticle->charge(), embedParticle->p4(), embedParticle->vertex(), embedParticle->pdgId()));
419 muonsAfterRad->push_back(
reco::Particle(embedParticle->charge(), embedParticleP4_corrected, embedParticle->vertex(), embedParticle->pdgId()));
421 genVtx_output->add_particle_out(
new HepMC::GenParticle((HepMC::FourVector)embedParticle->p4(), embedParticle->pdgId(), 1, HepMC::Flow(), HepMC::Polarization(0,0)));
426 double ppCollisionPosX = 0.;
427 double ppCollisionPosY = 0.;
428 double ppCollisionPosZ = 0.;
430 for ( std::vector<reco::Particle>::const_iterator embedParticle = embedParticles.begin();
431 embedParticle != embedParticles.end(); ++embedParticle ) {
435 genMotherP4 += embedParticle->p4();
437 ppCollisionPosX += embedParticleVertex.x();
438 ppCollisionPosY += embedParticleVertex.y();
439 ppCollisionPosZ += embedParticleVertex.z();
443 int numEmbedParticles = embedParticles.size();
444 if ( numEmbedParticles > 0 ) {
445 ppCollisionPosX /= numEmbedParticles;
446 ppCollisionPosY /= numEmbedParticles;
447 ppCollisionPosZ /= numEmbedParticles;
450 ppCollisionVtx =
new HepMC::GenVertex(HepMC::FourVector(ppCollisionPosX*10., ppCollisionPosY*10., ppCollisionPosZ*10., 0.));
453 ppCollisionVtx->add_particle_in(
new HepMC::GenParticle(HepMC::FourVector(0., 0., +protonPz, protonEn), 2212, 3));
454 ppCollisionVtx->add_particle_in(
new HepMC::GenParticle(HepMC::FourVector(0., 0., -protonPz, protonEn), 2212, 3));
456 HepMC::GenVertex* genMotherDecayVtx =
new HepMC::GenVertex(HepMC::FourVector(ppCollisionPosX*10., ppCollisionPosY*10., ppCollisionPosZ*10., 0.));
459 int chargedLepPdgId = embedParticles.begin()->pdgId();
460 int motherPdgId = -24*chargedLepPdgId/
std::abs(chargedLepPdgId);
461 genMother->set_pdg_id(motherPdgId);
464 ppCollisionVtx->add_particle_out(genMother);
466 genMotherDecayVtx->add_particle_in(genMother);
467 for ( std::vector<reco::Particle>::const_iterator embedParticle = embedParticles.begin();
468 embedParticle != embedParticles.end(); ++embedParticle ) {
471 for ( std::vector<reco::Particle>::const_iterator otherParticle = embedParticles.begin();
472 otherParticle != embedParticles.end(); ++otherParticle ) {
473 if (
deltaR(otherParticle->p4(), embedParticle->p4()) > 1.
e-3 ) sumOtherParticlesP4 += otherParticle->p4();
487 double embedParticlePx_corrected = embedParticle->px() + muonFSR.px();
488 double embedParticlePy_corrected = embedParticle->py() + muonFSR.py();
489 double embedParticlePz_corrected = embedParticle->pz() + muonFSR.pz();
490 double embedParticleEn_corrected =
sqrt(
square(embedParticlePx_corrected) +
square(embedParticlePy_corrected) +
square(embedParticlePz_corrected) +
square(embedParticle->mass()));
491 reco::Candidate::LorentzVector embedParticleP4_corrected(embedParticlePx_corrected, embedParticlePy_corrected, embedParticlePz_corrected, embedParticleEn_corrected);
497 genMotherDecayVtx->add_particle_out(
new HepMC::GenParticle((HepMC::FourVector)embedParticleP4_corrected, embedParticle->pdgId(), 1, HepMC::Flow(), HepMC::Polarization(0,0)));
502 muonsBeforeRad->push_back(
reco::Particle(embedParticle->charge(), embedParticleP4_corrected, embedParticle->vertex(), embedParticle->pdgId()));
503 muonsAfterRad->push_back(
reco::Particle(embedParticle->charge(), embedParticle->p4(), embedParticle->vertex(), embedParticle->pdgId()));
505 genMotherDecayVtx->add_particle_out(
new HepMC::GenParticle((HepMC::FourVector)embedParticle->p4(), embedParticle->pdgId(), 1, HepMC::Flow(), HepMC::Polarization(0,0)));
509 genEvt_output =
new HepMC::GenEvent();
510 genEvt_output->add_vertex(ppCollisionVtx);
511 genEvt_output->add_vertex(genMotherDecayVtx);
517 HepMC::GenEvent* passedEvt_output = 0;
519 unsigned int numEvents_tried = 0;
520 unsigned int numEvents_passed = 0;
524 HepMC::IO_HEPEVT
conv;
526 HepMC::GenEvent* tempEvt =
new HepMC::GenEvent(*genEvt_output);
530 <<
"Pythia is currently not supported !!\n";
532 conv.write_event(tempEvt);
538 assert(decayEvt == tempEvt);
541 bool passesVisPtCuts =
testEvent(tempEvt);
542 if ( passesVisPtCuts ) {
543 if ( !passedEvt_output ) passedEvt_output = tempEvt;
556 if ( !passedEvt_output ) {
558 <<
"Failed to create an event which satisfies the visible Pt cuts !!" << std::endl;
560 for ( std::vector<reco::Particle>::const_iterator
muon = muons.begin();
562 std::cout <<
" muon #" << idx <<
" (charge = " <<
muon->charge() <<
"): Pt = " <<
muon->pt() <<
", eta = " <<
muon->eta() <<
", phi = " <<
muon->phi() << std::endl;
565 return std::auto_ptr<HepMC::GenEvent>(0);
572 conv.write_event(passedEvt_output);
585 HepMC::GenEvent* passedEvt_pythia = conv.read_next_event();
593 for ( HepMC::GenEvent::vertex_const_iterator genVertex_pythia = passedEvt_pythia->vertices_begin();
594 genVertex_pythia != passedEvt_pythia->vertices_end(); ++genVertex_pythia ) {
595 bool isDecayVertex = ((*genVertex_pythia)->particles_in_size() >= 1 && (*genVertex_pythia)->particles_out_size() >= 2);
596 for ( HepMC::GenEvent::vertex_const_iterator genVertex_output = passedEvt_output->vertices_begin();
597 genVertex_output != passedEvt_output->vertices_end(); ++genVertex_output ) {
598 if ( matchesGenVertex(*genVertex_output, *genVertex_pythia,
true,
false) ) isDecayVertex =
false;
600 if ( !isDecayVertex )
continue;
604 HepMC::GenVertex* genVertex_output =
new HepMC::GenVertex((*genVertex_pythia)->position());
607 for ( HepMC::GenVertex::particles_in_const_iterator genParticle_pythia = (*genVertex_pythia)->particles_in_const_begin();
608 genParticle_pythia != (*genVertex_pythia)->particles_in_const_end(); ++genParticle_pythia ) {
609 for ( HepMC::GenEvent::particle_iterator genParticle_output = passedEvt_output->particles_begin();
610 genParticle_output != passedEvt_output->particles_end(); ++genParticle_output ) {
611 if ( matchesGenParticle(*genParticle_output, *genParticle_pythia) ) {
613 genVertex_output->add_particle_in(*genParticle_output);
615 (*genParticle_output)->set_status(2);
621 for ( HepMC::GenVertex::particles_out_const_iterator genParticle_pythia = (*genVertex_pythia)->particles_out_const_begin();
622 genParticle_pythia != (*genVertex_pythia)->particles_out_const_end(); ++genParticle_pythia ) {
624 (*genParticle_pythia)->momentum(),
625 (*genParticle_pythia)->pdg_id(),
626 (*genParticle_pythia)->status(),
627 (*genParticle_pythia)->flow(),
628 (*genParticle_pythia)->polarization());
629 genParticle_output->suggest_barcode((*genParticle_pythia)->barcode());
631 genVertex_output->add_particle_out(genParticle_output);
635 passedEvt_output->add_vertex(genVertex_output);
641 for ( std::vector<reco::Candidate::LorentzVector>::const_iterator auxPhotonP4 = auxPhotonP4s.begin();
642 auxPhotonP4 != auxPhotonP4s.end(); ++auxPhotonP4 ) {
643 ppCollisionVtx->add_particle_out(
new HepMC::GenParticle((HepMC::FourVector)*auxPhotonP4, 22, 1, HepMC::Flow(), HepMC::Polarization(0,0)));
647 delete passedEvt_pythia;
655 for ( HepMC::GenEvent::particle_iterator genParticle = passedEvt_output->particles_begin();
656 genParticle != passedEvt_output->particles_end(); ++genParticle ) {
657 if ( (*genParticle)->end_vertex() ) (*genParticle)->set_status(2);
658 else (*genParticle)->set_status(1);
665 for ( std::vector<reco::Particle>::const_iterator
muon = muons.begin();
667 sumMuonP4_replaced +=
muon->p4();
671 for ( HepMC::GenEvent::particle_iterator genParticle = passedEvt_output->particles_begin();
672 genParticle != passedEvt_output->particles_end(); ++genParticle ) {
673 if ( (*genParticle)->status() != 1 )
continue;
674 if (
abs((*genParticle)->pdg_id()) == 12 ||
abs((*genParticle)->pdg_id()) == 14 ||
abs((*genParticle)->pdg_id()) == 16 )
continue;
675 sumMuonP4_embedded +=
reco::Candidate::LorentzVector((*genParticle)->momentum().px(), (*genParticle)->momentum().py(), (*genParticle)->momentum().pz(), (*genParticle)->momentum().e());
678 if ( fabs(sumMuonP4_embedded.pt() - sumMuonP4_replaced.pt()) > (1.
e-3*sumMuonP4_replaced.pt()) ) {
680 <<
"Transverse momentum of embedded tau leptons = " << sumMuonP4_embedded.pt()
681 <<
" differs from transverse momentum of replaced muons = " << sumMuonP4_replaced.pt() <<
" !!" << std::endl;
684 std::auto_ptr<HepMC::GenEvent> passedEvt_output_ptr(passedEvt_output);
687 std::cout <<
" numEvents: tried = " << numEvents_tried <<
", passed = " << numEvents_passed << std::endl;
690 delete genVtx_output;
691 delete genEvt_output;
693 producer->
call_put(muonsBeforeRad,
"muonsBeforeRad");
694 producer->
call_put(muonsAfterRad,
"muonsAfterRad");
696 return passedEvt_output_ptr;
702 std::cout <<
"<ParticleReplacerZtautau::beginRun>: Initializing TAUOLA interface." << std::endl;
719 std::vector<double> muonPts;
720 std::vector<double> electronPts;
721 std::vector<double> tauJetPts;
722 std::vector<double> tauPts;
724 int genParticleIdx = 0;
725 for ( HepMC::GenEvent::particle_iterator genParticle = genEvt->particles_begin();
726 genParticle != genEvt->particles_end(); ++genParticle ) {
727 if (
abs((*genParticle)->pdg_id()) == 15 && (*genParticle)->end_vertex() ) {
729 std::queue<const HepMC::GenParticle*> decayProducts;
730 decayProducts.push(*genParticle);
731 enum { kELEC, kMU, kHAD };
733 int decayProductIdx = 0;
734 while ( !decayProducts.empty() && decayProductIdx < 100 ) {
737 std::cout <<
"decayProduct #" << (decayProductIdx + 1) <<
" (pdgId = " << decayProduct->pdg_id() <<
"):"
738 <<
" Pt = " << decayProduct->momentum().perp() <<
", eta = " << decayProduct->momentum().eta() <<
", phi = " << decayProduct->momentum().phi()
742 if ( !decayProduct->end_vertex() ) {
743 int absPdgId =
abs(decayProduct->pdg_id());
745 if ( absPdgId == 11 ) type = kELEC;
746 if ( absPdgId == 13 ) type = kMU;
748 HepMC::GenVertex* decayVtx = decayProduct->end_vertex();
749 for ( HepMC::GenVertex::particles_out_const_iterator daughter = decayVtx->particles_out_const_begin();
750 daughter != decayVtx->particles_out_const_end(); ++daughter ) {
751 decayProducts.push(*daughter);
757 double visPt = visP4.pt();
758 tauPts.push_back(visPt);
759 if ( type == kMU ) muonPts.push_back(visPt);
760 else if ( type == kELEC ) electronPts.push_back(visPt);
761 else if ( type == kHAD ) tauJetPts.push_back(visPt);
764 if ( type == kMU ) type_string =
"mu";
765 else if ( type == kELEC ) type_string =
"elec";
766 else if ( type == kHAD ) type_string =
"had";
767 std::cout <<
"visLeg #" << (genParticleIdx + 1) <<
" (type = " << type_string <<
"):"
768 <<
" Pt = " << visP4.pt() <<
", eta = " << visP4.eta() <<
", phi = " << visP4.phi()
769 <<
" (X = " << (visP4.energy()/(*genParticle)->momentum().e()) <<
")" << std::endl;
775 std::sort(tauPts.begin(), tauPts.end(), std::greater<double>());
776 std::sort(electronPts.begin(), electronPts.end(), std::greater<double>());
777 std::sort(muonPts.begin(), muonPts.end(), std::greater<double>());
778 std::sort(tauJetPts.begin(), tauJetPts.end(), std::greater<double>());
785 for ( std::vector<MinVisPtCutCombination>::const_iterator minVisPtCut =
minVisPtCuts_.begin();
789 bool passesMinVisCut =
true;
791 for ( std::vector<MinVisPtCut>::const_iterator
cut = minVisPtCut->cuts_.begin();
792 cut != minVisPtCut->cuts_.end(); ++
cut ) {
794 switch (
cut->type_ ) {
796 collection = &electronPts;
799 collection = &muonPts;
802 collection = &tauJetPts;
805 collection = &tauPts;
811 if (
cut->index_ >= collection->size() || (*collection)[
cut->index_] <
cut->threshold_ ) {
812 passesMinVisCut =
false;
819 if ( passesMinVisCut )
return true;
828 std::stack<HepMC::GenParticle*> genParticles_to_delete;
830 std::stack<HepMC::GenVertex*> genVertices_to_process;
831 std::stack<HepMC::GenVertex*> genVertices_to_delete;
833 for ( HepMC::GenVertex::particles_out_const_iterator genParticle = genVtx->particles_out_const_begin();
834 genParticle != genVtx->particles_out_const_end(); ++genParticle ) {
835 genParticles_to_delete.push(*genParticle);
836 if ( (*genParticle)->end_vertex() ) genVertices_to_process.push((*genParticle)->end_vertex());
839 while ( !genVertices_to_process.empty() ) {
840 HepMC::GenVertex* tempVtx = genVertices_to_process.top();
841 if ( tempVtx->particles_out_size() > 0 ) {
842 for ( HepMC::GenVertex::particles_out_const_iterator genParticle = tempVtx->particles_out_const_begin();
843 genParticle != tempVtx->particles_out_const_end(); ++genParticle ) {
844 if ( (*genParticle)->end_vertex() ) genVertices_to_process.push((*genParticle)->end_vertex());
848 genVertices_to_delete.push(tempVtx);
849 genVertices_to_process.pop();
852 while ( !genVertices_to_delete.empty() ) {
853 genEvt->remove_vertex(genVertices_to_delete.top());
854 genVertices_to_delete.pop();
857 while ( !genParticles_to_delete.empty() ) {
858 delete genVtx->remove_particle(genParticles_to_delete.top());
859 genParticles_to_delete.pop();
869 TVector3
p3(p4.px(), p4.py(), p4.pz());
870 p3.Rotate(angle, TVector3(axis.x(), axis.y(), axis.z()).Unit());
878 typedef ROOT::Math::DisplacementVector3D<ROOT::Math::Cartesian3D<double>, ROOT::Math::DefaultCoordinateSystemTag> RotVector3;
882 const RotVector3 pAxisOrtho = pAxis.Vect() - pAxis.Vect().Dot(zAxis.Vect().Unit()) * zAxis.Vect().Unit();
883 assert(fabs(pAxisOrtho.Dot(zAxis.Vect())) < 1
e-3);
887 const RotVector3
x = pAxisOrtho.Unit();
888 const RotVector3
z = zAxis.Vect().Unit();
889 const RotVector3
y = x.Cross(z).Unit();
892 const double ycomp1 = p4.Vect().Dot(y);
893 const RotVector3 y1 = p4.Vect() - 2 * ycomp1 *
y;
894 assert(fabs(ycomp1 + y1.Dot(y)) < 1
e-3);
902 std::cout << label <<
": En = " << p4.E() <<
", Pt = " << p4.pt() <<
" (Px = " << p4.px() <<
", Py = " << p4.py() <<
"),"
903 <<
" theta = " << p4.theta() <<
" (eta = " << p4.eta() <<
"), phi = " << p4.phi() <<
", mass = " << p4.mass();
905 double angle = TMath::ACos((p4.px()*p4_ref->px() + p4.py()*p4_ref->py() + p4.pz()*p4_ref->pz())/(p4.P()*p4_ref->P()));
906 std::cout <<
" (angle wrt. ref = " << angle <<
")";
921 ROOT::Math::Boost boost_to_rf(zP4_lab.BoostToCM());
922 ROOT::Math::Boost boost_to_lab(boost_to_rf.Inverse());
930 std::cout <<
"before rotation:" << std::endl;
931 print(
"muon1(lab)", muon1P4_lab, &zP4_lab);
932 print(
"muon2(lab)", muon2P4_lab, &zP4_lab);
933 print(
"Z(lab)", zP4_lab);
934 print(
"muon1(rf)", muon1P4_rf, &zP4_lab);
935 print(
"muon2(rf)", muon2P4_rf, &zP4_lab);
936 print(
"Z(rf)", zP4_rf);
942 double u = randomEngine.flat();
943 rfRotationAngle_value = 2.*
TMath::Pi()*u;
946 muon1P4_rf =
rotate(muon1P4_rf, zP4_lab, rfRotationAngle_value);
947 muon2P4_rf =
rotate(muon2P4_rf, zP4_lab, rfRotationAngle_value);
956 muon1P4_rf = mirror(muon1P4_rf, zP4_lab, pplus_rf);
957 muon2P4_rf = mirror(muon2P4_rf, zP4_lab, pplus_rf);
960 double muon1P_rf2 =
square(muon1P4_rf.px()) +
square(muon1P4_rf.py()) +
square(muon1P4_rf.pz());
962 double lep1En_rf = 0.5*zP4_rf.E();
963 double lep1P_rf2 =
square(lep1En_rf) - lep1Mass2;
964 if ( lep1P_rf2 < 0. ) lep1P_rf2 = 0.;
965 float scaleFactor1 =
sqrt(lep1P_rf2/muon1P_rf2);
967 scaleFactor1*muon1P4_rf.px(), scaleFactor1*muon1P4_rf.py(), scaleFactor1*muon1P4_rf.pz(), lep1En_rf);
969 double muon2P_rf2 =
square(muon2P4_rf.px()) +
square(muon2P4_rf.py()) +
square(muon2P4_rf.pz());
971 double lep2En_rf = 0.5*zP4_rf.E();
972 double lep2P_rf2 =
square(lep2En_rf) - lep2Mass2;
973 if ( lep2P_rf2 < 0. ) lep2P_rf2 = 0.;
974 float scaleFactor2 =
sqrt(lep2P_rf2/muon2P_rf2);
976 scaleFactor2*muon2P4_rf.px(), scaleFactor2*muon2P4_rf.py(), scaleFactor2*muon2P4_rf.pz(), lep2En_rf);
982 std::cout <<
"after rotation:" << std::endl;
983 print(
"lep1(rf)", muon1P4_rf, &zP4_lab);
984 print(
"lep2(rf)", muon2P4_rf, &zP4_lab);
986 print(
"lep1(lab)", lep1P4_lab, &zP4_lab);
987 print(
"lep2(lab)", lep2P4_lab, &zP4_lab);
988 print(
"lep1+2(lab)", lep1p2_lab);
996 if ( !(fabs(zP4_lab.mass() - (lep1P4_lab + lep2P4_lab).mass()) < (1.
e-3*zP4_lab.mass()) &&
997 fabs(zP4_lab.pt() - (lep1P4_lab + lep2P4_lab).
pt()) < (1.
e-3*zP4_lab.pt())) )
999 <<
"The kinematics of muons and embedded electrons/taus differ by more than 0.1%:" << std::endl
1000 <<
" mass(muon1 + muon2) = " << zP4_lab.mass() <<
", mass(lep1 + lep2) = " << (lep1P4_lab + lep2P4_lab).mass() << std::endl
1001 <<
" Pt(muon1 + muon2) = " << zP4_lab.pt() <<
", Pt(lep1 + lep2) = " << (lep1P4_lab + lep2P4_lab).
pt() <<
" --> please CHECK !!" << std::endl;
1003 muon1->
setP4(lep1P4_lab);
1004 muon2->
setP4(lep2P4_lab);
1023 ROOT::Math::Boost boost_to_rf(zP4_lab.BoostToCM());
1024 ROOT::Math::Boost boost_to_lab(boost_to_rf.Inverse());
1033 double muon1P_rf2 =
square(muon1P4_rf.px()) +
square(muon1P4_rf.py()) +
square(muon1P4_rf.pz());
1035 double tauEn_rf = 0.5*zP4_rf.E();
1036 double tauP_rf2 =
square(tauEn_rf) - tauMass2;
1037 if ( tauP_rf2 < 0. ) tauP_rf2 = 0.;
1038 float scaleFactor1 =
sqrt(tauP_rf2/muon1P_rf2)*(wMass/zP4_rf.mass());
1040 scaleFactor1*muon1P4_rf.px(), scaleFactor1*muon1P4_rf.py(), scaleFactor1*muon1P4_rf.pz(), tauEn_rf);
1042 double muon2P_rf2 =
square(muon2P4_rf.px()) +
square(muon2P4_rf.py()) +
square(muon2P4_rf.pz());
1045 double nuEn_rf = 0.5*zP4_rf.E();
1046 double nuP_rf2 =
square(nuEn_rf) - nuMass2;
1047 if ( nuP_rf2 < 0. ) nuP_rf2 = 0.;
1048 float scaleFactor2 =
sqrt(nuP_rf2/muon2P_rf2)*(wMass/zP4_rf.mass());
1050 scaleFactor2*muon2P4_rf.px(), scaleFactor2*muon2P4_rf.py(), scaleFactor2*muon2P4_rf.pz(), nuEn_rf);
1060 if ( !(
std::abs(zP4_lab.theta() - (tauP4_lab + nuP4_lab).
theta())/zP4_lab.theta() < 1.e-3 &&
1061 std::abs(zP4_lab.phi() - (tauP4_lab + nuP4_lab).
phi())/zP4_lab.phi() < 1.e-3) )
1063 <<
"The kinematics of muons and embedded tau/neutrino differ by more than 0.1%:" << std::endl
1064 <<
" mass(muon1 + muon2) = " << zP4_lab.mass() <<
", mass(lep1 + lep2) = " << (tauP4_lab + nuP4_lab).mass() << std::endl
1065 <<
" Pt(muon1 + muon2) = " << zP4_lab.pt() <<
", Pt(lep1 + lep2) = " << (tauP4_lab + nuP4_lab).
pt() <<
" --> please CHECK !!" << std::endl;
1067 muon1->
setP4(tauP4_lab);
1068 muon2->
setP4(nuP4_lab);
CLHEP::HepRandomEngine * randomEngine
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
double targetParticle2Mass_
edm::StreamID getStreamID() const
double deltaR(const T1 &t1, const T2 &t2)
double pz() const
z coordinate of momentum vector
void cleanEvent(HepMC::GenEvent *, HepMC::GenVertex *)
const LorentzVector & p4() const
four-momentum Lorentz vector
bool applyMuonRadiationCorrection_
virtual void statistics()
int pdgId() const
PDG identifier.
void transformMuMu2TauNu(reco::Particle *, reco::Particle *)
const Point & vertex() const
vertex position (overwritten by PF...)
T x() const
Cartesian x coordinate.
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)
void call_produces(const std::string &instanceName)
const double breitWignerWidthW
int charge() const
electric charge
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...
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
virtual void setRandomEngine(CLHEP::HepRandomEngine *v)=0
double px() const
x coordinate of momentum vector
math::XYZTLorentzVector LorentzVector
Lorentz vector.
void setStatus(int status)
set status word
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)