7 #include "HepMC/IO_HEPEVT.h"
10 #define TXGIVE txgive_
12 void TXGIVE(
const char*,
int length);
17 #define TXGIVE_INIT txgive_init_
25 generatorMode_(pset.getParameter<std::
string>(
"generatorMode")),
29 maxNumberOfAttempts_(pset.getUntrackedParameter<int>(
"maxNumberOfAttempts", 1000))
47 LogInfo(
"Replacer") <<
"won't do any transformation with the given mumu";
52 LogInfo(
"Replacer") <<
"will transform mumu into tautau";
57 LogInfo(
"Replacer") <<
"will transform mumu into taunu (as coming from a W boson)";
62 LogInfo(
"Replacer") <<
"Will transform mu-nu into tau-nu. No mass correction will be made.";
67 throw cms::Exception(
"ParticleReplacerClass") <<
"Unknown transformation mode!\n";
86 const char* startptr = minVisibleTransverseMomentumLine.c_str();
88 double d = strtod(startptr, &endptr);
89 if(*endptr ==
'\0' && endptr != startptr)
93 cuts[0].
pt_ = cuts[1].
pt_ = d;
95 minVisPtCuts_.push_back(std::vector<MinVisPtCut>(cuts, cuts+2));
102 pos = minVisibleTransverseMomentumLine.find(
';', prev);
103 if(
pos == std::string::npos)
pos = minVisibleTransverseMomentumLine.length();
105 std::string sub = minVisibleTransverseMomentumLine.substr(prev,
pos - prev);
106 std::vector<MinVisPtCut>
cuts;
107 const char* sub_c = sub.c_str();
108 while(*sub_c !=
'\0')
110 const char* sep = std::strchr(sub_c,
'_');
111 if(sep ==
NULL)
throw cms::Exception(
"Configuration") <<
"Minimum transverse parameter string must contain an underscore to separate type from pt threshold" << std::endl;
123 else throw cms::Exception(
"Configuration") <<
"'" << type <<
"' is not a valid type. Allowed values are elec1,mu1,had1,tau1,elec2,mu2,had2,tau2" << std::endl;
126 cut.
pt_ = strtod(sep + 1, &endptr);
127 if(endptr == sep + 1)
throw cms::Exception(
"Configuration") <<
"No pt threshold given" << std::endl;
137 if(fileService_.isAvailable()) {
138 outTree = fileService_->make<TTree>(
"event_generation",
"This tree stores information about the event generation");
143 if(!rng.isAvailable()) {
145 <<
"The RandomNumberProducer module requires the RandomNumberGeneratorService\n"
146 "which appears to be absent. Please add that service to your configuration\n"
147 "or remove the modules that require it." << std::endl;
168 using namespace HepMC;
171 throw cms::Exception(
"Configuration") <<
"ParticleReplacerClass does NOT support using primary vertex as the origin for taus" << std::endl;
173 HepMC::GenEvent * evt=0;
175 GenVertex * zvtx =
new GenVertex();
181 std::vector<reco::Particle> particles;
188 LogError(
"Replacer") <<
"the decay mode Z->mumu requires exactly two muons, aborting processing";
189 return std::auto_ptr<HepMC::GenEvent>(0);
199 particles.push_back(tau1);
200 particles.push_back(tau2);
207 LogError(
"Replacer") <<
"the decay mode Z->tautau requires exactly two muons, aborting processing";
208 return std::auto_ptr<HepMC::GenEvent>(0);
219 particles.push_back(tau1);
220 particles.push_back(tau2);
227 LogError(
"Replacer") <<
"the decay mode Z->tautau requires exactly two muons, aborting processing";
228 return std::auto_ptr<HepMC::GenEvent>(0);
239 particles.push_back(tau1);
240 particles.push_back(tau2);
247 LogError(
"Replacer") <<
"transformation mode mu-nu ->tau-nu - wrong input";
248 return std::auto_ptr<HepMC::GenEvent>(0);
253 int targetParticlePdgIDNu_ = 16;
258 muon1.
px()*muon1.
px()+
259 muon1.
py()*muon1.
py()+
266 particles.push_back(tau1);
271 particles.push_back(nutau);
278 if (particles.size()==0)
280 LogError(
"Replacer") <<
"the creation of the new particles failed somehow";
281 return std::auto_ptr<HepMC::GenEvent>(0);
285 LogInfo(
"Replacer") << particles.size() <<
" particles found, continue processing";
292 evt =
new HepMC::GenEvent(*genEvt);
296 GenVertex * vtx=(*p);
298 if ( vtx->particles_out_size()<=0 || vtx->particles_in_size()<=0)
301 bool temp_muon1=
false,temp_muon2=
false,temp_z=
false;
302 for (GenVertex::particles_out_const_iterator it = vtx->particles_out_const_begin(); it!=vtx->particles_out_const_end(); it++)
304 if ((*it)->pdg_id()==13) temp_muon1=
true;
305 if ((*it)->pdg_id()==-13) temp_muon2=
true;
306 if ((*it)->pdg_id()==23) temp_z=
true;
309 int mother_pdg=(*vtx->particles_in_const_begin())->pdg_id();
311 if ((vtx->particles_out_size()==2 && vtx->particles_in_size()>0
315 || (vtx->particles_out_size()>2 && vtx->particles_in_size()>0
317 && temp_muon1 && temp_muon2 && temp_z ))
327 for (GenEvent::particle_iterator it=evt->particles_begin();it!=evt->particles_end();it++)
328 (*it)->set_status(0);
330 for (std::vector<reco::Particle>::const_iterator it=particles.begin();it!=particles.end();it++)
332 zvtx->add_particle_out(
new HepMC::GenParticle((FourVector)it->p4(), it->pdgId(), 1, Flow(), Polarization(0,0)));
339 for (std::vector<reco::Particle>::const_iterator it=particles.begin();it!=particles.end();it++)
340 mother_particle_p4+=it->p4();
344 GenVertex* startVtx =
new GenVertex(FourVector(production_point.x()*10,production_point.y()*10,production_point.z()*10,0));
345 startVtx->add_particle_in(
new GenParticle( FourVector(0,0,7000,7000), 2212, 3 ) );
346 startVtx->add_particle_in(
new GenParticle( FourVector(0,0,-7000,7000), 2212, 3 ) );
348 GenVertex * decayvtx =
new GenVertex(FourVector(production_point.x()*10,production_point.y()*10,production_point.z()*10,0));
352 int muPDG = particles.begin()->pdgId();
354 mother_particle->set_pdg_id(
id);
357 startVtx->add_particle_out(mother_particle);
358 decayvtx->add_particle_in(mother_particle);
359 evt =
new HepMC::GenEvent();
360 for (std::vector<reco::Particle>::const_iterator it=particles.begin();it!=particles.end();it++)
363 decayvtx->add_particle_out(
new HepMC::GenParticle((FourVector)it->p4(), it->pdgId(), 1, Flow(), Polarization(0,0)));
366 evt->add_vertex(startVtx);
367 evt->add_vertex(decayvtx);
371 HepMC::GenEvent * retevt = 0;
372 HepMC::GenEvent * tempevt = 0;
377 unsigned int cntVisPt_all = 0;
378 unsigned int cntVisPt_pass = 0;
380 HepMC::IO_HEPEVT
conv;
386 LogError(
"Replacer") <<
"Pythia is currently not supported!";
387 return std::auto_ptr<HepMC::GenEvent>(evt);
392 conv.write_event(evt);
409 tried = cntVisPt_all;
412 std::cout <<
" " << cntVisPt_pass <<
"\t" << cntVisPt_all <<
"\n";
415 LogError(
"Replacer") <<
"failed to create an event which satisfies the minimum visible transverse momentum cuts ";
418 return std::auto_ptr<HepMC::GenEvent>(0);
426 for (GenEvent::particle_iterator it=retevt->particles_begin();it!=retevt->particles_end();it++)
428 if ((*it)->end_vertex())
429 (*it)->set_status(2);
431 (*it)->set_status(1);
435 std::auto_ptr<HepMC::GenEvent>
ret(retevt);
462 using namespace HepMC;
468 std::vector<double> mus;
469 std::vector<double> elecs;
470 std::vector<double> hads;
471 std::vector<double> taus;
473 for (GenEvent::particle_iterator it=evt->particles_begin();it!=evt->particles_end();it++)
475 if (
abs((*it)->pdg_id())==15 && (*it)->end_vertex())
477 FourVector vis_mom();
479 std::queue<const GenParticle *> decaying_particles;
480 decaying_particles.push(*it);
482 enum { ELEC, MU, HAD }
type = HAD;
483 while(!decaying_particles.empty() && (++t < 30))
486 decaying_particles.pop();
488 if (!front->end_vertex())
491 if (pdgId>10 && pdgId!=12 && pdgId!=14 && pdgId!=16)
494 if(pdgId == 11)
type = ELEC;
495 if(pdgId == 13)
type = MU;
499 GenVertex * temp_vert = front->end_vertex();
500 for (GenVertex::particles_out_const_iterator it2=temp_vert->particles_out_const_begin();it2!=temp_vert->particles_out_const_end();it2++)
501 decaying_particles.push((*it2));
505 double vis_pt = visible_momentum.pt();
506 taus.push_back(vis_pt);
507 if(
type == MU) mus.push_back(vis_pt);
508 if(
type == ELEC) elecs.push_back(vis_pt);
509 if(
type == HAD) hads.push_back(vis_pt);
513 std::sort(taus.begin(), taus.end(), std::greater<double>());
514 std::sort(elecs.begin(), elecs.end(), std::greater<double>());
515 std::sort(mus.begin(), mus.end(), std::greater<double>());
516 std::sort(hads.begin(), hads.end(), std::greater<double>());
520 std::vector<MinVisPtCut>::const_iterator iter2;
521 for(iter2 = iter->begin(); iter2 != iter->end(); ++iter2)
530 default: assert(
false);
break;
534 if(iter2->index_ >= collection->size() || (*collection)[iter2->index_] < iter2->pt_)
539 if(iter2 == iter->end())
543 LogInfo(
"Replacer") <<
"refusing the event as the sum of the visible transverse momenta is too small\n";
549 using namespace HepMC;
552 using namespace reco;
554 stack<HepMC::GenParticle *> deleteParticle;
556 stack<GenVertex *> deleteVertex;
557 stack<GenVertex *> queueVertex;
559 if (vtx->particles_out_size()>0)
561 for (GenVertex::particles_out_const_iterator it=vtx->particles_out_const_begin();it!=vtx->particles_out_const_end();it++)
563 deleteParticle.push(*it);
564 if ((*it)->end_vertex())
565 queueVertex.push((*it)->end_vertex());
569 while (!queueVertex.empty())
571 GenVertex * temp_vtx=queueVertex.top();
572 if (temp_vtx->particles_out_size()>0)
574 for (GenVertex::particles_out_const_iterator it=temp_vtx->particles_out_const_begin();it!=temp_vtx->particles_out_const_end();it++)
576 if ((*it)->end_vertex())
577 queueVertex.push((*it)->end_vertex());
581 deleteVertex.push(queueVertex.top());
585 while (!deleteVertex.empty())
587 evt->remove_vertex(deleteVertex.top());
591 while (!deleteParticle.empty())
593 delete vtx->remove_particle(deleteParticle.top());
594 deleteParticle.pop();
597 while (!deleteVertex.empty())
599 while (!queueVertex.empty())
607 using namespace HepMC;
614 while (!(*it)->suggest_barcode(-1*(++max_barc)))
619 for (GenEvent::particle_iterator it=evt->particles_begin(), next;it!=evt->particles_end();it=next)
622 while (!(*it)->suggest_barcode(++max_barc))
631 using namespace reco;
638 ROOT::Math::Boost booster(z_momentum.BoostToCM());
639 ROOT::Math::Boost invbooster(booster.Inverse());
648 double muonxb_mom2 = muon1b.x()*muon1b.x() + muon1b.y()*muon1b.y() + muon1b.z() * muon1b.z();
649 double tauxb_mom2 = 0.25 * Zb.t() * Zb.t() - tau_mass2;
651 float scaling1 =
sqrt(tauxb_mom2 / muonxb_mom2);
652 float scaling2 = scaling1;
654 float tauEnergy= Zb.t() / 2.;
656 if (tauEnergy*tauEnergy<tau_mass2)
671 assert(
std::abs((muon1_momentum+muon2_momentum).mass()-(tau1_mom+tau2_mom).mass())/(muon1_momentum+muon2_momentum).mass()<0.001);
672 assert(
std::abs((muon1_momentum+muon2_momentum).pt()-(tau1_mom+tau2_mom).pt())/(muon1_momentum+muon2_momentum).pt()<0.001);
674 muon1->
setP4(tau1_mom);
675 muon2->
setP4(tau2_mom);
689 using namespace reco;
696 ROOT::Math::Boost booster(z_momentum.BoostToCM());
697 ROOT::Math::Boost invbooster(booster.Inverse());
701 const double breitWignerWidth_Z = 2.4952;
702 const double breitWignerWidth_W = 2.141;
703 const double knownMass_W = 80.398;
704 const double knownMass_Z = 91.1876;
706 double Wb_mass = ( Zb.mass() - knownMass_Z ) * ( breitWignerWidth_W / breitWignerWidth_Z ) + knownMass_W;
707 std::cout <<
"Wb_mass: " << Wb_mass <<
"\n";
714 double muonxb_mom2 = muon1b.x()*muon1b.x() + muon1b.y()*muon1b.y() + muon1b.z() * muon1b.z();
715 double tauxb_mom2 = 0.25 * Zb.t() * Zb.t() - tau_mass2;
717 float scaling1 =
sqrt(tauxb_mom2 / muonxb_mom2) * Wb_mass/Zb.mass();
718 float scaling2 = scaling1;
720 float tauEnergy= Zb.t() / 2.;
722 if (tauEnergy*tauEnergy<tau_mass2)
728 std::cout <<
"muon1b_momentum: " << muon1b <<
"\n";
729 std::cout <<
"muon2b_momentum: " << muon2b <<
"\n";
731 std::cout <<
"tau1b_momentum: " << tau1b_mom <<
"\n";
732 std::cout <<
"tau2b_momentum: " << tau2b_mom <<
"\n";
734 std::cout <<
"zb_momentum: " << Zb <<
"\n";
735 std::cout <<
"wb_momentum: " << (tau1b_mom+tau2b_mom) <<
"\n";
742 assert((muon1b.phi()-tau1b_mom.phi())/muon1b.phi()<0.001);
743 assert((muon2b.phi()-tau2b_mom.phi())/muon2b.phi()<0.001);
744 assert((muon1b.theta()-tau1b_mom.theta())/muon1b.theta()<0.001);
745 assert((muon2b.theta()-tau2b_mom.theta())/muon2b.theta()<0.001);
759 part1->
setP4(tau1_mom);
760 part2->
setP4(tau2_mom);
T getParameter(std::string const &) const
double targetParticleMass_
T getUntrackedParameter(std::string const &, T const &) const
void repairBarcodes(HepMC::GenEvent *evt)
gen::TauolaInterface * tauola_
void setP4(const LorentzVector &p4)
set 4-momentum
HepMC::GenEvent * decay(HepMC::GenEvent *)
virtual const LorentzVector & p4() const GCC11_FINAL
four-momentum Lorentz vector
static HepMC::IO_HEPEVT conv
virtual const Point & vertex() const
vertex position (overwritten by PF...)
virtual int pdgId() const GCC11_FINAL
PDG identifier.
void setPSet(const edm::ParameterSet &)
ParticleReplacerClass(const edm::ParameterSet &, bool)
bool testEvent(HepMC::GenEvent *evt)
const LorentzVector & p4() const
four-momentum Lorentz vector
virtual double pz() const GCC11_FINAL
z coordinate of momentum vector
virtual double py() const GCC11_FINAL
y coordinate of momentum vector
int pdgId() const
PDG identifier.
std::vector< Muon > MuonCollection
collection of Muon objects
enum ParticleReplacerClass::MinVisPtCut::@519 type_
virtual void beginRun(const edm::Run &iRun, const edm::EventSetup &iSetup)
PtEtaPhiMLorentzVectorD PtEtaPhiMLorentzVector
Lorentz vector with cartesian internal representation.
virtual double px() const GCC11_FINAL
x coordinate of momentum vector
math::XYZPoint Point
point in the space
std::string generatorMode_
virtual int charge() const GCC11_FINAL
electric charge
unsigned int transformationMode_
math::XYZTLorentzVector LorentzVector
Lorentz vector.
void cleanEvent(HepMC::GenEvent *evt, HepMC::GenVertex *vtx)
void transformMuMu2TauNu(reco::Particle *muon1, reco::Particle *muon2)
transform a muon pair into tau nu (as coming from a W boson)
void tauola_(int *, int *)
void init(const edm::EventSetup &)
VertexRefVector::iterator vertex_iterator
iterator over a vector of references to Vertex objects in the same collection
CLHEP::HepRandomEngine * decayRandomEngine
void transformMuMu2TauTau(reco::Particle *muon1, reco::Particle *muon2)
transform a muon pair into a tau pair
virtual std::auto_ptr< HepMC::GenEvent > produce(const reco::MuonCollection &muons, const reco::Vertex *pvtx=0, const HepMC::GenEvent *genEvt=0)
math::XYZTLorentzVector LorentzVector
Lorentz vector.
void setStatus(int status)
set status word
std::vector< std::vector< MinVisPtCut > > minVisPtCuts_