27 #include "TLorentzVector.h" 58 #include "CLHEP/Random/RandExponential.h" 67 class HepRandomEngine;
74 edm::EndRunProducer> {
84 virtual void endJob()
override;
89 void fill_lhe_from_mumu(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton,
lhef::HEPEUP &outlhe, CLHEP::HepRandomEngine* engine);
90 void fill_lhe_with_particle(
lhef::HEPEUP &outlhe, TLorentzVector &particle,
int pdgid,
double spin,
double ctau);
92 void transform_mumu_to_tautau(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton);
95 void mirror(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton);
96 void rotate180(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton);
104 const double tauMass_ = 1.77682;
121 produces<LHEEventProduct>();
122 produces<LHERunInfoProduct, edm::Transition::EndRun>();
123 produces<math::XYZTLorentzVectorD>(
"vertexPosition");
127 switchToMuonEmbedding_ = iConfig.
getParameter<
bool>(
"switchToMuonEmbedding");
134 if (lhe_ouputfile !=
""){
143 <<
"The EmbeddingLHEProducer requires the RandomNumberGeneratorService\n" 144 "which is not present in the configuration file. \n" 145 "You must add the service\n" 146 "in the configuration file or remove the modules that require it.";
173 iEvent.
getByToken(muonsCollection_, muonHandle);
177 iEvent.
getByToken(vertexCollection_ , coll_vertices);
179 TLorentzVector positiveLepton, negativeLepton;
180 bool mu_plus_found =
false;
181 bool mu_minus_found =
false;
191 if (
muon->charge() == 1 && !mu_plus_found)
193 assign_4vector(positiveLepton, &(*
muon), studyFSRmode_);
194 mu_plus_found =
true;
196 else if (
muon->charge() == -1 && !mu_minus_found)
198 assign_4vector(negativeLepton, &(*
muon), studyFSRmode_);
199 mu_minus_found =
true;
201 else if (mu_minus_found && mu_plus_found)
break;
203 mirror(positiveLepton,negativeLepton);
204 rotate180(positiveLepton,negativeLepton);
205 transform_mumu_to_tautau(positiveLepton,negativeLepton);
206 fill_lhe_from_mumu(positiveLepton,negativeLepton,hepeup,engine);
208 double originalXWGTUP_ = 1.;
209 std::unique_ptr<LHEEventProduct> product(
new LHEEventProduct(hepeup,originalXWGTUP_) );
211 if (write_lheout)
std::copy(product->begin(), product->end(), std::ostream_iterator<std::string>(
file));
215 std::unique_ptr<math::XYZTLorentzVectorD> vertex_position (
new math::XYZTLorentzVectorD(coll_vertices->at(0).x(),coll_vertices->at(0).y(),coll_vertices->at(0).z(),0.0));
216 iEvent.
put(
std::move(vertex_position),
"vertexPosition");
271 runInfo->addHeader(give_slha());
274 if (write_lheout)
std::copy(runInfo->begin(), runInfo->end(),std::ostream_iterator<std::string>(
file));
294 TLorentzVector
Z = positiveLepton + negativeLepton;
295 int leptonPDGID = switchToMuonEmbedding_ ? 13 : 15;
298 double tau_ctau0 = 8.71100e-02;
299 double tau_ctau_p = tau_ctau0 * CLHEP::RandExponential::shoot(engine);
301 double tau_ctau_n = tau_ctau0 * CLHEP::RandExponential::shoot(engine);
304 fill_lhe_with_particle(outlhe, Z,23,9.0, 0);
305 fill_lhe_with_particle(outlhe, positiveLepton,-leptonPDGID,1.0, tau_ctau_p);
306 fill_lhe_with_particle(outlhe, negativeLepton,leptonPDGID,-1.0, tau_ctau_n);
317 int particleindex = outlhe.
NUP;
320 outlhe.
PUP[particleindex][0] = particle.Px();
321 outlhe.
PUP[particleindex][1] = particle.Py();
322 outlhe.
PUP[particleindex][2] = particle.Pz();
323 outlhe.
PUP[particleindex][3] = particle.E();
324 outlhe.
PUP[particleindex][4] = particle.M();
327 outlhe.
VTIMUP[particleindex] = ctau;
329 outlhe.
ICOLUP[particleindex].first = 0;
330 outlhe.
ICOLUP[particleindex].second = 0;
334 outlhe.
MOTHUP[particleindex].first = 0;
335 outlhe.
MOTHUP[particleindex].second = 0;
336 outlhe.
ISTUP[particleindex] = 2;
341 outlhe.
MOTHUP[particleindex].first = 1;
342 outlhe.
MOTHUP[particleindex].second = 1;
344 outlhe.
ISTUP[particleindex] = 1;
359 if (switchToMuonEmbedding_)
return;
361 TLorentzVector
Z = positiveLepton + negativeLepton;
363 TVector3 boost_from_Z_to_LAB = Z.BoostVector();
364 TVector3 boost_from_LAB_to_Z = -Z.BoostVector();
367 positiveLepton.Boost(boost_from_LAB_to_Z);
368 negativeLepton.Boost(boost_from_LAB_to_Z);
371 double tau_mass_squared = tauMass_*tauMass_;
372 double tau_energy_squared = 0.25*Z.M2();
373 double tau_3momentum_squared = tau_energy_squared - tau_mass_squared;
374 if (tau_3momentum_squared < 0)
381 double scale =
std::sqrt(tau_3momentum_squared/positiveLepton.Vect().Mag2());
382 positiveLepton.SetPxPyPzE(scale*positiveLepton.Px(),scale*positiveLepton.Py(),scale*positiveLepton.Pz(),
std::sqrt(tau_energy_squared));
383 negativeLepton.SetPxPyPzE(scale*negativeLepton.Px(),scale*negativeLepton.Py(),scale*negativeLepton.Pz(),
std::sqrt(tau_energy_squared));
386 positiveLepton.Boost(boost_from_Z_to_LAB);
387 negativeLepton.Boost(boost_from_Z_to_LAB);
394 if(
"afterFSR" == FSRmode && muon->
genParticle() != 0)
397 Lepton.SetPxPyPzE(afterFSRMuon->
p4().px(),afterFSRMuon->
p4().py(),afterFSRMuon->
p4().pz(), afterFSRMuon->
p4().e());
399 else if (
"beforeFSR" == FSRmode && muon->
genParticle() != 0)
402 Lepton.SetPxPyPzE(beforeFSRMuon->
p4().px(),beforeFSRMuon->
p4().py(),beforeFSRMuon->
p4().pz(), beforeFSRMuon->
p4().e());
406 Lepton.SetPxPyPzE(muon->
p4().px(),muon->
p4().py(),muon->
p4().pz(), muon->
p4().e());
413 if(muon->
mother(0) == 0)
return muon;
420 if (!rotate180_)
return;
421 edm::LogInfo(
"TauEmbedding") <<
"Applying 180<C2><B0> rotation" ;
424 TLorentzVector
Z = positiveLepton + negativeLepton;
426 edm::LogInfo(
"TauEmbedding") <<
"MuMinus before. Pt: " << negativeLepton.Pt() <<
" Eta: " << negativeLepton.Eta() <<
" Phi: " << negativeLepton.Phi() <<
" Mass: " << negativeLepton.M();
428 TVector3 Z3 = Z.Vect();
429 TVector3 positiveLepton3 = positiveLepton.Vect();
430 TVector3 negativeLepton3 = negativeLepton.Vect();
432 TVector3 p3_perp = positiveLepton3 - positiveLepton3.Dot(Z3)/Z3.Dot(Z3)*Z3;
433 p3_perp = p3_perp.Unit();
435 positiveLepton3 -= 2*positiveLepton3.Dot(p3_perp)*p3_perp;
436 negativeLepton3 -= 2*negativeLepton3.Dot(p3_perp)*p3_perp;
438 positiveLepton.SetVect(positiveLepton3);
439 negativeLepton.SetVect(negativeLepton3);
441 edm::LogInfo(
"TauEmbedding") <<
"MuMinus after. Pt: " << negativeLepton.Pt() <<
" Eta: " << negativeLepton.Eta() <<
" Phi: " << negativeLepton.Phi() <<
" Mass: " << negativeLepton.M();
450 TLorentzVector
Z = positiveLepton + negativeLepton;
452 edm::LogInfo(
"TauEmbedding") <<
"MuMinus before. Pt: " << negativeLepton.Pt() <<
" Eta: " << negativeLepton.Eta() <<
" Phi: " << negativeLepton.Phi() <<
" Mass: " << negativeLepton.M() ;
454 TVector3 Z3 = Z.Vect();
455 TVector3 positiveLepton3 = positiveLepton.Vect();
456 TVector3 negativeLepton3 = negativeLepton.Vect();
458 TVector3 beam(0.,0.,1.);
459 TVector3 perpToZandBeam = Z3.Cross(beam).Unit();
461 positiveLepton3 -= 2*positiveLepton3.Dot(perpToZandBeam)*perpToZandBeam;
462 negativeLepton3 -= 2*negativeLepton3.Dot(perpToZandBeam)*perpToZandBeam;
464 positiveLepton.SetVect(positiveLepton3);
465 negativeLepton.SetVect(negativeLepton3);
467 edm::LogInfo(
"TauEmbedding") <<
"MuMinus after. Pt: " << negativeLepton.Pt() <<
" Eta: " << negativeLepton.Eta() <<
" Phi: " << negativeLepton.Phi() <<
" Mass: " << negativeLepton.M() ;
476 slhah.
addLine(
"######################################################################\n");
477 slhah.
addLine(
"## PARAM_CARD AUTOMATICALY GENERATED BY MG5 FOLLOWING UFO MODEL ####\n");
478 slhah.
addLine(
"######################################################################\n");
480 slhah.
addLine(
"## Width set on Auto will be computed following the information ##\n");
481 slhah.
addLine(
"## present in the decay.py files of the model. ##\n");
482 slhah.
addLine(
"## See arXiv:1402.1178 for more details. ##\n");
484 slhah.
addLine(
"######################################################################\n");
486 slhah.
addLine(
"###################################\n");
487 slhah.
addLine(
"## INFORMATION FOR MASS\n");
488 slhah.
addLine(
"###################################\n");
489 slhah.
addLine(
"Block mass \n");
490 slhah.
addLine(
" 6 1.730000e+02 # MT \n");
491 slhah.
addLine(
" 15 1.777000e+00 # MTA \n");
492 slhah.
addLine(
" 23 9.118800e+01 # MZ \n");
493 slhah.
addLine(
" 25 1.250000e+02 # MH \n");
494 slhah.
addLine(
"## Dependent parameters, given by model restrictions.\n");
495 slhah.
addLine(
"## Those values should be edited following the \n");
496 slhah.
addLine(
"## analytical expression. MG5 ignores those values \n");
497 slhah.
addLine(
"## but they are important for interfacing the output of MG5\n");
498 slhah.
addLine(
"## to external program such as Pythia.\n");
499 slhah.
addLine(
" 1 0.000000 # d : 0.0 \n");
500 slhah.
addLine(
" 2 0.000000 # u : 0.0 \n");
501 slhah.
addLine(
" 3 0.000000 # s : 0.0 \n");
502 slhah.
addLine(
" 4 0.000000 # c : 0.0 \n");
503 slhah.
addLine(
" 5 0.000000 # b : 0.0 \n");
504 slhah.
addLine(
" 11 0.000000 # e- : 0.0 \n");
505 slhah.
addLine(
" 12 0.000000 # ve : 0.0 \n");
506 slhah.
addLine(
" 13 0.000000 # mu- : 0.0 \n");
507 slhah.
addLine(
" 14 0.000000 # vm : 0.0 \n");
508 slhah.
addLine(
" 16 0.000000 # vt : 0.0 \n");
509 slhah.
addLine(
" 21 0.000000 # g : 0.0 \n");
510 slhah.
addLine(
" 22 0.000000 # a : 0.0 \n");
511 slhah.
addLine(
" 24 80.419002 # w+ : cmath.sqrt(MZ__exp__2/2. + cmath.sqrt(MZ__exp__4/4. - (aEW*cmath.pi*MZ__exp__2)/(Gf*sqrt__2))) \n");
513 slhah.
addLine(
"###################################\n");
514 slhah.
addLine(
"## INFORMATION FOR SMINPUTS\n");
515 slhah.
addLine(
"###################################\n");
516 slhah.
addLine(
"Block sminputs \n");
517 slhah.
addLine(
" 1 1.325070e+02 # aEWM1 \n");
518 slhah.
addLine(
" 2 1.166390e-05 # Gf \n");
519 slhah.
addLine(
" 3 1.180000e-01 # aS \n");
521 slhah.
addLine(
"###################################\n");
522 slhah.
addLine(
"## INFORMATION FOR WOLFENSTEIN\n");
523 slhah.
addLine(
"###################################\n");
524 slhah.
addLine(
"Block wolfenstein \n");
525 slhah.
addLine(
" 1 2.253000e-01 # lamWS \n");
526 slhah.
addLine(
" 2 8.080000e-01 # AWS \n");
527 slhah.
addLine(
" 3 1.320000e-01 # rhoWS \n");
528 slhah.
addLine(
" 4 3.410000e-01 # etaWS \n");
530 slhah.
addLine(
"###################################\n");
531 slhah.
addLine(
"## INFORMATION FOR YUKAWA\n");
532 slhah.
addLine(
"###################################\n");
533 slhah.
addLine(
"Block yukawa \n");
534 slhah.
addLine(
" 6 1.730000e+02 # ymt \n");
535 slhah.
addLine(
" 15 1.777000e+00 # ymtau \n");
537 slhah.
addLine(
"###################################\n");
538 slhah.
addLine(
"## INFORMATION FOR DECAY\n");
539 slhah.
addLine(
"###################################\n");
540 slhah.
addLine(
"DECAY 6 1.491500e+00 # WT \n");
541 slhah.
addLine(
"DECAY 15 2.270000e-12 # WTau \n");
542 slhah.
addLine(
"DECAY 23 2.441404e+00 # WZ \n");
543 slhah.
addLine(
"DECAY 24 2.047600e+00 # WW \n");
544 slhah.
addLine(
"DECAY 25 6.382339e-03 # WH \n");
545 slhah.
addLine(
"## Dependent parameters, given by model restrictions.\n");
546 slhah.
addLine(
"## Those values should be edited following the \n");
547 slhah.
addLine(
"## analytical expression. MG5 ignores those values \n");
548 slhah.
addLine(
"## but they are important for interfacing the output of MG5\n");
549 slhah.
addLine(
"## to external program such as Pythia.\n");
550 slhah.
addLine(
"DECAY 1 0.000000 # d : 0.0 \n");
551 slhah.
addLine(
"DECAY 2 0.000000 # u : 0.0 \n");
552 slhah.
addLine(
"DECAY 3 0.000000 # s : 0.0 \n");
553 slhah.
addLine(
"DECAY 4 0.000000 # c : 0.0 \n");
554 slhah.
addLine(
"DECAY 5 0.000000 # b : 0.0 \n");
555 slhah.
addLine(
"DECAY 11 0.000000 # e- : 0.0 \n");
556 slhah.
addLine(
"DECAY 12 0.000000 # ve : 0.0 \n");
557 slhah.
addLine(
"DECAY 13 0.000000 # mu- : 0.0 \n");
558 slhah.
addLine(
"DECAY 14 0.000000 # vm : 0.0 \n");
559 slhah.
addLine(
"DECAY 16 0.000000 # vt : 0.0 \n");
560 slhah.
addLine(
"DECAY 21 0.000000 # g : 0.0 \n");
561 slhah.
addLine(
"DECAY 22 0.000000 # a : 0.0\n");
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
void mirror(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton)
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double > > XYZTLorentzVectorD
Lorentz vector with cylindrical internal representation using pseudorapidity.
const reco::GenParticle * genParticle(size_t idx=0) const
bool getByToken(EDGetToken token, Handle< PROD > &result) const
#define DEFINE_FWK_MODULE(type)
virtual const Candidate * mother(size_type i=0) const =0
return pointer to mother
std::string studyFSRmode_
std::vector< double > VTIMUP
void transform_mumu_to_tautau(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton)
virtual void beginJob() override
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &)=0
Use this engine in event methods.
void fill_lhe_with_particle(lhef::HEPEUP &outlhe, TLorentzVector &particle, int pdgid, double spin, double ctau)
virtual void beginRunProduce(edm::Run &run, edm::EventSetup const &es) override
LHERunInfoProduct::Header give_slha()
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
std::vector< std::pair< int, int > > MOTHUP
void addDefault(ParameterSetDescription const &psetDescription)
const_iterator begin() const
virtual void endJob() override
virtual const LorentzVector & p4() const =0
four-momentum Lorentz vector
virtual int pdgId() const =0
PDG identifier.
void assign_4vector(TLorentzVector &Lepton, const pat::Muon *muon, std::string FSRmode)
std::vector< FiveVector > PUP
std::vector< double > SPINUP
bool switchToMuonEmbedding_
Abs< T >::type abs(const T &t)
virtual void endRunProduce(edm::Run &, edm::EventSetup const &) override
std::vector< double > XERRUP
std::vector< double > XMAXUP
void put(std::unique_ptr< PROD > product)
Put a new product.
void rotate180(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton)
edm::EDGetTokenT< edm::View< pat::Muon > > muonsCollection_
virtual void produce(edm::Event &, const edm::EventSetup &) override
const reco::Candidate * find_original_muon(const reco::Candidate *muon)
boost::indirect_iterator< typename seq_t::const_iterator > const_iterator
StreamID streamID() const
edm::EDGetTokenT< reco::VertexCollection > vertexCollection_
static const std::string & endOfFile()
const_iterator end() const
void fill_lhe_from_mumu(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton, lhef::HEPEUP &outlhe, CLHEP::HepRandomEngine *engine)
std::vector< double > XSECUP
virtual const LorentzVector & p4() const final
four-momentum Lorentz vector
Analysis-level muon class.
std::vector< std::pair< int, int > > ICOLUP
EmbeddingLHEProducer(const edm::ParameterSet &)