27 #include "TLorentzVector.h" 57 #include "CLHEP/Random/RandExponential.h" 66 class HepRandomEngine;
73 edm::EndRunProducer> {
83 virtual void endJob()
override;
88 void fill_lhe_from_mumu(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton,
lhef::HEPEUP &outlhe, CLHEP::HepRandomEngine* engine);
89 void fill_lhe_with_particle(
lhef::HEPEUP &outlhe, TLorentzVector &particle,
int pdgid,
double spin,
double ctau);
91 void transform_mumu_to_tautau(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton);
94 void mirror(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton);
95 void rotate180(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton);
103 const double tauMass_ = 1.77682;
120 produces<LHEEventProduct>();
121 produces<LHERunInfoProduct, edm::InRun>();
122 produces<math::XYZTLorentzVectorD>(
"vertexPosition");
126 switchToMuonEmbedding_ = iConfig.
getParameter<
bool>(
"switchToMuonEmbedding");
133 if (lhe_ouputfile !=
""){
142 <<
"The EmbeddingLHEProducer requires the RandomNumberGeneratorService\n" 143 "which is not present in the configuration file. \n" 144 "You must add the service\n" 145 "in the configuration file or remove the modules that require it.";
172 iEvent.
getByToken(muonsCollection_, muonHandle);
176 iEvent.
getByToken(vertexCollection_ , coll_vertices);
178 TLorentzVector positiveLepton, negativeLepton;
179 bool mu_plus_found =
false;
180 bool mu_minus_found =
false;
190 if (
muon->charge() == 1 && !mu_plus_found)
192 assign_4vector(positiveLepton, &(*
muon), studyFSRmode_);
193 mu_plus_found =
true;
195 else if (
muon->charge() == -1 && !mu_minus_found)
197 assign_4vector(negativeLepton, &(*
muon), studyFSRmode_);
198 mu_minus_found =
true;
200 else if (mu_minus_found && mu_plus_found)
break;
202 mirror(positiveLepton,negativeLepton);
203 rotate180(positiveLepton,negativeLepton);
204 transform_mumu_to_tautau(positiveLepton,negativeLepton);
205 fill_lhe_from_mumu(positiveLepton,negativeLepton,hepeup,engine);
207 double originalXWGTUP_ = 1.;
208 std::unique_ptr<LHEEventProduct> product(
new LHEEventProduct(hepeup,originalXWGTUP_) );
210 if (write_lheout)
std::copy(product->begin(), product->end(), std::ostream_iterator<std::string>(
file));
214 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));
215 iEvent.
put(
std::move(vertex_position),
"vertexPosition");
270 runInfo->addHeader(give_slha());
273 if (write_lheout)
std::copy(runInfo->begin(), runInfo->end(),std::ostream_iterator<std::string>(
file));
293 TLorentzVector
Z = positiveLepton + negativeLepton;
294 int leptonPDGID = switchToMuonEmbedding_ ? 13 : 15;
297 double tau_ctau0 = 8.71100e-02;
298 double tau_ctau_p = tau_ctau0 * CLHEP::RandExponential::shoot(engine);
300 double tau_ctau_n = tau_ctau0 * CLHEP::RandExponential::shoot(engine);
303 fill_lhe_with_particle(outlhe, Z,23,9.0, 0);
304 fill_lhe_with_particle(outlhe, positiveLepton,-leptonPDGID,1.0, tau_ctau_p);
305 fill_lhe_with_particle(outlhe, negativeLepton,leptonPDGID,-1.0, tau_ctau_n);
316 int particleindex = outlhe.
NUP;
319 outlhe.
PUP[particleindex][0] = particle.Px();
320 outlhe.
PUP[particleindex][1] = particle.Py();
321 outlhe.
PUP[particleindex][2] = particle.Pz();
322 outlhe.
PUP[particleindex][3] = particle.E();
323 outlhe.
PUP[particleindex][4] = particle.M();
326 outlhe.
VTIMUP[particleindex] = ctau;
328 outlhe.
ICOLUP[particleindex].first = 0;
329 outlhe.
ICOLUP[particleindex].second = 0;
333 outlhe.
MOTHUP[particleindex].first = 0;
334 outlhe.
MOTHUP[particleindex].second = 0;
335 outlhe.
ISTUP[particleindex] = 2;
340 outlhe.
MOTHUP[particleindex].first = 1;
341 outlhe.
MOTHUP[particleindex].second = 1;
343 outlhe.
ISTUP[particleindex] = 1;
358 if (switchToMuonEmbedding_)
return;
360 TLorentzVector
Z = positiveLepton + negativeLepton;
362 TVector3 boost_from_Z_to_LAB = Z.BoostVector();
363 TVector3 boost_from_LAB_to_Z = -Z.BoostVector();
366 positiveLepton.Boost(boost_from_LAB_to_Z);
367 negativeLepton.Boost(boost_from_LAB_to_Z);
370 double tau_mass_squared = tauMass_*tauMass_;
371 double tau_energy_squared = 0.25*Z.M2();
372 double tau_3momentum_squared = tau_energy_squared - tau_mass_squared;
373 if (tau_3momentum_squared < 0)
380 double scale =
std::sqrt(tau_3momentum_squared/positiveLepton.Vect().Mag2());
381 positiveLepton.SetPxPyPzE(scale*positiveLepton.Px(),scale*positiveLepton.Py(),scale*positiveLepton.Pz(),
std::sqrt(tau_energy_squared));
382 negativeLepton.SetPxPyPzE(scale*negativeLepton.Px(),scale*negativeLepton.Py(),scale*negativeLepton.Pz(),
std::sqrt(tau_energy_squared));
385 positiveLepton.Boost(boost_from_Z_to_LAB);
386 negativeLepton.Boost(boost_from_Z_to_LAB);
393 if(
"afterFSR" == FSRmode && muon->
genParticle() != 0)
396 Lepton.SetPxPyPzE(afterFSRMuon->
p4().px(),afterFSRMuon->
p4().py(),afterFSRMuon->
p4().pz(), afterFSRMuon->
p4().e());
398 else if (
"beforeFSR" == FSRmode && muon->
genParticle() != 0)
401 Lepton.SetPxPyPzE(beforeFSRMuon->
p4().px(),beforeFSRMuon->
p4().py(),beforeFSRMuon->
p4().pz(), beforeFSRMuon->
p4().e());
405 Lepton.SetPxPyPzE(muon->
p4().px(),muon->
p4().py(),muon->
p4().pz(), muon->
p4().e());
412 if(muon->
mother(0) == 0)
return muon;
419 if (!rotate180_)
return;
420 edm::LogInfo(
"TauEmbedding") <<
"Applying 180<C2><B0> rotation" ;
423 TLorentzVector
Z = positiveLepton + negativeLepton;
425 edm::LogInfo(
"TauEmbedding") <<
"MuMinus before. Pt: " << negativeLepton.Pt() <<
" Eta: " << negativeLepton.Eta() <<
" Phi: " << negativeLepton.Phi() <<
" Mass: " << negativeLepton.M();
427 TVector3 Z3 = Z.Vect();
428 TVector3 positiveLepton3 = positiveLepton.Vect();
429 TVector3 negativeLepton3 = negativeLepton.Vect();
431 TVector3 p3_perp = positiveLepton3 - positiveLepton3.Dot(Z3)/Z3.Dot(Z3)*Z3;
432 p3_perp = p3_perp.Unit();
434 positiveLepton3 -= 2*positiveLepton3.Dot(p3_perp)*p3_perp;
435 negativeLepton3 -= 2*negativeLepton3.Dot(p3_perp)*p3_perp;
437 positiveLepton.SetVect(positiveLepton3);
438 negativeLepton.SetVect(negativeLepton3);
440 edm::LogInfo(
"TauEmbedding") <<
"MuMinus after. Pt: " << negativeLepton.Pt() <<
" Eta: " << negativeLepton.Eta() <<
" Phi: " << negativeLepton.Phi() <<
" Mass: " << negativeLepton.M();
449 TLorentzVector
Z = positiveLepton + negativeLepton;
451 edm::LogInfo(
"TauEmbedding") <<
"MuMinus before. Pt: " << negativeLepton.Pt() <<
" Eta: " << negativeLepton.Eta() <<
" Phi: " << negativeLepton.Phi() <<
" Mass: " << negativeLepton.M() ;
453 TVector3 Z3 = Z.Vect();
454 TVector3 positiveLepton3 = positiveLepton.Vect();
455 TVector3 negativeLepton3 = negativeLepton.Vect();
457 TVector3 beam(0.,0.,1.);
458 TVector3 perpToZandBeam = Z3.Cross(beam).Unit();
460 positiveLepton3 -= 2*positiveLepton3.Dot(perpToZandBeam)*perpToZandBeam;
461 negativeLepton3 -= 2*negativeLepton3.Dot(perpToZandBeam)*perpToZandBeam;
463 positiveLepton.SetVect(positiveLepton3);
464 negativeLepton.SetVect(negativeLepton3);
466 edm::LogInfo(
"TauEmbedding") <<
"MuMinus after. Pt: " << negativeLepton.Pt() <<
" Eta: " << negativeLepton.Eta() <<
" Phi: " << negativeLepton.Phi() <<
" Mass: " << negativeLepton.M() ;
475 slhah.
addLine(
"######################################################################\n");
476 slhah.
addLine(
"## PARAM_CARD AUTOMATICALY GENERATED BY MG5 FOLLOWING UFO MODEL ####\n");
477 slhah.
addLine(
"######################################################################\n");
479 slhah.
addLine(
"## Width set on Auto will be computed following the information ##\n");
480 slhah.
addLine(
"## present in the decay.py files of the model. ##\n");
481 slhah.
addLine(
"## See arXiv:1402.1178 for more details. ##\n");
483 slhah.
addLine(
"######################################################################\n");
485 slhah.
addLine(
"###################################\n");
486 slhah.
addLine(
"## INFORMATION FOR MASS\n");
487 slhah.
addLine(
"###################################\n");
488 slhah.
addLine(
"Block mass \n");
489 slhah.
addLine(
" 6 1.730000e+02 # MT \n");
490 slhah.
addLine(
" 15 1.777000e+00 # MTA \n");
491 slhah.
addLine(
" 23 9.118800e+01 # MZ \n");
492 slhah.
addLine(
" 25 1.250000e+02 # MH \n");
493 slhah.
addLine(
"## Dependent parameters, given by model restrictions.\n");
494 slhah.
addLine(
"## Those values should be edited following the \n");
495 slhah.
addLine(
"## analytical expression. MG5 ignores those values \n");
496 slhah.
addLine(
"## but they are important for interfacing the output of MG5\n");
497 slhah.
addLine(
"## to external program such as Pythia.\n");
498 slhah.
addLine(
" 1 0.000000 # d : 0.0 \n");
499 slhah.
addLine(
" 2 0.000000 # u : 0.0 \n");
500 slhah.
addLine(
" 3 0.000000 # s : 0.0 \n");
501 slhah.
addLine(
" 4 0.000000 # c : 0.0 \n");
502 slhah.
addLine(
" 5 0.000000 # b : 0.0 \n");
503 slhah.
addLine(
" 11 0.000000 # e- : 0.0 \n");
504 slhah.
addLine(
" 12 0.000000 # ve : 0.0 \n");
505 slhah.
addLine(
" 13 0.000000 # mu- : 0.0 \n");
506 slhah.
addLine(
" 14 0.000000 # vm : 0.0 \n");
507 slhah.
addLine(
" 16 0.000000 # vt : 0.0 \n");
508 slhah.
addLine(
" 21 0.000000 # g : 0.0 \n");
509 slhah.
addLine(
" 22 0.000000 # a : 0.0 \n");
510 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");
512 slhah.
addLine(
"###################################\n");
513 slhah.
addLine(
"## INFORMATION FOR SMINPUTS\n");
514 slhah.
addLine(
"###################################\n");
515 slhah.
addLine(
"Block sminputs \n");
516 slhah.
addLine(
" 1 1.325070e+02 # aEWM1 \n");
517 slhah.
addLine(
" 2 1.166390e-05 # Gf \n");
518 slhah.
addLine(
" 3 1.180000e-01 # aS \n");
520 slhah.
addLine(
"###################################\n");
521 slhah.
addLine(
"## INFORMATION FOR WOLFENSTEIN\n");
522 slhah.
addLine(
"###################################\n");
523 slhah.
addLine(
"Block wolfenstein \n");
524 slhah.
addLine(
" 1 2.253000e-01 # lamWS \n");
525 slhah.
addLine(
" 2 8.080000e-01 # AWS \n");
526 slhah.
addLine(
" 3 1.320000e-01 # rhoWS \n");
527 slhah.
addLine(
" 4 3.410000e-01 # etaWS \n");
529 slhah.
addLine(
"###################################\n");
530 slhah.
addLine(
"## INFORMATION FOR YUKAWA\n");
531 slhah.
addLine(
"###################################\n");
532 slhah.
addLine(
"Block yukawa \n");
533 slhah.
addLine(
" 6 1.730000e+02 # ymt \n");
534 slhah.
addLine(
" 15 1.777000e+00 # ymtau \n");
536 slhah.
addLine(
"###################################\n");
537 slhah.
addLine(
"## INFORMATION FOR DECAY\n");
538 slhah.
addLine(
"###################################\n");
539 slhah.
addLine(
"DECAY 6 1.491500e+00 # WT \n");
540 slhah.
addLine(
"DECAY 15 2.270000e-12 # WTau \n");
541 slhah.
addLine(
"DECAY 23 2.441404e+00 # WZ \n");
542 slhah.
addLine(
"DECAY 24 2.047600e+00 # WW \n");
543 slhah.
addLine(
"DECAY 25 6.382339e-03 # WH \n");
544 slhah.
addLine(
"## Dependent parameters, given by model restrictions.\n");
545 slhah.
addLine(
"## Those values should be edited following the \n");
546 slhah.
addLine(
"## analytical expression. MG5 ignores those values \n");
547 slhah.
addLine(
"## but they are important for interfacing the output of MG5\n");
548 slhah.
addLine(
"## to external program such as Pythia.\n");
549 slhah.
addLine(
"DECAY 1 0.000000 # d : 0.0 \n");
550 slhah.
addLine(
"DECAY 2 0.000000 # u : 0.0 \n");
551 slhah.
addLine(
"DECAY 3 0.000000 # s : 0.0 \n");
552 slhah.
addLine(
"DECAY 4 0.000000 # c : 0.0 \n");
553 slhah.
addLine(
"DECAY 5 0.000000 # b : 0.0 \n");
554 slhah.
addLine(
"DECAY 11 0.000000 # e- : 0.0 \n");
555 slhah.
addLine(
"DECAY 12 0.000000 # ve : 0.0 \n");
556 slhah.
addLine(
"DECAY 13 0.000000 # mu- : 0.0 \n");
557 slhah.
addLine(
"DECAY 14 0.000000 # vm : 0.0 \n");
558 slhah.
addLine(
"DECAY 16 0.000000 # vt : 0.0 \n");
559 slhah.
addLine(
"DECAY 21 0.000000 # g : 0.0 \n");
560 slhah.
addLine(
"DECAY 22 0.000000 # a : 0.0\n");
const double Z[kNumberCalorimeter]
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 &)