20 #include "TLorentzVector.h" 53 #include "CLHEP/Random/RandExponential.h" 60 class HepRandomEngine;
79 TLorentzVector &negativeLepton,
81 CLHEP::HepRandomEngine *engine);
87 void mirror(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton);
89 void rotate180(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton);
116 produces<LHEEventProduct>();
117 produces<LHERunInfoProduct, edm::Transition::BeginRun>();
118 produces<math::XYZTLorentzVectorD>(
"vertexPosition");
130 if (!lhe_ouputfile.empty()) {
138 throw cms::Exception(
"Configuration") <<
"The given particle to embed is not in the list of allowed particles.";
143 throw cms::Exception(
"Configuration") <<
"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.";
170 TLorentzVector positiveLepton, negativeLepton;
171 bool mu_plus_found =
false;
172 bool mu_minus_found =
false;
181 if (
muon->charge() == 1 && !mu_plus_found) {
183 mu_plus_found =
true;
184 }
else if (
muon->charge() == -1 && !mu_minus_found) {
186 mu_minus_found =
true;
187 }
else if (mu_minus_found && mu_plus_found)
193 mirror(positiveLepton, negativeLepton);
194 rotate180(positiveLepton, negativeLepton);
198 double originalXWGTUP_ = 1.;
199 std::unique_ptr<LHEEventProduct> product(
new LHEEventProduct(hepeup, originalXWGTUP_));
202 std::copy(product->begin(), product->end(), std::ostream_iterator<std::string>(
file));
206 std::unique_ptr<math::XYZTLorentzVectorD> vertex_position(
251 TLorentzVector &negativeLepton,
253 CLHEP::HepRandomEngine *engine) {
254 TLorentzVector
Z = positiveLepton + negativeLepton;
257 static constexpr double tau_ctau0 = 8.71100e-02;
258 double tau_ctau_p = tau_ctau0 * CLHEP::RandExponential::shoot(engine);
259 double tau_ctau_n = tau_ctau0 * CLHEP::RandExponential::shoot(engine);
269 lhef::HEPEUP &outlhe, TLorentzVector &particle,
int pdgid,
double spin,
double ctau) {
274 int particleindex = outlhe.
NUP;
277 outlhe.
PUP[particleindex][0] = particle.Px();
278 outlhe.
PUP[particleindex][1] = particle.Py();
279 outlhe.
PUP[particleindex][2] = particle.Pz();
280 outlhe.
PUP[particleindex][3] = particle.E();
281 outlhe.
PUP[particleindex][4] = particle.M();
283 outlhe.
SPINUP[particleindex] = spin;
284 outlhe.
VTIMUP[particleindex] = ctau;
286 outlhe.
ICOLUP[particleindex].first = 0;
287 outlhe.
ICOLUP[particleindex].second = 0;
290 outlhe.
MOTHUP[particleindex].first = 0;
291 outlhe.
MOTHUP[particleindex].second = 0;
292 outlhe.
ISTUP[particleindex] = 2;
297 outlhe.
MOTHUP[particleindex].first = 1;
298 outlhe.
MOTHUP[particleindex].second = 1;
300 outlhe.
ISTUP[particleindex] = 1;
317 TLorentzVector
Z = positiveLepton + negativeLepton;
319 TVector3 boost_from_Z_to_LAB =
Z.BoostVector();
320 TVector3 boost_from_LAB_to_Z = -
Z.BoostVector();
322 positiveLepton.Boost(boost_from_LAB_to_Z);
323 negativeLepton.Boost(boost_from_LAB_to_Z);
326 double lep_mass_squared = lep_mass * lep_mass;
327 double lep_energy_squared = 0.25 *
Z.M2();
328 double lep_3momentum_squared = lep_energy_squared - lep_mass_squared;
329 if (lep_3momentum_squared < 0) {
335 double scale =
std::sqrt(lep_3momentum_squared / positiveLepton.Vect().Mag2());
336 positiveLepton.SetPxPyPzE(
scale * positiveLepton.Px(),
337 scale * positiveLepton.Py(),
338 scale * positiveLepton.Pz(),
340 negativeLepton.SetPxPyPzE(
scale * negativeLepton.Px(),
341 scale * negativeLepton.Py(),
342 scale * negativeLepton.Pz(),
346 positiveLepton.Boost(boost_from_Z_to_LAB);
347 negativeLepton.Boost(boost_from_Z_to_LAB);
353 if (
"afterFSR" == FSRmode &&
muon->genParticle() !=
nullptr) {
356 afterFSRMuon->
p4().px(), afterFSRMuon->
p4().py(), afterFSRMuon->
p4().pz(), afterFSRMuon->
p4().e());
357 }
else if (
"beforeFSR" == FSRmode &&
muon->genParticle() !=
nullptr) {
360 beforeFSRMuon->
p4().px(), beforeFSRMuon->
p4().py(), beforeFSRMuon->
p4().pz(), beforeFSRMuon->
p4().e());
368 if (
muon->mother(0) ==
nullptr)
370 if (
muon->pdgId() ==
muon->mother(0)->pdgId())
379 edm::LogInfo(
"TauEmbedding") <<
"Applying 180<C2><B0> rotation";
382 TLorentzVector
Z = positiveLepton + negativeLepton;
384 edm::LogInfo(
"TauEmbedding") <<
"MuMinus before. Pt: " << negativeLepton.Pt() <<
" Eta: " << negativeLepton.Eta()
385 <<
" Phi: " << negativeLepton.Phi() <<
" Mass: " << negativeLepton.M();
387 TVector3 Z3 =
Z.Vect();
388 TVector3 positiveLepton3 = positiveLepton.Vect();
389 TVector3 negativeLepton3 = negativeLepton.Vect();
391 TVector3 p3_perp = positiveLepton3 - positiveLepton3.Dot(Z3) / Z3.Dot(Z3) * Z3;
392 p3_perp = p3_perp.Unit();
394 positiveLepton3 -= 2 * positiveLepton3.Dot(p3_perp) * p3_perp;
395 negativeLepton3 -= 2 * negativeLepton3.Dot(p3_perp) * p3_perp;
397 positiveLepton.SetVect(positiveLepton3);
398 negativeLepton.SetVect(negativeLepton3);
400 edm::LogInfo(
"TauEmbedding") <<
"MuMinus after. Pt: " << negativeLepton.Pt() <<
" Eta: " << negativeLepton.Eta()
401 <<
" Phi: " << negativeLepton.Phi() <<
" Mass: " << negativeLepton.M();
409 edm::LogInfo(
"TauEmbedding") <<
"Applying initial reconstruction correction";
410 TLorentzVector
Z = positiveLepton + negativeLepton;
411 edm::LogInfo(
"TauEmbedding") <<
"MuMinus before. Pt: " << negativeLepton.Pt() <<
" Mass: " << negativeLepton.M();
412 float diLeptonMass = (positiveLepton + negativeLepton).M();
413 if (diLeptonMass > 60. && diLeptonMass < 122.) {
415 float correction_deviation =
417 double EmbeddingCorrection =
419 EmbeddingCorrection /=
420 (EmbeddingCorrection -
421 (EmbeddingCorrection - 1.) *
exp(-
pow((diLeptonMass - zmass), 2.) / (2. *
pow(correction_deviation, 2.))));
422 EmbeddingCorrection = ((diLeptonMass + (EmbeddingCorrection - 1.) * zmass) / (diLeptonMass * EmbeddingCorrection));
423 double correctedpositiveLeptonEnergy =
425 pow(positiveLepton.Py(), 2) +
pow(positiveLepton.Pz(), 2));
426 double correctednegativeLeptonEnergy =
428 pow(negativeLepton.Py(), 2) +
pow(negativeLepton.Pz(), 2));
429 positiveLepton.SetE(correctedpositiveLeptonEnergy);
430 negativeLepton.SetE(correctednegativeLeptonEnergy);
431 positiveLepton *= EmbeddingCorrection;
432 negativeLepton *= EmbeddingCorrection;
433 edm::LogInfo(
"TauEmbedding") <<
"MuMinus after. Pt: " << negativeLepton.Pt() <<
" Mass: " << negativeLepton.M();
442 TLorentzVector
Z = positiveLepton + negativeLepton;
444 edm::LogInfo(
"TauEmbedding") <<
"MuMinus before. Pt: " << negativeLepton.Pt() <<
" Eta: " << negativeLepton.Eta()
445 <<
" Phi: " << negativeLepton.Phi() <<
" Mass: " << negativeLepton.M();
447 TVector3 Z3 =
Z.Vect();
448 TVector3 positiveLepton3 = positiveLepton.Vect();
449 TVector3 negativeLepton3 = negativeLepton.Vect();
451 TVector3
beam(0., 0., 1.);
452 TVector3 perpToZandBeam = Z3.Cross(
beam).Unit();
454 positiveLepton3 -= 2 * positiveLepton3.Dot(perpToZandBeam) * perpToZandBeam;
455 negativeLepton3 -= 2 * negativeLepton3.Dot(perpToZandBeam) * perpToZandBeam;
457 positiveLepton.SetVect(positiveLepton3);
458 negativeLepton.SetVect(negativeLepton3);
460 edm::LogInfo(
"TauEmbedding") <<
"MuMinus after. Pt: " << negativeLepton.Pt() <<
" Eta: " << negativeLepton.Eta()
461 <<
" Phi: " << negativeLepton.Phi() <<
" Mass: " << negativeLepton.M();
469 slhah.
addLine(
"######################################################################\n");
470 slhah.
addLine(
"## PARAM_CARD AUTOMATICALY GENERATED BY MG5 FOLLOWING UFO MODEL ####\n");
471 slhah.
addLine(
"######################################################################\n");
473 slhah.
addLine(
"## Width set on Auto will be computed following the information ##\n");
474 slhah.
addLine(
"## present in the decay.py files of the model. ##\n");
475 slhah.
addLine(
"## See arXiv:1402.1178 for more details. ##\n");
477 slhah.
addLine(
"######################################################################\n");
479 slhah.
addLine(
"###################################\n");
480 slhah.
addLine(
"## INFORMATION FOR MASS\n");
481 slhah.
addLine(
"###################################\n");
482 slhah.
addLine(
"Block mass \n");
483 slhah.
addLine(
" 6 1.730000e+02 # MT \n");
484 slhah.
addLine(
" 15 1.777000e+00 # MTA \n");
485 slhah.
addLine(
" 23 9.118800e+01 # MZ \n");
486 slhah.
addLine(
" 25 1.250000e+02 # MH \n");
487 slhah.
addLine(
"## Dependent parameters, given by model restrictions.\n");
488 slhah.
addLine(
"## Those values should be edited following the \n");
489 slhah.
addLine(
"## analytical expression. MG5 ignores those values \n");
490 slhah.
addLine(
"## but they are important for interfacing the output of MG5\n");
491 slhah.
addLine(
"## to external program such as Pythia.\n");
492 slhah.
addLine(
" 1 0.000000 # d : 0.0 \n");
493 slhah.
addLine(
" 2 0.000000 # u : 0.0 \n");
494 slhah.
addLine(
" 3 0.000000 # s : 0.0 \n");
495 slhah.
addLine(
" 4 0.000000 # c : 0.0 \n");
496 slhah.
addLine(
" 5 0.000000 # b : 0.0 \n");
497 slhah.
addLine(
" 11 0.000000 # e- : 0.0 \n");
498 slhah.
addLine(
" 12 0.000000 # ve : 0.0 \n");
499 slhah.
addLine(
" 13 0.000000 # mu- : 0.0 \n");
500 slhah.
addLine(
" 14 0.000000 # vm : 0.0 \n");
501 slhah.
addLine(
" 16 0.000000 # vt : 0.0 \n");
502 slhah.
addLine(
" 21 0.000000 # g : 0.0 \n");
503 slhah.
addLine(
" 22 0.000000 # a : 0.0 \n");
505 " 24 80.419002 # w+ : cmath.sqrt(MZ__exp__2/2. + cmath.sqrt(MZ__exp__4/4. - " 506 "(aEW*cmath.pi*MZ__exp__2)/(Gf*sqrt__2))) \n");
508 slhah.
addLine(
"###################################\n");
509 slhah.
addLine(
"## INFORMATION FOR SMINPUTS\n");
510 slhah.
addLine(
"###################################\n");
511 slhah.
addLine(
"Block sminputs \n");
512 slhah.
addLine(
" 1 1.325070e+02 # aEWM1 \n");
513 slhah.
addLine(
" 2 1.166390e-05 # Gf \n");
514 slhah.
addLine(
" 3 1.180000e-01 # aS \n");
516 slhah.
addLine(
"###################################\n");
517 slhah.
addLine(
"## INFORMATION FOR WOLFENSTEIN\n");
518 slhah.
addLine(
"###################################\n");
519 slhah.
addLine(
"Block wolfenstein \n");
520 slhah.
addLine(
" 1 2.253000e-01 # lamWS \n");
521 slhah.
addLine(
" 2 8.080000e-01 # AWS \n");
522 slhah.
addLine(
" 3 1.320000e-01 # rhoWS \n");
523 slhah.
addLine(
" 4 3.410000e-01 # etaWS \n");
525 slhah.
addLine(
"###################################\n");
526 slhah.
addLine(
"## INFORMATION FOR YUKAWA\n");
527 slhah.
addLine(
"###################################\n");
528 slhah.
addLine(
"Block yukawa \n");
529 slhah.
addLine(
" 6 1.730000e+02 # ymt \n");
530 slhah.
addLine(
" 15 1.777000e+00 # ymtau \n");
532 slhah.
addLine(
"###################################\n");
533 slhah.
addLine(
"## INFORMATION FOR DECAY\n");
534 slhah.
addLine(
"###################################\n");
535 slhah.
addLine(
"DECAY 6 1.491500e+00 # WT \n");
536 slhah.
addLine(
"DECAY 15 2.270000e-12 # WTau \n");
537 slhah.
addLine(
"DECAY 23 2.441404e+00 # WZ \n");
538 slhah.
addLine(
"DECAY 24 2.047600e+00 # WW \n");
539 slhah.
addLine(
"DECAY 25 6.382339e-03 # WH \n");
540 slhah.
addLine(
"## Dependent parameters, given by model restrictions.\n");
541 slhah.
addLine(
"## Those values should be edited following the \n");
542 slhah.
addLine(
"## analytical expression. MG5 ignores those values \n");
543 slhah.
addLine(
"## but they are important for interfacing the output of MG5\n");
544 slhah.
addLine(
"## to external program such as Pythia.\n");
545 slhah.
addLine(
"DECAY 1 0.000000 # d : 0.0 \n");
546 slhah.
addLine(
"DECAY 2 0.000000 # u : 0.0 \n");
547 slhah.
addLine(
"DECAY 3 0.000000 # s : 0.0 \n");
548 slhah.
addLine(
"DECAY 4 0.000000 # c : 0.0 \n");
549 slhah.
addLine(
"DECAY 5 0.000000 # b : 0.0 \n");
550 slhah.
addLine(
"DECAY 11 0.000000 # e- : 0.0 \n");
551 slhah.
addLine(
"DECAY 12 0.000000 # ve : 0.0 \n");
552 slhah.
addLine(
"DECAY 13 0.000000 # mu- : 0.0 \n");
553 slhah.
addLine(
"DECAY 14 0.000000 # vm : 0.0 \n");
554 slhah.
addLine(
"DECAY 16 0.000000 # vt : 0.0 \n");
555 slhah.
addLine(
"DECAY 21 0.000000 # g : 0.0 \n");
556 slhah.
addLine(
"DECAY 22 0.000000 # a : 0.0\n");
T getParameter(std::string const &) const
void mirror(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton)
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double > > XYZTLorentzVectorD
Lorentz vector with cylindrical internal representation using pseudorapidity.
void InitialRecoCorrection(TLorentzVector &positiveLepton, TLorentzVector &negativeLepton)
std::vector< std::pair< int, int > > ICOLUP
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
T getUntrackedParameter(std::string const &, T const &) const
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
bool InitialRecoCorrection_
std::vector< double > SPINUP
Abs< T >::type abs(const T &t)
const int embeddingParticles[3]
static constexpr double tauMass_
#define DEFINE_FWK_MODULE(type)
void endRunProduce(edm::Run &, edm::EventSetup const &) override
std::vector< std::pair< int, int > > MOTHUP
std::vector< double > XERRUP
Log< level::Info, false > LogInfo
std::vector< double > XMAXUP
static constexpr double elMass_
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
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)
const_iterator begin() const
std::vector< double > XSECUP
Log< level::Warning, false > LogWarning
Analysis-level muon class.
const_iterator end() const
Power< A, B >::type pow(const A &a, const B &b)
static constexpr double muonMass_
EmbeddingLHEProducer(const edm::ParameterSet &)
virtual const LorentzVector & p4() const =0
four-momentum Lorentz vector