26 #include "TLorentzVector.h"
57 #include "CLHEP/Random/RandExponential.h"
64 class HepRandomEngine;
83 TLorentzVector &negativeLepton,
85 CLHEP::HepRandomEngine *engine);
91 void mirror(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton);
92 void rotate180(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton);
118 produces<LHEEventProduct>();
119 produces<LHERunInfoProduct, edm::Transition::BeginRun>();
120 produces<math::XYZTLorentzVectorD>(
"vertexPosition");
131 if (!lhe_ouputfile.empty()) {
139 throw cms::Exception(
"Configuration") <<
"The given particle to embed is not in the list of allowed particles.";
144 throw cms::Exception(
"Configuration") <<
"The EmbeddingLHEProducer requires the RandomNumberGeneratorService\n"
145 "which is not present in the configuration file. \n"
146 "You must add the service\n"
147 "in the configuration file or remove the modules that require it.";
171 TLorentzVector positiveLepton, negativeLepton;
172 bool mu_plus_found =
false;
173 bool mu_minus_found =
false;
182 if (
muon->charge() == 1 && !mu_plus_found) {
184 mu_plus_found =
true;
185 }
else if (
muon->charge() == -1 && !mu_minus_found) {
187 mu_minus_found =
true;
188 }
else if (mu_minus_found && mu_plus_found)
191 mirror(positiveLepton, negativeLepton);
192 rotate180(positiveLepton, negativeLepton);
196 double originalXWGTUP_ = 1.;
197 std::unique_ptr<LHEEventProduct> product(
new LHEEventProduct(hepeup, originalXWGTUP_));
200 std::copy(product->begin(), product->end(), std::ostream_iterator<std::string>(
file));
204 std::unique_ptr<math::XYZTLorentzVectorD> vertex_position(
206 iEvent.
put(
std::move(vertex_position),
"vertexPosition");
255 std::copy(runInfo->begin(), runInfo->end(), std::ostream_iterator<std::string>(
file));
267 TLorentzVector &negativeLepton,
269 CLHEP::HepRandomEngine *engine) {
270 TLorentzVector
Z = positiveLepton + negativeLepton;
274 double tau_ctau0 = 8.71100e-02;
276 tau_ctau0 * CLHEP::RandExponential::shoot(engine);
278 double tau_ctau_n = tau_ctau0 * CLHEP::RandExponential::shoot(engine);
289 lhef::HEPEUP &outlhe, TLorentzVector &particle,
int pdgid,
double spin,
double ctau) {
294 int particleindex = outlhe.
NUP;
297 outlhe.
PUP[particleindex][0] = particle.Px();
298 outlhe.
PUP[particleindex][1] = particle.Py();
299 outlhe.
PUP[particleindex][2] = particle.Pz();
300 outlhe.
PUP[particleindex][3] = particle.E();
301 outlhe.
PUP[particleindex][4] = particle.M();
302 outlhe.
IDUP[particleindex] = pdgid;
303 outlhe.
SPINUP[particleindex] = spin;
304 outlhe.
VTIMUP[particleindex] = ctau;
306 outlhe.
ICOLUP[particleindex].first = 0;
307 outlhe.
ICOLUP[particleindex].second = 0;
310 outlhe.
MOTHUP[particleindex].first = 0;
311 outlhe.
MOTHUP[particleindex].second = 0;
312 outlhe.
ISTUP[particleindex] = 2;
317 outlhe.
MOTHUP[particleindex].first = 1;
318 outlhe.
MOTHUP[particleindex].second = 1;
320 outlhe.
ISTUP[particleindex] = 1;
337 TLorentzVector
Z = positiveLepton + negativeLepton;
339 TVector3 boost_from_Z_to_LAB = Z.BoostVector();
340 TVector3 boost_from_LAB_to_Z = -Z.BoostVector();
343 positiveLepton.Boost(boost_from_LAB_to_Z);
344 negativeLepton.Boost(boost_from_LAB_to_Z);
347 double lep_mass_squared = lep_mass * lep_mass;
348 double lep_energy_squared = 0.25 * Z.M2();
349 double lep_3momentum_squared = lep_energy_squared - lep_mass_squared;
350 if (lep_3momentum_squared < 0) {
356 double scale =
std::sqrt(lep_3momentum_squared / positiveLepton.Vect().Mag2());
357 positiveLepton.SetPxPyPzE(scale * positiveLepton.Px(),
358 scale * positiveLepton.Py(),
359 scale * positiveLepton.Pz(),
361 negativeLepton.SetPxPyPzE(scale * negativeLepton.Px(),
362 scale * negativeLepton.Py(),
363 scale * negativeLepton.Pz(),
367 positiveLepton.Boost(boost_from_Z_to_LAB);
368 negativeLepton.Boost(boost_from_Z_to_LAB);
374 if (
"afterFSR" == FSRmode && muon->
genParticle() !=
nullptr) {
377 afterFSRMuon->
p4().px(), afterFSRMuon->
p4().py(), afterFSRMuon->
p4().pz(), afterFSRMuon->
p4().e());
378 }
else if (
"beforeFSR" == FSRmode && muon->
genParticle() !=
nullptr) {
381 beforeFSRMuon->
p4().px(), beforeFSRMuon->
p4().py(), beforeFSRMuon->
p4().pz(), beforeFSRMuon->
p4().e());
383 Lepton.SetPxPyPzE(muon->
p4().px(), muon->
p4().py(), muon->
p4().pz(), muon->
p4().e());
389 if (muon->
mother(0) ==
nullptr)
400 edm::LogInfo(
"TauEmbedding") <<
"Applying 180<C2><B0> rotation";
403 TLorentzVector
Z = positiveLepton + negativeLepton;
405 edm::LogInfo(
"TauEmbedding") <<
"MuMinus before. Pt: " << negativeLepton.Pt() <<
" Eta: " << negativeLepton.Eta()
406 <<
" Phi: " << negativeLepton.Phi() <<
" Mass: " << negativeLepton.M();
408 TVector3 Z3 = Z.Vect();
409 TVector3 positiveLepton3 = positiveLepton.Vect();
410 TVector3 negativeLepton3 = negativeLepton.Vect();
412 TVector3 p3_perp = positiveLepton3 - positiveLepton3.Dot(Z3) / Z3.Dot(Z3) * Z3;
413 p3_perp = p3_perp.Unit();
415 positiveLepton3 -= 2 * positiveLepton3.Dot(p3_perp) * p3_perp;
416 negativeLepton3 -= 2 * negativeLepton3.Dot(p3_perp) * p3_perp;
418 positiveLepton.SetVect(positiveLepton3);
419 negativeLepton.SetVect(negativeLepton3);
421 edm::LogInfo(
"TauEmbedding") <<
"MuMinus after. Pt: " << negativeLepton.Pt() <<
" Eta: " << negativeLepton.Eta()
422 <<
" Phi: " << negativeLepton.Phi() <<
" Mass: " << negativeLepton.M();
431 TLorentzVector
Z = positiveLepton + negativeLepton;
433 edm::LogInfo(
"TauEmbedding") <<
"MuMinus before. Pt: " << negativeLepton.Pt() <<
" Eta: " << negativeLepton.Eta()
434 <<
" Phi: " << negativeLepton.Phi() <<
" Mass: " << negativeLepton.M();
436 TVector3 Z3 = Z.Vect();
437 TVector3 positiveLepton3 = positiveLepton.Vect();
438 TVector3 negativeLepton3 = negativeLepton.Vect();
440 TVector3
beam(0., 0., 1.);
441 TVector3 perpToZandBeam = Z3.Cross(beam).Unit();
443 positiveLepton3 -= 2 * positiveLepton3.Dot(perpToZandBeam) * perpToZandBeam;
444 negativeLepton3 -= 2 * negativeLepton3.Dot(perpToZandBeam) * perpToZandBeam;
446 positiveLepton.SetVect(positiveLepton3);
447 negativeLepton.SetVect(negativeLepton3);
449 edm::LogInfo(
"TauEmbedding") <<
"MuMinus after. Pt: " << negativeLepton.Pt() <<
" Eta: " << negativeLepton.Eta()
450 <<
" Phi: " << negativeLepton.Phi() <<
" Mass: " << negativeLepton.M();
458 slhah.
addLine(
"######################################################################\n");
459 slhah.
addLine(
"## PARAM_CARD AUTOMATICALY GENERATED BY MG5 FOLLOWING UFO MODEL ####\n");
460 slhah.
addLine(
"######################################################################\n");
462 slhah.
addLine(
"## Width set on Auto will be computed following the information ##\n");
463 slhah.
addLine(
"## present in the decay.py files of the model. ##\n");
464 slhah.
addLine(
"## See arXiv:1402.1178 for more details. ##\n");
466 slhah.
addLine(
"######################################################################\n");
468 slhah.
addLine(
"###################################\n");
469 slhah.
addLine(
"## INFORMATION FOR MASS\n");
470 slhah.
addLine(
"###################################\n");
471 slhah.
addLine(
"Block mass \n");
472 slhah.
addLine(
" 6 1.730000e+02 # MT \n");
473 slhah.
addLine(
" 15 1.777000e+00 # MTA \n");
474 slhah.
addLine(
" 23 9.118800e+01 # MZ \n");
475 slhah.
addLine(
" 25 1.250000e+02 # MH \n");
476 slhah.
addLine(
"## Dependent parameters, given by model restrictions.\n");
477 slhah.
addLine(
"## Those values should be edited following the \n");
478 slhah.
addLine(
"## analytical expression. MG5 ignores those values \n");
479 slhah.
addLine(
"## but they are important for interfacing the output of MG5\n");
480 slhah.
addLine(
"## to external program such as Pythia.\n");
481 slhah.
addLine(
" 1 0.000000 # d : 0.0 \n");
482 slhah.
addLine(
" 2 0.000000 # u : 0.0 \n");
483 slhah.
addLine(
" 3 0.000000 # s : 0.0 \n");
484 slhah.
addLine(
" 4 0.000000 # c : 0.0 \n");
485 slhah.
addLine(
" 5 0.000000 # b : 0.0 \n");
486 slhah.
addLine(
" 11 0.000000 # e- : 0.0 \n");
487 slhah.
addLine(
" 12 0.000000 # ve : 0.0 \n");
488 slhah.
addLine(
" 13 0.000000 # mu- : 0.0 \n");
489 slhah.
addLine(
" 14 0.000000 # vm : 0.0 \n");
490 slhah.
addLine(
" 16 0.000000 # vt : 0.0 \n");
491 slhah.
addLine(
" 21 0.000000 # g : 0.0 \n");
492 slhah.
addLine(
" 22 0.000000 # a : 0.0 \n");
494 " 24 80.419002 # w+ : cmath.sqrt(MZ__exp__2/2. + cmath.sqrt(MZ__exp__4/4. - "
495 "(aEW*cmath.pi*MZ__exp__2)/(Gf*sqrt__2))) \n");
497 slhah.
addLine(
"###################################\n");
498 slhah.
addLine(
"## INFORMATION FOR SMINPUTS\n");
499 slhah.
addLine(
"###################################\n");
500 slhah.
addLine(
"Block sminputs \n");
501 slhah.
addLine(
" 1 1.325070e+02 # aEWM1 \n");
502 slhah.
addLine(
" 2 1.166390e-05 # Gf \n");
503 slhah.
addLine(
" 3 1.180000e-01 # aS \n");
505 slhah.
addLine(
"###################################\n");
506 slhah.
addLine(
"## INFORMATION FOR WOLFENSTEIN\n");
507 slhah.
addLine(
"###################################\n");
508 slhah.
addLine(
"Block wolfenstein \n");
509 slhah.
addLine(
" 1 2.253000e-01 # lamWS \n");
510 slhah.
addLine(
" 2 8.080000e-01 # AWS \n");
511 slhah.
addLine(
" 3 1.320000e-01 # rhoWS \n");
512 slhah.
addLine(
" 4 3.410000e-01 # etaWS \n");
514 slhah.
addLine(
"###################################\n");
515 slhah.
addLine(
"## INFORMATION FOR YUKAWA\n");
516 slhah.
addLine(
"###################################\n");
517 slhah.
addLine(
"Block yukawa \n");
518 slhah.
addLine(
" 6 1.730000e+02 # ymt \n");
519 slhah.
addLine(
" 15 1.777000e+00 # ymtau \n");
521 slhah.
addLine(
"###################################\n");
522 slhah.
addLine(
"## INFORMATION FOR DECAY\n");
523 slhah.
addLine(
"###################################\n");
524 slhah.
addLine(
"DECAY 6 1.491500e+00 # WT \n");
525 slhah.
addLine(
"DECAY 15 2.270000e-12 # WTau \n");
526 slhah.
addLine(
"DECAY 23 2.441404e+00 # WZ \n");
527 slhah.
addLine(
"DECAY 24 2.047600e+00 # WW \n");
528 slhah.
addLine(
"DECAY 25 6.382339e-03 # WH \n");
529 slhah.
addLine(
"## Dependent parameters, given by model restrictions.\n");
530 slhah.
addLine(
"## Those values should be edited following the \n");
531 slhah.
addLine(
"## analytical expression. MG5 ignores those values \n");
532 slhah.
addLine(
"## but they are important for interfacing the output of MG5\n");
533 slhah.
addLine(
"## to external program such as Pythia.\n");
534 slhah.
addLine(
"DECAY 1 0.000000 # d : 0.0 \n");
535 slhah.
addLine(
"DECAY 2 0.000000 # u : 0.0 \n");
536 slhah.
addLine(
"DECAY 3 0.000000 # s : 0.0 \n");
537 slhah.
addLine(
"DECAY 4 0.000000 # c : 0.0 \n");
538 slhah.
addLine(
"DECAY 5 0.000000 # b : 0.0 \n");
539 slhah.
addLine(
"DECAY 11 0.000000 # e- : 0.0 \n");
540 slhah.
addLine(
"DECAY 12 0.000000 # ve : 0.0 \n");
541 slhah.
addLine(
"DECAY 13 0.000000 # mu- : 0.0 \n");
542 slhah.
addLine(
"DECAY 14 0.000000 # vm : 0.0 \n");
543 slhah.
addLine(
"DECAY 16 0.000000 # vt : 0.0 \n");
544 slhah.
addLine(
"DECAY 21 0.000000 # g : 0.0 \n");
545 slhah.
addLine(
"DECAY 22 0.000000 # a : 0.0\n");
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.
virtual const Candidate * mother(size_type i=0) const =0
return pointer to mother
const reco::GenParticle * genParticle(size_t idx=0) const
bool getByToken(EDGetToken token, Handle< PROD > &result) const
std::vector< std::pair< int, int > > ICOLUP
#define DEFINE_FWK_MODULE(type)
std::string studyFSRmode_
std::vector< double > VTIMUP
void transform_mumu_to_tautau(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
~EmbeddingLHEProducer() override
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &)=0
Use this engine in event methods.
const LorentzVector & p4() const final
four-momentum Lorentz vector
void fill_lhe_with_particle(lhef::HEPEUP &outlhe, TLorentzVector &particle, int pdgid, double spin, double ctau)
void beginRunProduce(edm::Run &run, edm::EventSetup const &es) override
LHERunInfoProduct::Header give_slha()
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
void addDefault(ParameterSetDescription const &psetDescription)
void assign_4vector(TLorentzVector &Lepton, const pat::Muon *muon, std::string FSRmode)
std::vector< FiveVector > PUP
std::vector< double > SPINUP
Abs< T >::type abs(const T &t)
const int embeddingParticles[3]
void endRunProduce(edm::Run &, edm::EventSetup const &) override
std::vector< std::pair< int, int > > MOTHUP
std::vector< double > XERRUP
virtual int pdgId() const =0
PDG identifier.
Log< level::Info, false > LogInfo
std::vector< double > XMAXUP
T getParameter(std::string const &) const
void put(std::unique_ptr< PROD > product)
Put a new product.
void rotate180(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton)
edm::EDGetTokenT< edm::View< pat::Muon > > muonsCollection_
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()
void fill_lhe_from_mumu(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton, lhef::HEPEUP &outlhe, CLHEP::HepRandomEngine *engine)
std::vector< double > XSECUP
Log< level::Warning, false > LogWarning
Analysis-level muon class.
EmbeddingLHEProducer(const edm::ParameterSet &)
virtual const LorentzVector & p4() const =0
four-momentum Lorentz vector