6 #include "HepMC/IO_HEPEVT.h"
11 void TXGIVE(
const char*,
int length);
16 #define TXGIVE_INIT txgive_init_
22 namespace ParticleReplacerVar{
28 generatorMode_(pset.getParameter<std::
string>(
"generatorMode")),
31 maxNumberOfAttempts_(pset.getUntrackedParameter<int>(
"maxNumberOfAttempts", 1000))
49 LogInfo(
"Replacer") <<
"won't do any transformation with the given mumu";
54 LogInfo(
"Replacer") <<
"will transform mumu into tautau";
59 LogInfo(
"Replacer") <<
"will transform mumu into taunu (as coming from a W boson)";
64 LogInfo(
"Replacer") <<
"Will transform mu-nu into tau-nu. No mass correction will be made.";
69 throw cms::Exception(
"ParticleReplacerClass") <<
"Unknown transformation mode!\n";
88 const char* startptr = minVisibleTransverseMomentumLine.c_str();
90 double d = strtod(startptr, &endptr);
91 if(*endptr ==
'\0' && endptr != startptr)
95 cuts[0].
pt_ = cuts[1].
pt_ = d;
97 minVisPtCuts_.push_back(std::vector<MinVisPtCut>(cuts, cuts+2));
104 pos = minVisibleTransverseMomentumLine.find(
';', prev);
105 if(
pos == std::string::npos)
pos = minVisibleTransverseMomentumLine.length();
107 std::string sub = minVisibleTransverseMomentumLine.substr(prev,
pos - prev);
108 std::vector<MinVisPtCut>
cuts;
109 const char* sub_c = sub.c_str();
110 while(*sub_c !=
'\0')
112 const char* sep = std::strchr(sub_c,
'_');
113 if(sep ==
NULL)
throw cms::Exception(
"Configuration") <<
"Minimum transverse parameter string must contain an underscore to separate type from pt threshold" << std::endl;
125 else throw cms::Exception(
"Configuration") <<
"'" << type <<
"' is not a valid type. Allowed values are elec1,mu1,had1,tau1,elec2,mu2,had2,tau2" << std::endl;
128 cut.
pt_ = strtod(sep + 1, &endptr);
129 if(endptr == sep + 1)
throw cms::Exception(
"Configuration") <<
"No pt threshold given" << std::endl;
139 if(fileService_.isAvailable()) {
140 outTree = fileService_->make<TTree>(
"event_generation",
"This tree stores information about the event generation");
145 if(!rng.isAvailable()) {
147 <<
"The RandomNumberProducer module requires the RandomNumberGeneratorService\n"
148 "which appears to be absent. Please add that service to your configuration\n"
149 "or remove the modules that require it." << std::endl;
170 using namespace HepMC;
173 throw cms::Exception(
"Configuration") <<
"ParticleReplacerClass does NOT support using primary vertex as the origin for taus" << std::endl;
175 HepMC::GenEvent * evt=0;
177 GenVertex * zvtx =
new GenVertex();
183 std::vector<reco::Particle> particles;
190 LogError(
"Replacer") <<
"the decay mode Z->mumu requires exactly two muons, aborting processing";
191 return std::auto_ptr<HepMC::GenEvent>(0);
201 particles.push_back(tau1);
202 particles.push_back(tau2);
209 LogError(
"Replacer") <<
"the decay mode Z->tautau requires exactly two muons, aborting processing";
210 return std::auto_ptr<HepMC::GenEvent>(0);
221 particles.push_back(tau1);
222 particles.push_back(tau2);
229 LogError(
"Replacer") <<
"the decay mode Z->tautau requires exactly two muons, aborting processing";
230 return std::auto_ptr<HepMC::GenEvent>(0);
241 particles.push_back(tau1);
242 particles.push_back(tau2);
249 LogError(
"Replacer") <<
"transformation mode mu-nu ->tau-nu - wrong input";
250 return std::auto_ptr<HepMC::GenEvent>(0);
255 int targetParticlePdgIDNu_ = 16;
260 muon1.
px()*muon1.
px()+
261 muon1.
py()*muon1.
py()+
268 particles.push_back(tau1);
273 particles.push_back(nutau);
280 if (particles.size()==0)
282 LogError(
"Replacer") <<
"the creation of the new particles failed somehow";
283 return std::auto_ptr<HepMC::GenEvent>(0);
287 LogInfo(
"Replacer") << particles.size() <<
" particles found, continue processing";
294 evt =
new HepMC::GenEvent(*genEvt);
298 GenVertex * vtx=(*p);
300 if ( vtx->particles_out_size()<=0 || vtx->particles_in_size()<=0)
303 bool temp_muon1=
false,temp_muon2=
false,temp_z=
false;
304 for (GenVertex::particles_out_const_iterator it = vtx->particles_out_const_begin(); it!=vtx->particles_out_const_end(); it++)
306 if ((*it)->pdg_id()==13) temp_muon1=
true;
307 if ((*it)->pdg_id()==-13) temp_muon2=
true;
308 if ((*it)->pdg_id()==23) temp_z=
true;
311 int mother_pdg=(*vtx->particles_in_const_begin())->pdg_id();
313 if ((vtx->particles_out_size()==2 && vtx->particles_in_size()>0
317 || (vtx->particles_out_size()>2 && vtx->particles_in_size()>0
319 && temp_muon1 && temp_muon2 && temp_z ))
329 for (GenEvent::particle_iterator it=evt->particles_begin();it!=evt->particles_end();it++)
330 (*it)->set_status(0);
332 for (std::vector<reco::Particle>::const_iterator it=particles.begin();it!=particles.end();it++)
334 zvtx->add_particle_out(
new HepMC::GenParticle((FourVector)it->p4(), it->pdgId(), 1, Flow(), Polarization(0,0)));
341 for (std::vector<reco::Particle>::const_iterator it=particles.begin();it!=particles.end();it++)
342 mother_particle_p4+=it->p4();
346 GenVertex* startVtx =
new GenVertex(FourVector(production_point.x()*10,production_point.y()*10,production_point.z()*10,0));
347 startVtx->add_particle_in(
new GenParticle( FourVector(0,0,7000,7000), 2212, 3 ) );
348 startVtx->add_particle_in(
new GenParticle( FourVector(0,0,-7000,7000), 2212, 3 ) );
350 GenVertex * decayvtx =
new GenVertex(FourVector(production_point.x()*10,production_point.y()*10,production_point.z()*10,0));
354 int muPDG = particles.begin()->pdgId();
356 mother_particle->set_pdg_id(
id);
359 startVtx->add_particle_out(mother_particle);
360 decayvtx->add_particle_in(mother_particle);
361 evt =
new HepMC::GenEvent();
362 for (std::vector<reco::Particle>::const_iterator it=particles.begin();it!=particles.end();it++)
365 decayvtx->add_particle_out(
new HepMC::GenParticle((FourVector)it->p4(), it->pdgId(), 1, Flow(), Polarization(0,0)));
368 evt->add_vertex(startVtx);
369 evt->add_vertex(decayvtx);
373 HepMC::GenEvent * retevt = 0;
374 HepMC::GenEvent * tempevt = 0;
379 unsigned int cntVisPt_all = 0;
380 unsigned int cntVisPt_pass = 0;
382 HepMC::IO_HEPEVT
conv;
388 LogError(
"Replacer") <<
"Pythia is currently not supported!";
389 return std::auto_ptr<HepMC::GenEvent>(evt);
394 conv.write_event(evt);
411 tried = cntVisPt_all;
414 std::cout <<
" " << cntVisPt_pass <<
"\t" << cntVisPt_all <<
"\n";
417 LogError(
"Replacer") <<
"failed to create an event which satisfies the minimum visible transverse momentum cuts ";
420 return std::auto_ptr<HepMC::GenEvent>(0);
428 for (GenEvent::particle_iterator it=retevt->particles_begin();it!=retevt->particles_end();it++)
430 if ((*it)->end_vertex())
431 (*it)->set_status(2);
433 (*it)->set_status(1);
437 std::auto_ptr<HepMC::GenEvent>
ret(retevt);
464 using namespace HepMC;
470 std::vector<double> mus;
471 std::vector<double> elecs;
472 std::vector<double> hads;
473 std::vector<double> taus;
475 for (GenEvent::particle_iterator it=evt->particles_begin();it!=evt->particles_end();it++)
477 if (
abs((*it)->pdg_id())==15 && (*it)->end_vertex())
479 FourVector vis_mom();
481 std::queue<const GenParticle *> decaying_particles;
482 decaying_particles.push(*it);
484 enum { ELEC, MU, HAD }
type = HAD;
485 while(!decaying_particles.empty() && (++t < 30))
488 decaying_particles.pop();
490 if (!front->end_vertex())
493 if (pdgId>10 && pdgId!=12 && pdgId!=14 && pdgId!=16)
496 if(pdgId == 11)
type = ELEC;
497 if(pdgId == 13)
type = MU;
501 GenVertex * temp_vert = front->end_vertex();
502 for (GenVertex::particles_out_const_iterator it2=temp_vert->particles_out_const_begin();it2!=temp_vert->particles_out_const_end();it2++)
503 decaying_particles.push((*it2));
507 double vis_pt = visible_momentum.pt();
508 taus.push_back(vis_pt);
509 if(
type == MU) mus.push_back(vis_pt);
510 if(
type == ELEC) elecs.push_back(vis_pt);
511 if(
type == HAD) hads.push_back(vis_pt);
515 std::sort(taus.begin(), taus.end(), std::greater<double>());
516 std::sort(elecs.begin(), elecs.end(), std::greater<double>());
517 std::sort(mus.begin(), mus.end(), std::greater<double>());
518 std::sort(hads.begin(), hads.end(), std::greater<double>());
522 std::vector<MinVisPtCut>::const_iterator iter2;
523 for(iter2 = iter->begin(); iter2 != iter->end(); ++iter2)
532 default: assert(
false);
break;
536 if(iter2->index_ >= collection->size() || (*collection)[iter2->index_] < iter2->pt_)
541 if(iter2 == iter->end())
545 LogInfo(
"Replacer") <<
"refusing the event as the sum of the visible transverse momenta is too small\n";
551 using namespace HepMC;
554 using namespace reco;
556 stack<HepMC::GenParticle *> deleteParticle;
558 stack<GenVertex *> deleteVertex;
559 stack<GenVertex *> queueVertex;
561 if (vtx->particles_out_size()>0)
563 for (GenVertex::particles_out_const_iterator it=vtx->particles_out_const_begin();it!=vtx->particles_out_const_end();it++)
565 deleteParticle.push(*it);
566 if ((*it)->end_vertex())
567 queueVertex.push((*it)->end_vertex());
571 while (!queueVertex.empty())
573 GenVertex * temp_vtx=queueVertex.top();
574 if (temp_vtx->particles_out_size()>0)
576 for (GenVertex::particles_out_const_iterator it=temp_vtx->particles_out_const_begin();it!=temp_vtx->particles_out_const_end();it++)
578 if ((*it)->end_vertex())
579 queueVertex.push((*it)->end_vertex());
583 deleteVertex.push(queueVertex.top());
587 while (!deleteVertex.empty())
589 evt->remove_vertex(deleteVertex.top());
593 while (!deleteParticle.empty())
595 delete vtx->remove_particle(deleteParticle.top());
596 deleteParticle.pop();
599 while (!deleteVertex.empty())
601 while (!queueVertex.empty())
609 using namespace HepMC;
616 while (!(*it)->suggest_barcode(-1*(++max_barc)))
621 for (GenEvent::particle_iterator it=evt->particles_begin(), next;it!=evt->particles_end();it=next)
624 while (!(*it)->suggest_barcode(++max_barc))
633 using namespace reco;
640 ROOT::Math::Boost booster(z_momentum.BoostToCM());
641 ROOT::Math::Boost invbooster(booster.Inverse());
650 double muonxb_mom2 = muon1b.x()*muon1b.x() + muon1b.y()*muon1b.y() + muon1b.z() * muon1b.z();
651 double tauxb_mom2 = 0.25 * Zb.t() * Zb.t() - tau_mass2;
653 float scaling1 =
sqrt(tauxb_mom2 / muonxb_mom2);
654 float scaling2 = scaling1;
656 float tauEnergy= Zb.t() / 2.;
658 if (tauEnergy*tauEnergy<tau_mass2)
673 assert(
std::abs((muon1_momentum+muon2_momentum).mass()-(tau1_mom+tau2_mom).mass())/(muon1_momentum+muon2_momentum).mass()<0.001);
674 assert(
std::abs((muon1_momentum+muon2_momentum).pt()-(tau1_mom+tau2_mom).pt())/(muon1_momentum+muon2_momentum).pt()<0.001);
676 muon1->
setP4(tau1_mom);
677 muon2->
setP4(tau2_mom);
691 using namespace reco;
698 ROOT::Math::Boost booster(z_momentum.BoostToCM());
699 ROOT::Math::Boost invbooster(booster.Inverse());
703 const double breitWignerWidth_Z = 2.4952;
704 const double breitWignerWidth_W = 2.141;
705 const double knownMass_W = 80.398;
706 const double knownMass_Z = 91.1876;
708 double Wb_mass = ( Zb.mass() - knownMass_Z ) * ( breitWignerWidth_W / breitWignerWidth_Z ) + knownMass_W;
709 std::cout <<
"Wb_mass: " << Wb_mass <<
"\n";
716 double muonxb_mom2 = muon1b.x()*muon1b.x() + muon1b.y()*muon1b.y() + muon1b.z() * muon1b.z();
717 double tauxb_mom2 = 0.25 * Zb.t() * Zb.t() - tau_mass2;
719 float scaling1 =
sqrt(tauxb_mom2 / muonxb_mom2) * Wb_mass/Zb.mass();
720 float scaling2 = scaling1;
722 float tauEnergy= Zb.t() / 2.;
724 if (tauEnergy*tauEnergy<tau_mass2)
730 std::cout <<
"muon1b_momentum: " << muon1b <<
"\n";
731 std::cout <<
"muon2b_momentum: " << muon2b <<
"\n";
733 std::cout <<
"tau1b_momentum: " << tau1b_mom <<
"\n";
734 std::cout <<
"tau2b_momentum: " << tau2b_mom <<
"\n";
736 std::cout <<
"zb_momentum: " << Zb <<
"\n";
737 std::cout <<
"wb_momentum: " << (tau1b_mom+tau2b_mom) <<
"\n";
744 assert((muon1b.phi()-tau1b_mom.phi())/muon1b.phi()<0.001);
745 assert((muon2b.phi()-tau2b_mom.phi())/muon2b.phi()<0.001);
746 assert((muon1b.theta()-tau1b_mom.theta())/muon1b.theta()<0.001);
747 assert((muon2b.theta()-tau2b_mom.theta())/muon2b.theta()<0.001);
761 part1->
setP4(tau1_mom);
762 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)
virtual void SetDecayRandomEngine(CLHEP::HepRandomEngine *decayRandomEngine)
void setP4(const LorentzVector &p4)
set 4-momentum
virtual const LorentzVector & p4() const GCC11_FINAL
four-momentum Lorentz vector
virtual void init(const edm::EventSetup &)
static HepMC::IO_HEPEVT conv
virtual const Point & vertex() const
vertex position (overwritten by PF...)
virtual int pdgId() const GCC11_FINAL
PDG identifier.
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
virtual void statistics()
int pdgId() const
PDG identifier.
std::vector< Muon > MuonCollection
collection of Muon objects
virtual void beginRun(const edm::Run &iRun, const edm::EventSetup &iSetup)
PtEtaPhiMLorentzVectorD PtEtaPhiMLorentzVector
Lorentz vector with cartesian internal representation.
gen::TauolaInterfaceBase * tauola_
enum ParticleReplacerClass::MinVisPtCut::@520 type_
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
virtual HepMC::GenEvent * decay(HepMC::GenEvent *evt)
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)
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_
T get(const Candidate &c)