Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F10664392
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
255 KB
Subscribers
None
View Options
diff --git a/MatrixElement/Lepton/MEee2gZ2qq.h b/MatrixElement/Lepton/MEee2gZ2qq.h
--- a/MatrixElement/Lepton/MEee2gZ2qq.h
+++ b/MatrixElement/Lepton/MEee2gZ2qq.h
@@ -1,580 +1,580 @@
// -*- C++ -*-
//
// MEee2gZ2qq.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_MEee2gZ2qq_H
#define HERWIG_MEee2gZ2qq_H
//
// This is the declaration of the MEee2gZ2qq class.
//
#include "Herwig++/MatrixElement/HwMEBase.h"
#include "Herwig++/Models/StandardModel/StandardModel.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/Rebinder.h"
#include "Herwig++/MatrixElement/ProductionMatrixElement.h"
#include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
#include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
namespace Herwig {
using namespace ThePEG;
/**
* The MEee2gZ2qq class implements the matrix element
* for \f$e^+e^-\to Z/\gamma \to q\bar{q}\f$ including spin correlations.
* The class includes greater control over the type of quark produced than is available
* in the corresponding matrix element from ThePEG, in addition to spin correlations.
*
* @see \ref MEee2gZ2qqInterfaces "The interfaces"
* defined for MEee2gZ2qq.
*/
class MEee2gZ2qq: public HwMEBase {
public:
/**
* The default constructor.
*/
MEee2gZ2qq() : minflav_(1), maxflav_(5), massopt_(1), pTmin_(GeV),
preFactor_(6.)
{}
/**
* Members for hard corrections to the emission of QCD radiation
*/
//@{
/**
* Has a POWHEG style correction
*/
virtual bool hasPOWHEGCorrection() {return true;}
/**
* Has an old fashioned ME correction
*/
virtual bool hasMECorrection() {return true;}
/**
* Initialize the ME correction
*/
virtual void initializeMECorrection(ShowerTreePtr, double &,
double & );
/**
* Apply the hard matrix element correction to a given hard process or decay
*/
virtual void applyHardMatrixElementCorrection(ShowerTreePtr);
/**
* Apply the soft matrix element correction
* @param initial The particle from the hard process which started the
* shower
* @param parent The initial particle in the current branching
* @param br The branching struct
* @return If true the emission should be vetoed
*/
virtual bool softMatrixElementVeto(ShowerProgenitorPtr initial,
ShowerParticlePtr parent,
Branching br);
/**
* Apply the POWHEG style correction
*/
virtual HardTreePtr generateHardest(ShowerTreePtr);
//@}
/** @name Virtual functions required by the MEBase class. */
//@{
/**
* Return the order in \f$\alpha_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInAlphaS() const;
/**
* Return the order in \f$\alpha_{EW}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInAlphaEW() const;
/**
* The matrix element for the kinematical configuration
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
* @return the matrix element scaled with sHat() to give a
* dimensionless number.
*/
virtual double me2() const;
/**
* Return the scale associated with the last set phase space point.
*/
virtual Energy2 scale() const;
/**
* Add all possible diagrams with the add() function.
*/
virtual void getDiagrams() const;
/**
* Get diagram selector. With the information previously supplied with the
* setKinematics method, a derived class may optionally
* override this method to weight the given diagrams with their
* (although certainly not physical) relative probabilities.
* @param dv the diagrams to be weighted.
* @return a Selector relating the given diagrams to their weights.
*/
virtual Selector<DiagramIndex> diagrams(const DiagramVector & dv) const;
/**
* Return a Selector with possible colour geometries for the selected
* diagram weighted by their relative probabilities.
* @param diag the diagram chosen.
* @return the possible colour geometries weighted by their
* relative probabilities.
*/
virtual Selector<const ColourLines *>
colourGeometries(tcDiagPtr diag) const;
/**
* Construct the vertex of spin correlations.
*/
virtual void constructVertex(tSubProPtr);
//@}
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const {return new_ptr(*this);}
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const {return new_ptr(*this);}
//@}
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* Initialize this object after the setup phase before saving an
* EventGenerator to disk.
* @throws InitException if object could not be initialized properly.
*/
virtual void doinit();
/**
* Rebind pointer to other Interfaced objects. Called in the setup phase
* after all objects used in an EventGenerator has been cloned so that
* the pointers will refer to the cloned objects afterwards.
* @param trans a TranslationMap relating the original objects to
* their respective clones.
* @throws RebindException if no cloned object was found for a given
* pointer.
*/
virtual void rebind(const TranslationMap & trans)
;
/**
* Return a vector of all pointers to Interfaced objects used in this
* object.
* @return a vector of pointers.
*/
virtual IVector getReferences();
//@}
protected:
/**
* Calculate the matrix element for \f$e^-e^-\to q \bar q\f$.
* @param partons The incoming and outgoing particles
* @param momenta The momenta of the incoming and outgoing particles
* @param first Whether or not to calculate the spin correlations
*/
double loME(const vector<cPDPtr> & partons,
const vector<Lorentz5Momentum> & momenta,
bool first) const;
/**
* Member to calculate the matrix element
* @param fin Spinors for incoming fermion
* @param ain Spinors for incoming antifermion
* @param fout Spinors for outgoing fermion
* @param aout Spinors for outgong antifermion
* @param me Spin summed Matrix element
* @param cont The continuum piece of the matrix element
* @param BW The Z piece of the matrix element
*/
ProductionMatrixElement HelicityME(vector<SpinorWaveFunction> & fin,
vector<SpinorBarWaveFunction> & ain,
vector<SpinorBarWaveFunction> & fout,
vector<SpinorWaveFunction> & aout,
double & me,
double & cont,
double & BW ) const;
/**
* The ratio of the matrix element for one additional jet over the
* leading order result. In practice
- * \f[\frac{\hat{s}|\overline{\mathcal{M}}|^2_2|D_{\rm emit}|}{4\pi C_F\alpha_S|\overline{\mathcal{M}}|^2_3\left(|D_{\rm emit}|+|D_{\rm spect}\right)}}\f]
+ * \f[\frac{\hat{s}|\overline{\mathcal{M}}|^2_2|D_{\rm emit}|}{4\pi C_F\alpha_S|\overline{\mathcal{M}}|^2_3\left(|D_{\rm emit}|+|D_{\rm spect}|\right)}\f]
* is returned where \f$\|\overline{\mathcal{M}}|^2\f$ is
* the spin and colour summed/averaged matrix element.
* @param partons The incoming and outgoing particles
* @param momenta The momenta of the incoming and outgoing particles
* @param iemitter Whether the quark or antiquark is regardede as the emitter
* @param subtract Whether or not to subtract the relevant dipole term
*/
double meRatio(vector<cPDPtr> partons,
vector<Lorentz5Momentum> momenta,
unsigned int iemitter,
bool subtract =false) const;
/**
* Calculate the matrix element for \f$e^-e^-\to q \bar q g\f$.
* @param partons The incoming and outgoing particles
* @param momenta The momenta of the incoming and outgoing particles
*/
InvEnergy2 realME(const vector<cPDPtr> & partons,
const vector<Lorentz5Momentum> & momenta) const;
private:
/**
* Apply the hard matrix element
*/
vector<Lorentz5Momentum> applyHard(const ParticleVector &p);
/**
* Get the weight for hard emission
*/
double getHard(double &, double &);
/**
* Set the \f$\rho\f$ parameter
*/
void setRho(double);
/**
* Set the \f$\tilde{\kappa}\f$ parameters symmetrically
*/
void setKtildeSymm();
/**
* Set second \f$\tilde{\kappa}\f$, given the first.
*/
void setKtilde2();
/**
* Translate the variables from \f$x_q,x_{\bar{q}}\f$ to \f$\tilde{\kappa},z\f$
*/
//@{
/**
* Calculate \f$z\f$.
*/
double getZfromX(double, double);
/**
* Calculate \f$\tilde{\kappa}\f$.
*/
double getKfromX(double, double);
//@}
/**
* Calculate \f$x_{q},x_{\bar{q}}\f$ from \f$\tilde{\kappa},z\f$.
* @param kt \f$\tilde{\kappa}\f$
* @param z \f$z\f$
* @param x \f$x_{q}\f$
* @param xbar \f$x_{\bar{q}}\f$
*/
void getXXbar(double kt, double z, double & x, double & xbar);
/**
* Soft weight
*/
//@{
/**
* Soft quark weight calculated from \f$x_{q},x_{\bar{q}}\f$
* @param x \f$x_{q}\f$
* @param xbar \f$x_{\bar{q}}\f$
*/
double qWeight(double x, double xbar);
/**
* Soft antiquark weight calculated from \f$x_{q},x_{\bar{q}}\f$
* @param x \f$x_{q}\f$
* @param xbar \f$x_{\bar{q}}\f$
*/
double qbarWeight(double x, double xbar);
/**
* Soft quark weight calculated from \f$\tilde{q},z\f$
* @param qtilde \f$\tilde{q}\f$
* @param z \f$z\f$
*/
double qWeightX(Energy qtilde, double z);
/**
* Soft antiquark weight calculated from \f$\tilde{q},z\f$
* @param qtilde \f$\tilde{q}\f$
* @param z \f$z\f$
*/
double qbarWeightX(Energy qtilde, double z);
//@}
/**
* ????
*/
double u(double);
/**
* Vector and axial vector parts of the matrix element
*/
//@{
/**
* Vector part of the matrix element
*/
double MEV(double, double);
/**
* Axial vector part of the matrix element
*/
double MEA(double, double);
/**
* The matrix element, given \f$x_1\f$, \f$x_2\f$.
* @param x1 \f$x_1\f$
* @param x2 \f$x_2\f$
*/
double PS(double x1, double x2);
//@}
protected:
/**
* Pointer to the fermion-antifermion Z vertex
*/
AbstractFFVVertexPtr FFZVertex() const {return FFZVertex_;}
/**
* Pointer to the fermion-antifermion photon vertex
*/
AbstractFFVVertexPtr FFPVertex() const {return FFPVertex_;}
/**
* Pointer to the particle data object for the Z
*/
PDPtr Z0() const {return Z0_;}
/**
* Pointer to the particle data object for the photon
*/
PDPtr gamma() const {return gamma_;}
/**
* Pointer to the particle data object for the gluon
*/
PDPtr gluon() const {return gluon_;}
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<MEee2gZ2qq> initMEee2gZ2qq;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MEee2gZ2qq & operator=(const MEee2gZ2qq &);
private:
/**
* Pointer to the fermion-antifermion Z vertex
*/
AbstractFFVVertexPtr FFZVertex_;
/**
* Pointer to the fermion-antifermion photon vertex
*/
AbstractFFVVertexPtr FFPVertex_;
/**
* Pointer to the fermion-antifermion photon vertex
*/
AbstractFFVVertexPtr FFGVertex_;
/**
* Pointer to the particle data object for the Z
*/
PDPtr Z0_;
/**
* Pointer to the particle data object for the photon
*/
PDPtr gamma_;
/**
* Pointer to the particle data object for the gluon
*/
PDPtr gluon_;
/**
* The minimum PDG of the quarks to be produced
*/
int minflav_;
/**
* The maximum PDG of the quarks to be produced
*/
int maxflav_;
/**
* Option for the treatment of the top quark mass
*/
unsigned int massopt_;
/**
* CM energy
*/
Energy d_Q_;
/**
* Quark mass
*/
Energy d_m_;
/**
* The rho parameter
*/
double d_rho_;
/**
* The v parameter
*/
double d_v_;
/**
* The initial kappa-tilde values for radiation from the quark
*/
double d_kt1_;
/**
* The initial kappa-tilde values for radiation from the antiquark
*/
double d_kt2_;
/**
* Cut-off parameter
*/
static const double EPS_;
/**
* Pointer to the coupling
*/
ShowerAlphaPtr alpha_;
private:
/**
* Variables for the POWHEG style corrections
*/
//@{
/**
* The cut off on pt, assuming massless quarks.
*/
Energy pTmin_;
/**
* Overestimate for the prefactor
*/
double preFactor_;
/**
* ParticleData objects for the partons
*/
vector<cPDPtr> partons_;
/**
* Momenta of the leading-order partons
*/
vector<Lorentz5Momentum> loMomenta_;
//@}
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of MEee2gZ2qq. */
template <>
struct BaseClassTrait<Herwig::MEee2gZ2qq,1> {
/** Typedef of the first base class of MEee2gZ2qq. */
typedef Herwig::HwMEBase NthBase;
};
/** This template specialization informs ThePEG about the name of
* the MEee2gZ2qq class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::MEee2gZ2qq>
: public ClassTraitsBase<Herwig::MEee2gZ2qq> {
/** Return a platform-independent class name */
static string className() { return "Herwig::MEee2gZ2qq"; }
/** Return the name(s) of the shared library (or libraries) be loaded to get
* access to the MEee2gZ2qq class and any other class on which it depends
* (except the base class). */
static string library() { return "HwMELepton.so"; }
};
/** @endcond */
}
#endif /* HERWIG_MEee2gZ2qq_H */
diff --git a/MatrixElement/Powheg/MEPP2VVPowheg.cc b/MatrixElement/Powheg/MEPP2VVPowheg.cc
--- a/MatrixElement/Powheg/MEPP2VVPowheg.cc
+++ b/MatrixElement/Powheg/MEPP2VVPowheg.cc
@@ -1,5360 +1,5374 @@
// -*- C++ -*-
//
// MEPP2VVPowheg.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MEPP2VVPowheg class.
//
#include "MEPP2VVPowheg.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/Handlers/StandardXComb.h"
#include "Herwig++/Models/StandardModel/StandardModel.h"
#include "Herwig++/MatrixElement/HardVertex.h"
#include "Herwig++/Decay/DecayMatrixElement.h"
using namespace Herwig;
MEPP2VVPowheg::MEPP2VVPowheg() :
tiny(1.e-10), CF_(4./3.), TR_(0.5), NC_(3.),
contrib_(1), channels_(0), nlo_alphaS_opt_(0) , fixed_alphaS_(0.1180346226),
removebr_(1), scaleopt_(1), mu_F_(100.*GeV), mu_UV_(100.*GeV),
ckm_(3,vector<Complex>(3,0.0)),
helicityConservation_(true),
realMESpinCorrelations_(true), power_(2.0),
preqqbar_(3.7),preqg_(16.0),pregqbar_(11.0),
b0_((11.-2./3.*5.)/4./Constants::pi),
LambdaQCD_(91.118*GeV*exp(-1./2./((11.-2./3.*5.)/4./Constants::pi)/0.118)),
min_pT_(2.*GeV){
massOption(vector<unsigned int>(2,1));
}
void MEPP2VVPowheg::persistentOutput(PersistentOStream & os) const {
os << contrib_ << channels_ << nlo_alphaS_opt_ << fixed_alphaS_
<< removebr_ << scaleopt_ << ounit(mu_F_,GeV) << ounit(mu_UV_,GeV)
<< ckm_ << helicityConservation_
<< FFPvertex_ << FFWvertex_ << FFZvertex_ << WWWvertex_ << FFGvertex_
<< realMESpinCorrelations_
<< showerAlphaS_ << power_
<< preqqbar_ << preqg_ << pregqbar_ << prefactor_
<< b0_ << ounit(LambdaQCD_,GeV)
<< ounit( min_pT_,GeV );
}
void MEPP2VVPowheg::persistentInput(PersistentIStream & is, int) {
is >> contrib_ >> channels_ >> nlo_alphaS_opt_ >> fixed_alphaS_
>> removebr_ >> scaleopt_ >> iunit(mu_F_,GeV) >> iunit(mu_UV_,GeV)
>> ckm_ >> helicityConservation_
>> FFPvertex_ >> FFWvertex_ >> FFZvertex_ >> WWWvertex_ >> FFGvertex_
>> realMESpinCorrelations_
>> showerAlphaS_ >> power_
>> preqqbar_ >> preqg_ >> pregqbar_ >> prefactor_
>> b0_ >> iunit(LambdaQCD_,GeV)
>> iunit( min_pT_, GeV );
}
ClassDescription<MEPP2VVPowheg> MEPP2VVPowheg::initMEPP2VVPowheg;
// Definition of the static class description member.
void MEPP2VVPowheg::Init() {
+ static ClassDocumentation<MEPP2VVPowheg> documentation
+ ("The MEPP2VVPowheg class implements the NLO matrix elements for the production of"
+ "pairs of electroweak vector bosons.",
+ "The calcultaion of $W^+W^-$, $W^\\pm Z^0$ and $Z^0Z^0$ production"
+ " in hadron collisions at next-to-leading order in the POWHEG scheme"
+ " is described in \\cite{Hamilton:2010mb}.",
+ "\\bibitem{Hamilton:2010mb}\n"
+ " K.~Hamilton,\n"
+ "%``A positive-weight next-to-leading order simulation of weak boson pair\n"
+ "%production,''\n"
+ "JHEP {\bf 1101} (2011) 009\n"
+ "[arXiv:1009.5391 [hep-ph]].\n"
+ "%%CITATION = JHEPA,1101,009;%%\n");
+
static Switch<MEPP2VVPowheg,unsigned int> interfaceContribution
("Contribution",
"Which contributions to the cross section to include",
&MEPP2VVPowheg::contrib_, 1, false, false);
static SwitchOption interfaceContributionLeadingOrder
(interfaceContribution,
"LeadingOrder",
"Just generate the leading order cross section",
0);
static SwitchOption interfaceContributionPositiveNLO
(interfaceContribution,
"PositiveNLO",
"Generate the positive contribution to the full NLO cross section",
1);
static SwitchOption interfaceContributionNegativeNLO
(interfaceContribution,
"NegativeNLO",
"Generate the negative contribution to the full NLO cross section",
2);
static Switch<MEPP2VVPowheg,unsigned int> interfaceChannels
("Channels",
"Which channels to include in the cross section",
&MEPP2VVPowheg::channels_, 0, false, false);
static SwitchOption interfaceChannelsAll
(interfaceChannels,
"All",
"All channels required for the full NLO cross section: qqb, qg, gqb",
0);
static SwitchOption interfaceChannelsAnnihilation
(interfaceChannels,
"Annihilation",
"Only include the qqb annihilation channel, omitting qg and gqb channels",
1);
static SwitchOption interfaceChannelsCompton
(interfaceChannels,
"Compton",
"Only include the qg and gqb compton channels, omitting all qqb processes",
2);
static Switch<MEPP2VVPowheg,unsigned int> interfaceNLOalphaSopt
("NLOalphaSopt",
"An option allowing you to supply a fixed value of alpha_S "
"through the FixedNLOAlphaS interface.",
&MEPP2VVPowheg::nlo_alphaS_opt_, 0, false, false);
static SwitchOption interfaceNLOalphaSoptRunningAlphaS
(interfaceNLOalphaSopt,
"RunningAlphaS",
"Use the usual running QCD coupling evaluated at scale mu_UV2()",
0);
static SwitchOption interfaceNLOalphaSoptFixedAlphaS
(interfaceNLOalphaSopt,
"FixedAlphaS",
"Use a constant QCD coupling for comparison/debugging purposes",
1);
static Parameter<MEPP2VVPowheg,double> interfaceFixedNLOalphaS
("FixedNLOalphaS",
"The value of alphaS to use for the nlo weight if nlo_alphaS_opt_=1",
&MEPP2VVPowheg::fixed_alphaS_, 0.1180346226, 0., 1.0,
false, false, Interface::limited);
static Switch<MEPP2VVPowheg,unsigned int> interfaceremovebr
("removebr",
"Whether to multiply the event weights by the MCFM branching ratios",
&MEPP2VVPowheg::removebr_, 1, false, false);
static SwitchOption interfaceProductionCrossSection
(interfaceremovebr,
"true",
"Do not multiply in the branching ratios (default running)",
1);
static SwitchOption interfaceIncludeBRs
(interfaceremovebr,
"false",
"Multiply by MCFM branching ratios for comparison/debugging purposes",
0);
static Switch<MEPP2VVPowheg,unsigned int> interfaceScaleOption
("ScaleOption",
"Option for running / fixing EW and QCD factorization & renormalization scales",
&MEPP2VVPowheg::scaleopt_, 1, false, false);
static SwitchOption interfaceDynamic
(interfaceScaleOption,
"Dynamic",
"QCD factorization & renormalization scales are (mT(V1)+mT(V2))/2. "
"EW scale is (mV1^2+mV2^2)/2 (similar to MCatNLO)",
1);
static SwitchOption interfaceFixed
(interfaceScaleOption,
"Fixed",
"QCD factorization fixed to value by FactorizationScaleValue."
"EW and QCD renormalization scales fixed by RenormalizationScaleValue.",
2);
static Parameter<MEPP2VVPowheg,Energy> interfaceFactorizationScaleValue
("FactorizationScaleValue",
"Value to use for the QCD factorization scale if fixed scales"
"have been requested with the ScaleOption interface.",
&MEPP2VVPowheg::mu_F_, GeV, 100.0*GeV, 50.0*GeV, 500.0*GeV,
true, false, Interface::limited);
static Parameter<MEPP2VVPowheg,Energy> interfaceRenormalizationScaleValue
("RenormalizationScaleValue",
"Value to use for the EW and QCD renormalization scales if fixed "
"scales have been requested with the ScaleOption interface.",
&MEPP2VVPowheg::mu_UV_, GeV, 100.0*GeV, 50.0*GeV, 500.0*GeV,
true, false, Interface::limited);
static Switch<MEPP2VVPowheg,bool> interfaceSpinCorrelations
("SpinCorrelations",
"Flag to select leading order spin correlations or a "
"calculation taking into account the real NLO effects",
&MEPP2VVPowheg::realMESpinCorrelations_, 1, false, false);
static SwitchOption interfaceSpinCorrelationsLeadingOrder
(interfaceSpinCorrelations,
"LeadingOrder",
"Decay bosons using a leading order 2->2 calculation of the "
"production spin density matrix",
0);
static SwitchOption interfaceSpinCorrelationsRealNLO
(interfaceSpinCorrelations,
"RealNLO",
"Decay bosons using a production spin density matrix which "
"takes into account the effects of real radiation",
1);
static Reference<MEPP2VVPowheg,ShowerAlpha> interfaceCoupling
("Coupling",
"The object calculating the strong coupling constant",
&MEPP2VVPowheg::showerAlphaS_, false, false, true, false, false);
static Parameter<MEPP2VVPowheg,double> interfacePower
("Power",
"The power for the sampling of the matrix elements",
&MEPP2VVPowheg::power_, 2.0, 1.0, 10.0,
false, false, Interface::limited);
static Parameter<MEPP2VVPowheg,double> interfacePrefactorqqbar
("Prefactorqqbar",
"The prefactor for the sampling of the q qbar channel",
&MEPP2VVPowheg::preqqbar_, 5.0, 0.0, 1000.0,
false, false, Interface::limited);
static Parameter<MEPP2VVPowheg,double> interfacePrefactorqg
("Prefactorqg",
"The prefactor for the sampling of the q g channel",
&MEPP2VVPowheg::preqg_, 3.0, 0.0, 1000.0,
false, false, Interface::limited);
static Parameter<MEPP2VVPowheg,double> interfacePrefactorgqbar
("Prefactorgqbar",
"The prefactor for the sampling of the g qbar channel",
&MEPP2VVPowheg::pregqbar_, 3.0, 0.0, 1000.0,
false, false, Interface::limited);
static Parameter<MEPP2VVPowheg, Energy> interfacepTMin
("minPt",
"The pT cut on hardest emision generation"
"2*(1-Beta)*exp(-sqr(intrinsicpT/RMS))/sqr(RMS)",
&MEPP2VVPowheg::min_pT_, GeV, 2.*GeV, ZERO, 100000.0*GeV,
false, false, Interface::limited);
}
Energy2 MEPP2VVPowheg::scale() const {
// N.B. This scale is the electroweak scale!
// It is used in the evaluation of the LO code
// in the MEPP2VV base class. This means it
// should appear in the denominator of the
// NLOweight here and all other LO parts like
// the function for the lumi ratio (Lhat). It
// should also be used for evaluating any EW
// parameters / vertices in the numerator.
// The scaleopt_ == 1 "running" option is
// chosen to be like the MC@NLO one (it ought
// to be more like sHat instead?).
return scaleopt_ == 1 ?
// 0.5*(meMomenta()[2].m2()+meMomenta()[3].m2()) : sqr(mu_UV_);
sHat() : sqr(mu_UV_);
}
Energy2 MEPP2VVPowheg::mu_F2() const {
return scaleopt_ == 1 ?
// ((H_.k1r()).m2()+k1r_perp2_lab_+(H_.k2r()).m2()+k2r_perp2_lab_)/2. : sqr(mu_F_);
sHat() : sqr(mu_F_);
}
Energy2 MEPP2VVPowheg::mu_UV2() const {
return scaleopt_ == 1 ?
// ((H_.k1r()).m2()+k1r_perp2_lab_+(H_.k2r()).m2()+k2r_perp2_lab_)/2. : sqr(mu_UV_);
sHat() : sqr(mu_UV_);
}
void MEPP2VVPowheg::doinit() {
MEPP2VV::doinit();
// get the vertices we need
// get a pointer to the standard model object in the run
static const tcHwSMPtr hwsm
= dynamic_ptr_cast<tcHwSMPtr>(standardModel());
if (!hwsm) throw InitException()
<< "missing hwsm pointer in MEPP2VVPowheg::doinit()"
<< Exception::abortnow;
// get pointers to all required Vertex objects
FFPvertex_ = hwsm->vertexFFP();
FFZvertex_ = hwsm->vertexFFZ();
WWWvertex_ = hwsm->vertexWWW();
FFWvertex_ = hwsm->vertexFFW();
FFGvertex_ = hwsm->vertexFFG();
// get the ckm object
Ptr<StandardCKM>::pointer
theCKM=dynamic_ptr_cast<Ptr<StandardCKM>::pointer>(SM().CKM());
if(!theCKM) throw InitException() << "MEPP2VVPowheg::doinit() "
<< "the CKM object must be the Herwig one"
<< Exception::runerror;
unsigned int ix,iy;
// get the CKM matrix (unsquared for interference)
vector< vector<Complex > > CKM(theCKM->getUnsquaredMatrix(SM().families()));
for(ix=0;ix<3;++ix){for(iy=0;iy<3;++iy){ckm_[ix][iy]=CKM[ix][iy];}}
// insert the different prefactors in the vector for easy look up
prefactor_.push_back(preqqbar_);
prefactor_.push_back(preqg_);
prefactor_.push_back(pregqbar_);
}
int MEPP2VVPowheg::nDim() const {
int output = MEPP2VV::nDim();
// See related comment in MEPP2VVPowheg::generateKinematics!
if(contrib_>0) output += 2;
return output;
}
bool MEPP2VVPowheg::generateKinematics(const double * r) {
// N.B. A fix was made to make theta2 a radiative
// variable in r4532. Originally theta2 was take to
// be the azimuthal angle coming from the generation
// of the Born kinematics inherited from MEPP2VV i.e.
// before the change theta2 was a random number between
// 0 and 2pi. On changing theta2 was set to be
// theta2 = (*(r+3)) * 2.*Constants::pi;
// and nDim returned if(contrib_>0) output += 3;
// In the months following it was noticed that agreement
// with MCFM was per mille at Tevatron energies but got
// close to 1 percent for LHC energies (for all VV
// processes). After searching back up the svn branch
// running 2M events each time, the change was spotted
// to occur on r4532. Changing:
// if(contrib_>0) output += 3;
// in ::nDim() and also,
// xt = (*(r +nDim() -3));
// y = (*(r +nDim() -2)) * 2. - 1.;
// theta2 = (*(r +nDim() -1)) * 2.*Constants::pi;
// did not fix the problem. The following code gives the
// same good level of agreement at LHC and TVT:
double xt( -999.);
double y( -999.);
double theta2( -999.);
if(contrib_>0) {
// Generate the radiative integration variables:
xt = (*(r +nDim() -2));
y = (*(r +nDim() -1)) * 2. - 1.;
// KH 19th August - next line changed for phi in 0->pi not 0->2pi
// theta2 = UseRandom::rnd() * 2.*Constants::pi;
theta2 = UseRandom::rnd() *Constants::pi;
}
// Continue with lo matrix element code:
bool output(MEPP2VV::generateKinematics(r));
// Work out the kinematics for the leading order / virtual process
// and also get the leading order luminosity function:
getKinematics(xt,y,theta2);
return output;
}
double MEPP2VVPowheg::me2() const {
double output(0.0);
useMe();
output = MEPP2VV::me2();
double mcfm_brs(1.);
if(!removebr_) {
switch(MEPP2VV::process()) {
case 1: // W+(->e+,nu_e) W-(->e-,nu_ebar) (MCFM: 61 [nproc])
mcfm_brs *= 0.109338816;
mcfm_brs *= 0.109338816;
break;
case 2: // W+/-(mu+,nu_mu / mu-,nu_mubar) Z(nu_e,nu_ebar)
// (MCFM: 72+77 [nproc])
mcfm_brs *= 0.109338816;
mcfm_brs *= 0.06839002;
break;
case 3: // Z(mu-,mu+) Z(e-,e+) (MCFM: 86 [nproc])
mcfm_brs *= 0.034616433;
mcfm_brs *= 0.034616433;
mcfm_brs *= 2.; // as identical particle factor 1/2 is now obsolete.
break;
case 4: // W+(mu+,nu_mu) Z(nu_e,nu_ebar) (MCFM: 72 [nproc])
mcfm_brs *= 0.109338816;
mcfm_brs *= 0.06839002;
break;
case 5: // W-(mu-,nu_mubar) Z(nu_e,nu_ebar) (MCFM: 77 [nproc])
mcfm_brs *= 0.109338816;
mcfm_brs *= 0.06839002;
break;
}
}
// Store the value of the leading order squared matrix element:
lo_me2_ = output;
output *= NLOweight();
output *= mcfm_brs;
return output;
}
void MEPP2VVPowheg::getKinematics(double xt, double y, double theta2) {
// In this member we want to get the lo_lumi_ as this is a
// common denominator in the NLO weight. We want also the
// bornVVKinematics object and all of the realVVKinematics
// objects needed for the NLO weight.
// Check if the W- is first in W+W- production. Already confirmed
// mePartonData()[0] is a quark, and mePartonData()[1] is an antiquark.
// We assume mePartonData[2] and mePartonData[3] are, respectively,
// W+/- Z, W+/- W-/+, or Z Z.
bool wminus_first(false);
if((mePartonData()[2]->id()==-24)&&(mePartonData()[3]->id()==24))
wminus_first=true;
// Now get all data on the LO process needed for the NLO computation:
// The +z hadron in the lab:
hadron_A_=dynamic_ptr_cast<Ptr<BeamParticleData>::transient_const_pointer>
(lastParticles().first->dataPtr());
// The -z hadron in the lab:
hadron_B_=dynamic_ptr_cast<Ptr<BeamParticleData>::transient_const_pointer>
(lastParticles().second->dataPtr());
// Leading order momentum fractions:
double xa(lastX1()); // The +z momentum fraction in the lab.
double xb(lastX2()); // The -z momentum fraction in the lab.
// Particle data for incoming +z & -z QCD particles respectively:
ab_ = lastPartons().first ->dataPtr(); // The +z momentum parton in the lab.
bb_ = lastPartons().second->dataPtr(); // The -z momentum parton in the lab.
// We checked TVT & LHC for all VV channels with 10K events:
// lastParticles().first ->momentum().z() is always positive
// lastParticles().second->momentum().z() is always negative
// lastParticles().first ->momentum().z()*xa=lastPartons().first ->momentum().z() 1 in 10^6
// lastParticles().second->momentum().z()*xb=lastPartons().second->momentum().z() 1 in 10^6
// Set the quark and antiquark data pointers.
quark_ = mePartonData()[0];
antiquark_ = mePartonData()[1];
if(quark_->id()<0) swap(quark_,antiquark_);
// Now in _our_ calculation we basically define the +z axis as being
// given by the direction of the incoming quark for q+qb & q+g processes
// and the incoming gluon for g+qbar processes. So now we might need to
// flip the values of hadron_A_, hadron_B_, ab_, bb_, xa, xb accordingly:
if(ab_->id()!=quark_->id()) {
swap(hadron_A_,hadron_B_);
swap(ab_,bb_);
swap(xa,xb);
}
// So hadron_A_ is the thing containing a quark (ab_) with momentum frac xa,
// hadron_B_ is the thing containing an antiquark (bb_) with momentum frac xb.
// Now get the partonic flux for the Born process:
lo_lumi_ = hadron_A_->pdf()->xfx(hadron_A_,ab_,scale(),xa)/xa
* hadron_B_->pdf()->xfx(hadron_B_,bb_,scale(),xb)/xb;
// For W+W- events make sure k1 corresponds to the W+ momentum:
if(MEPP2VV::process()==1&&wminus_first) swap(meMomenta()[2],meMomenta()[3]);
// Create the object containing all 2->2 __kinematic__ information:
B_ = bornVVKinematics(meMomenta(),xa,xb);
// We checked that meMomenta()[0] (quark) is in the +z direction and meMomenta()[1]
// is in the -z direction (antiquark).
// Revert momentum swap in case meMomenta and mePartonData correlation
// needs preserving for other things.
if(MEPP2VV::process()==1&&wminus_first) swap(meMomenta()[2],meMomenta()[3]);
// Check the Born kinematics objects is internally consistent:
// B_.sanityCheck();
// If we are going beyond leading order then lets calculate all of
// the necessary real emission kinematics.
if(contrib_>0) {
// Soft limit of the 2->3 real emission kinematics:
S_ = realVVKinematics(B_, 1., y, theta2);
// Soft-collinear limit of the 2->3 kinematics (emission in +z direction):
SCp_ = realVVKinematics(B_, 1., 1., theta2);
// Soft-collinear limit of the 2->3 kinematics (emission in -z direction):
SCm_ = realVVKinematics(B_, 1.,-1., theta2);
// Collinear limit of the 2->3 kinematics (emission in +z direction):
Cp_ = realVVKinematics(B_, xt, 1., theta2);
// Collinear limit of the 2->3 kinematics (emission in -z direction):
Cm_ = realVVKinematics(B_, xt,-1., theta2);
// The resolved 2->3 real emission kinematics:
H_ = realVVKinematics(B_, xt, y, theta2);
// Borrowed from VVhardGenerator (lab momenta of k1,k2):
Energy pT(sqrt(H_.pT2_in_lab()));
LorentzRotation yzRotation;
yzRotation.setRotateX(-atan2(pT/GeV,sqrt(B_.sb())/GeV));
LorentzRotation boostFrompTisZero;
boostFrompTisZero.setBoostY(-pT/sqrt(B_.sb()+pT*pT));
LorentzRotation boostFromYisZero;
boostFromYisZero.setBoostZ(tanh(B_.Yb()));
k1r_perp2_lab_ = (boostFromYisZero*boostFrompTisZero*yzRotation*(H_.k1r())).perp2();
k2r_perp2_lab_ = (boostFromYisZero*boostFrompTisZero*yzRotation*(H_.k2r())).perp2();
// Check all the real kinematics objects are internally consistent:
// S_.sanityCheck();
// SCp_.sanityCheck();
// SCm_.sanityCheck();
// Cp_.sanityCheck();
// Cm_.sanityCheck();
// H_.sanityCheck();
}
return;
}
double MEPP2VVPowheg::NLOweight() const {
// If only leading order is required return 1:
if(contrib_==0) return lo_me()/lo_me2_;
// Calculate alpha_S and alpha_S/(2*pi).
alphaS_ = nlo_alphaS_opt_==1 ? fixed_alphaS_ : SM().alphaS(mu_UV2());
double alsOn2pi(alphaS_/2./pi);
// Particle data objects for the new plus and minus colliding partons.
tcPDPtr gluon;
gluon = getParticleData(ParticleID::g);
// Get the all couplings.
gW_ = sqrt(4.0*pi*SM().alphaEM(scale())/SM().sin2ThetaW());
sin2ThetaW_ = SM().sin2ThetaW();
double cosThetaW(sqrt(1.-sin2ThetaW_));
guL_ = gW_/2./cosThetaW*( 1.-4./3.*sin2ThetaW_);
gdL_ = gW_/2./cosThetaW*(-1.+2./3.*sin2ThetaW_);
guR_ = gW_/2./cosThetaW*( -4./3.*sin2ThetaW_);
gdR_ = gW_/2./cosThetaW*( +2./3.*sin2ThetaW_);
eZ_ = gW_*cosThetaW;
eZ2_ = sqr(eZ_);
// MCFM has gwsq = 0.4389585130009 -> gw = 0.662539442600115
// Here we have gW_ = 0.662888
// MCFM has xw = 0.22224653300000 -> sqrt(xw) = 0.471430306
// Here we have 0.222247
// MCFM has esq = 0.097557007645279 -> e = 0.31234117187024679
// Here we have 4.0*pi*SM().alphaEM(sqr(100.*GeV)) = 0.0976596
// If the process is W-Z instead of W+Z we must transform these
// couplings as follows, according to NPB 383(1992)3-44 Eq.3.23
if(mePartonData()[2]->id()==-24&&mePartonData()[3]->id()==23) {
swap(guL_,gdL_);
eZ_ *= -1.;
}
// Get the CKM entry. Note that this code was debugged
// considerably; the call to CKM(particle,particle)
// did not appear to work, so we extract the elements
// as follows below. The right numbers now appear to
// to be associated with the right quarks.
double Kij(-999.);
// W+Z / W-Z
if(abs(mePartonData()[2]->id())==24&&mePartonData()[3]->id()==23) {
int up_id(-999),dn_id(-999);
if(abs(quark_->id())%2==0&&abs(antiquark_->id())%2==1) {
up_id = abs(quark_->id());
dn_id = abs(antiquark_->id());
}
else if(abs(quark_->id())%2==1&&abs(antiquark_->id())%2==0) {
up_id = abs(antiquark_->id());
dn_id = abs(quark_->id());
}
else {
cout << "MEPP2VVPowheg:" << endl;
cout << "WZ needs an up and a down type quark as incoming!" << endl;
}
up_id /= 2;
up_id -= 1;
dn_id -= 1;
dn_id /= 2;
Kij = sqrt(SM().CKM(up_id,dn_id));
}
// W+W-
else if(abs(mePartonData()[2]->id())==24&&abs(mePartonData()[3]->id())==24) {
if(abs(quark_->id())%2==0&&abs(antiquark_->id())%2==0) {
int up_ida(abs(quark_->id())/2-1);
int up_idb(abs(antiquark_->id())/2-1);
Kij = sqrt(std::norm( CKM(up_ida,0)*CKM(up_idb,0)
+ CKM(up_ida,1)*CKM(up_idb,1)
+ CKM(up_ida,2)*CKM(up_idb,2)));
}
else if(abs(quark_->id())%2==1&&abs(antiquark_->id())%2==1) {
int dn_ida((abs(quark_->id())-1)/2);
int dn_idb((abs(antiquark_->id())-1)/2);
Kij = sqrt(std::norm( CKM(0,dn_ida)*CKM(0,dn_idb)
+ CKM(1,dn_ida)*CKM(1,dn_idb)
+ CKM(2,dn_ida)*CKM(2,dn_idb)));
}
else {
cout << "MEPP2VVPowheg:" << endl;
cout << "WW needs 2 down-type / 2 up-type!" << endl;
}
}
// ZZ
else if(mePartonData()[2]->id()==23&&mePartonData()[3]->id()==23) {
Kij = 2.*sqrt(2.)/gW_;
}
else {
cout << "MEPP2VVPowheg: incompatible final state particles!" << endl;
}
Fij2_ = sqr(gW_/2./sqrt(2.)*Kij);
// Get the leading order matrix element (this is necessary!)
M_Born_ = M_Born_WZ(B_);
// // Get the regular part of the virtual correction (only needed for sanityCheck()!)
// M_V_regular_ = M_V_regular(S_);
// // Get the q + qbar real emission matrix element (only needed for sanityCheck()!)
// t_u_M_R_qqb_ = t_u_M_R_qqb(H_);
// Calculate the integrand
double wgt(0.);
double wqqb(0.);
double wgqb(0.);
double wqg(0.);
double wqqbvirt(0.);
double wqqbcollin(0.);
double wqqbreal(0.);
double wqgcollin(0.);
double wqgreal(0.);
double wgqbcollin(0.);
double wgqbreal(0.);
if(channels_==0||channels_==1) {
// q+qb
wqqbvirt = Vtilde_universal(S_) + M_V_regular(S_)/lo_me2_;
wqqbcollin = alsOn2pi*( Ctilde_Ltilde_qq_on_x(quark_,antiquark_,Cp_)
+ Ctilde_Ltilde_qq_on_x(quark_,antiquark_,Cm_) );
wqqbreal = alsOn2pi*Rtilde_Ltilde_qqb_on_x(quark_,antiquark_);
wqqb = wqqbvirt + wqqbcollin + wqqbreal;
}
if(channels_==0||channels_==2) {
// q+g
wqgcollin = alsOn2pi*Ctilde_Ltilde_gq_on_x(quark_,gluon,Cm_);
wqgreal = alsOn2pi*Rtilde_Ltilde_qg_on_x(quark_,gluon);
wqg = wqgreal + wqgcollin;
// g+qb
wgqbcollin = alsOn2pi*Ctilde_Ltilde_gq_on_x(gluon,antiquark_,Cp_);
wgqbreal = alsOn2pi*Rtilde_Ltilde_gqb_on_x(gluon,antiquark_);
wgqb = wgqbreal+wgqbcollin;
}
// total contribution
wgt = 1.+(wqqb+wgqb+wqg);
// If restricting to qg, gqb channels then subtract the LO contribution:
if(channels_==2) wgt -= 1.;
if(isnan(wgt)||isinf(wgt)) {
cout << "MEPP2VVPowheg:: NLO weight "
<< "is bad: wgt = " << wgt << endl;
cout << "MEPP2VVPowheg sanityCheck invoked!" << endl;
cout << ab_->PDGName() << ", "
<< bb_->PDGName() << ", "
<< mePartonData()[2]->PDGName() << ", "
<< mePartonData()[3]->PDGName() << endl;
cout << "lo_me2_ - M_Born_ (rel) = "
<< lo_me2_-M_Born_ << " ("
<< (lo_me2_-M_Born_)/M_Born_ << ")\n";
cout << "lo_me2_, M_Born_ " << lo_me2_ << ", " << M_Born_ << endl;
cout << "xr = " << H_.xr() << " 1-xr = " << 1.-H_.xr() << " y = " << H_.y() << endl;
cout << "tkr = " << H_.tkr()/GeV2 << " ukr = " << H_.ukr()/GeV2 << endl;
cout << "root(sb) = " << sqrt(B_.sb())/GeV << endl;
cout << "sb+tb+ub = "
<< B_.sb()/GeV2 << " + "
<< B_.tb()/GeV2 << " + " << B_.ub()/GeV2 << endl;
cout << "sqrt(k12) " << sqrt(H_.k12r())/GeV << endl;
cout << "sqrt(k22) " << sqrt(H_.k22r())/GeV << endl;
cout << "sqr(Kij) " << Kij*Kij << endl;
cout << "wqqbvirt " << wqqbvirt << endl;
cout << "wqqbcollin " << wqqbcollin << endl;
cout << "wqqbreal " << wqqbreal << endl;
cout << "wqqb " << wqqb << endl;
cout << "wqgcollin " << wqgcollin << endl;
cout << "wqgreal " << wqgreal << endl;
cout << "wqg " << wqg << endl;
cout << "wgqbcollin " << wgqbcollin << endl;
cout << "wgqbreal " << wgqbreal << endl;
cout << "wgqb " << wgqb << endl;
cout << "wgt " << wgt << endl;
throw Exception() << "MEPP2VVPowheg:: NLO weight "
<< "is bad: " << wgt
<< Exception::eventerror;
}
return contrib_==1 ? max(0.,wgt) : max(0.,-wgt);
}
double MEPP2VVPowheg::Lhat_ab(tcPDPtr a, tcPDPtr b,
realVVKinematics Kinematics) const {
if(!(abs(a->id())<=6||a->id()==21)||!(abs(b->id())<=6||b->id()==21))
cout << "MEPP2VVPowheg::Lhat_ab: Error,"
<< "particle a = " << a->PDGName() << ", "
<< "particle b = " << b->PDGName() << endl;
double nlo_lumi(-999.);
double x1(Kinematics.x1r()),x2(Kinematics.x2r());
nlo_lumi = (hadron_A_->pdf()->xfx(hadron_A_,a,mu_F2(),x1)/x1)
* (hadron_B_->pdf()->xfx(hadron_B_,b,mu_F2(),x2)/x2);
return nlo_lumi / lo_lumi_;
}
double MEPP2VVPowheg::Vtilde_universal(realVVKinematics S) const {
double xbar_y = S.xbar();
double y = S.y();
double eta1b(S.bornVariables().eta1b());
double eta2b(S.bornVariables().eta2b());
Energy2 sb(S.s2r());
return alphaS_/2./pi*CF_
* ( log(sb/mu_F2())
* (3. + 4.*log(eta1b)+4.*log(eta2b))
+ 8.*sqr(log(eta1b)) +8.*sqr(log(eta2b))
- 2.*sqr(pi)/3.
)
+ alphaS_/2./pi*CF_
* ( 8./(1.+y)*log(sqrt(1.-xbar_y)/eta2b)
+ 8./(1.-y)*log(sqrt(1.-xbar_y)/eta1b)
);
}
double MEPP2VVPowheg::Ctilde_Ltilde_qq_on_x(tcPDPtr a, tcPDPtr b,
realVVKinematics C) const {
if(C.y()!= 1.&&C.y()!=-1.)
cout << "\nCtilde_qq::y value not allowed.";
if(C.y()== 1.&&!(abs(a->id())>0&&abs(a->id())<7))
cout << "\nCtilde_qq::for Cqq^plus a must be a quark! id = "
<< a->id() << "\n";
if(C.y()==-1.&&!(abs(b->id())>0&&abs(b->id())<7))
cout << "\nCtilde_qq::for Cqq^minus b must be a quark! id = "
<< b->id() << "\n";
double xt = C.xt();
double x = C.xr();
double etab = C.y() == 1. ? C.bornVariables().eta1b()
: C.bornVariables().eta2b() ;
Energy2 sb(C.s2r());
if(fabs(1.-xt)<=tiny||fabs(1.-H_.xr())<=tiny) return 0.;
return ( ( (1./(1.-xt))*log(sb/mu_F2()/x)+4.*log(etab)/(1.-xt)
+ 2.*log(1.-xt)/(1.-xt)
)*CF_*(1.+sqr(x))
+ sqr(etab)*CF_*(1.-x)
)*Lhat_ab(a,b,C) / x
- ( ( (1./(1.-xt))*log(sb/mu_F2() )+4.*log(etab)/(1.-xt)
+ 2.*log(1.-xt)/(1.-xt)
)*CF_*2.
)*Lhat_ab(a,b,S_);
}
double MEPP2VVPowheg::Ctilde_Ltilde_gq_on_x(tcPDPtr a, tcPDPtr b,
realVVKinematics C) const {
if(C.y()!= 1.&&C.y()!=-1.)
cout << "\nCtilde_gq::y value not allowed.";
if(C.y()== 1.&&a->id()!=21)
cout << "\nCtilde_gq::for Cgq^plus a must be a gluon! id = "
<< a->id() << "\n";
if(C.y()==-1.&&b->id()!=21)
cout << "\nCtilde_gq::for Cgq^minus b must be a gluon! id = "
<< b->id() << "\n";
double xt = C.xt();
double x = C.xr();
double etab = C.y() == 1. ? C.bornVariables().eta1b()
: C.bornVariables().eta2b() ;
Energy2 sb(C.s2r());
return ( ( (1./(1.-xt))*log(sb/mu_F2()/x)+4.*log(etab)/(1.-xt)
+ 2.*log(1.-xt)/(1.-xt)
)*(1.-x)*TR_*(sqr(x)+sqr(1.-x))
+ sqr(etab)*TR_*2.*x*(1.-x)
)*Lhat_ab(a,b,C) / x;
}
double MEPP2VVPowheg::Rtilde_Ltilde_qqb_on_x(tcPDPtr a , tcPDPtr b) const {
if(!(abs(a->id())<=6||a->id()==21)||!(abs(b->id())<=6||b->id()==21))
cout << "MEPP2VVPowheg::Rtilde_Ltilde_qqb_on_x: Error,"
<< "particle a = " << a->PDGName() << ", "
<< "particle b = " << b->PDGName() << endl;
double xt(H_.xt());
double y(H_.y());
Energy2 s(H_.sr());
Energy2 sCp(Cp_.sr());
Energy2 sCm(Cm_.sr());
Energy2 t_u_M_R_qqb_H (t_u_M_R_qqb(H_ ));
Energy2 t_u_M_R_qqb_Cp(t_u_M_R_qqb(Cp_));
Energy2 t_u_M_R_qqb_Cm(t_u_M_R_qqb(Cm_));
// Energy2 t_u_M_R_qqb_H (t_u_M_R_qqb_hel_amp(H_));
// Energy2 t_u_M_R_qqb_Cp(8.*pi*alphaS_*Cp_.sr()/Cp_.xr()
// *CF_*(1.+sqr(Cp_.xr()))*lo_me2_);
// Energy2 t_u_M_R_qqb_Cm(8.*pi*alphaS_*Cm_.sr()/Cm_.xr()
// *CF_*(1.+sqr(Cm_.xr()))*lo_me2_);
int config(0);
if(fabs(1.-xt)<=tiny||fabs(1.-H_.xr())<=tiny) return 0.;
if(fabs(1.-y )<=tiny) { t_u_M_R_qqb_H = t_u_M_R_qqb_Cp ; config = 1; }
if(fabs(1.+y )<=tiny) { t_u_M_R_qqb_H = t_u_M_R_qqb_Cm ; config = -1; }
if(fabs(H_.tkr()/s)<=tiny) { t_u_M_R_qqb_H = t_u_M_R_qqb_Cp ; config = 1; }
if(fabs(H_.ukr()/s)<=tiny) { t_u_M_R_qqb_H = t_u_M_R_qqb_Cm ; config = -1; }
if(config== 0)
return
( ( (t_u_M_R_qqb_H*Lhat_ab(a,b,H_)/s - t_u_M_R_qqb_Cp*Lhat_ab(a,b,Cp_)/sCp)
)*2./(1.-y)/(1.-xt)
+ ( (t_u_M_R_qqb_H*Lhat_ab(a,b,H_)/s - t_u_M_R_qqb_Cm*Lhat_ab(a,b,Cm_)/sCm)
)*2./(1.+y)/(1.-xt)
) / lo_me2_ / 8. / pi / alphaS_;
else if(config== 1)
return
( (t_u_M_R_qqb_H*Lhat_ab(a,b,H_)/s - t_u_M_R_qqb_Cm*Lhat_ab(a,b,Cm_)/sCm)
)*2./(1.+y)/(1.-xt) / lo_me2_ / 8. / pi / alphaS_;
else if(config==-1)
return
( (t_u_M_R_qqb_H*Lhat_ab(a,b,H_)/s - t_u_M_R_qqb_Cp*Lhat_ab(a,b,Cp_)/sCp)
)*2./(1.-y)/(1.-xt) / lo_me2_ / 8. / pi / alphaS_;
else
throw Exception()
<< "MEPP2VVPowheg::Rtilde_Ltilde_qqb_on_x\n"
<< "The configuration is not identified as hard / soft / fwd collinear or bwd collinear."
<< "config = " << config << "\n"
<< "xt = " << xt << " 1.-xt = " << 1.-xt << "\n"
<< "y = " << y << " 1.-y = " << 1.-y << "\n"
<< Exception::eventerror;
}
double MEPP2VVPowheg::Rtilde_Ltilde_gqb_on_x(tcPDPtr a , tcPDPtr b) const {
if(!(abs(a->id())<=6||a->id()==21)||!(abs(b->id())<=6||b->id()==21))
cout << "MEPP2VVPowheg::Rtilde_Ltilde_gqb_on_x: Error,"
<< "particle a = " << a->PDGName() << ", "
<< "particle b = " << b->PDGName() << endl;
double xt(H_.xt());
double y(H_.y());
Energy2 s(H_.sr());
Energy2 sCp(Cp_.sr());
Energy2 sCm(Cm_.sr());
Energy2 t_u_M_R_gqb_H (t_u_M_R_gqb(H_ ));
Energy2 t_u_M_R_gqb_Cp(t_u_M_R_gqb(Cp_));
Energy2 t_u_M_R_gqb_Cm(t_u_M_R_gqb(Cm_));
// Energy2 t_u_M_R_gqb_H (t_u_M_R_gqb_hel_amp(H_));
// Energy2 t_u_M_R_gqb_Cp(8.*pi*alphaS_*Cp_.sr()/Cp_.xr()*(1.-Cp_.xr())
// *TR_*(sqr(Cp_.xr())+sqr(1.-Cp_.xr()))*lo_me2_);
// Energy2 t_u_M_R_gqb_Cm(t_u_M_R_gqb(Cm_));
// // Energy2 t_u_M_R_gqb_Cm(t_u_M_R_gqb_hel_amp(Cm_));
int config(0);
if(fabs(1.-xt)<=tiny||fabs(1.-H_.xr())<=tiny) return 0.;
if(fabs(1.-y )<=tiny) { t_u_M_R_gqb_H = t_u_M_R_gqb_Cp ; config = 1; }
if(fabs(1.+y )<=tiny) { t_u_M_R_gqb_H = t_u_M_R_gqb_Cm ; config = -1; }
if(fabs(H_.tkr()/s)<=tiny) { t_u_M_R_gqb_H = t_u_M_R_gqb_Cp ; config = 1; }
if(fabs(H_.ukr()/s)<=tiny) { t_u_M_R_gqb_H = t_u_M_R_gqb_Cm ; config = -1; }
if(config== 0)
return
( ( (t_u_M_R_gqb_H*Lhat_ab(a,b,H_)/s - t_u_M_R_gqb_Cp*Lhat_ab(a,b,Cp_)/sCp)
)*2./(1.-y)/(1.-xt)
+ ( (t_u_M_R_gqb_H*Lhat_ab(a,b,H_)/s - t_u_M_R_gqb_Cm*Lhat_ab(a,b,Cm_)/sCm)
)*2./(1.+y)/(1.-xt)
) / lo_me2_ / 8. / pi / alphaS_;
else if(config== 1)
return
( (t_u_M_R_gqb_H*Lhat_ab(a,b,H_)/s - t_u_M_R_gqb_Cm*Lhat_ab(a,b,Cm_)/sCm)
)*2./(1.+y)/(1.-xt) / lo_me2_ / 8. / pi / alphaS_;
else if(config==-1)
return
( (t_u_M_R_gqb_H*Lhat_ab(a,b,H_)/s - t_u_M_R_gqb_Cp*Lhat_ab(a,b,Cp_)/sCp)
)*2./(1.-y)/(1.-xt) / lo_me2_ / 8. / pi / alphaS_;
else
throw Exception()
<< "MEPP2VVPowheg::Rtilde_Ltilde_gqb_on_x\n"
<< "The configuration is not identified as hard / soft / fwd collinear or bwd collinear."
<< "config = " << config << "\n"
<< "xt = " << xt << " 1.-xt = " << 1.-xt << "\n"
<< "y = " << y << " 1.-y = " << 1.-y << "\n"
<< Exception::eventerror;
}
double MEPP2VVPowheg::Rtilde_Ltilde_qg_on_x(tcPDPtr a , tcPDPtr b) const {
if(!(abs(a->id())<=6||a->id()==21)||!(abs(b->id())<=6||b->id()==21))
cout << "MEPP2VVPowheg::Rtilde_Ltilde_qg_on_x: Error,"
<< "particle a = " << a->PDGName() << ", "
<< "particle b = " << b->PDGName() << endl;
double xt(H_.xt());
double y(H_.y());
Energy2 s(H_.sr());
Energy2 sCp(Cp_.sr());
Energy2 sCm(Cm_.sr());
Energy2 t_u_M_R_qg_H (t_u_M_R_qg(H_ ));
Energy2 t_u_M_R_qg_Cp(t_u_M_R_qg(Cp_));
Energy2 t_u_M_R_qg_Cm(t_u_M_R_qg(Cm_));
// Energy2 t_u_M_R_qg_H (t_u_M_R_qg_hel_amp(H_));
// Energy2 t_u_M_R_qg_Cp(t_u_M_R_qg(Cp_));
// // Energy2 t_u_M_R_qg_Cp(t_u_M_R_qg_hel_amp(Cp_));
// Energy2 t_u_M_R_qg_Cm(8.*pi*alphaS_*Cm_.sr()/Cm_.xr()*(1.-Cm_.xr())
// *TR_*(sqr(Cm_.xr())+sqr(1.-Cm_.xr()))*lo_me2_);
int config(0);
if(fabs(1.-xt)<=tiny||fabs(1.-H_.xr())<=tiny) return 0.;
if(fabs(1.-y )<=tiny) { t_u_M_R_qg_H = t_u_M_R_qg_Cp ; config = 1; }
if(fabs(1.+y )<=tiny) { t_u_M_R_qg_H = t_u_M_R_qg_Cm ; config = -1; }
if(fabs(H_.tkr()/s)<=tiny) { t_u_M_R_qg_H = t_u_M_R_qg_Cp ; config = 1; }
if(fabs(H_.ukr()/s)<=tiny) { t_u_M_R_qg_H = t_u_M_R_qg_Cm ; config = -1; }
if(config== 0)
return
( ( (t_u_M_R_qg_H*Lhat_ab(a,b,H_)/s - t_u_M_R_qg_Cp*Lhat_ab(a,b,Cp_)/sCp)
)*2./(1.-y)/(1.-xt)
+ ( (t_u_M_R_qg_H*Lhat_ab(a,b,H_)/s - t_u_M_R_qg_Cm*Lhat_ab(a,b,Cm_)/sCm)
)*2./(1.+y)/(1.-xt)
) / lo_me2_ / 8. / pi / alphaS_;
else if(config== 1)
return
( (t_u_M_R_qg_H*Lhat_ab(a,b,H_)/s - t_u_M_R_qg_Cm*Lhat_ab(a,b,Cm_)/sCm)
)*2./(1.+y)/(1.-xt) / lo_me2_ / 8. / pi / alphaS_;
else if(config==-1)
return
( (t_u_M_R_qg_H*Lhat_ab(a,b,H_)/s - t_u_M_R_qg_Cp*Lhat_ab(a,b,Cp_)/sCp)
)*2./(1.-y)/(1.-xt) / lo_me2_ / 8. / pi / alphaS_;
else
throw Exception()
<< "MEPP2VVPowheg::Rtilde_Ltilde_qg_on_x\n"
<< "The configuration is not identified as hard / soft / fwd collinear or bwd collinear."
<< "config = " << config << "\n"
<< "xt = " << xt << " 1.-xt = " << 1.-xt << "\n"
<< "y = " << y << " 1.-y = " << 1.-y << "\n"
<< Exception::eventerror;
}
/***************************************************************************/
// The following three functions are identically \tilde{I}_{4,t},
// \tilde{I}_{3,WZ} and \tilde{I}_{3,W} given in Eqs. B.8,B.9,B.10
// of NPB 383(1992)3-44, respectively. They are related to / derived
// from the loop integrals in Eqs. A.3, A.5 and A.8 of the same paper.
InvEnergy4 TildeI4t(Energy2 s, Energy2 t, Energy2 mW2, Energy2 mZ2);
InvEnergy2 TildeI3WZ(Energy2 s, Energy2 mW2, Energy2 mZ2, double beta);
InvEnergy2 TildeI3W(Energy2 s, Energy2 t, Energy2 mW2);
/***************************************************************************/
// The following six functions are identically I_{dd}^{(1)}, I_{ud}^{(1)},
// I_{uu}^{(1)}, F_{u}^{(1)}, F_{d}^{(1)}, H^{(1)} from Eqs. B.4, B.5, B.3,
// B.3, B.6, B.7 of NPB 383(1992)3-44, respectively. They make up the
// one-loop matrix element. Ixx functions correspond to the graphs
// with no TGC, Fx functions are due to non-TGC graphs interfering
// with TGC graphs, while the H function is due purely to TGC graphs.
double Idd1(Energy2 s,Energy2 t,Energy2 u,Energy2 mW2,Energy2 mZ2,double beta);
double Iud1(Energy2 s,Energy2 t,Energy2 u,Energy2 mW2,Energy2 mZ2,double beta);
double Iuu1(Energy2 s,Energy2 t,Energy2 u,Energy2 mW2,Energy2 mZ2,double beta);
Energy2 Fu1(Energy2 s,Energy2 t,Energy2 u,Energy2 mW2,Energy2 mZ2,double beta);
Energy2 Fd1(Energy2 s,Energy2 t,Energy2 u,Energy2 mW2,Energy2 mZ2,double beta);
Energy4 H1 (Energy2 s,Energy2 t,Energy2 u,Energy2 mW2,Energy2 mZ2);
/***************************************************************************/
// M_V_Regular is the regular part of the one-loop matrix element
// exactly as defined in Eqs. B.1 and B.2 of of NPB 383(1992)3-44.
double MEPP2VVPowheg::M_V_regular(realVVKinematics S) const {
Energy2 s(S.bornVariables().sb());
Energy2 t(S.bornVariables().tb());
Energy2 u(S.bornVariables().ub());
Energy2 mW2(S.k12r()); // N.B. the diboson masses are preserved in getting
Energy2 mZ2(S.k22r()); // the 2->2 from the 2->3 kinematics.
double beta(S.betaxr()); // N.B. for x=1 \beta_x=\beta in NPB 383(1992)3-44.
double cosThetaW(sqrt(1.-sin2ThetaW_));
double eZ2(eZ2_);
double eZ(eZ_);
double gdL(gdL_);
double guL(guL_);
double gdR(gdR_);
double guR(guR_);
// W+W-
if(abs(mePartonData()[2]->id())==24&&abs(mePartonData()[3]->id())==24) {
double e2(sqr(gW_)*sin2ThetaW_);
if(abs(quark_->id())%2==0&&abs(antiquark_->id())%2==0) {
// N.B. OLD eZ used to calculate new eZ2 *then* new eZ is set!
if(quark_->id()==-antiquark_->id()) {
eZ2 = 1./2.*sqr(s-mW2)/Fij2_
* (e2*e2/s/s*(sqr( 2./3.+eZ*(guL+guR)/2./e2*s/(s-mW2/sqr(cosThetaW)))
+sqr( eZ*(guL-guR)/2./e2*s/(s-mW2/sqr(cosThetaW))))
);
eZ = -1./2./Fij2_/(gW_*gW_/4./sqrt(Fij2_))*(s-mW2)
* (gW_*gW_*e2/4./s *( 2./3.+2.*eZ*guL/2./e2*s/(s-mW2/sqr(cosThetaW))));
} else {
eZ2 =0.;
eZ =0.;
}
gdL = gW_/sqrt(2.);
guL = 0.;
}
else if(abs(quark_->id())%2==1&&abs(antiquark_->id())%2==1) {
// N.B. OLD eZ used to calculate new eZ2 *then* new eZ is set!
if(quark_->id()==-antiquark_->id()) {
eZ2 = 1./2.*sqr(s-mW2)/Fij2_
* (e2*e2/s/s*(sqr(-1./3.+eZ*(gdL+gdR)/2./e2*s/(s-mW2/sqr(cosThetaW)))
+sqr( eZ*(gdL-gdR)/2./e2*s/(s-mW2/sqr(cosThetaW))))
);
eZ = -1./2./Fij2_/(gW_*gW_/4./sqrt(Fij2_))*(s-mW2)
* (gW_*gW_*e2/4./s *(-1./3.+2.*eZ*gdL/2./e2*s/(s-mW2/sqr(cosThetaW))));
} else {
eZ2 =0.;
eZ =0.;
}
guL = gW_/sqrt(2.);
gdL = 0.;
}
}
// ZZ
else if(mePartonData()[2]->id()==23&&mePartonData()[3]->id()==23) {
eZ = 0.;
eZ2 = 0.;
double gV2,gA2;
gV2 = sqr(guL/2.-gW_/2./cosThetaW*2./3.*sin2ThetaW_);
gA2 = sqr(guL/2.+gW_/2./cosThetaW*2./3.*sin2ThetaW_);
guL = sqrt(gV2*gV2+gA2*gA2+6.*gA2*gV2)/2.;
gV2 = sqr(gdL/2.+gW_/2./cosThetaW*1./3.*sin2ThetaW_);
gA2 = sqr(gdL/2.-gW_/2./cosThetaW*1./3.*sin2ThetaW_);
gdL = sqrt(gV2*gV2+gA2*gA2+6.*gA2*gV2)/2.;
if(abs(quark_->id())%2==0&&abs(antiquark_->id())%2==0) gdL = guL;
else if(abs(quark_->id())%2==1&&abs(antiquark_->id())%2==1) guL = gdL;
else {
cout << "MEPP2VVPowheg:" << endl;
cout << "ZZ needs 2 down-type / 2 up-type!" << endl;
}
}
return 4.*pi*alphaS_*Fij2_*CF_*(1./sqr(4.*pi))/NC_
* ( gdL*gdL*Idd1(s,t,u,mW2,mZ2,beta)
+ gdL*guL*Iud1(s,t,u,mW2,mZ2,beta)
+ guL*guL*Iuu1(s,t,u,mW2,mZ2,beta)
- eZ/(s-mW2) * ( gdL*Fd1(s,t,u,mW2,mZ2,beta)
- guL*Fu1(s,t,u,mW2,mZ2,beta)
)
+ eZ2/sqr(s-mW2) * H1(s,t,u,mW2,mZ2)
);
}
/***************************************************************************/
InvEnergy4 TildeI4t(Energy2 s, Energy2 t, Energy2 mW2, Energy2 mZ2) {
double sqrBrackets;
sqrBrackets = ( sqr(log(-t/mW2))/2.+log(-t/mW2)*log(-t/mZ2)/2.
- 2.*log(-t/mW2)*log((mW2-t)/mW2)-2.*ReLi2(t/mW2)
);
swap(mW2,mZ2);
sqrBrackets+= ( sqr(log(-t/mW2))/2.+log(-t/mW2)*log(-t/mZ2)/2.
- 2.*log(-t/mW2)*log((mW2-t)/mW2)-2.*ReLi2(t/mW2)
);
swap(mW2,mZ2);
return sqrBrackets/s/t;
}
InvEnergy2 TildeI3WZ(Energy2 s, Energy2 mW2, Energy2 mZ2, double beta) {
Energy2 sig(mZ2+mW2);
Energy2 del(mZ2-mW2);
double sqrBrackets ;
sqrBrackets = ( ReLi2(2.*mW2/(sig-del*(del/s+beta)))
+ ReLi2((1.-del/s+beta)/2.)
+ sqr(log((1.-del/s+beta)/2.))/2.
+ log((1.-del/s-beta)/2.)*log((1.+del/s-beta)/2.)
);
beta *= -1;
sqrBrackets -= ( ReLi2(2.*mW2/(sig-del*(del/s+beta)))
+ ReLi2((1.-del/s+beta)/2.)
+ sqr(log((1.-del/s+beta)/2.))/2.
+ log((1.-del/s-beta)/2.)*log((1.+del/s-beta)/2.)
);
beta *= -1;
swap(mW2,mZ2);
del *= -1.;
sqrBrackets += ( ReLi2(2.*mW2/(sig-del*(del/s+beta)))
+ ReLi2((1.-del/s+beta)/2.)
+ sqr(log((1.-del/s+beta)/2.))/2.
+ log((1.-del/s-beta)/2.)*log((1.+del/s-beta)/2.)
);
swap(mW2,mZ2);
del *= -1.;
beta *= -1;
swap(mW2,mZ2);
del *= -1.;
sqrBrackets -= ( ReLi2(2.*mW2/(sig-del*(del/s+beta)))
+ ReLi2((1.-del/s+beta)/2.)
+ sqr(log((1.-del/s+beta)/2.))/2.
+ log((1.-del/s-beta)/2.)*log((1.+del/s-beta)/2.)
);
beta *= -1;
swap(mW2,mZ2);
del *= -1.;
return sqrBrackets/s/beta;
}
InvEnergy2 TildeI3W(Energy2 s, Energy2 t, Energy2 mW2) {
return
1./(mW2-t)*(sqr(log(mW2/s))/2.-sqr(log(-t/s))/2.-sqr(pi)/2.);
}
/***************************************************************************/
double Idd1(Energy2 s, Energy2 t, Energy2 u, Energy2 mW2, Energy2 mZ2, double beta) {
Energy2 sig(mZ2+mW2);
Energy2 del(mZ2-mW2);
double Val(0.);
Val += 2.*(22.*t*t+t*(19.*s-18.*sig)+18.*mW2*mZ2)/t/t
- 8.*(u*t+2*s*sig)/mW2/mZ2
- 2.*sqr(t-u)/t/s/sqr(beta);
Val += +( 2.*(8.*t*t+4.*t*(s-3.*sig)+4*sqr(sig)-5.*s*sig+s*s)/t/s/sqr(beta)
+ 4.*(t*(3.*u+s)-3.*mW2*mZ2)/t/t
+ 6.*(t+u)*sqr(t-u)/t/s/s/sqr(sqr(beta))
)*log(-t/s);
Val += +( ( 8.*t*t*(-2.*s+del)+8.*t*(-s*s+3.*s*sig-2.*del*sig)
- 2.*(s-sig)*(s*s-4.*s*sig+3.*del*sig)
)/t/s/s/beta/beta
+ 16.*s*(t-mZ2)/(t*(u+s)-mW2*mZ2)
+ 2.*(4.*t*t+t*(10.*s-3.*mZ2-9.*mW2)+12.*mW2*mZ2)/t/t
-6.*(s-del)*(t+u)*sqr(t-u)/t/s/s/s/sqr(sqr(beta))
)*log(-t/mW2);
Val += ( - ( 4.*t*t*(2.*sig-3.*s)
- 4.*t*(s-sig)*(2.*s-3.*sig)
- 2.*(s-2.*sig)*sqr(s-sig)
)/t/s/beta/beta
+ ( 4.*sig*t-3.*s*s+4.*s*sig
- 4.*(mW2*mW2+mZ2*mZ2)
)/t
- 3.*sqr(t*t-u*u)/t/s/s/sqr(sqr(beta))
)*TildeI3WZ(s,mW2,mZ2,beta);
Val += +( 4.*(t*u+2.*s*sig)/3./mW2/mZ2 - 4.*(t-2.*u)/3./t
)*pi*pi;
Val += -( 4.*s*(t*u-2.*mW2*mZ2)/t
)*TildeI4t(s,t,mW2,mZ2);
Val += ( 8.*(t-mW2)*(u*t-2.*mW2*mZ2)/t/t
)*TildeI3W(s,t,mW2);
swap(mW2,mZ2);
del *= -1;
Val += 2.*(22.*t*t+t*(19.*s-18.*sig)+18.*mW2*mZ2)/t/t
- 8.*(u*t+2*s*sig)/mW2/mZ2
- 2.*sqr(t-u)/t/s/sqr(beta);
Val += +( 2.*(8.*t*t+4.*t*(s-3.*sig)+4*sqr(sig)-5.*s*sig+s*s)/t/s/sqr(beta)
+ 4.*(t*(3.*u+s)-3.*mW2*mZ2)/t/t
+ 6.*(t+u)*sqr(t-u)/t/s/s/sqr(sqr(beta))
)*log(-t/s);
Val += +( ( 8.*t*t*(-2.*s+del)+8.*t*(-s*s+3.*s*sig-2.*del*sig)
- 2.*(s-sig)*(s*s-4.*s*sig+3.*del*sig)
)/t/s/s/beta/beta
+ 16.*s*(t-mZ2)/(t*(u+s)-mW2*mZ2)
+ 2.*(4.*t*t+t*(10.*s-3.*mZ2-9.*mW2)+12.*mW2*mZ2)/t/t
-6.*(s-del)*(t+u)*sqr(t-u)/t/s/s/s/sqr(sqr(beta))
)*log(-t/mW2);
Val += ( - ( 4.*t*t*(2.*sig-3.*s)
- 4.*t*(s-sig)*(2.*s-3.*sig)
- 2.*(s-2.*sig)*sqr(s-sig)
)/t/s/beta/beta
+ ( 4.*sig*t-3.*s*s+4.*s*sig
- 4.*(mW2*mW2+mZ2*mZ2)
)/t
- 3.*sqr(t*t-u*u)/t/s/s/sqr(sqr(beta))
)*TildeI3WZ(s,mW2,mZ2,beta);
Val += +( 4.*(t*u+2.*s*sig)/3./mW2/mZ2 - 4.*(t-2.*u)/3./t
)*pi*pi;
Val += -( 4.*s*(t*u-2.*mW2*mZ2)/t
)*TildeI4t(s,t,mW2,mZ2);
Val += ( 8.*(t-mW2)*(u*t-2.*mW2*mZ2)/t/t
)*TildeI3W(s,t,mW2);
swap(mW2,mZ2);
del *= -1;
return Val;
}
/***************************************************************************/
double Iud1(Energy2 s, Energy2 t, Energy2 u, Energy2 mW2, Energy2 mZ2, double beta) {
Energy2 sig(mZ2+mW2);
Energy2 del(mZ2-mW2);
double Val(0.);
Val += 2.*(4.*t*t+t*(9.*s-4.*sig)-18.*s*sig)/t/u
+ 8.*(t*u+2.*s*sig)/mW2/mZ2
+ 4.*s*s*(2.*t-sig)/u/(mW2*mZ2-t*(u+s))
- 2.*sqr(t-u)/u/s/sqr(beta);
Val += ( 2.*(8.*t*t-4.*t*(s+3.*sig)-(s-sig)*(3.*s+4.*sig))/u/s/sqr(beta)
+ 6.*(t+u)*sqr(t-u)/u/s/s/sqr(sqr(beta))
- 12.*s*(t-sig)/t/u
)*log(-t/s);
Val += ( (2./u/s/s/sqr(beta))*( 4.*t*t*(-2.*s+del)
+ 4.*t*(s*s+s*(mZ2+5.*mW2)-2.*sig*del)
+ (s-sig)*(3.*s*s+8.*mW2*s-3.*sig*del)
)
+ (2.*t*(18.*s+3.*mW2+mZ2)-24.*s*sig)/t/u
- 8.*s*(2.*t*t-t*(3.*s+4.*mZ2+2.*mW2)+2.*mZ2*(s+sig))
/u/(mW2*mZ2-t*(u+s))
- 8.*s*s*t*(2.*t-sig)*(t-mZ2)/u/sqr(mW2*mZ2-t*(u+s))
+ 6.*(s-del)*(s-sig)*sqr(t-u)/u/s/s/s/sqr(sqr(beta))
)*log(-t/mW2);
Val += ( -2.*(2.*t*t*(2.*sig-3.*s)+6.*sig*t*(s-sig)+sqr(s-sig)*(s+2.*sig))
/u/s/sqr(beta)
+3.*s*(4.*t-4.*sig-s)/u
-3.*sqr(s-sig)*sqr(t-u)/u/s/s/sqr(sqr(beta))
)*TildeI3WZ(s,mW2,mZ2,beta);
Val += ( 4.*(u+4.*s)/3./u - 4.*(u*t+2.*s*sig)/3./mW2/mZ2
)*pi*pi;
Val += -( 16.*s*(t-sig)*(t-mW2)/t/u
)*TildeI3W(s,t,mW2);
Val += ( 8.*s*s*(t-sig)/u
)*TildeI4t(s,t,mW2,mZ2);
swap(t,u);
Val += 2.*(4.*t*t+t*(9.*s-4.*sig)-18.*s*sig)/t/u
+ 8.*(t*u+2.*s*sig)/mW2/mZ2
+ 4.*s*s*(2.*t-sig)/u/(mW2*mZ2-t*(u+s))
- 2.*sqr(t-u)/u/s/sqr(beta);
Val += ( 2.*(8.*t*t-4.*t*(s+3.*sig)-(s-sig)*(3.*s+4.*sig))/u/s/sqr(beta)
+ 6.*(t+u)*sqr(t-u)/u/s/s/sqr(sqr(beta))
- 12.*s*(t-sig)/t/u
)*log(-t/s);
Val += ( (2./u/s/s/sqr(beta))*( 4.*t*t*(-2.*s+del)
+ 4.*t*(s*s+s*(mZ2+5.*mW2)-2.*sig*del)
+ (s-sig)*(3.*s*s+8.*mW2*s-3.*sig*del)
)
+ (2.*t*(18.*s+3.*mW2+mZ2)-24.*s*sig)/t/u
- 8.*s*(2.*t*t-t*(3.*s+4.*mZ2+2.*mW2)+2.*mZ2*(s+sig))
/u/(mW2*mZ2-t*(u+s))
- 8.*s*s*t*(2.*t-sig)*(t-mZ2)/u/sqr(mW2*mZ2-t*(u+s))
+ 6.*(s-del)*(s-sig)*sqr(t-u)/u/s/s/s/sqr(sqr(beta))
)*log(-t/mW2);
Val += ( -2.*(2.*t*t*(2.*sig-3.*s)+6.*sig*t*(s-sig)+sqr(s-sig)*(s+2.*sig))
/u/s/sqr(beta)
+3.*s*(4.*t-4.*sig-s)/u
-3.*sqr(s-sig)*sqr(t-u)/u/s/s/sqr(sqr(beta))
)*TildeI3WZ(s,mW2,mZ2,beta);
Val += ( 4.*(u+4.*s)/3./u - 4.*(u*t+2.*s*sig)/3./mW2/mZ2
)*pi*pi;
Val += -( 16.*s*(t-sig)*(t-mW2)/t/u
)*TildeI3W(s,t,mW2);
Val += ( 8.*s*s*(t-sig)/u
)*TildeI4t(s,t,mW2,mZ2);
swap(t,u);
swap(mW2,mZ2);
del *= -1;
Val += 2.*(4.*t*t+t*(9.*s-4.*sig)-18.*s*sig)/t/u
+ 8.*(t*u+2.*s*sig)/mW2/mZ2
+ 4.*s*s*(2.*t-sig)/u/(mW2*mZ2-t*(u+s))
- 2.*sqr(t-u)/u/s/sqr(beta);
Val += ( 2.*(8.*t*t-4.*t*(s+3.*sig)-(s-sig)*(3.*s+4.*sig))/u/s/sqr(beta)
+ 6.*(t+u)*sqr(t-u)/u/s/s/sqr(sqr(beta))
- 12.*s*(t-sig)/t/u
)*log(-t/s);
Val += ( (2./u/s/s/sqr(beta))*( 4.*t*t*(-2.*s+del)
+ 4.*t*(s*s+s*(mZ2+5.*mW2)-2.*sig*del)
+ (s-sig)*(3.*s*s+8.*mW2*s-3.*sig*del)
)
+ (2.*t*(18.*s+3.*mW2+mZ2)-24.*s*sig)/t/u
- 8.*s*(2.*t*t-t*(3.*s+4.*mZ2+2.*mW2)+2.*mZ2*(s+sig))
/u/(mW2*mZ2-t*(u+s))
- 8.*s*s*t*(2.*t-sig)*(t-mZ2)/u/sqr(mW2*mZ2-t*(u+s))
+ 6.*(s-del)*(s-sig)*sqr(t-u)/u/s/s/s/sqr(sqr(beta))
)*log(-t/mW2);
Val += ( -2.*(2.*t*t*(2.*sig-3.*s)+6.*sig*t*(s-sig)+sqr(s-sig)*(s+2.*sig))
/u/s/sqr(beta)
+3.*s*(4.*t-4.*sig-s)/u
-3.*sqr(s-sig)*sqr(t-u)/u/s/s/sqr(sqr(beta))
)*TildeI3WZ(s,mW2,mZ2,beta);
Val += ( 4.*(u+4.*s)/3./u - 4.*(u*t+2.*s*sig)/3./mW2/mZ2
)*pi*pi;
Val += -( 16.*s*(t-sig)*(t-mW2)/t/u
)*TildeI3W(s,t,mW2);
Val += ( 8.*s*s*(t-sig)/u
)*TildeI4t(s,t,mW2,mZ2);
swap(mW2,mZ2);
del *= -1;
swap(t,u);
swap(mW2,mZ2);
del *= -1;
Val += 2.*(4.*t*t+t*(9.*s-4.*sig)-18.*s*sig)/t/u
+ 8.*(t*u+2.*s*sig)/mW2/mZ2
+ 4.*s*s*(2.*t-sig)/u/(mW2*mZ2-t*(u+s))
- 2.*sqr(t-u)/u/s/sqr(beta);
Val += ( 2.*(8.*t*t-4.*t*(s+3.*sig)-(s-sig)*(3.*s+4.*sig))/u/s/sqr(beta)
+ 6.*(t+u)*sqr(t-u)/u/s/s/sqr(sqr(beta))
- 12.*s*(t-sig)/t/u
)*log(-t/s);
Val += ( (2./u/s/s/sqr(beta))*( 4.*t*t*(-2.*s+del)
+ 4.*t*(s*s+s*(mZ2+5.*mW2)-2.*sig*del)
+ (s-sig)*(3.*s*s+8.*mW2*s-3.*sig*del)
)
+ (2.*t*(18.*s+3.*mW2+mZ2)-24.*s*sig)/t/u
- 8.*s*(2.*t*t-t*(3.*s+4.*mZ2+2.*mW2)+2.*mZ2*(s+sig))
/u/(mW2*mZ2-t*(u+s))
- 8.*s*s*t*(2.*t-sig)*(t-mZ2)/u/sqr(mW2*mZ2-t*(u+s))
+ 6.*(s-del)*(s-sig)*sqr(t-u)/u/s/s/s/sqr(sqr(beta))
)*log(-t/mW2);
Val += ( -2.*(2.*t*t*(2.*sig-3.*s)+6.*sig*t*(s-sig)+sqr(s-sig)*(s+2.*sig))
/u/s/sqr(beta)
+3.*s*(4.*t-4.*sig-s)/u
-3.*sqr(s-sig)*sqr(t-u)/u/s/s/sqr(sqr(beta))
)*TildeI3WZ(s,mW2,mZ2,beta);
Val += ( 4.*(u+4.*s)/3./u - 4.*(u*t+2.*s*sig)/3./mW2/mZ2
)*pi*pi;
Val += -( 16.*s*(t-sig)*(t-mW2)/t/u
)*TildeI3W(s,t,mW2);
Val += ( 8.*s*s*(t-sig)/u
)*TildeI4t(s,t,mW2,mZ2);
swap(t,u);
swap(mW2,mZ2);
del *= -1;
return Val;
}
/***************************************************************************/
double Iuu1(Energy2 s, Energy2 t, Energy2 u, Energy2 mW2, Energy2 mZ2, double beta) {
double Val(Idd1(s,u,t,mW2,mZ2,beta));
return Val;
}
/***************************************************************************/
Energy2 Fd1 (Energy2 s, Energy2 t, Energy2 u, Energy2 mW2, Energy2 mZ2, double beta) {
Energy2 sig(mZ2+mW2);
Energy2 del(mZ2-mW2);
Energy2 Val(0.*GeV2);
Val += 4.*(17.*t*t+t*(11.*s-13.*sig)+17.*(s*sig+mW2*mZ2))/t
+ 16.*(s-sig)*(t*u+2.*s*sig)/mW2/mZ2
+ 4*s*s*(2.*t-sig)/(t*(u+s)-mW2*mZ2);
Val += ( 8.*(t-u)/sqr(beta)
- 4.*(3.*t*t-t*(s+3.*sig)+3.*(s*sig+mW2*mZ2))/t
)*log(-t/s);
Val += ( 8.*(t*t-t*(2.*s+3.*mW2+mZ2)+3.*(s*sig+mW2*mZ2))/t
+ 8.*s*(t*(3.*s+2.*sig)-2.*mZ2*(s+sig))/(t*(u+s)-mW2*mZ2)
+ 8.*s*s*t*(2.*t-sig)*(t-mZ2)/sqr(t*(u+s)-mW2*mZ2)
- 8.*(s-del)*(t-u)/s/sqr(beta)
)*log(-t/mW2);
Val += ( 4.*(s-sig)*(t-u)/sqr(beta)
+ 4.*(sig-3.*s)*t
+ 4.*(4.*s*sig-mZ2*mZ2-mW2*mW2)
)*TildeI3WZ(s,mW2,mZ2,beta);
Val += -( 8.*(3.*t*t+2.*t*(2.*s-sig)+2.*(s*sig+mW2*mZ2))/3./t
+ 8.*(s-sig)*(t*u+2.*s*sig)/3./mW2/mZ2
)*pi*pi;
Val += ( 4.*(s*t*t-s*(s+sig)*t+2.*s*(s*sig+mW2*mZ2))
)*TildeI4t(s,t,mW2,mZ2);
Val += -( 8.*(t-mW2)*(t*t-t*(s+sig)+2.*(s*sig+mW2*mZ2))/t
)*TildeI3W(s,t,mW2);
swap(mW2,mZ2);
del *= -1;
Val += 4.*(17.*t*t+t*(11.*s-13.*sig)+17.*(s*sig+mW2*mZ2))/t
+ 16.*(s-sig)*(t*u+2.*s*sig)/mW2/mZ2
+ 4*s*s*(2.*t-sig)/(t*(u+s)-mW2*mZ2);
Val += ( 8.*(t-u)/sqr(beta)
- 4.*(3.*t*t-t*(s+3.*sig)+3.*(s*sig+mW2*mZ2))/t
)*log(-t/s);
Val += ( 8.*(t*t-t*(2.*s+3.*mW2+mZ2)+3.*(s*sig+mW2*mZ2))/t
+ 8.*s*(t*(3.*s+2.*sig)-2.*mZ2*(s+sig))/(t*(u+s)-mW2*mZ2)
+ 8.*s*s*t*(2.*t-sig)*(t-mZ2)/sqr(t*(u+s)-mW2*mZ2)
- 8.*(s-del)*(t-u)/s/sqr(beta)
)*log(-t/mW2);
Val += ( 4.*(s-sig)*(t-u)/sqr(beta)
+ 4.*(sig-3.*s)*t
+ 4.*(4.*s*sig-mZ2*mZ2-mW2*mW2)
)*TildeI3WZ(s,mW2,mZ2,beta);
Val += -( 8.*(3.*t*t+2.*t*(2.*s-sig)+2.*(s*sig+mW2*mZ2))/3./t
+ 8.*(s-sig)*(t*u+2.*s*sig)/3./mW2/mZ2
)*pi*pi;
Val += ( 4.*(s*t*t-s*(s+sig)*t+2.*s*(s*sig+mW2*mZ2))
)*TildeI4t(s,t,mW2,mZ2);
Val += -( 8.*(t-mW2)*(t*t-t*(s+sig)+2.*(s*sig+mW2*mZ2))/t
)*TildeI3W(s,t,mW2);
swap(mW2,mZ2);
del *= -1;
return Val;
}
/***************************************************************************/
Energy2 Fu1 (Energy2 s, Energy2 t, Energy2 u, Energy2 mW2, Energy2 mZ2, double beta) {
Energy2 Val(Fd1(s,u,t,mW2,mZ2,beta));
return Val;
}
/***************************************************************************/
Energy4 H1 (Energy2 s, Energy2 t, Energy2 u, Energy2 mW2, Energy2 mZ2) {
Energy2 sig(mZ2+mW2);
Energy4 Val(0.*GeV2*GeV2);
Val = 8.*t*t+8.*t*(s-sig)+s*s+6.*s*sig+mZ2*mZ2+10.*mW2*mZ2+mW2*mW2
- sqr(s-sig)*(t*u+2.*s*sig)/mW2/mZ2;
Val *= ( 16.-8.*pi*pi/3.);
return Val;
}
Energy2 t_u_Rdd(Energy2 s , Energy2 tk , Energy2 uk , Energy2 q1 , Energy2 q2,
Energy2 mW2, Energy2 mZ2);
Energy2 t_u_Rud(Energy2 s , Energy2 tk , Energy2 uk , Energy2 q1 , Energy2 q2,
Energy2 q1h, Energy2 q2h, Energy2 mW2, Energy2 mZ2);
Energy2 t_u_Ruu(Energy2 s , Energy2 tk , Energy2 uk, Energy2 q1h, Energy2 q2h,
Energy2 mW2, Energy2 mZ2);
Energy4 t_u_RZds(Energy2 s ,Energy2 tk , Energy2 uk , Energy2 q1, Energy2 q2,
Energy2 s2,Energy2 mW2, Energy2 mZ2);
Energy4 t_u_RZda(Energy2 s , Energy2 tk , Energy2 uk , Energy2 q1, Energy2 q2,
Energy2 s2, Energy2 mW2, Energy2 mZ2);
Energy4 t_u_RZd(Energy2 s , Energy2 tk , Energy2 uk , Energy2 q1 , Energy2 q2 ,
Energy2 s2 , Energy2 mW2, Energy2 mZ2);
Energy4 t_u_RZu(Energy2 s , Energy2 tk , Energy2 uk , Energy2 q1h, Energy2 q2h,
Energy2 s2 , Energy2 mW2, Energy2 mZ2);
Energy6 t_u_RZs(Energy2 s , Energy2 tk , Energy2 uk , Energy2 q1, Energy2 q2,
Energy2 s2, Energy2 mW2, Energy2 mZ2);
Energy6 t_u_RZa(Energy2 s , Energy2 tk , Energy2 uk , Energy2 q1, Energy2 q2,
Energy2 s2, Energy2 mW2, Energy2 mZ2);
Energy6 t_u_RZ(Energy2 s , Energy2 tk , Energy2 uk , Energy2 q1, Energy2 q2,
Energy2 s2 , Energy2 mW2, Energy2 mZ2);
/***************************************************************************/
// t_u_M_R_qqb is the real emission q + qb -> n + g matrix element
// exactly as defined in Eqs. C.1 of NPB 383(1992)3-44, multiplied by
// tk * uk!
Energy2 MEPP2VVPowheg::t_u_M_R_qqb(realVVKinematics R) const {
// First the Born variables:
Energy2 s2(R.s2r());
Energy2 mW2(R.k12r());
Energy2 mZ2(R.k22r());
// Then the rest:
Energy2 s(R.sr());
Energy2 tk(R.tkr());
Energy2 uk(R.ukr());
Energy2 q1(R.q1r());
Energy2 q2(R.q2r());
Energy2 q1h(R.q1hatr());
Energy2 q2h(R.q2hatr());
double cosThetaW(sqrt(1.-sin2ThetaW_));
double eZ2(eZ2_);
double eZ(eZ_);
double gdL(gdL_);
double guL(guL_);
double gdR(gdR_);
double guR(guR_);
// W+W-
if(abs(mePartonData()[2]->id())==24&&abs(mePartonData()[3]->id())==24) {
double e2(sqr(gW_)*sin2ThetaW_);
if(abs(quark_->id())%2==0&&abs(antiquark_->id())%2==0) {
// N.B. OLD eZ used to calculate new eZ2 *then* new eZ is set!
if(quark_->id()==-antiquark_->id()) {
eZ2 = 1./2.*sqr(s2-mW2)/Fij2_
* (e2*e2/s2/s2*(sqr( 2./3.+eZ*(guL+guR)/2./e2*s2/(s2-mW2/sqr(cosThetaW)))
+sqr( eZ*(guL-guR)/2./e2*s2/(s2-mW2/sqr(cosThetaW))))
);
eZ = -1./2./Fij2_/(gW_*gW_/4./sqrt(Fij2_))*(s2-mW2)
* (gW_*gW_*e2/4./s2 *( 2./3.+2.*eZ*guL/2./e2*s2/(s2-mW2/sqr(cosThetaW))));
} else {
eZ2 =0.;
eZ =0.;
}
gdL = gW_/sqrt(2.);
guL = 0.;
}
else if(abs(quark_->id())%2==1&&abs(antiquark_->id())%2==1) {
// N.B. OLD eZ used to calculate new eZ2 *then* new eZ is set!
if(quark_->id()==-antiquark_->id()) {
eZ2 = 1./2.*sqr(s2-mW2)/Fij2_
* (e2*e2/s2/s2*(sqr(-1./3.+eZ*(gdL+gdR)/2./e2*s2/(s2-mW2/sqr(cosThetaW)))
+sqr( eZ*(gdL-gdR)/2./e2*s2/(s2-mW2/sqr(cosThetaW))))
);
eZ = -1./2./Fij2_/(gW_*gW_/4./sqrt(Fij2_))*(s2-mW2)
* (gW_*gW_*e2/4./s2 *(-1./3.+2.*eZ*gdL/2./e2*s2/(s2-mW2/sqr(cosThetaW))));
} else {
eZ2 =0.;
eZ =0.;
}
guL = gW_/sqrt(2.);
gdL = 0.;
}
}
// ZZ
else if(mePartonData()[2]->id()==23&&mePartonData()[3]->id()==23) {
eZ = 0.;
eZ2 = 0.;
double gV2,gA2;
gV2 = sqr(guL/2.-gW_/2./cosThetaW*2./3.*sin2ThetaW_);
gA2 = sqr(guL/2.+gW_/2./cosThetaW*2./3.*sin2ThetaW_);
guL = sqrt(gV2*gV2+gA2*gA2+6.*gA2*gV2)/2.;
gV2 = sqr(gdL/2.+gW_/2./cosThetaW*1./3.*sin2ThetaW_);
gA2 = sqr(gdL/2.-gW_/2./cosThetaW*1./3.*sin2ThetaW_);
gdL = sqrt(gV2*gV2+gA2*gA2+6.*gA2*gV2)/2.;
if(abs(quark_->id())%2==0&&abs(antiquark_->id())%2==0) gdL = guL;
else if(abs(quark_->id())%2==1&&abs(antiquark_->id())%2==1) guL = gdL;
else {
cout << "MEPP2VVPowheg:" << endl;
cout << "ZZ needs 2 down-type / 2 up-type!" << endl;
}
}
return -2.*pi*alphaS_*Fij2_*CF_/NC_
* ( gdL*gdL*t_u_Rdd(s,tk,uk,q1,q2,mW2,mZ2)
+ 2.*gdL*guL*t_u_Rud(s,tk,uk,q1,q2,q1h,q2h,mW2,mZ2)
+ guL*guL*t_u_Ruu(s,tk,uk,q1h,q2h,mW2,mZ2)
- 2.*eZ/(s2-mW2) * ( gdL
* t_u_RZd(s,tk,uk,q1 ,q2 ,s2,mW2,mZ2)
- guL
* t_u_RZu(s,tk,uk,q1h,q2h,s2,mW2,mZ2)
)
+ eZ2/sqr(s2-mW2) *t_u_RZ(s,tk,uk,q1,q2,s2,mW2,mZ2)
);
}
Energy2 t_u_Rdd(Energy2 s ,Energy2 tk ,Energy2 uk ,Energy2 q1,Energy2 q2,
Energy2 mW2, Energy2 mZ2) {
Energy2 Val(0.*GeV2);
Val += 4.*(q2*(uk+2.*s+q2)+q1*(s+q1))/mW2/mZ2*uk
+ 16.*(uk+s)/q2*uk
- 4.*(2.*uk+4.*s+q2)/mW2*uk
- 4.*(2.*uk+5.*s+q2+2.*q1-mW2)/mZ2*uk
+ 4.*q1*s*(s+q1)/mW2/mZ2
+ 16.*s*(s+q2-mZ2-mW2)/q1
- 4.*s*(4.*s+q2+q1)/mW2
+ 16.*mW2*mZ2*s/q1/q2
+ 4.*s
+ 16.*mZ2*(tk-2.*mW2)/q1/q2/q2*tk*uk
+ 16.*(2.*mZ2+mW2-tk)/q1/q2*tk*uk
+ 16.*mW2*(s-mZ2-mW2)/q1/q2*uk
+ 16.*mZ2*(q1-2.*mW2)/q2/q2*uk
+ 32.*mW2*mW2*mZ2/q1/q2/q2*uk
+ 16.*mW2/q1*uk
+ 4.*uk
+ 8./q2*tk*uk
+ 4.*q1/mW2/mZ2*tk*uk
- 24./q1*tk*uk
- 4./mW2*tk*uk;
swap(mW2,mZ2);
swap(q1,q2);
swap(tk,uk);
Val += 4.*(q2*(uk+2.*s+q2)+q1*(s+q1))/mW2/mZ2*uk
+ 16.*(uk+s)/q2*uk
- 4.*(2.*uk+4.*s+q2)/mW2*uk
- 4.*(2.*uk+5.*s+q2+2.*q1-mW2)/mZ2*uk
+ 4.*q1*s*(s+q1)/mW2/mZ2
+ 16.*s*(s+q2-mZ2-mW2)/q1
- 4.*s*(4.*s+q2+q1)/mW2
+ 16.*mW2*mZ2*s/q1/q2
+ 4.*s
+ 16.*mZ2*(tk-2.*mW2)/q1/q2/q2*tk*uk
+ 16.*(2.*mZ2+mW2-tk)/q1/q2*tk*uk
+ 16.*mW2*(s-mZ2-mW2)/q1/q2*uk
+ 16.*mZ2*(q1-2.*mW2)/q2/q2*uk
+ 32.*mW2*mW2*mZ2/q1/q2/q2*uk
+ 16.*mW2/q1*uk
+ 4.*uk
+ 8./q2*tk*uk
+ 4.*q1/mW2/mZ2*tk*uk
- 24./q1*tk*uk
- 4./mW2*tk*uk;
swap(mW2,mZ2);
swap(q1,q2);
swap(tk,uk);
return Val;
}
Energy2 t_u_Rud(Energy2 s ,Energy2 tk ,Energy2 uk ,Energy2 q1,Energy2 q2,
Energy2 q1h,Energy2 q2h,Energy2 mW2, Energy2 mZ2) {
Energy2 Val(0.*GeV2);
Val += (uk*s*(uk+3.*s+q1h)+s*s*(s+mZ2)-(s+uk)*(2.*mZ2*s+3.*mW2*s+mW2*q1h)
) * 8./q1/q2h/q2*uk
- (uk*(uk+3.*s+q1h-mW2)-(q2+s)*(q2-s)+s*(q2-mW2)+q1h*(q2-mW2)+mW2*q2
) * 4.*s/mZ2/q1/q2h*uk
- 4.*((s+uk+q2h-2.*mZ2)*(s+q1h-mZ2)-mZ2*q1)/mW2/q2*uk
+ 4.*(2.*s*uk+2.*mW2*uk+5.*s*s+2.*q1h*s-2.*mZ2*s)/q1/q2h*uk
+ 4.*(2.*s*uk-s*s-2.*q1h*s+2.*mW2*s+2.*mW2*q1h)/q1/q2h/q2*tk*uk
+ ((2.*uk+s)*(s+q1h)+s*(q2+q2h)+2.*q2*(s+q2h)-q1*s+q1*q2+q1h*q2h
) /mW2/mZ2*uk
+ 8.*s*(uk-q1h+mZ2)/q1/q2*uk
+ 4.*s*(-uk+s-q2+q1+q1h)/mZ2/q2h*uk
+ 4.*s*(-uk-q2+q1h)/mZ2/q1*uk
+ 8.*(mZ2*uk-s*s+mW2*s-2.*mZ2*q1-2.*mZ2*q1h)/q2h/q2*uk
+ 2.*(-uk-9.*s-4.*q2-5.*q2h-3.*q1-4.*q1h+8.*mZ2)/mW2*uk
+ 2.*(-4.*uk+3.*s+5.*q1+4.*q1h)/q2h*uk
+ 2.*(s*tk+q2*tk+s*s-q2*q2+q1h*q2)/mW2/mZ2*tk
- 8.*s*(tk+s+q1h)/mW2/q2*tk
+ 2.*(-tk+3.*s+q2-q1h)/mW2*tk
- 8.*s*s*s/q1h/q2
- 2.*s*q2*(s+q2)/mW2/mZ2
+ 2.*s*(2.*s+q2)/mZ2
+ 2.*s*(2.*s+q2)/mW2
- 16.*s*s/q1h
- 2.*s
- 16.*s*s/q1h/q2*tk
- 8.*s/q2*tk
- 16.*s/q1h*tk
+ 6.*s/mZ2*tk
+ 4.*s/q1*uk
+ 4.*s/mZ2*uk
+ 12.*uk
+ 4.*s*(tk+q1h-mW2)/mZ2/q1/q2h*tk*uk
+ 2.*(s+4.*q1+5.*q1h-4.*mZ2)/q2*uk
- 4.*s*s*s/q1h/q1/q2h/q2*tk*uk
- 4.*s*s/q1h/q2h/q2*tk*uk
- 4.*s*s/q1h/q1/q2*tk*uk
+ 8.*s*s/mW2/q1h/q2*tk*uk
- 4.*s*s/q1h/q1/q2h*tk*uk
+ 4.*(s+mZ2)/mW2/q2*tk*uk
- 4.*s/q1h/q2h*tk*uk
- 4.*s/q1h/q1*tk*uk
+ 12.*s/mW2/q1h*tk*uk
- (s+4.*q2)/mW2/mZ2*tk*uk
- 4.*(s+2.*mZ2)/q2h/q2*tk*uk
- 4.*(3.*s+2.*q1h)/q1/q2*tk*uk
- 8.*mW2/q1/q2h*tk*uk
+ 8./q2h*tk*uk
+ 8./q1*tk*uk;
swap(mW2,mZ2);
swap(q1,q2);
swap(tk,uk);
swap(q1h,q2h); // Note this swap is done in accordance with MC@NLO.
// It is not in NPB 383(1992)3-44 Eq.C.4!
Val += (uk*s*(uk+3.*s+q1h)+s*s*(s+mZ2)-(s+uk)*(2.*mZ2*s+3.*mW2*s+mW2*q1h)
) * 8./q1/q2h/q2*uk
- (uk*(uk+3.*s+q1h-mW2)-(q2+s)*(q2-s)+s*(q2-mW2)+q1h*(q2-mW2)+mW2*q2
) * 4.*s/mZ2/q1/q2h*uk
- 4.*((s+uk+q2h-2.*mZ2)*(s+q1h-mZ2)-mZ2*q1)/mW2/q2*uk
+ 4.*(2.*s*uk+2.*mW2*uk+5.*s*s+2.*q1h*s-2.*mZ2*s)/q1/q2h*uk
+ 4.*(2.*s*uk-s*s-2.*q1h*s+2.*mW2*s+2.*mW2*q1h)/q1/q2h/q2*tk*uk
+ ((2.*uk+s)*(s+q1h)+s*(q2+q2h)+2.*q2*(s+q2h)-q1*s+q1*q2+q1h*q2h
) /mW2/mZ2*uk
+ 8.*s*(uk-q1h+mZ2)/q1/q2*uk
+ 4.*s*(-uk+s-q2+q1+q1h)/mZ2/q2h*uk
+ 4.*s*(-uk-q2+q1h)/mZ2/q1*uk
+ 8.*(mZ2*uk-s*s+mW2*s-2.*mZ2*q1-2.*mZ2*q1h)/q2h/q2*uk
+ 2.*(-uk-9.*s-4.*q2-5.*q2h-3.*q1-4.*q1h+8.*mZ2)/mW2*uk
+ 2.*(-4.*uk+3.*s+5.*q1+4.*q1h)/q2h*uk
+ 2.*(s*tk+q2*tk+s*s-q2*q2+q1h*q2)/mW2/mZ2*tk
- 8.*s*(tk+s+q1h)/mW2/q2*tk
+ 2.*(-tk+3.*s+q2-q1h)/mW2*tk
- 8.*s*s*s/q1h/q2
- 2.*s*q2*(s+q2)/mW2/mZ2
+ 2.*s*(2.*s+q2)/mZ2
+ 2.*s*(2.*s+q2)/mW2
- 16.*s*s/q1h
- 2.*s
- 16.*s*s/q1h/q2*tk
- 8.*s/q2*tk
- 16.*s/q1h*tk
+ 6.*s/mZ2*tk
+ 4.*s/q1*uk
+ 4.*s/mZ2*uk
+ 12.*uk
+ 4.*s*(tk+q1h-mW2)/mZ2/q1/q2h*tk*uk
+ 2.*(s+4.*q1+5.*q1h-4.*mZ2)/q2*uk
- 4.*s*s*s/q1h/q1/q2h/q2*tk*uk
- 4.*s*s/q1h/q2h/q2*tk*uk
- 4.*s*s/q1h/q1/q2*tk*uk
+ 8.*s*s/mW2/q1h/q2*tk*uk
- 4.*s*s/q1h/q1/q2h*tk*uk
+ 4.*(s+mZ2)/mW2/q2*tk*uk
- 4.*s/q1h/q2h*tk*uk
- 4.*s/q1h/q1*tk*uk
+ 12.*s/mW2/q1h*tk*uk
- (s+4.*q2)/mW2/mZ2*tk*uk
- 4.*(s+2.*mZ2)/q2h/q2*tk*uk
- 4.*(3.*s+2.*q1h)/q1/q2*tk*uk
- 8.*mW2/q1/q2h*tk*uk
+ 8./q2h*tk*uk
+ 8./q1*tk*uk;
swap(mW2,mZ2);
swap(q1,q2);
swap(tk,uk);
swap(q1h,q2h); // Note this swap is done in accordance with MC@NLO.
// It is not in NPB 383(1992)3-44 Eq.C.4!
swap(tk,uk);
swap(q1,q2h);
swap(q2,q1h);
Val += (uk*s*(uk+3.*s+q1h)+s*s*(s+mZ2)-(s+uk)*(2.*mZ2*s+3.*mW2*s+mW2*q1h)
) * 8./q1/q2h/q2*uk
- (uk*(uk+3.*s+q1h-mW2)-(q2+s)*(q2-s)+s*(q2-mW2)+q1h*(q2-mW2)+mW2*q2
) * 4.*s/mZ2/q1/q2h*uk
- 4.*((s+uk+q2h-2.*mZ2)*(s+q1h-mZ2)-mZ2*q1)/mW2/q2*uk
+ 4.*(2.*s*uk+2.*mW2*uk+5.*s*s+2.*q1h*s-2.*mZ2*s)/q1/q2h*uk
+ 4.*(2.*s*uk-s*s-2.*q1h*s+2.*mW2*s+2.*mW2*q1h)/q1/q2h/q2*tk*uk
+ ((2.*uk+s)*(s+q1h)+s*(q2+q2h)+2.*q2*(s+q2h)-q1*s+q1*q2+q1h*q2h
) /mW2/mZ2*uk
+ 8.*s*(uk-q1h+mZ2)/q1/q2*uk
+ 4.*s*(-uk+s-q2+q1+q1h)/mZ2/q2h*uk
+ 4.*s*(-uk-q2+q1h)/mZ2/q1*uk
+ 8.*(mZ2*uk-s*s+mW2*s-2.*mZ2*q1-2.*mZ2*q1h)/q2h/q2*uk
+ 2.*(-uk-9.*s-4.*q2-5.*q2h-3.*q1-4.*q1h+8.*mZ2)/mW2*uk
+ 2.*(-4.*uk+3.*s+5.*q1+4.*q1h)/q2h*uk
+ 2.*(s*tk+q2*tk+s*s-q2*q2+q1h*q2)/mW2/mZ2*tk
- 8.*s*(tk+s+q1h)/mW2/q2*tk
+ 2.*(-tk+3.*s+q2-q1h)/mW2*tk
- 8.*s*s*s/q1h/q2
- 2.*s*q2*(s+q2)/mW2/mZ2
+ 2.*s*(2.*s+q2)/mZ2
+ 2.*s*(2.*s+q2)/mW2
- 16.*s*s/q1h
- 2.*s
- 16.*s*s/q1h/q2*tk
- 8.*s/q2*tk
- 16.*s/q1h*tk
+ 6.*s/mZ2*tk
+ 4.*s/q1*uk
+ 4.*s/mZ2*uk
+ 12.*uk
+ 4.*s*(tk+q1h-mW2)/mZ2/q1/q2h*tk*uk
+ 2.*(s+4.*q1+5.*q1h-4.*mZ2)/q2*uk
- 4.*s*s*s/q1h/q1/q2h/q2*tk*uk
- 4.*s*s/q1h/q2h/q2*tk*uk
- 4.*s*s/q1h/q1/q2*tk*uk
+ 8.*s*s/mW2/q1h/q2*tk*uk
- 4.*s*s/q1h/q1/q2h*tk*uk
+ 4.*(s+mZ2)/mW2/q2*tk*uk
- 4.*s/q1h/q2h*tk*uk
- 4.*s/q1h/q1*tk*uk
+ 12.*s/mW2/q1h*tk*uk
- (s+4.*q2)/mW2/mZ2*tk*uk
- 4.*(s+2.*mZ2)/q2h/q2*tk*uk
- 4.*(3.*s+2.*q1h)/q1/q2*tk*uk
- 8.*mW2/q1/q2h*tk*uk
+ 8./q2h*tk*uk
+ 8./q1*tk*uk;
swap(tk,uk);
swap(q1,q2h);
swap(q2,q1h);
swap(mW2,mZ2);
swap(q1,q1h);
swap(q2,q2h);
Val += (uk*s*(uk+3.*s+q1h)+s*s*(s+mZ2)-(s+uk)*(2.*mZ2*s+3.*mW2*s+mW2*q1h)
) * 8./q1/q2h/q2*uk
- (uk*(uk+3.*s+q1h-mW2)-(q2+s)*(q2-s)+s*(q2-mW2)+q1h*(q2-mW2)+mW2*q2
) * 4.*s/mZ2/q1/q2h*uk
- 4.*((s+uk+q2h-2.*mZ2)*(s+q1h-mZ2)-mZ2*q1)/mW2/q2*uk
+ 4.*(2.*s*uk+2.*mW2*uk+5.*s*s+2.*q1h*s-2.*mZ2*s)/q1/q2h*uk
+ 4.*(2.*s*uk-s*s-2.*q1h*s+2.*mW2*s+2.*mW2*q1h)/q1/q2h/q2*tk*uk
+ ((2.*uk+s)*(s+q1h)+s*(q2+q2h)+2.*q2*(s+q2h)-q1*s+q1*q2+q1h*q2h
) /mW2/mZ2*uk
+ 8.*s*(uk-q1h+mZ2)/q1/q2*uk
+ 4.*s*(-uk+s-q2+q1+q1h)/mZ2/q2h*uk
+ 4.*s*(-uk-q2+q1h)/mZ2/q1*uk
+ 8.*(mZ2*uk-s*s+mW2*s-2.*mZ2*q1-2.*mZ2*q1h)/q2h/q2*uk
+ 2.*(-uk-9.*s-4.*q2-5.*q2h-3.*q1-4.*q1h+8.*mZ2)/mW2*uk
+ 2.*(-4.*uk+3.*s+5.*q1+4.*q1h)/q2h*uk
+ 2.*(s*tk+q2*tk+s*s-q2*q2+q1h*q2)/mW2/mZ2*tk
- 8.*s*(tk+s+q1h)/mW2/q2*tk
+ 2.*(-tk+3.*s+q2-q1h)/mW2*tk
- 8.*s*s*s/q1h/q2
- 2.*s*q2*(s+q2)/mW2/mZ2
+ 2.*s*(2.*s+q2)/mZ2
+ 2.*s*(2.*s+q2)/mW2
- 16.*s*s/q1h
- 2.*s
- 16.*s*s/q1h/q2*tk
- 8.*s/q2*tk
- 16.*s/q1h*tk
+ 6.*s/mZ2*tk
+ 4.*s/q1*uk
+ 4.*s/mZ2*uk
+ 12.*uk
+ 4.*s*(tk+q1h-mW2)/mZ2/q1/q2h*tk*uk
+ 2.*(s+4.*q1+5.*q1h-4.*mZ2)/q2*uk
- 4.*s*s*s/q1h/q1/q2h/q2*tk*uk
- 4.*s*s/q1h/q2h/q2*tk*uk
- 4.*s*s/q1h/q1/q2*tk*uk
+ 8.*s*s/mW2/q1h/q2*tk*uk
- 4.*s*s/q1h/q1/q2h*tk*uk
+ 4.*(s+mZ2)/mW2/q2*tk*uk
- 4.*s/q1h/q2h*tk*uk
- 4.*s/q1h/q1*tk*uk
+ 12.*s/mW2/q1h*tk*uk
- (s+4.*q2)/mW2/mZ2*tk*uk
- 4.*(s+2.*mZ2)/q2h/q2*tk*uk
- 4.*(3.*s+2.*q1h)/q1/q2*tk*uk
- 8.*mW2/q1/q2h*tk*uk
+ 8./q2h*tk*uk
+ 8./q1*tk*uk;
swap(mW2,mZ2);
swap(q1,q1h);
swap(q2,q2h);
return Val;
}
Energy2 t_u_Ruu(Energy2 s ,Energy2 tk ,Energy2 uk ,Energy2 q1h,Energy2 q2h,
Energy2 mW2, Energy2 mZ2) {
return t_u_Rdd(s,tk,uk,q1h,q2h,mZ2,mW2);
}
Energy4 t_u_RZds(Energy2 s ,Energy2 tk ,Energy2 uk ,Energy2 q1,Energy2 q2,
Energy2 s2, Energy2 mW2, Energy2 mZ2) {
Energy4 Val(0.*GeV2*GeV2);
Energy2 sig(mZ2+mW2);
Val += ( q1*q2*(5./2.*s*s+5.*s*tk+3.*tk*tk)+(tk*uk*uk+q1*q1*q2)*(tk+s)
+ q1*(tk*tk*uk+s*uk*uk-s*s*tk+s*s*uk)+q1*q1*q1*(uk+s)-q1*q1*s*s2
) * 8./q1/q2
- ( tk*tk*(4.*uk+s+q1-2.*q2)+tk*(sqr(q1+q2)-q1*s-3.*q2*s-2.*q1*q1)
- q1*s*(4.*s-2.*q1-q2)+tk*uk*(q1+3.*s)
) * 4.*sig/q1/q2
- 4.*sig*sig*(s*(2.*s+q1)+tk*(uk+5./2.*tk+5.*s+q1+q2)
)/mW2/mZ2
+ 2.*sig*s2*(4.*sqr(s+tk)+tk*(uk+s+4.*q1+2.*q2)+2.*q1*(2.*s+q1)
)/mW2/mZ2
+ 4.*sig*sig*(s2+s-q1+q2)/q1/q2*tk
- 16.*mW2*mZ2*(tk*uk/2.+q2*tk-q1*s)/q1/q2
- 4.*s2*s2*q1*(tk+s+q1)/mW2/mZ2
+ sig*sig*sig*(uk+tk)/mW2/mZ2
+ 4.*mW2*mZ2*sig*(uk+tk)/q1/q2;
swap(mW2,mZ2);
swap(q1,q2);
swap(tk,uk);
Val += ( q1*q2*(5./2.*s*s+5.*s*tk+3.*tk*tk)+(tk*uk*uk+q1*q1*q2)*(tk+s)
+ q1*(tk*tk*uk+s*uk*uk-s*s*tk+s*s*uk)+q1*q1*q1*(uk+s)-q1*q1*s*s2
) * 8./q1/q2
- ( tk*tk*(4.*uk+s+q1-2.*q2)+tk*(sqr(q1+q2)-q1*s-3.*q2*s-2.*q1*q1)
- q1*s*(4.*s-2.*q1-q2)+tk*uk*(q1+3.*s)
) * 4.*sig/q1/q2
- 4.*sig*sig*(s*(2.*s+q1)+tk*(uk+5./2.*tk+5.*s+q1+q2)
)/mW2/mZ2
+ 2.*sig*s2*(4.*sqr(s+tk)+tk*(uk+s+4.*q1+2.*q2)+2.*q1*(2.*s+q1)
)/mW2/mZ2
+ 4.*sig*sig*(s2+s-q1+q2)/q1/q2*tk
- 16.*mW2*mZ2*(tk*uk/2.+q2*tk-q1*s)/q1/q2
- 4.*s2*s2*q1*(tk+s+q1)/mW2/mZ2
+ sig*sig*sig*(uk+tk)/mW2/mZ2
+ 4.*mW2*mZ2*sig*(uk+tk)/q1/q2;
swap(mW2,mZ2);
swap(q1,q2);
swap(tk,uk);
return Val;
}
Energy4 t_u_RZda(Energy2 s ,Energy2 tk ,Energy2 uk ,Energy2 q1,Energy2 q2,
Energy2 s2, Energy2 mW2, Energy2 mZ2) {
Energy4 Val(0.*GeV2*GeV2);
Val += 4.*mZ2*(2.*uk*uk-s*tk+q1*(uk-tk-s+q1+0.5*q2)+q2*(s-3.*q2)
) /q1/q2*tk
- 4.*mZ2*mZ2*(q1-tk-2.*s-q2)/q1/q2*tk
- 2.*mZ2*(tk+2.*s+2.*q2)/mW2*tk
- 2.*s2*(s+2.*q2)/mZ2*tk
+ 8.*mW2*mZ2*mZ2/q1/q2*tk
+ 2.*mZ2*mZ2/mW2*tk;
swap(mW2,mZ2); // N.B. Here we subtract!
Val -= 4.*mZ2*(2.*uk*uk-s*tk+q1*(uk-tk-s+q1+0.5*q2)+q2*(s-3.*q2)
) /q1/q2*tk
- 4.*mZ2*mZ2*(q1-tk-2.*s-q2)/q1/q2*tk
- 2.*mZ2*(tk+2.*s+2.*q2)/mW2*tk
- 2.*s2*(s+2.*q2)/mZ2*tk
+ 8.*mW2*mZ2*mZ2/q1/q2*tk
+ 2.*mZ2*mZ2/mW2*tk;
swap(mW2,mZ2);
swap(q1,q2); // N.B. Here we subtract!
swap(tk,uk);
Val -= 4.*mZ2*(2.*uk*uk-s*tk+q1*(uk-tk-s+q1+0.5*q2)+q2*(s-3.*q2)
) /q1/q2*tk
- 4.*mZ2*mZ2*(q1-tk-2.*s-q2)/q1/q2*tk
- 2.*mZ2*(tk+2.*s+2.*q2)/mW2*tk
- 2.*s2*(s+2.*q2)/mZ2*tk
+ 8.*mW2*mZ2*mZ2/q1/q2*tk
+ 2.*mZ2*mZ2/mW2*tk;
swap(q1,q2);
swap(tk,uk);
swap(mW2,mZ2); // N.B. Here we add!
swap(q1,q2);
swap(tk,uk);
Val += 4.*mZ2*(2.*uk*uk-s*tk+q1*(uk-tk-s+q1+0.5*q2)+q2*(s-3.*q2)
) /q1/q2*tk
- 4.*mZ2*mZ2*(q1-tk-2.*s-q2)/q1/q2*tk
- 2.*mZ2*(tk+2.*s+2.*q2)/mW2*tk
- 2.*s2*(s+2.*q2)/mZ2*tk
+ 8.*mW2*mZ2*mZ2/q1/q2*tk
+ 2.*mZ2*mZ2/mW2*tk;
swap(mW2,mZ2);
swap(q1,q2);
swap(tk,uk);
return Val;
}
Energy4 t_u_RZd(Energy2 s , Energy2 tk , Energy2 uk , Energy2 q1 , Energy2 q2 ,
Energy2 s2, Energy2 mW2, Energy2 mZ2) {
Energy4 Val(0.*GeV2*GeV2);
Val = t_u_RZds(s,tk,uk,q1,q2,s2,mW2,mZ2)
+ t_u_RZda(s,tk,uk,q1,q2,s2,mW2,mZ2);
return Val;
}
Energy4 t_u_RZu(Energy2 s , Energy2 tk , Energy2 uk , Energy2 q1h, Energy2 q2h,
Energy2 s2, Energy2 mW2, Energy2 mZ2) {
Energy4 Val(0.*GeV2*GeV2);
Val = t_u_RZd(s,tk,uk,q1h,q2h,s2,mZ2,mW2);
return Val;
}
Energy6 t_u_RZs(Energy2 s,Energy2 tk,Energy2 uk,Energy2 q1,Energy2 q2,
Energy2 s2,Energy2 mW2,Energy2 mZ2) {
Energy6 Val(0.*GeV2*GeV2*GeV2);
Energy2 sig(mZ2+mW2);
Val += 2.*sig*sig*s2*( tk*(3.*uk+9.*tk+19.*s+6.*q1+4.*q2)+8.*s*s+6.*q1*s
+ 2.*q1*q1
)/mW2/mZ2
- 2.*sig*sig*sig*(tk*(3.*uk+6.*tk+11.*s+2.*q1+2.*q2)+2.*s*(2.*s+q1))
/ mW2/mZ2
- 2.*sig*s2*s2*(tk*(uk+4.*tk+9.*s+6.*q1+2.*q2)+4.*sqr(s+q1)-2.*q1*s)
/mW2/mZ2
- 16.*sig*(2.*tk*(uk/2.-tk-s+q1+q2)-s*(3.*s/2.-2.*q1))
+ 8.*s2*(s*(s/2.+tk)+4.*q1*(tk+s+q1))
+ 4.*s2*s2*s2*q1*(tk+s+q1)/mW2/mZ2
+ 8.*sig*sig*(2.*tk+s/2.)
+ 2.*sig*sig*sig*sig*tk/mW2/mZ2
+ 32.*mW2*mZ2*s;
swap(mW2,mZ2);
swap(q1,q2);
swap(tk,uk);
Val += 2.*sig*sig*s2*( tk*(3.*uk+9.*tk+19.*s+6.*q1+4.*q2)+8.*s*s+6.*q1*s
+ 2.*q1*q1
)/mW2/mZ2
- 2.*sig*sig*sig*(tk*(3.*uk+6.*tk+11.*s+2.*q1+2.*q2)+2.*s*(2.*s+q1))
/ mW2/mZ2
- 2.*sig*s2*s2*(tk*(uk+4.*tk+9.*s+6.*q1+2.*q2)+4.*sqr(s+q1)-2.*q1*s)
/mW2/mZ2
- 16.*sig*(2.*tk*(uk/2.-tk-s+q1+q2)-s*(3.*s/2.-2.*q1))
+ 8.*s2*(s*(s/2.+tk)+4.*q1*(tk+s+q1))
+ 4.*s2*s2*s2*q1*(tk+s+q1)/mW2/mZ2
+ 8.*sig*sig*(2.*tk+s/2.)
+ 2.*sig*sig*sig*sig*tk/mW2/mZ2
+ 32.*mW2*mZ2*s;
swap(mW2,mZ2);
swap(q1,q2);
swap(tk,uk);
return Val;
}
Energy6 t_u_RZa(Energy2 s,Energy2 tk,Energy2 uk,Energy2 q1,Energy2 q2,
Energy2 s2,Energy2 mW2,Energy2 mZ2) {
Energy6 Val(0.*GeV2*GeV2*GeV2);
Val += - 2.*mZ2*(2.*tk+11.*s+18.*q2)*tk
- 2.*mZ2*mZ2*(2.*tk+3.*s+2.*q2)/mW2*tk
+ 2.*mZ2*s2*(tk+3.*s+4.*q2)/mW2*tk
- 2.*s2*s2*(s+2.*q2)/mW2*tk
+ 2.*mZ2*mZ2*mZ2/mW2*tk
+ 20.*mZ2*mZ2*tk;
swap(mW2,mZ2);
Val -= - 2.*mZ2*(2.*tk+11.*s+18.*q2)*tk
- 2.*mZ2*mZ2*(2.*tk+3.*s+2.*q2)/mW2*tk
+ 2.*mZ2*s2*(tk+3.*s+4.*q2)/mW2*tk
- 2.*s2*s2*(s+2.*q2)/mW2*tk
+ 2.*mZ2*mZ2*mZ2/mW2*tk
+ 20.*mZ2*mZ2*tk;
swap(mW2,mZ2);
swap(q1,q2);
swap(tk,uk);
Val -= - 2.*mZ2*(2.*tk+11.*s+18.*q2)*tk
- 2.*mZ2*mZ2*(2.*tk+3.*s+2.*q2)/mW2*tk
+ 2.*mZ2*s2*(tk+3.*s+4.*q2)/mW2*tk
- 2.*s2*s2*(s+2.*q2)/mW2*tk
+ 2.*mZ2*mZ2*mZ2/mW2*tk
+ 20.*mZ2*mZ2*tk;
swap(q1,q2);
swap(tk,uk);
swap(mW2,mZ2);
swap(q1,q2);
swap(tk,uk);
Val += - 2.*mZ2*(2.*tk+11.*s+18.*q2)*tk
- 2.*mZ2*mZ2*(2.*tk+3.*s+2.*q2)/mW2*tk
+ 2.*mZ2*s2*(tk+3.*s+4.*q2)/mW2*tk
- 2.*s2*s2*(s+2.*q2)/mW2*tk
+ 2.*mZ2*mZ2*mZ2/mW2*tk
+ 20.*mZ2*mZ2*tk;
swap(mW2,mZ2);
swap(q1,q2);
swap(tk,uk);
return Val;
}
Energy6 t_u_RZ(Energy2 s , Energy2 tk , Energy2 uk , Energy2 q1, Energy2 q2,
Energy2 s2, Energy2 mW2, Energy2 mZ2) {
Energy6 Val(0.*GeV2*GeV2*GeV2);
Val = t_u_RZs(s,tk,uk,q1,q2,s2,mW2,mZ2)
+ t_u_RZa(s,tk,uk,q1,q2,s2,mW2,mZ2);
return Val;
}
/***************************************************************************/
// t_u_M_R_qg is the real emission q + qb -> n + g matrix element
// exactly as defined in Eqs. C.9 of NPB 383(1992)3-44, multiplied by
// tk * uk!
Energy2 MEPP2VVPowheg::t_u_M_R_qg(realVVKinematics R) const {
// First the Born variables:
Energy2 s2(R.s2r());
Energy2 mW2(R.k12r());
Energy2 mZ2(R.k22r());
// Then the rest:
Energy2 s(R.sr());
Energy2 tk(R.tkr());
Energy2 uk(R.ukr());
Energy2 q1(R.q1r());
Energy2 q2(R.q2r());
Energy2 q1h(R.q1hatr());
Energy2 q2h(R.q2hatr());
Energy2 w1(R.w1r());
Energy2 w2(R.w2r());
double cosThetaW(sqrt(1.-sin2ThetaW_));
double eZ2(eZ2_);
double eZ(eZ_);
double gdL(gdL_);
double guL(guL_);
double gdR(gdR_);
double guR(guR_);
// W+W-
if(abs(mePartonData()[2]->id())==24&&abs(mePartonData()[3]->id())==24) {
double e2(sqr(gW_)*sin2ThetaW_);
if(abs(quark_->id())%2==0&&abs(antiquark_->id())%2==0) {
// N.B. OLD eZ used to calculate new eZ2 *then* new eZ is set!
if(quark_->id()==-antiquark_->id()) {
eZ2 = 1./2.*sqr(s2-mW2)/Fij2_
* (e2*e2/s2/s2*(sqr( 2./3.+eZ*(guL+guR)/2./e2*s2/(s2-mW2/sqr(cosThetaW)))
+sqr( eZ*(guL-guR)/2./e2*s2/(s2-mW2/sqr(cosThetaW))))
);
eZ = -1./2./Fij2_/(gW_*gW_/4./sqrt(Fij2_))*(s2-mW2)
* (gW_*gW_*e2/4./s2 *( 2./3.+2.*eZ*guL/2./e2*s2/(s2-mW2/sqr(cosThetaW))));
} else {
eZ2 =0.;
eZ =0.;
}
gdL = gW_/sqrt(2.);
guL = 0.;
}
else if(abs(quark_->id())%2==1&&abs(antiquark_->id())%2==1) {
// N.B. OLD eZ used to calculate new eZ2 *then* new eZ is set!
if(quark_->id()==-antiquark_->id()) {
eZ2 = 1./2.*sqr(s2-mW2)/Fij2_
* (e2*e2/s2/s2*(sqr(-1./3.+eZ*(gdL+gdR)/2./e2*s2/(s2-mW2/sqr(cosThetaW)))
+sqr( eZ*(gdL-gdR)/2./e2*s2/(s2-mW2/sqr(cosThetaW))))
);
eZ = -1./2./Fij2_/(gW_*gW_/4./sqrt(Fij2_))*(s2-mW2)
* (gW_*gW_*e2/4./s2 *(-1./3.+2.*eZ*gdL/2./e2*s2/(s2-mW2/sqr(cosThetaW))));
} else {
eZ2 =0.;
eZ =0.;
}
guL = gW_/sqrt(2.);
gdL = 0.;
}
}
// ZZ
else if(mePartonData()[2]->id()==23&&mePartonData()[3]->id()==23) {
eZ = 0.;
eZ2 = 0.;
double gV2,gA2;
gV2 = sqr(guL/2.-gW_/2./cosThetaW*2./3.*sin2ThetaW_);
gA2 = sqr(guL/2.+gW_/2./cosThetaW*2./3.*sin2ThetaW_);
guL = sqrt(gV2*gV2+gA2*gA2+6.*gA2*gV2)/2.;
gV2 = sqr(gdL/2.+gW_/2./cosThetaW*1./3.*sin2ThetaW_);
gA2 = sqr(gdL/2.-gW_/2./cosThetaW*1./3.*sin2ThetaW_);
gdL = sqrt(gV2*gV2+gA2*gA2+6.*gA2*gV2)/2.;
if(abs(quark_->id())%2==0&&abs(antiquark_->id())%2==0) gdL = guL;
else if(abs(quark_->id())%2==1&&abs(antiquark_->id())%2==1) guL = gdL;
else {
cout << "MEPP2VVPowheg:" << endl;
cout << "ZZ needs 2 down-type / 2 up-type!" << endl;
}
}
Energy2 Val(0.*GeV2);
swap(s,tk);
swap(q2,w2);
swap(q2h,w1);
Val = -2.*pi*alphaS_*Fij2_*CF_/NC_
* ( gdL*gdL*t_u_Rdd(s,tk,uk,q1,q2,mW2,mZ2)
+ 2.*gdL*guL*t_u_Rud(s,tk,uk,q1,q2,q1h,q2h,mW2,mZ2)
+ guL*guL*t_u_Ruu(s,tk,uk,q1h,q2h,mW2,mZ2)
- 2.*eZ/(s2-mW2) * ( gdL
* t_u_RZd(s,tk,uk,q1 ,q2 ,s2,mW2,mZ2)
- guL
* t_u_RZu(s,tk,uk,q1h,q2h,s2,mW2,mZ2)
)
+ eZ2/sqr(s2-mW2) *t_u_RZ(s,tk,uk,q1,q2,s2,mW2,mZ2)
);
swap(s,tk);
swap(q2,w2);
swap(q2h,w1);
Val *= -tk/s * TR_/CF_;
return Val;
}
/***************************************************************************/
// t_u_M_R_gqb is the real emission g + qb -> n + q matrix element
// exactly as defined in Eqs. C.9 of NPB 383(1992)3-44, multiplied by
// tk * uk!
Energy2 MEPP2VVPowheg::t_u_M_R_gqb(realVVKinematics R) const {
// First the Born variables:
Energy2 s2(R.s2r());
Energy2 mW2(R.k12r());
Energy2 mZ2(R.k22r());
// Then the rest:
Energy2 s(R.sr());
Energy2 tk(R.tkr());
Energy2 uk(R.ukr());
Energy2 q1(R.q1r());
Energy2 q2(R.q2r());
Energy2 q1h(R.q1hatr());
Energy2 q2h(R.q2hatr());
Energy2 w1(R.w1r());
Energy2 w2(R.w2r());
double cosThetaW(sqrt(1.-sin2ThetaW_));
double eZ2(eZ2_);
double eZ(eZ_);
double gdL(gdL_);
double guL(guL_);
double gdR(gdR_);
double guR(guR_);
// W+W-
if(abs(mePartonData()[2]->id())==24&&abs(mePartonData()[3]->id())==24) {
double e2(sqr(gW_)*sin2ThetaW_);
if(abs(quark_->id())%2==0&&abs(antiquark_->id())%2==0) {
// N.B. OLD eZ used to calculate new eZ2 *then* new eZ is set!
if(quark_->id()==-antiquark_->id()) {
eZ2 = 1./2.*sqr(s2-mW2)/Fij2_
* (e2*e2/s2/s2*(sqr( 2./3.+eZ*(guL+guR)/2./e2*s2/(s2-mW2/sqr(cosThetaW)))
+sqr( eZ*(guL-guR)/2./e2*s2/(s2-mW2/sqr(cosThetaW))))
);
eZ = -1./2./Fij2_/(gW_*gW_/4./sqrt(Fij2_))*(s2-mW2)
* (gW_*gW_*e2/4./s2 *( 2./3.+2.*eZ*guL/2./e2*s2/(s2-mW2/sqr(cosThetaW))));
} else {
eZ2 =0.;
eZ =0.;
}
gdL = gW_/sqrt(2.);
guL = 0.;
}
else if(abs(quark_->id())%2==1&&abs(antiquark_->id())%2==1) {
// N.B. OLD eZ used to calculate new eZ2 *then* new eZ is set!
if(quark_->id()==-antiquark_->id()) {
eZ2 = 1./2.*sqr(s2-mW2)/Fij2_
* (e2*e2/s2/s2*(sqr(-1./3.+eZ*(gdL+gdR)/2./e2*s2/(s2-mW2/sqr(cosThetaW)))
+sqr( eZ*(gdL-gdR)/2./e2*s2/(s2-mW2/sqr(cosThetaW))))
);
eZ = -1./2./Fij2_/(gW_*gW_/4./sqrt(Fij2_))*(s2-mW2)
* (gW_*gW_*e2/4./s2 *(-1./3.+2.*eZ*gdL/2./e2*s2/(s2-mW2/sqr(cosThetaW))));
} else {
eZ2 =0.;
eZ =0.;
}
guL = gW_/sqrt(2.);
gdL = 0.;
}
}
// ZZ
else if(mePartonData()[2]->id()==23&&mePartonData()[3]->id()==23) {
eZ = 0.;
eZ2 = 0.;
double gV2,gA2;
gV2 = sqr(guL/2.-gW_/2./cosThetaW*2./3.*sin2ThetaW_);
gA2 = sqr(guL/2.+gW_/2./cosThetaW*2./3.*sin2ThetaW_);
guL = sqrt(gV2*gV2+gA2*gA2+6.*gA2*gV2)/2.;
gV2 = sqr(gdL/2.+gW_/2./cosThetaW*1./3.*sin2ThetaW_);
gA2 = sqr(gdL/2.-gW_/2./cosThetaW*1./3.*sin2ThetaW_);
gdL = sqrt(gV2*gV2+gA2*gA2+6.*gA2*gV2)/2.;
if(abs(quark_->id())%2==0&&abs(antiquark_->id())%2==0) gdL = guL;
else if(abs(quark_->id())%2==1&&abs(antiquark_->id())%2==1) guL = gdL;
else {
cout << "MEPP2VVPowheg:" << endl;
cout << "ZZ needs 2 down-type / 2 up-type!" << endl;
}
}
Energy2 Val(0.*GeV2);
swap(s,uk);
swap(q1,w1);
swap(q1h,w2);
Val = -2.*pi*alphaS_*Fij2_*CF_/NC_
* ( gdL*gdL*t_u_Rdd(s,tk,uk,q1,q2,mW2,mZ2)
+ 2.*gdL*guL*t_u_Rud(s,tk,uk,q1,q2,q1h,q2h,mW2,mZ2)
+ guL*guL*t_u_Ruu(s,tk,uk,q1h,q2h,mW2,mZ2)
- 2.*eZ/(s2-mW2) * ( gdL
* t_u_RZd(s,tk,uk,q1 ,q2 ,s2,mW2,mZ2)
- guL
* t_u_RZu(s,tk,uk,q1h,q2h,s2,mW2,mZ2)
)
+ eZ2/sqr(s2-mW2) *t_u_RZ(s,tk,uk,q1,q2,s2,mW2,mZ2)
);
swap(s,uk);
swap(q1,w1);
swap(q1h,w2);
Val *= -uk/s * TR_/CF_;
return Val;
}
/***************************************************************************/
// The following six functions are I_{dd}^{(0)}, I_{ud}^{(0)},
// I_{uu}^{(0)}, F_{u}^{(0)}, F_{d}^{(0)}, H^{(0)} from Eqs. 3.9 - 3.14
// They make up the Born matrix element. Ixx functions correspond to the
// graphs with no TGC, Fx functions are due to non-TGC graphs interfering
// with TGC graphs, while the H function is due purely to TGC graphs.
double Idd0(Energy2 s,Energy2 t,Energy2 u,Energy2 mW2,Energy2 mZ2);
double Iud0(Energy2 s,Energy2 t,Energy2 u,Energy2 mW2,Energy2 mZ2);
double Iuu0(Energy2 s,Energy2 t,Energy2 u,Energy2 mW2,Energy2 mZ2);
Energy2 Fu0(Energy2 s,Energy2 t,Energy2 u,Energy2 mW2,Energy2 mZ2);
Energy2 Fd0(Energy2 s,Energy2 t,Energy2 u,Energy2 mW2,Energy2 mZ2);
Energy4 H0 (Energy2 s,Energy2 t,Energy2 u,Energy2 mW2,Energy2 mZ2);
/***************************************************************************/
// M_Born_WZ is the Born matrix element exactly as defined in Eqs. 3.3-3.14
// of of NPB 383(1992)3-44 (with a spin*colour averaging factor 1./4./NC_/NC_).
double MEPP2VVPowheg::M_Born_WZ(bornVVKinematics B) const {
Energy2 s(B.sb());
Energy2 t(B.tb());
Energy2 u(B.ub());
Energy2 mW2(B.k12b()); // N.B. the diboson masses are preserved in getting
Energy2 mZ2(B.k22b()); // the 2->2 from the 2->3 kinematics.
double cosThetaW(sqrt(1.-sin2ThetaW_));
double eZ2(eZ2_);
double eZ(eZ_);
double gdL(gdL_);
double guL(guL_);
double gdR(gdR_);
double guR(guR_);
// W+W-
if(abs(mePartonData()[2]->id())==24&&abs(mePartonData()[3]->id())==24) {
double e2(sqr(gW_)*sin2ThetaW_);
if(abs(quark_->id())%2==0&&abs(antiquark_->id())%2==0) {
// N.B. OLD eZ used to calculate new eZ2 *then* new eZ is set!
if(quark_->id()==-antiquark_->id()) {
eZ2 = 1./2.*sqr(s-mW2)/Fij2_
* (e2*e2/s/s*(sqr( 2./3.+eZ*(guL+guR)/2./e2*s/(s-mW2/sqr(cosThetaW)))
+sqr( eZ*(guL-guR)/2./e2*s/(s-mW2/sqr(cosThetaW))))
);
eZ = -1./2./Fij2_/(gW_*gW_/4./sqrt(Fij2_))*(s-mW2)
* (gW_*gW_*e2/4./s *( 2./3.+2.*eZ*guL/2./e2*s/(s-mW2/sqr(cosThetaW))));
} else {
eZ2 =0.;
eZ =0.;
}
gdL = gW_/sqrt(2.);
guL = 0.;
}
else if(abs(quark_->id())%2==1&&abs(antiquark_->id())%2==1) {
// N.B. OLD eZ used to calculate new eZ2 *then* new eZ is set!
if(quark_->id()==-antiquark_->id()) {
eZ2 = 1./2.*sqr(s-mW2)/Fij2_
* (e2*e2/s/s*(sqr(-1./3.+eZ*(gdL+gdR)/2./e2*s/(s-mW2/sqr(cosThetaW)))
+sqr( eZ*(gdL-gdR)/2./e2*s/(s-mW2/sqr(cosThetaW))))
);
eZ = -1./2./Fij2_/(gW_*gW_/4./sqrt(Fij2_))*(s-mW2)
* (gW_*gW_*e2/4./s *(-1./3.+2.*eZ*gdL/2./e2*s/(s-mW2/sqr(cosThetaW))));
} else {
eZ2 =0.;
eZ =0.;
}
guL = gW_/sqrt(2.);
gdL = 0.;
}
}
// ZZ
else if(mePartonData()[2]->id()==23&&mePartonData()[3]->id()==23) {
eZ = 0.;
eZ2 = 0.;
double gV2,gA2;
gV2 = sqr(guL/2.-gW_/2./cosThetaW*2./3.*sin2ThetaW_);
gA2 = sqr(guL/2.+gW_/2./cosThetaW*2./3.*sin2ThetaW_);
guL = sqrt(gV2*gV2+gA2*gA2+6.*gA2*gV2)/2.;
gV2 = sqr(gdL/2.+gW_/2./cosThetaW*1./3.*sin2ThetaW_);
gA2 = sqr(gdL/2.-gW_/2./cosThetaW*1./3.*sin2ThetaW_);
gdL = sqrt(gV2*gV2+gA2*gA2+6.*gA2*gV2)/2.;
if(abs(quark_->id())%2==0&&abs(antiquark_->id())%2==0) gdL = guL;
else if(abs(quark_->id())%2==1&&abs(antiquark_->id())%2==1) guL = gdL;
else {
cout << "MEPP2VVPowheg:" << endl;
cout << "ZZ needs 2 down-type / 2 up-type!" << endl;
}
}
return Fij2_/2./NC_
* (
gdL*gdL*Idd0(s,t,u,mW2,mZ2)
+ 2.*gdL*guL*Iud0(s,t,u,mW2,mZ2)
+ guL*guL*Iuu0(s,t,u,mW2,mZ2)
- 2.*eZ/(s-mW2) * ( gdL*Fd0(s,t,u,mW2,mZ2)
- guL*Fu0(s,t,u,mW2,mZ2)
)
+ eZ2/sqr(s-mW2) * H0(s,t,u,mW2,mZ2)
);
}
/***************************************************************************/
double Idd0(Energy2 s, Energy2 t, Energy2 u, Energy2 mW2, Energy2 mZ2) {
return 8.*((u*t/mW2/mZ2-1.)/4.+s/2.*(mW2+mZ2)/mW2/mZ2)
+ 8.*(u/t-mW2*mZ2/t/t);
}
/***************************************************************************/
double Iud0(Energy2 s, Energy2 t, Energy2 u, Energy2 mW2, Energy2 mZ2) {
return - 8.*((u*t/mW2/mZ2-1.)/4.+s/2.*(mW2+mZ2)/mW2/mZ2)
+ 8.*s/t/u*(mW2+mZ2);
}
/***************************************************************************/
double Iuu0(Energy2 s, Energy2 t, Energy2 u, Energy2 mW2, Energy2 mZ2) {
return Idd0(s,u,t,mW2,mZ2);
}
/***************************************************************************/
Energy2 Fd0 (Energy2 s, Energy2 t, Energy2 u, Energy2 mW2, Energy2 mZ2) {
return - 8.*s*( (u*t/mW2/mZ2-1.)*(1.-(mW2+mZ2)/s-4.*mW2*mZ2/s/t)/4.
+ (mW2+mZ2)/2./mW2/mZ2*(s-mW2-mZ2+2.*mW2*mZ2/t)
);
}
/***************************************************************************/
Energy2 Fu0 (Energy2 s, Energy2 t, Energy2 u, Energy2 mW2, Energy2 mZ2) {
return Fd0(s,u,t,mW2,mZ2);
}
/***************************************************************************/
Energy4 H0 (Energy2 s, Energy2 t, Energy2 u, Energy2 mW2, Energy2 mZ2) {
return 8.*s*s*(u*t/mW2/mZ2-1.)*( 1./4.-(mW2+mZ2)/2./s
+ (sqr(mW2+mZ2)+8.*mW2*mZ2)/4./s/s
)
+ 8.*s*s*(mW2+mZ2)/mW2/mZ2*(s/2.-mW2-mZ2+sqr(mW2-mZ2)/2./s);
}
/***************************************************************************/
bool MEPP2VVPowheg::sanityCheck() const {
bool alarm(false);
Energy2 prefacs(8.*pi*alphaS_*S_.sr() /S_.xr() );
Energy2 prefacsp(8.*pi*alphaS_*SCp_.sr() /SCp_.xr() );
Energy2 prefacsm(8.*pi*alphaS_*SCm_.sr() /SCm_.xr() );
Energy2 prefacp(8.*pi*alphaS_*Cp_.sr()/Cp_.xr());
Energy2 prefacm(8.*pi*alphaS_*Cm_.sr()/Cm_.xr());
double xp(Cp_.xr());
double xm(Cm_.xr());
double M_B_WW(M_Born_WW(B_));
double M_B_ZZ(M_Born_ZZ(B_));
double M_V_reg_WW(M_V_regular_WW(S_));
double M_V_reg_ZZ(M_V_regular_ZZ(S_));
Energy2 t_u_qqb_WW(t_u_M_R_qqb_WW(H_));
Energy2 t_u_qqb_ZZ(t_u_M_R_qqb_ZZ(H_));
// Check that the native leading order Herwig++ matrix
// element is equivalent to the WZ leading order matrix
// element in NPB 383 (1992) 3-44, with the relevant WZ->WW
// WZ->ZZ transformation applied (M_Born_).
// if(fabs((lo_me2_ - M_Born_)/M_Born_)>1.e-2) {
// alarm=true;
// cout << "lo_me2_ - M_Born_ (%) = "
// << lo_me2_ - M_Born_ << " ("
// << (lo_me2_ - M_Born_)/M_Born_*100. << ")\n";
// }
// Check that the transformation from NPB 383 (1992) 3-44 WZ
// matrix elements to WW matrix elements actually works, by
// comparing them to the explicit WW matrix elements in
// NPB 410 (1993) 280-324.
if(abs(mePartonData()[2]->id())==24&&abs(mePartonData()[3]->id())==24) {
if(fabs((M_Born_ -M_B_WW )/M_B_WW )>1.e-6) {
alarm=true;
cout << "WZ->WW transformation error!\n";
cout << "M_Born_ - M_B_WW (rel) = "
<< M_Born_ - M_B_WW << " ("
<< (M_Born_ - M_B_WW)/M_B_WW << ")\n";
cout << "M_Born_ = " << M_Born_ << endl;
cout << "M_B_WW = " << M_B_WW << endl;
}
if(fabs((M_V_regular_-M_V_reg_WW)/M_V_reg_WW)>1.e-6) {
alarm=true;
cout << "WZ->WW transformation error!\n";
cout << "M_V_regular_ - M_V_reg_WW (rel) = "
<< M_V_regular_ - M_V_reg_WW << " ("
<< (M_V_regular_ - M_V_reg_WW)/M_V_reg_WW << ")\n";
cout << "M_V_regular_ = " << M_V_regular_ << endl;
cout << "M_V_reg_WW = " << M_V_reg_WW << endl;
}
if(fabs((t_u_M_R_qqb_-t_u_qqb_WW)/t_u_qqb_WW)>1.e-6) {
alarm=true;
cout << "WZ->WW transformation error!\n";
cout << "t_u_M_R_qqb_ - t_u_qqb_WW (rel) = "
<< (t_u_M_R_qqb_ - t_u_qqb_WW)/GeV2 << " ("
<< (t_u_M_R_qqb_ - t_u_qqb_WW)/t_u_qqb_WW << ")\n";
cout << "t_u_M_R_qqb_ = " << t_u_M_R_qqb_/GeV2 << endl;
cout << "t_u_qqb_WW = " << t_u_qqb_WW /GeV2 << endl;
}
}
// Check that the transformation from NPB 383 (1992) 3-44 WZ
// matrix elements to ZZ matrix elements actually works, by
// comparing them to the explicit ZZ matrix elements in
// NPB 357 (1991) 409-438.
if(abs(mePartonData()[2]->id())==23&&abs(mePartonData()[3]->id())==23) {
if(fabs((M_Born_ -M_B_ZZ )/M_B_ZZ )>1.e-6) {
alarm=true;
cout << "WZ->ZZ transformation error!\n";
cout << "M_Born_ - M_B_ZZ (rel) = "
<< M_Born_ - M_B_ZZ << " ("
<< (M_Born_ - M_B_ZZ)/M_B_ZZ << ")\n";
cout << "M_Born_ = " << M_Born_ << endl;
cout << "M_B_ZZ = " << M_B_ZZ << endl;
}
if(fabs((M_V_regular_-M_V_reg_ZZ)/M_V_reg_ZZ)>1.e-6) {
alarm=true;
cout << "WZ->ZZ transformation error!\n";
cout << "M_V_regular_ - M_V_reg_ZZ (rel) = "
<< M_V_regular_ - M_V_reg_ZZ << " ("
<< (M_V_regular_ - M_V_reg_ZZ)/M_V_reg_ZZ << ")\n";
cout << "M_V_regular_ = " << M_V_regular_ << endl;
cout << "M_V_reg_ZZ = " << M_V_reg_ZZ << endl;
}
if(fabs((t_u_M_R_qqb_-t_u_qqb_ZZ)/t_u_qqb_ZZ)>1.e-6) {
alarm=true;
cout << "WZ->ZZ transformation error!\n";
cout << "t_u_M_R_qqb_ - t_u_qqb_ZZ (rel) = "
<< (t_u_M_R_qqb_ - t_u_qqb_ZZ)/GeV2 << " ("
<< (t_u_M_R_qqb_ - t_u_qqb_ZZ)/t_u_qqb_ZZ << ")\n";
cout << "t_u_M_R_qqb_ = " << t_u_M_R_qqb_/GeV2 << endl;
cout << "t_u_qqb_ZZ = " << t_u_qqb_ZZ /GeV2 << endl;
}
}
// Check the soft limit of the q + qbar matrix element.
Energy2 absDiff_qqbs
= t_u_M_R_qqb(S_) - prefacs*2.*CF_*M_Born_;
double relDiff_qqbs = absDiff_qqbs / t_u_M_R_qqb(S_);
if(fabs(relDiff_qqbs)>1.e-6) {
alarm=true;
cout << "\n";
cout << "t_u_M_R_qqb(S_) " << t_u_M_R_qqb(S_) /GeV2 << endl;
cout << "t_u_M_R_qqb(S_)-8*pi*alphaS*sHat/x*2*Cab*M_Born_ (rel):\n"
<< absDiff_qqbs / GeV2 << " (" << relDiff_qqbs << ")\n";
}
// Check the positive soft-collinearlimit of the q + qbar matrix element.
Energy2 absDiff_qqbsp
= t_u_M_R_qqb(SCp_) - prefacsp*2.*CF_*M_Born_;
double relDiff_qqbsp = absDiff_qqbsp / t_u_M_R_qqb(SCp_);
if(fabs(relDiff_qqbsp)>1.e-6) {
alarm=true;
cout << "\n";
cout << "t_u_M_R_qqb(SCp_) " << t_u_M_R_qqb(SCp_)/GeV2 << endl;
cout << "t_u_M_R_qqb(SCp_)-8*pi*alphaS*sHat/x*2*Cab*M_Born_ (rel):\n"
<< absDiff_qqbsp / GeV2 << " (" << relDiff_qqbsp << ")\n";
}
// Check the negative soft-collinearlimit of the q + qbar matrix element.
Energy2 absDiff_qqbsm
= t_u_M_R_qqb(SCm_) - prefacsm*2.*CF_*M_Born_;
double relDiff_qqbsm = absDiff_qqbsm / t_u_M_R_qqb(SCm_);
if(fabs(relDiff_qqbsm)>1.e-6) {
alarm=true;
cout << "\n";
cout << "t_u_M_R_qqb(SCm_) " << t_u_M_R_qqb(SCm_)/GeV2 << endl;
cout << "t_u_M_R_qqb(SCm_)-8*pi*alphaS*sHat/x*2*Cab*M_Born_ (rel):\n"
<< absDiff_qqbsm / GeV2 << " (" << relDiff_qqbsm << ")\n";
}
// Check the positive collinearlimit of the q + qbar matrix element.
Energy2 absDiff_qqbp
= t_u_M_R_qqb(Cp_) - prefacp*CF_*(1.+xp*xp)*M_Born_;
double relDiff_qqbp = absDiff_qqbp / t_u_M_R_qqb(Cp_);
if(fabs(relDiff_qqbp)>1.e-6) {
alarm=true;
cout << "\n";
cout << "t_u_M_R_qqb(Cp_) " << t_u_M_R_qqb(Cp_) /GeV2 << endl;
cout << "t_u_M_R_qqb(Cp_)-8*pi*alphaS*sHat/x*(1-x)*Pqq*M_Born_ (rel):\n"
<< absDiff_qqbp / GeV2 << " (" << relDiff_qqbp << ")\n";
}
// Check the negative collinearlimit of the q + qbar matrix element.
Energy2 absDiff_qqbm
= t_u_M_R_qqb(Cm_) - prefacm*CF_*(1.+xm*xm)*M_Born_;
double relDiff_qqbm = absDiff_qqbm / t_u_M_R_qqb(Cm_);
if(fabs(relDiff_qqbm)>1.e-6) {
alarm=true;
cout << "\n";
cout << "t_u_M_R_qqb(Cm_) " << t_u_M_R_qqb(Cm_) /GeV2 << endl;
cout << "t_u_M_R_qqb(Cm_)-8*pi*alphaS*sHat/x*(1-x)*Pqq*M_Born_ (rel):\n"
<< absDiff_qqbm / GeV2 << " (" << relDiff_qqbm << ")\n";
}
// Check the positive collinear limit of the g + qbar matrix element.
Energy2 absDiff_gqbp
= t_u_M_R_gqb(Cp_) - prefacp*(1.-xp)*TR_*(xp*xp+sqr(1.-xp))*M_Born_;
double relDiff_gqbp = absDiff_gqbp/ t_u_M_R_gqb(Cp_);
if(fabs(relDiff_gqbp)>1.e-6) {
alarm=true;
cout << "\n";
cout << "t_u_M_R_gqb(Cp_) " << t_u_M_R_gqb(Cp_) /GeV2 << endl;
cout << "t_u_M_R_gqb(Cp_)-8*pi*alphaS*sHat/x*(1-x)*Pgq*M_Born_ (rel):\n"
<< absDiff_gqbp / GeV2 << " (" << relDiff_gqbp << ")\n";
}
// Check the negative collinear limit of the q + g matrix element.
Energy2 absDiff_qgm
= t_u_M_R_qg(Cm_) - prefacm*(1.-xm)*TR_*(xm*xm+sqr(1.-xm))*M_Born_;
double relDiff_qgm = absDiff_qgm / t_u_M_R_qg(Cm_);
if(fabs(relDiff_qgm)>1.e-6) {
alarm=true;
cout << "\n";
cout << "t_u_M_R_qg(Cm_) " << t_u_M_R_qg(Cm_) /GeV2 << endl;
cout << "t_u_M_R_qg(Cm_)-8*pi*alphaS*sHat/x*(1-x)*Pgq*M_Born_ (rel):\n"
<< absDiff_qgm / GeV2 << " (" << relDiff_qgm << ")\n";
}
return alarm;
}
/***************************************************************************/
// M_Born_ZZ is the Born matrix element exactly as defined in Eqs. 2.18-2.19
// of of NPB 357(1991)409-438.
double MEPP2VVPowheg::M_Born_ZZ(bornVVKinematics B) const {
Energy2 s(B.sb());
Energy2 t(B.tb());
Energy2 u(B.ub());
Energy2 mZ2(B.k22b()); // the 2->2 from the 2->3 kinematics.
double cosThetaW(sqrt(1.-sin2ThetaW_));
double gV2,gA2,gX,gY,gZ;
gV2 = sqr(guL_/2.-gW_/2./cosThetaW*2./3.*sin2ThetaW_);
gA2 = sqr(guL_/2.+gW_/2./cosThetaW*2./3.*sin2ThetaW_);
gX = sqrt(gV2*gV2+gA2*gA2+6.*gA2*gV2)/2.;
gV2 = sqr(gdL_/2.+gW_/2./cosThetaW*1./3.*sin2ThetaW_);
gA2 = sqr(gdL_/2.-gW_/2./cosThetaW*1./3.*sin2ThetaW_);
gY = sqrt(gV2*gV2+gA2*gA2+6.*gA2*gV2)/2.;
gZ = gX;
if(abs(quark_->id())%2==1&&abs(antiquark_->id())%2==1) gZ = gY;
return 1./NC_*sqr(gZ*2.)*(t/u+u/t+4.*mZ2*s/t/u-mZ2*mZ2*(1./t/t+1./u/u));
}
/***************************************************************************/
// M_V_regular_ZZ is the one-loop ZZ matrix element exactly as defined in
// Eqs. B.1 & B.2 of NPB 357(1991)409-438.
double MEPP2VVPowheg::M_V_regular_ZZ(realVVKinematics S) const {
Energy2 s(S.bornVariables().sb());
Energy2 t(S.bornVariables().tb());
Energy2 u(S.bornVariables().ub());
Energy2 mZ2(S.k22r()); // the 2->2 from the 2->3 kinematics.
double beta(S.betaxr()); // N.B. for x=1 \beta_x=\beta in NPB 383(1992)3-44.
double cosThetaW(sqrt(1.-sin2ThetaW_));
double gV2,gA2,gX,gY,gZ;
gV2 = sqr(guL_/2.-gW_/2./cosThetaW*2./3.*sin2ThetaW_);
gA2 = sqr(guL_/2.+gW_/2./cosThetaW*2./3.*sin2ThetaW_);
gX = sqrt(gV2*gV2+gA2*gA2+6.*gA2*gV2)/2.;
gV2 = sqr(gdL_/2.+gW_/2./cosThetaW*1./3.*sin2ThetaW_);
gA2 = sqr(gdL_/2.-gW_/2./cosThetaW*1./3.*sin2ThetaW_);
gY = sqrt(gV2*gV2+gA2*gA2+6.*gA2*gV2)/2.;
gZ = gX;
if(abs(quark_->id())%2==1&&abs(antiquark_->id())%2==1) gZ = gY;
double M_V_reg(0.);
M_V_reg = 2.*s*sqr(gZ*2.)*4.*pi*alphaS_*CF_/NC_/sqr(4.*pi)/2.
*( 2.*sqr(t+mZ2)/sqr(beta)/s/t/u + 4.*s/(t-mZ2)/u
- ( 16.*t*t*t+(28.*s-68.*mZ2)*t*t+(18.*s*s-36.*mZ2*s+88.*mZ2*mZ2)*t
+ 18.*mZ2*mZ2*s-36.*mZ2*mZ2*mZ2
)/t/t/s/u
+ ( 12.*s/(t-mZ2)/u-4.*mZ2*s/sqr(t-mZ2)/u+2.*(t+4.*s)/s/u
- 6.*(s*s+mZ2*mZ2)/s/t/u+6.*mZ2*mZ2*(2.*mZ2-s)/t/t/s/u
)*log(-t/mZ2)
+ ( - ( 5.*t*t*t+(8.*s-18.*mZ2)*t*t+(6.*s*s+25.*mZ2*mZ2)*t
+ 6.*mZ2*mZ2*s-12.*mZ2*mZ2*mZ2
)/t/t/s/u
- 12.*mZ2*sqr(t+mZ2)/sqr(sqr(beta))/s/s/t/u
+ ( 3.*t*t-26.*mZ2*t-25.*mZ2*mZ2)/sqr(beta)/s/t/u
)*log(s/mZ2)
+ ( (-2.*t*t+8.*mZ2*t-2.*s*s-12.*mZ2*mZ2)/u + 4.*mZ2*mZ2*(2.*mZ2-s)/t/u)
/ (s*t)
* ( 2.*sqr(log(-t/mZ2))-4.*log(-t/mZ2)*log((mZ2-t)/mZ2)-4.*ReLi2(t/mZ2))
+ ( 4.*(t*t-5.*mZ2*t+s*s+10.*mZ2*mZ2)/s/u
+ 4.*mZ2*(-s*s+2.*mZ2*s-10.*mZ2*mZ2)/s/t/u
+ 8.*mZ2*mZ2*mZ2*(2.*mZ2-s)/t/t/s/u
)
/ (t-mZ2)
* (pi*pi/2.+log(-t/mZ2)*log(-t/s)-1./2.*sqr(log(-t/mZ2)))
+ ( ( (2.*s-3.*mZ2)*t*t+(6.*mZ2*mZ2-8.*mZ2*s)*t+2.*s*s*s-4.*mZ2*s*s
+ 12.*mZ2*mZ2*s-3.*mZ2*mZ2*mZ2
) /s/t/u
+ 12.*mZ2*mZ2*sqr(t+mZ2)/sqr(sqr(beta))/s/s/t/u
- (mZ2*t*t-30.*mZ2*mZ2*t-27.*mZ2*mZ2*mZ2)/beta/beta/s/t/u
)
/ (beta*s)
* (pi*pi/3.+sqr(log((1.-beta)/(1.+beta)))+4.*ReLi2(-(1.-beta)/(1.+beta)))
+ (4.*(t+4.*s-4.*mZ2)/3./s/u+4.*sqr(s-2.*mZ2)/3./s/t/u)*pi*pi
);
swap(t,u);
M_V_reg += 2.*s*sqr(gZ*2.)*4.*pi*alphaS_*CF_/NC_/sqr(4.*pi)/2.
*( 2.*sqr(t+mZ2)/sqr(beta)/s/t/u + 4.*s/(t-mZ2)/u
- ( 16.*t*t*t+(28.*s-68.*mZ2)*t*t+(18.*s*s-36.*mZ2*s+88.*mZ2*mZ2)*t
+ 18.*mZ2*mZ2*s-36.*mZ2*mZ2*mZ2
)/t/t/s/u
+ ( 12.*s/(t-mZ2)/u-4.*mZ2*s/sqr(t-mZ2)/u+2.*(t+4.*s)/s/u
- 6.*(s*s+mZ2*mZ2)/s/t/u+6.*mZ2*mZ2*(2.*mZ2-s)/t/t/s/u
)*log(-t/mZ2)
+ ( - ( 5.*t*t*t+(8.*s-18.*mZ2)*t*t+(6.*s*s+25.*mZ2*mZ2)*t
+ 6.*mZ2*mZ2*s-12.*mZ2*mZ2*mZ2
)/t/t/s/u
- 12.*mZ2*sqr(t+mZ2)/sqr(sqr(beta))/s/s/t/u
+ ( 3.*t*t-26.*mZ2*t-25.*mZ2*mZ2)/sqr(beta)/s/t/u
)*log(s/mZ2)
+ ( (-2.*t*t+8.*mZ2*t-2.*s*s-12.*mZ2*mZ2)/u + 4.*mZ2*mZ2*(2.*mZ2-s)/t/u)
/ (s*t)
* ( 2.*sqr(log(-t/mZ2))-4.*log(-t/mZ2)*log((mZ2-t)/mZ2)-4.*ReLi2(t/mZ2))
+ ( 4.*(t*t-5.*mZ2*t+s*s+10.*mZ2*mZ2)/s/u
+ 4.*mZ2*(-s*s+2.*mZ2*s-10.*mZ2*mZ2)/s/t/u
+ 8.*mZ2*mZ2*mZ2*(2.*mZ2-s)/t/t/s/u
)
/ (t-mZ2)
* (pi*pi/2.+log(-t/mZ2)*log(-t/s)-1./2.*sqr(log(-t/mZ2)))
+ ( ( (2.*s-3.*mZ2)*t*t+(6.*mZ2*mZ2-8.*mZ2*s)*t+2.*s*s*s-4.*mZ2*s*s
+ 12.*mZ2*mZ2*s-3.*mZ2*mZ2*mZ2
) /s/t/u
+ 12.*mZ2*mZ2*sqr(t+mZ2)/sqr(sqr(beta))/s/s/t/u
- (mZ2*t*t-30.*mZ2*mZ2*t-27.*mZ2*mZ2*mZ2)/beta/beta/s/t/u
)
/ (beta*s)
* (pi*pi/3.+sqr(log((1.-beta)/(1.+beta)))+4.*ReLi2(-(1.-beta)/(1.+beta)))
+ (4.*(t+4.*s-4.*mZ2)/3./s/u+4.*sqr(s-2.*mZ2)/3./s/t/u)*pi*pi
);
return M_V_reg;
}
/***************************************************************************/
// t_u_M_R_qqb_ZZ is the real emission q + qb -> n + g matrix element
// exactly as defined in Eqs. C.1 of NPB 357(1991)409-438, multiplied by
// tk * uk!
Energy2 MEPP2VVPowheg::t_u_M_R_qqb_ZZ(realVVKinematics R) const {
// First the Born variables:
Energy2 mZ2(R.k22r());
// Then the rest:
Energy2 s(R.sr());
Energy2 tk(R.tkr());
Energy2 uk(R.ukr());
Energy2 q1(R.q1r());
Energy2 q2(R.q2r());
Energy2 q1h(R.q1hatr());
Energy2 q2h(R.q2hatr());
double cosThetaW(sqrt(1.-sin2ThetaW_));
double gV2,gA2,gX,gY,gZ;
gV2 = sqr(guL_/2.-gW_/2./cosThetaW*2./3.*sin2ThetaW_);
gA2 = sqr(guL_/2.+gW_/2./cosThetaW*2./3.*sin2ThetaW_);
gX = sqrt(gV2*gV2+gA2*gA2+6.*gA2*gV2)/2.;
gV2 = sqr(gdL_/2.+gW_/2./cosThetaW*1./3.*sin2ThetaW_);
gA2 = sqr(gdL_/2.-gW_/2./cosThetaW*1./3.*sin2ThetaW_);
gY = sqrt(gV2*gV2+gA2*gA2+6.*gA2*gV2)/2.;
gZ = gX;
if(abs(quark_->id())%2==1&&abs(antiquark_->id())%2==1) gZ = gY;
Energy2 t_u_qqb(0.*GeV2);
t_u_qqb = (2.*s)*sqr(gZ*2.)*4.*pi*alphaS_*CF_/NC_/2.
* ( - ( tk*uk*uk+2.*s*uk*uk-tk*tk*uk
- 2.*s*tk*uk+mZ2*(tk*tk-uk*uk+2.*s*uk-2.*s*tk-2.*s*s)
)/q1h/q1/q2h/s*tk
+ 2.*(tk*uk*uk-mZ2*uk*(s+3.*tk)+mZ2*mZ2*(2.*uk-s))/q1/q2/s
+ ( tk*uk*(uk+s)-mZ2*(uk*uk+3.*tk*uk+3.*s*uk+s*tk)
+ 2.*mZ2*mZ2*(uk+tk+2.*s)
)/q1h/q1/q2/s*tk
+ ( tk*(uk*uk+tk*uk-s*s)+mZ2*(4.*s*uk-3.*tk*uk-tk*tk+4.*s*s)
)/q1h/q2/s
- ( tk*uk+s*uk-s*tk-s*s+2.*mZ2*(s-tk) ) /q1h/q1/s*tk
+ q2*(tk*uk-s*uk-2.*s*tk-2.*s*s)/q1/q2h/s
+ 2.*(tk*uk-tk*tk-s*tk-s*s+mZ2*(2.*s-uk))/q1/s
- 2.*mZ2*(uk*uk-2.*mZ2*uk+2.*mZ2*mZ2)/q1/q1/q2/s*tk
+ (2.*s*uk+tk*tk+3.*s*tk+2*s*s)/q1h/s
+ q1*(uk+s)*(uk+tk)/q1h/q2h/s
+ (tk*uk+s*uk+3.*s*tk+2.*s*s-mZ2*(uk+tk+2.*s))/q1h/q2h/s*uk
+ (uk-tk)/2./q1h/q2h/s*(q1*(uk+s)/q2/tk-q2*(tk+s)/q1/uk)*tk*uk
+ (tk-2.*mZ2)*(uk-2.*mZ2)/q1h/q1/q2h/q2*tk*uk
- (q1*q1+q2*q2)/q1/q2
- 2.*mZ2*(q2-2.*mZ2)/q1/q1/s*tk
);
swap(tk ,uk );
swap(q1 ,q2 );
swap(q1h,q2h);
t_u_qqb += (2.*s)*sqr(gZ*2.)*4.*pi*alphaS_*CF_/NC_/2.
* ( - ( tk*uk*uk+2.*s*uk*uk-tk*tk*uk
- 2.*s*tk*uk+mZ2*(tk*tk-uk*uk+2.*s*uk-2.*s*tk-2.*s*s)
)/q1h/q1/q2h/s*tk
+ 2.*(tk*uk*uk-mZ2*uk*(s+3.*tk)+mZ2*mZ2*(2.*uk-s))/q1/q2/s
+ ( tk*uk*(uk+s)-mZ2*(uk*uk+3.*tk*uk+3.*s*uk+s*tk)
+ 2.*mZ2*mZ2*(uk+tk+2.*s)
)/q1h/q1/q2/s*tk
+ ( tk*(uk*uk+tk*uk-s*s)+mZ2*(4.*s*uk-3.*tk*uk-tk*tk+4.*s*s)
)/q1h/q2/s
- ( tk*uk+s*uk-s*tk-s*s+2.*mZ2*(s-tk) ) /q1h/q1/s*tk
+ q2*(tk*uk-s*uk-2.*s*tk-2.*s*s)/q1/q2h/s
+ 2.*(tk*uk-tk*tk-s*tk-s*s+mZ2*(2.*s-uk))/q1/s
- 2.*mZ2*(uk*uk-2.*mZ2*uk+2.*mZ2*mZ2)/q1/q1/q2/s*tk
+ (2.*s*uk+tk*tk+3.*s*tk+2*s*s)/q1h/s
+ q1*(uk+s)*(uk+tk)/q1h/q2h/s
+ (tk*uk+s*uk+3.*s*tk+2.*s*s-mZ2*(uk+tk+2.*s))/q1h/q2h/s*uk
+ (uk-tk)/2./q1h/q2h/s*(q1*(uk+s)/q2/tk-q2*(tk+s)/q1/uk)*tk*uk
+ (tk-2.*mZ2)*(uk-2.*mZ2)/q1h/q1/q2h/q2*tk*uk
- (q1*q1+q2*q2)/q1/q2
- 2.*mZ2*(q2-2.*mZ2)/q1/q1/s*tk
);
swap(tk ,uk );
swap(q1 ,q2 );
swap(q1h,q2h);
swap(q1 ,q1h);
swap(q2 ,q2h);
t_u_qqb += (2.*s)*sqr(gZ*2.)*4.*pi*alphaS_*CF_/NC_/2.
* ( - ( tk*uk*uk+2.*s*uk*uk-tk*tk*uk
- 2.*s*tk*uk+mZ2*(tk*tk-uk*uk+2.*s*uk-2.*s*tk-2.*s*s)
)/q1h/q1/q2h/s*tk
+ 2.*(tk*uk*uk-mZ2*uk*(s+3.*tk)+mZ2*mZ2*(2.*uk-s))/q1/q2/s
+ ( tk*uk*(uk+s)-mZ2*(uk*uk+3.*tk*uk+3.*s*uk+s*tk)
+ 2.*mZ2*mZ2*(uk+tk+2.*s)
)/q1h/q1/q2/s*tk
+ ( tk*(uk*uk+tk*uk-s*s)+mZ2*(4.*s*uk-3.*tk*uk-tk*tk+4.*s*s)
)/q1h/q2/s
- ( tk*uk+s*uk-s*tk-s*s+2.*mZ2*(s-tk) ) /q1h/q1/s*tk
+ q2*(tk*uk-s*uk-2.*s*tk-2.*s*s)/q1/q2h/s
+ 2.*(tk*uk-tk*tk-s*tk-s*s+mZ2*(2.*s-uk))/q1/s
- 2.*mZ2*(uk*uk-2.*mZ2*uk+2.*mZ2*mZ2)/q1/q1/q2/s*tk
+ (2.*s*uk+tk*tk+3.*s*tk+2*s*s)/q1h/s
+ q1*(uk+s)*(uk+tk)/q1h/q2h/s
+ (tk*uk+s*uk+3.*s*tk+2.*s*s-mZ2*(uk+tk+2.*s))/q1h/q2h/s*uk
+ (uk-tk)/2./q1h/q2h/s*(q1*(uk+s)/q2/tk-q2*(tk+s)/q1/uk)*tk*uk
+ (tk-2.*mZ2)*(uk-2.*mZ2)/q1h/q1/q2h/q2*tk*uk
- (q1*q1+q2*q2)/q1/q2
- 2.*mZ2*(q2-2.*mZ2)/q1/q1/s*tk
);
swap(q1 ,q1h);
swap(q2 ,q2h);
swap(tk ,uk );
swap(q1 ,q2h);
swap(q2 ,q1h);
t_u_qqb += (2.*s)*sqr(gZ*2.)*4.*pi*alphaS_*CF_/NC_/2.
* ( - ( tk*uk*uk+2.*s*uk*uk-tk*tk*uk
- 2.*s*tk*uk+mZ2*(tk*tk-uk*uk+2.*s*uk-2.*s*tk-2.*s*s)
)/q1h/q1/q2h/s*tk
+ 2.*(tk*uk*uk-mZ2*uk*(s+3.*tk)+mZ2*mZ2*(2.*uk-s))/q1/q2/s
+ ( tk*uk*(uk+s)-mZ2*(uk*uk+3.*tk*uk+3.*s*uk+s*tk)
+ 2.*mZ2*mZ2*(uk+tk+2.*s)
)/q1h/q1/q2/s*tk
+ ( tk*(uk*uk+tk*uk-s*s)+mZ2*(4.*s*uk-3.*tk*uk-tk*tk+4.*s*s)
)/q1h/q2/s
- ( tk*uk+s*uk-s*tk-s*s+2.*mZ2*(s-tk) ) /q1h/q1/s*tk
+ q2*(tk*uk-s*uk-2.*s*tk-2.*s*s)/q1/q2h/s
+ 2.*(tk*uk-tk*tk-s*tk-s*s+mZ2*(2.*s-uk))/q1/s
- 2.*mZ2*(uk*uk-2.*mZ2*uk+2.*mZ2*mZ2)/q1/q1/q2/s*tk
+ (2.*s*uk+tk*tk+3.*s*tk+2*s*s)/q1h/s
+ q1*(uk+s)*(uk+tk)/q1h/q2h/s
+ (tk*uk+s*uk+3.*s*tk+2.*s*s-mZ2*(uk+tk+2.*s))/q1h/q2h/s*uk
+ (uk-tk)/2./q1h/q2h/s*(q1*(uk+s)/q2/tk-q2*(tk+s)/q1/uk)*tk*uk
+ (tk-2.*mZ2)*(uk-2.*mZ2)/q1h/q1/q2h/q2*tk*uk
- (q1*q1+q2*q2)/q1/q2
- 2.*mZ2*(q2-2.*mZ2)/q1/q1/s*tk
);
swap(tk ,uk );
swap(q1 ,q2h);
swap(q2 ,q1h);
return t_u_qqb;
}
/***************************************************************************/
// M_B_WW is the Born matrix element exactly as defined in Eqs. 3.2-3.8
// of of NPB 410(1993)280-384.
double MEPP2VVPowheg::M_Born_WW(bornVVKinematics B) const {
Energy2 s(B.sb());
Energy2 t(B.tb());
Energy2 u(B.ub());
Energy2 mW2(B.k12b()); // N.B. the diboson masses are preserved in getting
bool up_type = abs(quark_->id())%2==0 ? true : false;
double Qi = up_type ? 2./3. : -1./3. ;
double giL = up_type ? guL_/2. : gdL_/2.;
double giR = up_type ? guR_/2. : gdR_/2.;
double e2 = sqr(gW_)*sin2ThetaW_;
double cos2ThetaW(1.-sin2ThetaW_);
double ctt_i(gW_*gW_*gW_*gW_/16.);
InvEnergy2 cts_i(gW_*gW_*e2/4./s *(Qi+2.*eZ_*giL/e2*s/(s-mW2/cos2ThetaW)));
InvEnergy4 css_i(e2*e2/s/s*(sqr(Qi+eZ_*(giL+giR)/e2*s/(s-mW2/cos2ThetaW))
+sqr( eZ_*(giL-giR)/e2*s/(s-mW2/cos2ThetaW)))
);
ctt_i *= 8.*Fij2_/gW_/gW_;
cts_i *= sqrt(8.*Fij2_/gW_/gW_);
if(quark_->id()!=-antiquark_->id()) {
cts_i = 0./GeV2;
css_i = 0./GeV2/GeV2;
}
if(!up_type) swap(t,u);
double signf = up_type ? 1. : -1.;
return 1./4./NC_
* (
ctt_i*( 16.*(u*t/mW2/mW2-1.)*(1./4.+mW2*mW2/t/t)+16.*s/mW2)
- cts_i*( 16.*(u*t/mW2/mW2-1.)*(s/4.-mW2/2.-mW2*mW2/t)
+ 16.*s*(s/mW2-2.+2.*mW2/t)
)
*signf
+
css_i*( 8.*(u*t/mW2/mW2-1.)*(s*s/4.-s*mW2+3.*mW2*mW2)
+ 8.*s*s*(s/mW2-4.)
)
);
}
/***************************************************************************/
// M_V_regular_WW is the regular part of the one-loop WW matrix element
// exactly as defined in Eqs. C.1 - C.7 of of NPB 410(1993)280-324 ***
// modulo a factor 1/(2s) ***, which is a flux factor that those authors
// absorb in the matrix element.
double MEPP2VVPowheg::M_V_regular_WW(realVVKinematics S) const {
Energy2 s(S.bornVariables().sb());
Energy2 t(S.bornVariables().tb());
Energy2 u(S.bornVariables().ub());
Energy2 mW2(S.k12r()); // N.B. the diboson masses are preserved in getting
double beta(S.betaxr()); // N.B. for x=1 \beta_x=\beta in NPB 383(1992)3-44.
bool up_type = abs(quark_->id())%2==0 ? true : false;
double Qi = up_type ? 2./3. : -1./3.;
double giL = up_type ? guL_/2. : gdL_/2.;
double giR = up_type ? guR_/2. : gdR_/2.;
double e2 = sqr(gW_)*sin2ThetaW_;
double cos2ThetaW(1.-sin2ThetaW_);
double ctt_i(gW_*gW_*gW_*gW_/16.);
InvEnergy2 cts_i(gW_*gW_*e2/4./s *(Qi+2.*eZ_*giL/e2*s/(s-mW2/cos2ThetaW)));
InvEnergy4 css_i(e2*e2/s/s*(sqr(Qi+eZ_*(giL+giR)/e2*s/(s-mW2/cos2ThetaW))
+sqr( eZ_*(giL-giR)/e2*s/(s-mW2/cos2ThetaW)))
);
ctt_i *= 8.*Fij2_/gW_/gW_;
cts_i *= sqrt(8.*Fij2_/gW_/gW_);
if(quark_->id()!=-antiquark_->id()) {
cts_i = 0./GeV2;
css_i = 0./GeV2/GeV2;
}
if(!up_type) swap(t,u);
double signf = up_type ? 1. : -1.;
InvEnergy4 TildeI4 = ( 2.*sqr(log(-t/mW2))-4.*log((mW2-t)/mW2)*log(-t/mW2)
- 4.*ReLi2(t/mW2) )/s/t;
InvEnergy2 TildeI3t = 1./(mW2-t)
*(sqr(log(mW2/s))/2.-sqr(log(-t/s))/2.-pi*pi/2.);
InvEnergy2 TildeI3l = 1./s/beta*( 4.*ReLi2((beta-1.)/(beta+1.))
+ sqr(log((1.-beta)/(1.+beta)))
+ pi*pi/3.);
double Fup1_st(0.);
Fup1_st = 4.*(80.*t*t+73.*s*t-140.*mW2*t+72.*mW2*mW2)/t/t
- 4.*sqr(4.*t+s)/s/beta/beta/t
- 128.*(t+2.*s)/mW2
+ 64.*t*(t+s)/mW2/mW2
- (32.*(t*t-3.*s*t-3.*mW2*mW2)/t/t+128.*s/(t-mW2))*log(-t/mW2)
+ ( 8.*(6.*t*t+8.*s*t-19.*mW2*t+12.*mW2*mW2)/t/t
- (32.*t*t-128.*s*t-26.*s*s)/s/beta/beta/t
+ 6.*sqr(4.*t+s)/s/sqr(sqr(beta))/t
)*log(s/mW2)
+ 32.*s*(2.*mW2*mW2/t-u)*TildeI4
- 64.*(t-mW2)*(2.*mW2*mW2/t/t-u/t)*TildeI3t
+ ( (16.*t*(4.*mW2-u)-49.*s*s+72.*mW2*s-48.*mW2*mW2)/2./t
+ 2.*(8.*t*t-14.*s*t-3.*s*s)/beta/beta/t
- 3.*sqr(4.*t+s)/2./sqr(sqr(beta))/t
)*TildeI3l
+ 32./3.*( 2.*(t+2.*s)/mW2
- (3.*t+2.*s-4.*mW2)/t
- t*(t+s)/mW2/mW2
)*pi*pi;
Energy2 Jup1_st(0.*GeV2);
Jup1_st = -128.*(t*t+2.*s*t+2.*s*s)/mW2
- 16.*(t*t-21.*s*t-26.*mW2*t+34.*mW2*s+17.*mW2*mW2)/t
+ 64.*s*t*(t+s)/mW2/mW2 +32.*s*s/(t-mW2)
+ ( 16.*(t-5.*s+2.*mW2)-48.*mW2*(2.*s+mW2)/t
+ 64.*s*(2.*t+s)/(t-mW2) - 32.*s*s*t/sqr(t-mW2)
)*log(-t/mW2)
+ ( 16.*(4.*t+s)/beta/beta
- 16.*(3.*t-2.*s)
+ 48.*mW2*(2.*t-2.*s-mW2)/t
)*log(s/mW2)
+ 16.*s*(t*(2.*s+u)-2.*mW2*(2.*s+mW2))*TildeI4
+ 32.*(t-mW2)*(2.*mW2*(2.*s+mW2)/t-2.*s-u)*TildeI3t
+ ( 32.*s*t-12.*s*s+32.*mW2*mW2
- 16.*mW2*(2.*t+7.*s)-4.*s*(4.*t+s)/beta/beta
)*TildeI3l
+ 32./3.*( 2.*(t*t+2.*s*t+2.*s*s)/mW2
- s*t*(t+s)/mW2/mW2-2.*mW2*(2.*t-2.*s-mW2)/t-t-4.*s
)*pi*pi;
Energy4 Kup1_st(0.*GeV2*GeV2);
Kup1_st = 16.*( 12.*t*t+20.*s*t-24.*mW2*t+17.*s*s-4.*mW2*s+12.*mW2*mW2
+ s*s*t*(t+s)/mW2/mW2-2.*s*(2.*t*t+3.*s*t+2.*s*s)/mW2)
*(2.-pi*pi/3.);
return pi*alphaS_*CF_/NC_/(sqr(4.*pi))
* ( ctt_i*Fup1_st - cts_i*Jup1_st*signf + css_i*Kup1_st );
}
/***************************************************************************/
// t_u_M_R_qqb is the real emission q + qb -> n + g matrix element
// exactly as defined in Eqs. C.1 of NPB 383(1992)3-44, multiplied by
// tk * uk!
Energy2 MEPP2VVPowheg::t_u_M_R_qqb_WW(realVVKinematics R) const {
// First the Born variables:
Energy2 s2(R.s2r());
Energy2 mW2(R.k12r());
// Then the rest:
Energy2 s(R.sr());
Energy2 tk(R.tkr());
Energy2 uk(R.ukr());
Energy2 q1(R.q1r());
Energy2 q2(R.q2r());
Energy2 q1h(R.q1hatr());
Energy2 q2h(R.q2hatr());
bool up_type = abs(quark_->id())%2==0 ? true : false;
double Qi = up_type ? 2./3. : -1./3.;
double giL = up_type ? guL_/2. : gdL_/2.;
double giR = up_type ? guR_/2. : gdR_/2.;
double e2 = sqr(gW_)*sin2ThetaW_;
double cos2ThetaW(1.-sin2ThetaW_);
double ctt_i(gW_*gW_*gW_*gW_/16.);
InvEnergy2 cts_i(gW_*gW_*e2/4./s2*(Qi+2.*eZ_*giL/e2*s2/(s2-mW2/cos2ThetaW)));
InvEnergy4 css_i(e2*e2/s2/s2*(sqr(Qi+eZ_*(giL+giR)/e2*s2/(s2-mW2/cos2ThetaW))
+sqr( eZ_*(giL-giR)/e2*s2/(s2-mW2/cos2ThetaW)))
);
ctt_i *= 8.*Fij2_/gW_/gW_;
cts_i *= sqrt(8.*Fij2_/gW_/gW_);
if(quark_->id()!=-antiquark_->id()) {
cts_i = 0./GeV2;
css_i = 0./GeV2/GeV2;
}
if(!up_type) {
swap(q1,q1h);
swap(q2,q2h);
}
double signf = up_type ? 1. : -1.;
Energy2 t_u_Xup(0.*GeV2);
Energy4 t_u_Yup(0.*GeV2*GeV2);
Energy6 t_u_Zup(0.*GeV2*GeV2*GeV2);
t_u_Xup = 32.*mW2*(tk*uk+3.*q2*uk+q2*s+q1*q2)/q1/q2/q2*tk
+ 32.*mW2*q1/q2/q2*uk
- 64.*mW2*s/q2
- 32.*tk*(uk-q2)/q1/q2*tk
+ 64.*mW2*mW2*mW2/q1/q1/q2*tk
- 16.*(2.*tk-2.*s-q2)/q2*uk
+ 16.*s*(2.*s+2.*q1+q2/2.)/q2
- 8.*(4.*tk+uk+9.*s+2.*q2+2.*q1)/mW2*tk
- 16.*s*(2.*s+q1)/mW2
- 64.*mW2*mW2*(tk*uk+q2*tk+q1*uk-q2*s/2.)/q1/q2/q2
+ 8.*s2*q1*(tk+s+q1)/mW2/mW2;
swap(tk,uk);
swap(q1,q2);
t_u_Xup += 32.*mW2*(tk*uk+3.*q2*uk+q2*s+q1*q2)/q1/q2/q2*tk
+ 32.*mW2*q1/q2/q2*uk
- 64.*mW2*s/q2
- 32.*tk*(uk-q2)/q1/q2*tk
+ 64.*mW2*mW2*mW2/q1/q1/q2*tk
- 16.*(2.*tk-2.*s-q2)/q2*uk
+ 16.*s*(2.*s+2.*q1+q2/2.)/q2
- 8.*(4.*tk+uk+9.*s+2.*q2+2.*q1)/mW2*tk
- 16.*s*(2.*s+q1)/mW2
- 64.*mW2*mW2*(tk*uk+q2*tk+q1*uk-q2*s/2.)/q1/q2/q2
+ 8.*s2*q1*(tk+s+q1)/mW2/mW2;
swap(tk,uk);
swap(q1,q2);
t_u_Yup = - 16.*tk*(uk*(uk+s+q1)+q2*(s-2.*q1))/q1/q2*tk
- 32.*mW2*mW2*s/q2
- 32.*mW2*mW2*mW2/q1/q2*tk
+ 16.*(2.*q2*uk+s*s+q1*s+5.*q2*s+q1*q2+2.*q2*q2)/q2*tk
- 16.*(q2*q2+s*s-q2*s)/q1*tk
+ 16.*s*(q1*s+3./2.*q2*s+q1*q2-q1*q1)/q2
+ 16.*mW2*tk*(4.*uk+s+q1-2.*q2)/q1/q2*tk
+ 16.*mW2*(3.*s*uk+q1*uk-q1*s-3.*q2*s-q1*q1+q2*q2)/q1/q2*tk
+ 16.*mW2*s*(q2-4.*s+2.*q1)/q2
- 8.*s2*(4.*tk+uk+9.*s+4.*q1+2.*q2)/mW2*tk
- 16.*s2*(2.*s*s+2.*q1*s+q1*q1)/mW2
- 32.*mW2*mW2*(tk+uk/2.+2.*s-q1)/q1/q2*tk
+ 8.*s2*s2*q1*(tk+s+q1)/mW2/mW2;
swap(tk,uk);
swap(q1,q2);
t_u_Yup += - 16.*tk*(uk*(uk+s+q1)+q2*(s-2.*q1))/q1/q2*tk
- 32.*mW2*mW2*s/q2
- 32.*mW2*mW2*mW2/q1/q2*tk
+ 16.*(2.*q2*uk+s*s+q1*s+5.*q2*s+q1*q2+2.*q2*q2)/q2*tk
- 16.*(q2*q2+s*s-q2*s)/q1*tk
+ 16.*s*(q1*s+3./2.*q2*s+q1*q2-q1*q1)/q2
+ 16.*mW2*tk*(4.*uk+s+q1-2.*q2)/q1/q2*tk
+ 16.*mW2*(3.*s*uk+q1*uk-q1*s-3.*q2*s-q1*q1+q2*q2)/q1/q2*tk
+ 16.*mW2*s*(q2-4.*s+2.*q1)/q2
- 8.*s2*(4.*tk+uk+9.*s+4.*q1+2.*q2)/mW2*tk
- 16.*s2*(2.*s*s+2.*q1*s+q1*q1)/mW2
- 32.*mW2*mW2*(tk+uk/2.+2.*s-q1)/q1/q2*tk
+ 8.*s2*s2*q1*(tk+s+q1)/mW2/mW2;
swap(tk,uk);
swap(q1,q2);
t_u_Zup = 8.*s2*(9.*tk+3.*uk+20.*s+10.*q1+4.*q2)*tk
+ 8.*s2*(17./2.*s*s+10.*q1*s+6.*q1*q1)
- 4.*s2*s2*(4.*tk+uk+9.*s+6.*q1+2.*q2)/mW2*tk
- 8.*s2*s2*(2.*s*s+3.*q1*s+2.*q1*q1)/mW2
- 16.*mW2*(2.*tk+5.*uk+7.*s+6.*q1+6.*q2)*tk
- 16.*mW2*s*(s+6.*q1)
+ 4.*s2*s2*s2*q1*(tk+s+q1)/mW2/mW2
+ 48.*mW2*mW2*s2;
swap(tk,uk);
swap(q1,q2);
t_u_Zup += 8.*s2*(9.*tk+3.*uk+20.*s+10.*q1+4.*q2)*tk
+ 8.*s2*(17./2.*s*s+10.*q1*s+6.*q1*q1)
- 4.*s2*s2*(4.*tk+uk+9.*s+6.*q1+2.*q2)/mW2*tk
- 8.*s2*s2*(2.*s*s+3.*q1*s+2.*q1*q1)/mW2
- 16.*mW2*(2.*tk+5.*uk+7.*s+6.*q1+6.*q2)*tk
- 16.*mW2*s*(s+6.*q1)
+ 4.*s2*s2*s2*q1*(tk+s+q1)/mW2/mW2
+ 48.*mW2*mW2*s2;
swap(tk,uk);
swap(q1,q2);
return -pi*alphaS_*CF_/NC_
* ( ctt_i*t_u_Xup - cts_i*t_u_Yup*signf + css_i*t_u_Zup );
}
/***************************************************************************/
// The game here is to get this helicity amplitude squared to return all the
// same values as t_u_M_R_qqb above, TIMES a further factor tk*uk!
Energy2 MEPP2VVPowheg::t_u_M_R_qqb_hel_amp(realVVKinematics R) const {
using namespace ThePEG::Helicity;
// qqb_hel_amps_.reset(ProductionMatrixElement(PDT::Spin1Half,PDT::Spin1Half,
// PDT::Spin1,PDT::Spin1,
// PDT::Spin1));
double sum_hel_amps_sqr(0.);
tcPDPtr p1data(quark_);
tcPDPtr p2data(antiquark_);
tcPDPtr k1data(mePartonData()[2]);
tcPDPtr k2data(mePartonData()[3]);
tcPDPtr kdata(getParticleData(ParticleID::g));
if(k1data->id()==-24&&k2data->id()==24) swap(k1data,k2data);
SpinorWaveFunction qSpinor(R.p1r(),p1data,incoming);
SpinorBarWaveFunction qbSpinor(R.p2r(),p2data,incoming);
vector<SpinorWaveFunction> q;
vector<SpinorBarWaveFunction> qb;
for(unsigned int ix=0;ix<2;ix++) {
qSpinor.reset(ix);
qbSpinor.reset(ix);
q.push_back(qSpinor);
qb.push_back(qbSpinor);
}
VectorWaveFunction v1Polarization(R.k1r(),k1data,outgoing);
VectorWaveFunction v2Polarization(R.k2r(),k2data,outgoing);
vector<VectorWaveFunction> v1;
vector<VectorWaveFunction> v2;
for(unsigned int ix=0;ix<3;ix++) {
v1Polarization.reset(ix);
v2Polarization.reset(ix);
v1.push_back(v1Polarization);
v2.push_back(v2Polarization);
}
VectorWaveFunction gPolarization(R.kr(),kdata,outgoing);
vector<VectorWaveFunction> g;
for(unsigned int ix=0;ix<3;ix+=2) {
gPolarization.reset(ix);
g.push_back(gPolarization);
}
AbstractFFVVertexPtr ffg = FFGvertex_;
AbstractFFVVertexPtr ffv1 = k1data->id()==23 ? FFZvertex_ : FFWvertex_;
AbstractFFVVertexPtr ffv2 = k2data->id()==23 ? FFZvertex_ : FFWvertex_;
// Collecting information for intermediate fermions
vector<tcPDPtr> tc;
if(abs(k1data->id())==24&&abs(k2data->id())==24) {
if(abs(p1data->id())%2==0)
for(int ix=0;ix<3;++ix) tc.push_back(getParticleData(1+2*ix));
else
for(int ix=0;ix<3;++ix) tc.push_back(getParticleData(2+2*ix));
}
else if(k1data->id()==23&&k2data->id()==23) tc.push_back(p1data);
else if(abs(k1data->id())==24&&k2data->id()==23) tc.push_back(p2data);
// Loop over helicities summing the relevant diagrams
for(unsigned int p1hel=0;p1hel<2;++p1hel) {
for(unsigned int p2hel=0;p2hel<2;++p2hel) {
for(unsigned int khel=0;khel<2;++khel) {
SpinorWaveFunction p1_k = ffg->evaluate(mu_UV2(),5,p1data,q[p1hel],g[khel]);
SpinorBarWaveFunction p2_k = ffg->evaluate(mu_UV2(),5,p2data,qb[p2hel],g[khel]);
for(unsigned int k1hel=0;k1hel<3;++k1hel) {
for(unsigned int k2hel=0;k2hel<3;++k2hel) {
// If helicity is exactly conserved (massless quarks) skip if p1hel=p2hel
// but if the production ME is required first fill it with (0.,0.).
if((p1hel==p2hel)&&helicityConservation_) {
// if(getMatrix) {
// if(khel==0)
// qqb_hel_amps_(p1hel,p2hel,k1hel,k2hel,0) = Complex(0.,0.);
// else
// qqb_hel_amps_(p1hel,p2hel,k1hel,k2hel,2) = Complex(0.,0.);
// }
continue;
}
vector<Complex> diagrams;
// Get all t-channel diagram contributions
tcPDPtr intermediate_t;
for(unsigned int ix=0;ix<tc.size();ix++) {
intermediate_t = (!(k1data->id()==24&&k2data->id()==-24)) ? p2data : tc[ix];
SpinorWaveFunction p1_v1 = ffv1->evaluate(scale(),5,intermediate_t,q[p1hel],v1[k1hel]);
SpinorBarWaveFunction p2_v2 = ffv2->evaluate(scale(),5,intermediate_t,qb[p2hel],v2[k2hel]);
// First calculate all the off-shell fermion currents
// Now calculate the 6 t-channel diagrams
// q+qb->g+v1+v2, q+qb->v1+g+v2, q+qb->v1+v2+g
if(!((k1data->id()==24&&k2data->id()==-24)&&(abs(p1data->id())%2==1))) {
diagrams.push_back(ffv1->evaluate(scale(),p1_k,p2_v2,v1[k1hel]));
diagrams.push_back(ffg->evaluate(mu_UV2(),p1_v1,p2_v2,g[khel]));
diagrams.push_back(ffv2->evaluate(scale(),p1_v1,p2_k,v2[k2hel]));
}
intermediate_t = (!(k1data->id()==24&&k2data->id()==-24)) ? p1data : tc[ix];
SpinorWaveFunction p1_v2 = ffv2->evaluate(scale(),5,intermediate_t,q[p1hel],v2[k2hel]);
SpinorBarWaveFunction p2_v1 = ffv1->evaluate(scale(),5,intermediate_t,qb[p2hel],v1[k1hel]);
// q+qb->g+v2+v1, q+qb->v2+g+v1, q+qb->v2+v1+g
if(!((k1data->id()==24&&k2data->id()==-24)&&(abs(p1data->id())%2==0))) {
diagrams.push_back(ffv2->evaluate(scale(),p1_k,p2_v1,v2[k2hel]));
diagrams.push_back(ffg->evaluate(mu_UV2(),p1_v2,p2_v1,g[khel]));
diagrams.push_back(ffv1->evaluate(scale(),p1_v2,p2_k,v1[k1hel]));
}
}
// Note: choosing 3 as the second argument in WWWvertex_->evaluate()
// sets option 3 in thepeg/Helicity/Vertex/VertexBase.cc , which
// means the propagator does not contain a width factor (which is
// good re. gauge invariance).
// If W+Z / W-Z calculate the two V+jet-like s-channel diagrams
if(abs(k1data->id())==24&&k2data->id()==23) {
// The off-shell s-channel boson current
VectorWaveFunction k1_k2 =
WWWvertex_->evaluate(scale(),3,k1data->CC(),v2[k2hel],v1[k1hel]);
// q+qb->g+v1*->g+v1+v2, q+qb->v1*+g->v1+v2+g
diagrams.push_back(ffv1->evaluate(scale(),p1_k,qb[p2hel],k1_k2));
diagrams.push_back(ffv1->evaluate(scale(),q[p1hel],p2_k,k1_k2));
}
// If W+W- calculate the four V+jet-like s-channel diagrams
if((k1data->id()==24&&k2data->id()==-24)&&(p1data->id()==-p2data->id())) {
// The off-shell s-channel boson current
VectorWaveFunction k1_k2;
// q+qb->g+Z0*->g+v1+v2,q+qb->Z0*+g->v1+v2+g,
tcPDPtr Z0 = getParticleData(ParticleID::Z0);
k1_k2 = WWWvertex_->evaluate(scale(),3,Z0,v2[k2hel],v1[k1hel]);
diagrams.push_back(FFZvertex_->evaluate(scale(),p1_k,qb[p2hel],k1_k2));
diagrams.push_back(FFZvertex_->evaluate(scale(),q[p1hel],p2_k,k1_k2));
// q+qb->g+gamma*->g+v1+v2,q+qb->gamma*+g->v1+v2+g,
tcPDPtr gamma = getParticleData(ParticleID::gamma);
k1_k2 = WWWvertex_->evaluate(scale(),3,gamma,v2[k2hel],v1[k1hel]);
diagrams.push_back(FFPvertex_->evaluate(scale(),p1_k,qb[p2hel],k1_k2));
diagrams.push_back(FFPvertex_->evaluate(scale(),q[p1hel],p2_k,k1_k2));
}
// Add up all diagrams to get the total amplitude:
Complex hel_amp(0.);
for(unsigned int ix=0;ix<diagrams.size();ix++) hel_amp += diagrams[ix];
// If we need to fill the production ME we do it here:
// if(getMatrix) {
// if(khel==0)
// qqb_hel_amps_(p1hel,p2hel,k1hel,k2hel,0) = hel_amp;
// else
// qqb_hel_amps_(p1hel,p2hel,k1hel,k2hel,2) = hel_amp;
// }
sum_hel_amps_sqr += norm(hel_amp);
}
}
}
}
}
// Fill up the remaining bits of the production ME, corresponding
// to longitudinal gluon polarization, with (0.,0.).
// if(getMatrix) {
// for(unsigned int p1hel=0;p1hel<2;++p1hel) {
// for(unsigned int p2hel=0;p2hel<2;++p2hel) {
// for(unsigned int k1hel=0;k1hel<3;++k1hel) {
// for(unsigned int k2hel=0;k2hel<3;++k2hel) {
// qqb_hel_amps_(p1hel,p2hel,k1hel,k2hel,1) = Complex(0.,0.);
// }
// }
// }
// }
// }
// Spin and colour averaging factors = 1/4 * CF * 1/3 = 1/9
sum_hel_amps_sqr /= 9.;
// Symmetry factor for identical Z bosons in the final state
if(k1data->id()==23&&k2data->id()==23) sum_hel_amps_sqr /= 2.;
return sum_hel_amps_sqr*R.tkr()*R.ukr()*UnitRemoval::InvE2;
}
/***************************************************************************/
// The game here is to get this helicity amplitude squared to return all the
// same values as t_u_M_R_qg above, TIMES a further factor tk*uk!
Energy2 MEPP2VVPowheg::t_u_M_R_qg_hel_amp(realVVKinematics R) const {
using namespace ThePEG::Helicity;
// qg_hel_amps_.reset(ProductionMatrixElement(PDT::Spin1Half,PDT::Spin1,
// PDT::Spin1,PDT::Spin1,
// PDT::Spin1Half));
double sum_hel_amps_sqr(0.);
tcPDPtr p1data(quark_);
tcPDPtr p2data(getParticleData(ParticleID::g));
tcPDPtr k1data(mePartonData()[2]);
tcPDPtr k2data(mePartonData()[3]);
tcPDPtr kdata (antiquark_->CC());
if(k1data->id()==-24&&k2data->id()==24) swap(k1data,k2data);
SpinorWaveFunction qinSpinor(R.p1r(),p1data,incoming);
SpinorBarWaveFunction qoutSpinor(R.kr(),kdata,outgoing);
vector<SpinorWaveFunction> qin;
vector<SpinorBarWaveFunction> qout;
for(unsigned int ix=0;ix<2;ix++) {
qinSpinor.reset(ix);
qoutSpinor.reset(ix);
qin.push_back(qinSpinor);
qout.push_back(qoutSpinor);
}
VectorWaveFunction v1Polarization(R.k1r(),k1data,outgoing);
VectorWaveFunction v2Polarization(R.k2r(),k2data,outgoing);
vector<VectorWaveFunction> v1;
vector<VectorWaveFunction> v2;
for(unsigned int ix=0;ix<3;ix++) {
v1Polarization.reset(ix);
v2Polarization.reset(ix);
v1.push_back(v1Polarization);
v2.push_back(v2Polarization);
}
VectorWaveFunction gPolarization(R.p2r(),p2data,incoming);
vector<VectorWaveFunction> g;
for(unsigned int ix=0;ix<3;ix+=2) {
gPolarization.reset(ix);
g.push_back(gPolarization);
}
AbstractFFVVertexPtr ffg = FFGvertex_;
AbstractFFVVertexPtr ffv1 = k1data->id()==23 ? FFZvertex_ : FFWvertex_;
AbstractFFVVertexPtr ffv2 = k2data->id()==23 ? FFZvertex_ : FFWvertex_;
// Collecting information for intermediate fermions
vector<tcPDPtr> tc;
if(abs(k1data->id())==24&&abs(k2data->id())==24) {
if(abs(p1data->id())%2==0)
for(int ix=0;ix<3;++ix) tc.push_back(getParticleData(1+2*ix));
else
for(int ix=0;ix<3;++ix) tc.push_back(getParticleData(2+2*ix));
}
else if(k1data->id()==23&&k2data->id()==23) tc.push_back(p1data);
else if(abs(k1data->id())==24&&k2data->id()==23) tc.push_back(kdata->CC());
// Loop over helicities summing the relevant diagrams
for(unsigned int p1hel=0;p1hel<2;++p1hel) {
for(unsigned int p2hel=0;p2hel<2;++p2hel) {
for(unsigned int khel=0;khel<2;++khel) {
SpinorWaveFunction p1_p2 = ffg->evaluate(mu_UV2(),5,p1data,qin[p1hel],g[p2hel]);
SpinorBarWaveFunction p2_k = ffg->evaluate(mu_UV2(),5,kdata->CC(),qout[khel],g[p2hel]);
for(unsigned int k1hel=0;k1hel<3;++k1hel) {
for(unsigned int k2hel=0;k2hel<3;++k2hel) {
// If helicity is exactly conserved (massless quarks) skip if p1hel!=khel
// but if the production ME is required first fill it with (0.,0.).
if((p1hel!=khel)&&helicityConservation_) {
// if(getMatrix) {
// if(p2hel==0)
// qg_hel_amps_(p1hel,0,k1hel,k2hel,khel) = Complex(0.,0.);
// else
// qg_hel_amps_(p1hel,2,k1hel,k2hel,khel) = Complex(0.,0.);
// }
continue;
}
vector<Complex> diagrams;
// Get all t-channel diagram contributions
tcPDPtr intermediate_q;
for(unsigned int ix=0;ix<tc.size();ix++) {
intermediate_q = (!(k1data->id()==24&&k2data->id()==-24)) ? antiquark_ : tc[ix];
SpinorWaveFunction p1_v1 = ffv1->evaluate(scale(),5,intermediate_q,qin[p1hel],v1[k1hel]);
SpinorBarWaveFunction k_v2 = ffv2->evaluate(scale(),5,intermediate_q,qout[khel],v2[k2hel]);
// First calculate all the off-shell fermion currents
// Now calculate the 6 abelian diagrams
// q+g->v1+v2+q with 2 t-channel propagators, 1 s- and 1 t-channel and 2 t-channel ones.
if(!((k1data->id()==24&&k2data->id()==-24)&&(abs(p1data->id())%2==1))) {
diagrams.push_back(ffv2->evaluate(scale(),p1_v1,p2_k,v2[k2hel]));
diagrams.push_back(ffg->evaluate(mu_UV2(),p1_v1,k_v2,g[p2hel]));
diagrams.push_back(ffv1->evaluate(scale(),p1_p2,k_v2,v1[k1hel]));
}
intermediate_q = (!(k1data->id()==24&&k2data->id()==-24)) ? p1data : tc[ix];
SpinorWaveFunction p1_v2 = ffv2->evaluate(scale(),5,intermediate_q,qin[p1hel],v2[k2hel]);
SpinorBarWaveFunction k_v1 = ffv1->evaluate(scale(),5,intermediate_q,qout[khel],v1[k1hel]);
// q+g->v2+v1+q, with 2 t-channel propagators, 1 s- and 1 t-channel and 2 t-channel ones.
if(!((k1data->id()==24&&k2data->id()==-24)&&(abs(p1data->id())%2==0))) {
diagrams.push_back(ffv1->evaluate(scale(),p1_v2,p2_k,v1[k1hel]));
diagrams.push_back(ffg->evaluate(mu_UV2(),p1_v2,k_v1,g[p2hel]));
diagrams.push_back(ffv2->evaluate(scale(),p1_p2,k_v1,v2[k2hel]));
}
}
// If W+Z / W-Z calculate the two V+jet-like s-channel diagrams
if(abs(k1data->id())==24&&k2data->id()==23) {
// The off-shell s-channel boson current
VectorWaveFunction k1_k2 =
WWWvertex_->evaluate(scale(),3,k1data->CC(),v2[k2hel],v1[k1hel]);
// q+qb->g+v1*->g+v1+v2, q+qb->v1*+g->v1+v2+g
diagrams.push_back(ffv1->evaluate(scale(),p1_p2,qout[khel],k1_k2));
diagrams.push_back(ffv1->evaluate(scale(),qin[p1hel],p2_k,k1_k2));
}
// If W+W- calculate the four V+jet-like s-channel diagrams
if((k1data->id()==24&&k2data->id()==-24)&&(p1data->id()==kdata->id())) {
// The off-shell s-channel boson current
VectorWaveFunction k1_k2;
// q+qb->g+Z0*->g+v1+v2,q+qb->Z0*+g->v1+v2+g,
tcPDPtr Z0 = getParticleData(ParticleID::Z0);
k1_k2 = WWWvertex_->evaluate(scale(),3,Z0,v2[k2hel],v1[k1hel]);
diagrams.push_back(FFZvertex_->evaluate(scale(),p1_p2,qout[khel],k1_k2));
diagrams.push_back(FFZvertex_->evaluate(scale(),qin[p1hel],p2_k,k1_k2));
// q+qb->g+gamma*->g+v1+v2,q+qb->gamma*+g->v1+v2+g,
tcPDPtr gamma = getParticleData(ParticleID::gamma);
k1_k2 = WWWvertex_->evaluate(scale(),3,gamma,v2[k2hel],v1[k1hel]);
diagrams.push_back(FFPvertex_->evaluate(scale(),p1_p2,qout[khel],k1_k2));
diagrams.push_back(FFPvertex_->evaluate(scale(),qin[p1hel],p2_k,k1_k2));
}
// Add up all diagrams to get the total amplitude:
Complex hel_amp(0.);
for(unsigned int ix=0;ix<diagrams.size();ix++) hel_amp += diagrams[ix];
// If we need to fill the production ME we do it here:
// if(getMatrix) {
// if(p2hel==0)
// qg_hel_amps_(p1hel,0,k1hel,k2hel,khel) = hel_amp;
// else
// qg_hel_amps_(p1hel,2,k1hel,k2hel,khel) = hel_amp;
// }
sum_hel_amps_sqr += norm(hel_amp);
}
}
}
}
}
// Fill up the remaining bits of the production ME, corresponding
// to longitudinal gluon polarization, with (0.,0.).
// if(getMatrix) {
// for(unsigned int p1hel=0;p1hel<2;++p1hel) {
// for(unsigned int k1hel=0;k1hel<3;++k1hel) {
// for(unsigned int k2hel=0;k2hel<3;++k2hel) {
// for(unsigned int khel=0;khel<2;++khel) {
// qg_hel_amps_(p1hel,1,k1hel,k2hel,khel) = Complex(0.,0.);
// }
// }
// }
// }
// }
// Spin and colour averaging factors = 1/4 * TR * 1/3 = 1/24
sum_hel_amps_sqr /= 24.;
// Symmetry factor for identical Z bosons in the final state
if(k1data->id()==23&&k2data->id()==23) sum_hel_amps_sqr /= 2.;
return sum_hel_amps_sqr*R.tkr()*R.ukr()*UnitRemoval::InvE2;
}
/***************************************************************************/
// The game here is to get this helicity amplitude squared to return all the
// same values as t_u_M_R_gqb above, TIMES a further factor tk*uk!
Energy2 MEPP2VVPowheg::t_u_M_R_gqb_hel_amp(realVVKinematics R) const {
using namespace ThePEG::Helicity;
// gqb_hel_amps_.reset(ProductionMatrixElement(PDT::Spin1,PDT::Spin1Half,
// PDT::Spin1,PDT::Spin1,
// PDT::Spin1Half));
double sum_hel_amps_sqr(0.);
tcPDPtr p1data(getParticleData(ParticleID::g));
tcPDPtr p2data(antiquark_);
tcPDPtr k1data(mePartonData()[2]);
tcPDPtr k2data(mePartonData()[3]);
tcPDPtr kdata (quark_->CC());
if(k1data->id()==-24&&k2data->id()==24) swap(k1data,k2data);
SpinorBarWaveFunction qbinSpinor(R.p2r(),p2data,incoming);
SpinorWaveFunction qboutSpinor(R.kr(),kdata,outgoing);
vector<SpinorBarWaveFunction> qbin;
vector<SpinorWaveFunction> qbout;
for(unsigned int ix=0;ix<2;ix++) {
qbinSpinor.reset(ix);
qboutSpinor.reset(ix);
qbin.push_back(qbinSpinor);
qbout.push_back(qboutSpinor);
}
VectorWaveFunction v1Polarization(R.k1r(),k1data,outgoing);
VectorWaveFunction v2Polarization(R.k2r(),k2data,outgoing);
vector<VectorWaveFunction> v1;
vector<VectorWaveFunction> v2;
for(unsigned int ix=0;ix<3;ix++) {
v1Polarization.reset(ix);
v2Polarization.reset(ix);
v1.push_back(v1Polarization);
v2.push_back(v2Polarization);
}
VectorWaveFunction gPolarization(R.p1r(),p1data,incoming);
vector<VectorWaveFunction> g;
for(unsigned int ix=0;ix<3;ix+=2) {
gPolarization.reset(ix);
g.push_back(gPolarization);
}
AbstractFFVVertexPtr ffg = FFGvertex_;
AbstractFFVVertexPtr ffv1 = k1data->id()==23 ? FFZvertex_ : FFWvertex_;
AbstractFFVVertexPtr ffv2 = k2data->id()==23 ? FFZvertex_ : FFWvertex_;
// Collecting information for intermediate fermions
vector<tcPDPtr> tc;
if(abs(k1data->id())==24&&abs(k2data->id())==24) {
if(abs(p2data->id())%2==0)
for(int ix=0;ix<3;++ix) tc.push_back(getParticleData(1+2*ix));
else
for(int ix=0;ix<3;++ix) tc.push_back(getParticleData(2+2*ix));
}
else if(k1data->id()==23&&k2data->id()==23) tc.push_back(p2data);
else if(abs(k1data->id())==24&&k2data->id()==23) tc.push_back(kdata->CC());
// Loop over helicities summing the relevant diagrams
for(unsigned int p1hel=0;p1hel<2;++p1hel) {
for(unsigned int p2hel=0;p2hel<2;++p2hel) {
for(unsigned int khel=0;khel<2;++khel) {
SpinorBarWaveFunction p1_p2 = ffg->evaluate(mu_UV2(),5,p2data,qbin[p2hel],g[p1hel]);
SpinorWaveFunction p1_k = ffg->evaluate(mu_UV2(),5,kdata->CC(),qbout[khel],g[p1hel]);
for(unsigned int k1hel=0;k1hel<3;++k1hel) {
for(unsigned int k2hel=0;k2hel<3;++k2hel) {
// If helicity is exactly conserved (massless quarks) skip if p2hel!=khel
// but if the production ME is required first fill it with (0.,0.).
if((p2hel!=khel)&&helicityConservation_) {
// if(getMatrix) {
// if(p1hel==0)
// gqb_hel_amps_(0,p2hel,k1hel,k2hel,khel) = Complex(0.,0.);
// else
// gqb_hel_amps_(2,p2hel,k1hel,k2hel,khel) = Complex(0.,0.);
// }
continue;
}
vector<Complex> diagrams;
// Get all t-channel diagram contributions
tcPDPtr intermediate_q;
for(unsigned int ix=0;ix<tc.size();ix++) {
intermediate_q = (!(k1data->id()==24&&k2data->id()==-24)) ? quark_ : tc[ix];
SpinorBarWaveFunction p2_v1 = ffv1->evaluate(scale(),5,intermediate_q,qbin[p2hel],v1[k1hel]);
SpinorWaveFunction k_v2 = ffv2->evaluate(scale(),5,intermediate_q,qbout[khel],v2[k2hel]);
// First calculate all the off-shell fermion currents
// Now calculate the 6 abelian diagrams q+g->v1+v2+q
// with 2 t-channel propagators, 1 s- and 1 t-channel
// and 2 t-channel ones.
if(!((k1data->id()==24&&k2data->id()==-24)&&(abs(p2data->id())%2==0))) {
diagrams.push_back(ffv2->evaluate(scale(),p1_k,p2_v1,v2[k2hel]));
diagrams.push_back(ffg->evaluate(mu_UV2(),k_v2,p2_v1,g[p1hel]));
diagrams.push_back(ffv1->evaluate(scale(),k_v2,p1_p2,v1[k1hel]));
}
intermediate_q = (!(k1data->id()==24&&k2data->id()==-24)) ? p2data : tc[ix];
SpinorBarWaveFunction p2_v2 = ffv2->evaluate(scale(),5,intermediate_q,qbin[p2hel],v2[k2hel]);
SpinorWaveFunction k_v1 = ffv1->evaluate(scale(),5,intermediate_q,qbout[khel],v1[k1hel]);
// q+g->v2+v1+q, with 2 t-channel propagators, 1 s- and 1 t-channel and 2 t-channel ones.
if(!((k1data->id()==24&&k2data->id()==-24)&&(abs(p2data->id())%2==1))) {
diagrams.push_back(ffv1->evaluate(scale(),p1_k,p2_v2,v1[k1hel]));
diagrams.push_back(ffg->evaluate(mu_UV2(),k_v1,p2_v2,g[p1hel]));
diagrams.push_back(ffv2->evaluate(scale(),k_v1,p1_p2,v2[k2hel]));
}
}
// If W+Z / W-Z calculate the two V+jet-like s-channel diagrams
if(abs(k1data->id())==24&&k2data->id()==23) {
// The off-shell s-channel boson current
VectorWaveFunction k1_k2 =
WWWvertex_->evaluate(scale(),3,k1data->CC(),v2[k2hel],v1[k1hel]);
// q+qb->g+v1*->g+v1+v2, q+qb->v1*+g->v1+v2+g
diagrams.push_back(ffv1->evaluate(scale(),qbout[khel],p1_p2,k1_k2));
diagrams.push_back(ffv1->evaluate(scale(),p1_k,qbin[p2hel],k1_k2));
}
// If W+W- calculate the four V+jet-like s-channel diagrams
if((k1data->id()==24&&k2data->id()==-24)&&(p2data->id()==kdata->id())) {
// The off-shell s-channel boson current
VectorWaveFunction k1_k2;
// q+qb->g+Z0*->g+v1+v2,q+qb->Z0*+g->v1+v2+g,
tcPDPtr Z0 = getParticleData(ParticleID::Z0);
k1_k2 = WWWvertex_->evaluate(scale(),3,Z0,v2[k2hel],v1[k1hel]);
diagrams.push_back(FFZvertex_->evaluate(scale(),qbout[khel],p1_p2,k1_k2));
diagrams.push_back(FFZvertex_->evaluate(scale(),p1_k,qbin[p2hel],k1_k2));
// q+qb->g+gamma*->g+v1+v2,q+qb->gamma*+g->v1+v2+g,
tcPDPtr gamma = getParticleData(ParticleID::gamma);
k1_k2 = WWWvertex_->evaluate(scale(),3,gamma,v2[k2hel],v1[k1hel]);
diagrams.push_back(FFPvertex_->evaluate(scale(),qbout[khel],p1_p2,k1_k2));
diagrams.push_back(FFPvertex_->evaluate(scale(),p1_k,qbin[p2hel],k1_k2));
}
// Add up all diagrams to get the total amplitude:
Complex hel_amp(0.);
for(unsigned int ix=0;ix<diagrams.size();ix++) hel_amp += diagrams[ix];
// If we need to fill the production ME we do it here:
// if(getMatrix) {
// if(p1hel==0)
// gqb_hel_amps_(0,p2hel,k1hel,k2hel,khel) = hel_amp;
// else
// gqb_hel_amps_(2,p2hel,k1hel,k2hel,khel) = hel_amp;
// }
sum_hel_amps_sqr += norm(hel_amp);
}
}
}
}
}
// Fill up the remaining bits of the production ME, corresponding
// to longitudinal gluon polarization, with (0.,0.).
// if(getMatrix) {
// for(unsigned int p2hel=0;p2hel<2;++p2hel) {
// for(unsigned int k1hel=0;k1hel<3;++k1hel) {
// for(unsigned int k2hel=0;k2hel<3;++k2hel) {
// for(unsigned int khel=0;khel<2;++khel) {
// gqb_hel_amps_(1,p2hel,k1hel,k2hel,khel) = Complex(0.,0.);
// }
// }
// }
// }
// }
// Spin and colour averaging factors = 1/4 * TR * 1/3 = 1/24
sum_hel_amps_sqr /= 24.;
// Symmetry factor for identical Z bosons in the final state
if(k1data->id()==23&&k2data->id()==23) sum_hel_amps_sqr /= 2.;
return sum_hel_amps_sqr*R.tkr()*R.ukr()*UnitRemoval::InvE2;
}
double MEPP2VVPowheg::lo_me() const {
using namespace ThePEG::Helicity;
double sum_hel_amps_sqr(0.);
tcPDPtr p1data(quark_);
tcPDPtr p2data(antiquark_);
tcPDPtr k1data(mePartonData()[2]);
tcPDPtr k2data(mePartonData()[3]);
if(k1data->id()==-24&&k2data->id()==24) swap(k1data,k2data); // Should never actually occur.
SpinorWaveFunction qSpinor(B_.p1b(),p1data,incoming);
SpinorBarWaveFunction qbSpinor(B_.p2b(),p2data,incoming);
vector<SpinorWaveFunction> q;
vector<SpinorBarWaveFunction> qb;
for(unsigned int ix=0;ix<2;ix++) {
qSpinor.reset(ix);
qbSpinor.reset(ix);
q.push_back(qSpinor);
qb.push_back(qbSpinor);
}
VectorWaveFunction v1Polarization(B_.k1b(),k1data,outgoing);
VectorWaveFunction v2Polarization(B_.k2b(),k2data,outgoing);
vector<VectorWaveFunction> v1;
vector<VectorWaveFunction> v2;
for(unsigned int ix=0;ix<3;ix++) {
v1Polarization.reset(ix);
v2Polarization.reset(ix);
v1.push_back(v1Polarization);
v2.push_back(v2Polarization);
}
AbstractFFVVertexPtr ffv1 = k1data->id()==23 ? FFZvertex_ : FFWvertex_;
AbstractFFVVertexPtr ffv2 = k2data->id()==23 ? FFZvertex_ : FFWvertex_;
// Collecting information for intermediate fermions
vector<tcPDPtr> tc;
if(abs(k1data->id())==24&&abs(k2data->id())==24) {
if(abs(p1data->id())%2==0)
for(int ix=0;ix<3;++ix) tc.push_back(getParticleData(1+2*ix));
else
for(int ix=0;ix<3;++ix) tc.push_back(getParticleData(2+2*ix));
}
else if(k1data->id()==23&&k2data->id()==23) tc.push_back(p1data);
else if(abs(k1data->id())==24&&k2data->id()==23) tc.push_back(p2data);
// Loop over helicities summing the relevant diagrams
for(unsigned int p1hel=0;p1hel<2;++p1hel) {
for(unsigned int p2hel=0;p2hel<2;++p2hel) {
if((p1hel==p2hel)&&helicityConservation_) continue;
for(unsigned int k1hel=0;k1hel<3;++k1hel) {
for(unsigned int k2hel=0;k2hel<3;++k2hel) {
vector<Complex> diagrams;
// Get all t-channel diagram contributions
tcPDPtr intermediate_t;
for(unsigned int ix=0;ix<tc.size();ix++) {
intermediate_t = (!(k1data->id()==24&&k2data->id()==-24)) ? p2data : tc[ix];
SpinorWaveFunction p1_v1 = ffv1->evaluate(scale(),5,intermediate_t,q[p1hel],v1[k1hel]);
// First calculate all the off-shell fermion currents
// Now calculate the 6 t-channel diagrams
// q+qb->v1+v2
if(!((k1data->id()==24&&k2data->id()==-24)&&(abs(p1data->id())%2==1)))
diagrams.push_back(ffv2->evaluate(scale(),p1_v1,qb[p2hel],v2[k2hel]));
intermediate_t = (!(k1data->id()==24&&k2data->id()==-24)) ? p1data : tc[ix];
SpinorWaveFunction p1_v2 = ffv2->evaluate(scale(),5,intermediate_t,q[p1hel],v2[k2hel]);
// q+qb->v2+v1
if(!((k1data->id()==24&&k2data->id()==-24)&&(abs(p1data->id())%2==0)))
diagrams.push_back(ffv1->evaluate(scale(),p1_v2,qb[p2hel],v1[k1hel]));
}
// If W+Z / W-Z calculate the two V+jet-like s-channel diagrams
if(abs(k1data->id())==24&&k2data->id()==23) {
// The off-shell s-channel boson current
VectorWaveFunction k1_k2 =
WWWvertex_->evaluate(scale(),3,k1data->CC(),v2[k2hel],v1[k1hel]);
// q+qb->v1*->v1+v2
diagrams.push_back(ffv1->evaluate(scale(),q[p1hel],qb[p2hel],k1_k2));
}
// If W+W- calculate the four V+jet-like s-channel diagrams
if((k1data->id()==24&&k2data->id()==-24)&&(p1data->id()==-p2data->id())) {
// The off-shell s-channel boson current
VectorWaveFunction k1_k2;
// q+qb->Z0*->v1+v2
tcPDPtr Z0 = getParticleData(ParticleID::Z0);
k1_k2 = WWWvertex_->evaluate(scale(),3,Z0,v2[k2hel],v1[k1hel]);
diagrams.push_back(FFZvertex_->evaluate(scale(),q[p1hel],qb[p2hel],k1_k2));
// q+qb->gamma*->v1+v2
tcPDPtr gamma = getParticleData(ParticleID::gamma);
k1_k2 = WWWvertex_->evaluate(scale(),3,gamma,v2[k2hel],v1[k1hel]);
diagrams.push_back(FFPvertex_->evaluate(scale(),q[p1hel],qb[p2hel],k1_k2));
}
// Add up all diagrams to get the total amplitude:
Complex hel_amp(0.);
for(unsigned int ix=0;ix<diagrams.size();ix++) hel_amp += diagrams[ix];
// If we need to fill the production ME we do it here:
// if(getMatrix) lo_hel_amps_(p1hel,p2hel,k1hel,k2hel) = hel_amp;
sum_hel_amps_sqr += norm(hel_amp);
}
}
}
}
// Spin and colour averaging factors = 1/4 * 1/3 = 1/12
sum_hel_amps_sqr /= 12.;
// Symmetry factor for identical Z bosons in the final state
if(k1data->id()==23&&k2data->id()==23) sum_hel_amps_sqr /= 2.;
return sum_hel_amps_sqr;
}
HardTreePtr MEPP2VVPowheg::generateHardest(ShowerTreePtr tree) {
// Now we want to set these data vectors according to the particles we've
// received from the current 2->2 hard collision:
vector<ShowerProgenitorPtr> particlesToShower;
for(map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator
cit=tree->incomingLines().begin();cit!=tree->incomingLines().end();++cit )
particlesToShower.push_back(cit->first);
qProgenitor_ = particlesToShower[0];
qbProgenitor_ = particlesToShower[1];
showerQuark_ = particlesToShower[0]->progenitor();
showerAntiquark_ = particlesToShower[1]->progenitor();
qHadron_ = particlesToShower[0]->beam();
qbHadron_ = particlesToShower[1]->beam();
if(showerQuark_->id()<0) {
swap(qProgenitor_,qbProgenitor_);
swap(showerQuark_,showerAntiquark_);
swap(qHadron_,qbHadron_);
}
// In _our_ calculation we basically define the +z axis as being given
// by the direction of the incoming quark for q+qb & q+g processes and
// the incoming gluon for g+qbar processes. So now we might need to flip
// the beams, bjorken x values, colliding partons accordingly:
flipped_ = showerQuark_->momentum().z()<ZERO ? true : false;
assert(tree->outgoingLines().size()==2);
for(map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator
cit=tree->outgoingLines().begin();cit!=tree->outgoingLines().end();++cit )
particlesToShower.push_back(cit->first);
V1_ = particlesToShower[2]->progenitor();
V2_ = particlesToShower[3]->progenitor();
gluon_ = getParticleData(ParticleID::g)->produceParticle();
// Abort the run if V1_ and V2_ are not just pointers to different gauge bosons
if(!V1_||!V2_)
throw Exception()
<< "MEPP2VVPowheg::generateHardest()\n"
<< "one or both of the gauge boson pointers is null." << Exception::abortnow;
if(!(abs(V1_->id())==24||V1_->id()==23)||!(abs(V2_->id())==24||V2_->id()==23))
throw Exception()
<< "MEPP2VVPowheg::generateHardest()\nmisidentified gauge bosons"
<< "V1_ = " << V1_->PDGName() << "\n"
<< "V2_ = " << V2_->PDGName() << "\n"
<< Exception::abortnow;
// Order the gauge bosons in the same way as in the NLO calculation
// (the same way as in the NLO matrix element):
// W+(->e+,nu_e) W-(->e-,nu_ebar) (MCFM: 61 [nproc])
if(V1_->id()==-24&&V2_->id()== 24) swap(V1_,V2_);
// W+/-(mu+,nu_mu / mu-,nu_mubar) Z(nu_e,nu_ebar) (MCFM: 72+77 [nproc])
if(V1_->id()== 23&&abs(V2_->id())== 24) swap(V1_,V2_);
// *** N.B. ***
// We should not have to do a swap in the ZZ case, even if the different
// (off-shell) masses of the Z's are taken into account by generating
// the Born variables using the WZ LO/NLO matrix element(s), because
// those transformed matrix elements are, according to mathematica,
// symmetric in the momenta (and therefore also the masses) of the 2 Z's.
// If the vector bosons have decayed already then we may want to
// to get the children_ (and any associated photons) to correct
// spin correlations:
StepPtr theSubProcess = generator()->eventHandler()->currentStep();
tPVector outgoing = theSubProcess->getFinalState();
children_.clear();
photons_.clear();
if(outgoing.size()>=4) {
for(unsigned int ix=0;ix<outgoing.size();ix++)
if(outgoing[ix]->parents()[0]&&
(abs(outgoing[ix]->parents()[0]->id())==24||
abs(outgoing[ix]->parents()[0]->id())==23)) {
if(outgoing[ix]->id()!=ParticleID::gamma)
children_.push_back(outgoing[ix]);
else
photons_.push_back(outgoing[ix]);
}
assert(children_.size()==4);
if(children_[0]->parents()[0]!=children_[1]->parents()[0])
swap(children_[0],children_[2]);
if(children_[0]->parents()[0]!=children_[1]->parents()[0])
swap(children_[0],children_[3]);
if(children_[0]->parents()[0]->id()!=V1_->id()) {
swap(children_[0],children_[2]);
swap(children_[1],children_[3]);
}
if(children_[0]->id()<0) swap(children_[0],children_[1]);
if(children_[2]->id()<0) swap(children_[2],children_[3]);
assert(children_[0]->parents()[0]==children_[1]->parents()[0]);
assert(children_[2]->parents()[0]==children_[3]->parents()[0]);
}
// Now we want to construct a bornVVKinematics object. The
// constructor for that needs all 4 momenta, q, qbar, V1_, V2_
// in that order, as well as the Bjorken xq and xqbar.
// Get the momenta first:
vector<Lorentz5Momentum> theBornMomenta;
theBornMomenta.push_back(showerQuark_->momentum());
theBornMomenta.push_back(showerAntiquark_->momentum());
theBornMomenta.push_back(V1_->momentum());
theBornMomenta.push_back(V2_->momentum());
// N.B. if the showerQuark_ travels in the -z direction the born kinematics object
// will detect this and rotate all particles by pi about the y axis!
// Leading order momentum fractions:
tcPPtr qHadron = generator()->currentEvent()->primaryCollision()->incoming().first;
tcPPtr qbHadron = generator()->currentEvent()->primaryCollision()->incoming().second;
assert(qHadron->children().size()>0&&qbHadron->children().size()>0);
if(qHadron->children()[0]->id()<0) swap(qHadron,qbHadron);
// quark and antiquark momentum fractions respectively
double xa = showerQuark_ ->momentum().z()/qHadron ->momentum().z();
double xb = showerAntiquark_->momentum().z()/qbHadron->momentum().z();
// Create the object containing all 2->2 __kinematic__ information:
B_ = bornVVKinematics(theBornMomenta,xa,xb);
// lo_me_ is the colour & spin averaged n-body matrix element squared:
lo_me_ = lo_me(true);
// Attempt to generate some radiative variables and their kinematics:
vector<Lorentz5Momentum> theRealMomenta;
channel_ = 999;
if(!getEvent(theRealMomenta,channel_)) return HardTreePtr();
// Set the maximum pT for subsequent emissions:
pT_ < min_pT_ ? qProgenitor_ ->maximumpT(min_pT_) : qProgenitor_ ->maximumpT(pT_);
pT_ < min_pT_ ? qbProgenitor_->maximumpT(min_pT_) : qbProgenitor_->maximumpT(pT_);
// Determine whether the quark or antiquark emitted:
fermionNumberOfMother_=0;
if((channel_==0&&theRealMomenta[0].z()/theRealMomenta[4].z()>=ZERO)||
channel_==2) fermionNumberOfMother_ = 1;
else if((channel_==0&&theRealMomenta[0].z()/theRealMomenta[4].z()<ZERO)||
channel_==1) fermionNumberOfMother_ = -1;
assert(fermionNumberOfMother_!=0);
// If the quark in the original tree was travelling in the -z direction
// then we need to unflip the event (flips are automatically carried out
// when the original quark travels in the in -z direction when the
// bornVVKinematics object is created):
if(flipped_)
for(unsigned int ix=0;ix<theRealMomenta.size();ix++)
theRealMomenta[ix].rotateY(-Constants::pi);
// Randomly rotate the event about the beam axis:
double randomPhi(UseRandom::rnd()*2.*Constants::pi);
for(unsigned int ix=0;ix<theRealMomenta.size();ix++)
theRealMomenta[ix].rotateZ(randomPhi);
// Warn if momentum conservation is not obeyed:
Lorentz5Momentum inMinusOut(theRealMomenta[0]+theRealMomenta[1]
-theRealMomenta[2]-theRealMomenta[3]
-theRealMomenta[4]);
if(inMinusOut.t()>0.1*GeV||inMinusOut.x()>0.1*GeV||
inMinusOut.y()>0.1*GeV||inMinusOut.z()>0.1*GeV)
cout << "MEPP2VVPowheg::generateHardest\n"
<< "Momentum imbalance in V1 V2 rest frame\n"
<< "P_in minus P_out = " << inMinusOut/GeV << endl;
// From the radiative kinematics we now have to form ShowerParticle objects:
ShowerParticlePtr p1;
ShowerParticlePtr p2;
ShowerParticlePtr k1(new_ptr(ShowerParticle(V1_->dataPtr(),true )));
ShowerParticlePtr k2(new_ptr(ShowerParticle(V2_->dataPtr(),true )));
ShowerParticlePtr k ;
// q+qbar -> V1+V2+g
if(channel_==0) {
p1 = new_ptr(ShowerParticle(showerQuark_->dataPtr() ,false));
p2 = new_ptr(ShowerParticle(showerAntiquark_->dataPtr() ,false));
k = new_ptr(ShowerParticle(gluon_->dataPtr() ,true ));
}
// q+g -> V1+V2+q
else if(channel_==1) {
p1 = new_ptr(ShowerParticle(showerQuark_->dataPtr() ,false));
p2 = new_ptr(ShowerParticle(gluon_->dataPtr() ,false));
k = new_ptr(ShowerParticle(showerAntiquark_->dataPtr()->CC() ,true ));
}
// g+qbar -> V1+V2+qbar
else {
p1 = new_ptr(ShowerParticle(gluon_->dataPtr() ,false));
p2 = new_ptr(ShowerParticle(showerAntiquark_->dataPtr() ,false));
k = new_ptr(ShowerParticle(showerQuark_->dataPtr()->CC() ,true ));
}
// Set the momenta of the ShowerParticlePtr's:
p1->set5Momentum(theRealMomenta[0]);
p2->set5Momentum(theRealMomenta[1]);
k1->set5Momentum(theRealMomenta[2]);
k2->set5Momentum(theRealMomenta[3]);
k ->set5Momentum(theRealMomenta[4]);
// Then construct another set of ShowerPointers that will be
// useful in creating the hardTree, using this information:
ShowerParticlePtr mother;
ShowerParticlePtr spacelikeSon;
ShowerParticlePtr timelikeSon;
ShowerParticlePtr spectator;
if(fermionNumberOfMother_==1) {
mother = new_ptr(ShowerParticle(showerQuark_->dataPtr() ,false));
spacelikeSon = p1;
timelikeSon = k;
spectator = p2;
} else if(fermionNumberOfMother_==-1) {
mother = new_ptr(ShowerParticle(showerAntiquark_->dataPtr(),false));
spacelikeSon = p2;
timelikeSon = k;
spectator = p1;
} else {
throw Exception() << "MEPP2VVPowheg::generateHardest()"
<< "Failed to determine whether the q or qbar branched"
<< Exception::runerror;
}
Lorentz5Momentum motherMomentum(spacelikeSon->momentum()-timelikeSon->momentum());
motherMomentum.rescaleMass();
mother->set5Momentum(motherMomentum);
// Create HardBranchingPtrs for the particles
HardBranchingPtr spacelikeSonBranching =
new_ptr(HardBranching(spacelikeSon,SudakovPtr(),HardBranchingPtr() ,HardBranching::Incoming ));
HardBranchingPtr timelikeSonBranching =
new_ptr(HardBranching(timelikeSon ,SudakovPtr(),spacelikeSonBranching,HardBranching::Outgoing));
HardBranchingPtr spectatorBranching =
new_ptr(HardBranching(spectator ,SudakovPtr(),HardBranchingPtr() ,HardBranching::Incoming ));
HardBranchingPtr motherBranching =
new_ptr(HardBranching(mother ,SudakovPtr(),spacelikeSonBranching,HardBranching::Incoming ));
HardBranchingPtr V1_Branching =
new_ptr(HardBranching(k1 ,SudakovPtr(),HardBranchingPtr() ,HardBranching::Outgoing));
HardBranchingPtr V2_Branching =
new_ptr(HardBranching(k2 ,SudakovPtr(),HardBranchingPtr() ,HardBranching::Outgoing));
// N.B. The DrellYanHardGenerator first adds the timelikeSonBranching as a child
// child of the spacelikeSonBranching before adding the motherBranching. We do
// it the other way round in accordance with PowhegEvolver::checkShowerMomentum.
spacelikeSonBranching->addChild(motherBranching);
spacelikeSonBranching->addChild(timelikeSonBranching);
motherBranching->colourPartner(spectatorBranching);
spectatorBranching->colourPartner(motherBranching);
vector<HardBranchingPtr> spacelikeBranchings,hardBranchings;
spacelikeBranchings.push_back(fermionNumberOfMother_ == 1 ?
spacelikeSonBranching : spectatorBranching);
spacelikeBranchings.push_back(fermionNumberOfMother_ == -1 ?
spacelikeSonBranching : spectatorBranching);
hardBranchings.push_back(motherBranching);
hardBranchings.push_back(spectatorBranching);
hardBranchings.push_back(V1_Branching);
hardBranchings.push_back(V2_Branching);
// Recalculate the hard vertex for this event:
// For spin correlations, if an emission occurs go calculate the relevant
// combination of amplitudes for the ProductionMatrixElement.
if(realMESpinCorrelations_) {
// Here we reset the realVVKinematics n+1 momenta to be those
// of the lab frame in order to calculate the spin correlations.
// Note that these momenta are not used for anything else after
// this.
R_.p1r(theRealMomenta[0]);
R_.p2r(theRealMomenta[1]);
R_.k1r(theRealMomenta[2]);
R_.k2r(theRealMomenta[3]);
R_.kr (theRealMomenta[4]);
if(channel_==0) t_u_M_R_qqb_hel_amp(R_,true);
else if(channel_==1) t_u_M_R_qg_hel_amp (R_,true);
else if(channel_==2) t_u_M_R_gqb_hel_amp(R_,true);
recalculateVertex();
}
// Construct the HardTree object needed to perform the showers
HardTreePtr hardTree=new_ptr(HardTree(hardBranchings,spacelikeBranchings,
ShowerInteraction::QCD));
if(hardTree->branchings().size()!=4) throw Exception()
<< "MEPP2VVPowheg::generateHardest()\n"
<< "The hardTree has " << hardTree->branchings().size() << "branchings\n"
<< hardTree << "\n" << Exception::runerror;
if((motherBranching->parent()!=spacelikeSonBranching)&&
spacelikeSonBranching->parent()!=HardBranchingPtr()&&
spectatorBranching->parent()!=HardBranchingPtr()) throw Exception()
<< "MEPP2VVPowheg::generateHardest()\n"
<< "The parent-child relationships are not valid.\n"
<< "motherBranching->parent() = " << motherBranching->parent() << "\n"
<< "spacelikeSonBranching = " << spacelikeSonBranching << "\n"
<< "spectatorBranching->parent() = " << spectatorBranching->parent() << "\n"
<< "spacelikeSonBranching->parent() = " << spacelikeSonBranching->parent() << "\n"
<< Exception::runerror;
if(fermionNumberOfMother_== 1) {
hardTree->connect(showerQuark_ ,motherBranching );
hardTree->connect(showerAntiquark_,spectatorBranching);
spacelikeSonBranching->beam(qProgenitor_ ->original()->parents()[0]);
motherBranching ->beam(qProgenitor_ ->original()->parents()[0]);
spectatorBranching ->beam(qbProgenitor_->original()->parents()[0]);
} else if(fermionNumberOfMother_==-1) {
hardTree->connect(showerAntiquark_,motherBranching );
hardTree->connect(showerQuark_ ,spectatorBranching);
spacelikeSonBranching->beam(qbProgenitor_->original()->parents()[0]);
motherBranching ->beam(qbProgenitor_->original()->parents()[0]);
spectatorBranching ->beam(qProgenitor_ ->original()->parents()[0]);
}
// hardTree->connect(V1_ ,V1_Branching );
// hardTree->connect(V2_ ,V2_Branching );
// This if {...} else if {...} puts the mother and spectator on the same colour
// line. If we don't do this, then when reconstructFinalStateShower calls
// setInitialEvolutionScales it says it failed to set the colour partners, so
// it can't set the scale and it just forgets the emission / event. This seems
// like an unintrusive work-around until reconstructFinalStateShower is sorted.
ColinePtr bornColourLine=new_ptr(ColourLine());
if(fermionNumberOfMother_== 1) {
bornColourLine->addColoured(mother);
bornColourLine->addAntiColoured(spectator);
} else if(fermionNumberOfMother_==-1) {
bornColourLine->addAntiColoured(mother);
bornColourLine->addColoured(spectator);
}
// this is a pain but we need the boost, which we don't have yet here!!
vector<Lorentz5Momentum> pin(2);
vector<Lorentz5Momentum> pq (2);
vector<HardBranchingPtr>::iterator cit;
pin[0] = motherBranching ->branchingParticle()->momentum();
pin[1] = spectatorBranching->branchingParticle()->momentum();
Energy etemp = motherBranching ->beam()->momentum().z();
pq[0] = Lorentz5Momentum(ZERO, ZERO,etemp, abs(etemp));
etemp = spectatorBranching->beam()->momentum().z();
pq[1] = Lorentz5Momentum(ZERO, ZERO,etemp, abs(etemp));
// decompose the momenta
double alpha[2],beta[2];
Energy2 p12=pq[0]*pq[1];
Lorentz5Momentum pt[2];
for(unsigned int ix=0;ix<2;++ix) {
alpha[ix] = pin[ix]*pq[1]/p12;
beta [ix] = pin[ix]*pq[0]/p12;
pt[ix] = pin[ix]-alpha[ix]*pq[0]-beta[ix]*pq[1];
}
// parton level centre-of-mass
Lorentz5Momentum pcm=pin[0]+pin[1];
pcm.rescaleMass();
double rap=pcm.rapidity();
// hadron level cmf
Energy2 s = (pq[0] +pq[1] ).m2();
// calculate the x values
double x[2]={sqrt(pcm.mass2()/s*exp(2.*rap)),pcm.mass2()/s/x[0]};
if(pq[0].z()<ZERO) swap(x[0],x[1]);
Lorentz5Momentum pnew = x[0]*pq[0]+x[1]*pq[1];
LorentzRotation toRest = LorentzRotation(-pcm .boostVector());
LorentzRotation fromRest = LorentzRotation( pnew.boostVector());
Lorentz5Momentum pv[2]=
{fromRest*toRest*V1_Branching->branchingParticle()->momentum(),
fromRest*toRest*V2_Branching->branchingParticle()->momentum()};
LorentzRotation R(-(mother->momentum()+spectator ->momentum()).boostVector());
R.boost((showerQuark_->momentum()+showerAntiquark_->momentum()).boostVector());
for(map<tShowerTreePtr,pair<tShowerProgenitorPtr,tShowerParticlePtr> >::const_iterator
tit = tree->treelinks().begin();
tit != tree->treelinks().end();++tit) {
ShowerTreePtr decayTree = tit->first;
map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator
cit = decayTree->incomingLines().begin();
// reset the momentum of the decay particle
Lorentz5Momentum oldMomentum = cit->first->progenitor()->momentum();
Lorentz5Momentum newMomentum = tit->second.second == V1_ ? pv[0] : pv[1];
map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator cjt;
// reset the momenta of the decay products,
LorentzRotation boostToORF(newMomentum.findBoostToCM(),
newMomentum.e()/newMomentum.mass());
tPPtr children[2];
if(children_[0]->parents()[0]==cit->first->original()) {
children[0] = children_[0];
children[1] = children_[1];
}
else {
children[0] = children_[2];
children[1] = children_[3];
}
if(UseRandom::rndbool()) swap(children[0],children[1]);
double originalTheta0 = (boostToORF*R*children[0]->momentum()).theta();
double originalPhi0 = (boostToORF*R*children[0]->momentum()).phi();
boostToORF.rotateZ(-originalPhi0);
boostToORF.rotateY(-originalTheta0);
double originalPhi1 = (boostToORF*children[1]->momentum()).phi();
LorentzRotation boost(oldMomentum.findBoostToCM(),oldMomentum.e()/oldMomentum.mass());
tPPtr newChildren[2];
for(cjt=decayTree->outgoingLines().begin();
cjt!=decayTree->outgoingLines().end();++cjt) {
if(cjt->first->progenitor()->id()==children[0]->id())
newChildren[0] = cjt->first->progenitor();
else if(cjt->first->progenitor()->id()==children[1]->id())
newChildren[1] = cjt->first->progenitor();
}
boost.rotateZ(-(boost*newChildren[0]->momentum()).phi());
boost.rotateY(-(boost*newChildren[0]->momentum()).theta());
boost.rotateZ(-(boost*newChildren[1]->momentum()).phi());
boost.rotateZ( originalPhi1);
boost.rotateY( originalTheta0);
boost.rotateZ( originalPhi0);
boost.boost(-oldMomentum.findBoostToCM(),
oldMomentum.e()/oldMomentum.mass());
for(cjt=decayTree->outgoingLines().begin();
cjt!=decayTree->outgoingLines().end();++cjt) {
Lorentz5Momentum ptemp = boost*cjt->first->progenitor()->momentum();
cjt->first->original() ->set5Momentum(cjt->first->progenitor()->momentum());
cjt->first->progenitor()->deepTransform(boost);
cjt->first->original() ->deepTransform(boost);
cjt->first->copy() ->deepTransform(boost);
}
}
return hardTree;
}
double MEPP2VVPowheg::getResult(int channel, realVVKinematics R, Energy pT) {
// This routine should return the integrand of the exact Sudakov form factor,
// defined precisely as
// KH 19th August - next 2 lines changed for phi in 0->pi not 0->2pi
// \Delta(pT) = exp[ - \int_{pT}^{pTmax} dpT dYk d\phi/pi * getResult(...) ]
// (Where phi is in 0->pi NOT 0->2*pi !)
// Get pi for the prefactor:
using Constants::pi;
// Get the VV invariant mass^2:
Energy2 p2 = B_.sb();
// Get the momentum fractions for the n+1 body event:
double x1 = R.x1r();
double x2 = R.x2r();
// Reject the event if the x1 and x2 values are outside the phase space:
if(x1<0.||x1>1.||x2<0.||x2>1.||x1*x2<p2/sqr(generator()->maximumCMEnergy())) return 0.;
// Get the momentum fractions for the n body event:
double x1b = B_.x1b();
double x2b = B_.x2b();
// Get the mandelstam variables needed to calculate the n+1 body matrix element:
Energy2 s = R.sr() ;
Energy2 t_u_MR_o_MB;
double lo_lumi, nlo_lumi;
// The luminosity function for the leading order n-body process:
lo_lumi = qHadron_ ->pdf()->xfx(qHadron_ ,showerQuark_ ->dataPtr(),PDFScale_,x1b)*
qbHadron_->pdf()->xfx(qbHadron_,showerAntiquark_->dataPtr(),PDFScale_,x2b);
// Now we calculate the luminosity functions (product of the two pdfs) for the
// real emission process(es) and also their matrix elements:
// q + qbar -> V + V + g
if(channel==0) {
nlo_lumi = qHadron_ ->pdf()->xfx(qHadron_ ,showerQuark_ ->dataPtr() ,PDFScale_,x1)
* qbHadron_->pdf()->xfx(qbHadron_,showerAntiquark_->dataPtr() ,PDFScale_,x2);
t_u_MR_o_MB = t_u_M_R_qqb_hel_amp(R,false)/lo_me_;
}
// q + g -> V + V + q
else if(channel==1) {
nlo_lumi = qHadron_ ->pdf()->xfx(qHadron_ ,showerQuark_->dataPtr() ,PDFScale_,x1)
* qbHadron_->pdf()->xfx(qbHadron_,getParticleData(ParticleID::g),PDFScale_,x2);
t_u_MR_o_MB = t_u_M_R_qg_hel_amp(R,false)/lo_me_;
}
// g + qbar -> V + V + qbar
else {
nlo_lumi = qHadron_ ->pdf()->xfx(qHadron_ ,getParticleData(ParticleID::g),PDFScale_,x1)
* qbHadron_->pdf()->xfx(qbHadron_,showerAntiquark_->dataPtr() ,PDFScale_,x2);
t_u_MR_o_MB = t_u_M_R_gqb_hel_amp(R,false)/lo_me_;
}
// Multiply ratio of the real emission matrix elements to the Born matrix element
// by the ratio of the pdfs for the real emission and born processes to get theWeight
if(lo_lumi<=0.||nlo_lumi<=0.)
return 0.;
else
return t_u_MR_o_MB * ( nlo_lumi/lo_lumi * p2/s )
* sqr(p2/s)/8./pi/pi
/ pT / p2
* GeV;
}
bool MEPP2VVPowheg::getEvent(vector<Lorentz5Momentum> & theRealMomenta,
unsigned int & channel) {
// Invariant mass of the colliding hadrons:
Energy2 S = sqr(generator()->maximumCMEnergy());
// Born variables which are preserved (mass and rapidity of the diboson system):
Energy2 p2 = B_.sb();
double Yb = B_.Yb();
// Born variables which are not preserved but are needed (the momentum fractions):
double x1b(B_.x1b()), x2b(B_.x2b());
double x12b(x1b*x1b), x22b(x2b*x2b);
// Maximum jet pT (half of the hadronic C.O.M. energy. N.B. this is overestimated a lot):
Energy starting_pT = sqrt(S)/2.;
// Initialize the pT_ *integration limit* i.e. the pT of the generated emission:
pT_ = ZERO;
// The pT *integration variable*:
Energy pT;
// The x_1 & x_2 momentum fractions corresponding to incoming momenta p1 & p2:
double x1_(-999.), x2_(-999.);
double x1 (-999.), x2 (-999.);
// The jet rapidity *integration variable* and its limits:
double Yk, minYk(-8.0), maxYk(8.0);
// The theta2 integration variable (the azimuthal angle of the gluon w.r.t
// V1 in the V1 & V2 rest frame:
double theta2;
// The realVVKinematics object corresponding to the current integration
// set of integration variables:
realVVKinematics R;
// The veto algorithm rejection weight and a corresponding flag:
double rejectionWeight;
bool rejectEmission ;
// Initialize the flag indicating the selected radiation channel:
channel=999;
// Some product of constants used for the crude distribution:
double a(0.);
for(int j=0;j<3;j++) {
pT=starting_pT;
a =(maxYk-minYk)*prefactor_[j]/2./b0_;
do {
// Generate next pT according to exp[- \int^{pTold}_{pT} dpT a*(power-1)/(pT^power)]
// pT = GeV/pow( pow(GeV/pT,power_-1.) - log(UseRandom::rnd())/a
// , 1./(power_-1.) );
// Generate next pT according to exp[- \int^{pTold}_{pT} dpT alpha1loop*prefactor/pT ]
pT = LambdaQCD_*exp( 0.5*exp( log(log(sqr(pT/LambdaQCD_)))+log(UseRandom::rnd())/a ) );
// Generate rapidity of the jet:
Yk = minYk + UseRandom::rnd()*(maxYk - minYk);
// Generate the theta2 radiative variable:
// KH 19th August - next line changed for phi in 0->pi not 0->2pi
// theta2 = UseRandom::rnd() * 2.*Constants::pi;
theta2 = UseRandom::rnd() * Constants::pi;
// eT of the diboson system:
Energy eT = sqrt(pT*pT+p2);
// Calculate the eT and then solve for x_{\oplus} & x_{\ominus}:
x1 = (pT*exp( Yk)+eT*exp( Yb))/sqrt(S);
x2 = (pT*exp(-Yk)+eT*exp(-Yb))/sqrt(S);
// Calculate the xr radiative variable:
double xr(p2/(x1*x2*S));
// Then use this to calculate the y radiative variable:
double y(-((xr+1.)/(xr-1.))*(xr*sqr(x1/x1b)-1.)/(xr*sqr(x1/x1b)+1.));
// The y value above should equal the one commented out below this line:
// double y( ((xr+1.)/(xr-1.))*(xr*sqr(x2/x2b)-1.)/(xr*sqr(x2/x2b)+1.));
// Now we get the lower limit on the x integration, xbar:
double omy(1.-y), opy(1.+y);
double xbar1 = 2.*opy*x12b/(sqrt(sqr(1.+x12b)*sqr(omy)+16.*y*x12b)+omy*(1.-x1b)*(1.+x1b));
double xbar2 = 2.*omy*x22b/(sqrt(sqr(1.+x22b)*sqr(opy)-16.*y*x22b)+opy*(1.-x2b)*(1.+x2b));
double xbar = max(xbar1,xbar2);
// Now we can calculate xtilde:
double xt = (xr-xbar)/(1.-xbar);
// Finally we can make the realVVKinematics object:
R = realVVKinematics(B_,xt,y,theta2);
// The next thing we have to do is set the QCD, EW and PDF scales using R:
setTheScales(pT);
// ... and so calculate rejection weight:
rejectionWeight = getResult(j,R,pT);
// If generating according to exp[- \int^{pTold}_{pT} dpT a*(power-1)/(pT^power)]
// rejectionWeight/= showerAlphaS_->overestimateValue()*prefactor_[j]*pow(GeV/pT,power_);
// If generating according to exp[- \int^{pTold}_{pT} dpT alpha1loop*prefactor/pT ]
rejectionWeight/= 1./b0_/log(sqr(pT/LambdaQCD_))*prefactor_[j]*GeV/pT;
rejectEmission = UseRandom::rnd()>rejectionWeight;
// The event is a no-emission event if pT goes past min_pT_ - basically set to
// outside the histogram bounds (hopefully histogram objects just ignore it then).
if(pT<min_pT_) {
pT=ZERO;
rejectEmission = false;
}
if(rejectionWeight>1.) {
ostringstream stream;
stream << "MEPP2VVPowheg::getEvent weight for channel " << j
<< " is greater than one: " << rejectionWeight << endl;
generator()->logWarning( Exception(stream.str(), Exception::warning) );
}
}
while(rejectEmission);
// set pT of emission etc
if(pT>pT_) {
channel = j;
pT_ = pT;
Yk_ = Yk;
R_ = R ;
x1_ = x1;
x2_ = x2;
}
}
// Was this an (overall) no emission event?
if(pT_<min_pT_) {
pT_ = ZERO;
channel = 3;
}
if(channel==3) return false;
if(channel>3) throw Exception()
<< "MEPP2VVPowheg::getEvent() channel = " << channel
<< " pT = " << pT/GeV << " pT_ = " << pT_/GeV
<< Exception::abortnow;
// Work out the momenta in the lab frame, reserving the mass and rapidity
// of the VV system:
LorentzRotation yzRotation;
yzRotation.setRotateX(-atan2(pT_/GeV,sqrt(p2)/GeV));
LorentzRotation boostFrompTisZero;
boostFrompTisZero.setBoostY(-pT_/sqrt(p2+pT_*pT_));
LorentzRotation boostFromYisZero;
boostFromYisZero.setBoostZ(tanh(Yb));
theRealMomenta.resize(5);
theRealMomenta[0] = Lorentz5Momentum(ZERO,ZERO, x1_*sqrt(S)/2., x1_*sqrt(S)/2.,ZERO);
theRealMomenta[1] = Lorentz5Momentum(ZERO,ZERO,-x2_*sqrt(S)/2., x2_*sqrt(S)/2.,ZERO);
theRealMomenta[2] = boostFromYisZero*boostFrompTisZero*yzRotation*(R_.k1r());
theRealMomenta[3] = boostFromYisZero*boostFrompTisZero*yzRotation*(R_.k2r());
theRealMomenta[4] = Lorentz5Momentum(ZERO, pT_, pT_*sinh(Yk_), pT_*cosh(Yk_),ZERO);
return true;
}
void MEPP2VVPowheg::setTheScales(Energy pT) {
// Work out the scales we want to use in the matrix elements and the pdfs:
// Scale for alpha_S: pT^2 of the diboson system.
QCDScale_ = max(pT*pT,sqr(min_pT_));
// Scale for real emission PDF:
// pT^2+mVV^2 - as mcfm does in the case of a single W/Z boson).
// Energy2 PDFScale_ = max(R.pT2_in_lab(),sqr(min_pT_))+R.s2r();
// pT^2 - as advocated by Nason & Ridolfi for ZZ production & Alioli et al for gg->h:
PDFScale_ = max(pT*pT,sqr(min_pT_));
// Scale of electroweak vertices: mVV^2 the invariant mass of the diboson system.
// EWScale_ = B_.sb();
// ... And this choice is more like what can be seen in mcatnlo_vbmain.f (weird).
EWScale_ = 0.5*(B_.k12b()+B_.k22b());
return;
}
/***************************************************************************/
// This is identical to the code in the Powheg matrix element. It should
// equal t_u_M_R_qqb in there, which is supposed to be the real emission ME
// times tk*uk.
Energy2 MEPP2VVPowheg::t_u_M_R_qqb_hel_amp(realVVKinematics R, bool getMatrix) const {
using namespace ThePEG::Helicity;
ProductionMatrixElement qqb_hel_amps(PDT::Spin1Half,PDT::Spin1Half,
PDT::Spin1 ,PDT::Spin1 ,
PDT::Spin1);
double sum_hel_amps_sqr(0.);
tcPDPtr p1data(showerQuark_->dataPtr());
tcPDPtr p2data(showerAntiquark_->dataPtr());
tcPDPtr k1data(V1_->dataPtr());
tcPDPtr k2data(V2_->dataPtr());
tcPDPtr kdata(getParticleData(ParticleID::g));
if(k1data->id()==-24&&k2data->id()==24) swap(k1data,k2data);
SpinorWaveFunction qSpinor(R.p1r(),p1data,incoming);
SpinorBarWaveFunction qbSpinor(R.p2r(),p2data,incoming);
vector<SpinorWaveFunction> q;
vector<SpinorBarWaveFunction> qb;
for(unsigned int ix=0;ix<2;ix++) {
qSpinor.reset(ix);
qbSpinor.reset(ix);
q.push_back(qSpinor);
qb.push_back(qbSpinor);
}
VectorWaveFunction v1Polarization(R.k1r(),k1data,outgoing);
VectorWaveFunction v2Polarization(R.k2r(),k2data,outgoing);
vector<VectorWaveFunction> v1;
vector<VectorWaveFunction> v2;
for(unsigned int ix=0;ix<3;ix++) {
v1Polarization.reset(ix);
v2Polarization.reset(ix);
v1.push_back(v1Polarization);
v2.push_back(v2Polarization);
}
VectorWaveFunction gPolarization(R.kr(),kdata,outgoing);
vector<VectorWaveFunction> g;
for(unsigned int ix=0;ix<3;ix+=2) {
gPolarization.reset(ix);
g.push_back(gPolarization);
}
AbstractFFVVertexPtr ffg = FFGvertex_;
AbstractFFVVertexPtr ffv1 = k1data->id()==23 ? FFZvertex_ : FFWvertex_;
AbstractFFVVertexPtr ffv2 = k2data->id()==23 ? FFZvertex_ : FFWvertex_;
// Collecting information for intermediate fermions
vector<tcPDPtr> tc;
if(abs(k1data->id())==24&&abs(k2data->id())==24) {
if(abs(p1data->id())%2==0)
for(int ix=0;ix<3;++ix) tc.push_back(getParticleData(1+2*ix));
else
for(int ix=0;ix<3;++ix) tc.push_back(getParticleData(2+2*ix));
}
else if(k1data->id()==23&&k2data->id()==23) tc.push_back(p1data);
else if(abs(k1data->id())==24&&k2data->id()==23) tc.push_back(p2data);
// Loop over helicities summing the relevant diagrams
for(unsigned int p1hel=0;p1hel<2;++p1hel) {
for(unsigned int p2hel=0;p2hel<2;++p2hel) {
for(unsigned int khel=0;khel<2;++khel) {
SpinorWaveFunction p1_k = ffg->evaluate(QCDScale_,5,p1data,q[p1hel],g[khel]);
SpinorBarWaveFunction p2_k = ffg->evaluate(QCDScale_,5,p2data,qb[p2hel],g[khel]);
for(unsigned int k1hel=0;k1hel<3;++k1hel) {
for(unsigned int k2hel=0;k2hel<3;++k2hel) {
// If helicity is exactly conserved (massless quarks) skip if p1hel=p2hel
// but if the production ME is required first fill it with (0.,0.).
if((p1hel==p2hel)&&helicityConservation_) {
if(getMatrix) {
if(khel==0)
qqb_hel_amps(p1hel,p2hel,k1hel,k2hel,0) = Complex(0.,0.);
else
qqb_hel_amps(p1hel,p2hel,k1hel,k2hel,2) = Complex(0.,0.);
}
continue;
}
vector<Complex> diagrams;
// Get all t-channel diagram contributions
tcPDPtr intermediate_t;
for(unsigned int ix=0;ix<tc.size();ix++) {
intermediate_t = (!(k1data->id()==24&&k2data->id()==-24)) ? p2data : tc[ix];
// Note: choosing 5 as the second argument ffvX_->evaluate() sets
// option 5 in thepeg/Helicity/Vertex/VertexBase.cc, which makes
// the (fermion) propagator denominator massless: 1/p^2.
// If W+Z / W-Z calculate the two V+jet-like s-channel diagrams
SpinorWaveFunction p1_v1 = ffv1->evaluate(EWScale_,5,intermediate_t,q[p1hel],v1[k1hel]);
SpinorBarWaveFunction p2_v2 = ffv2->evaluate(EWScale_,5,intermediate_t,qb[p2hel],v2[k2hel]);
// First calculate all the off-shell fermion currents
// Now calculate the 6 t-channel diagrams
// q+qb->g+v1+v2, q+qb->v1+g+v2, q+qb->v1+v2+g
if(!((k1data->id()==24&&k2data->id()==-24)&&(abs(p1data->id())%2==1))) {
diagrams.push_back(ffv1->evaluate(EWScale_,p1_k,p2_v2,v1[k1hel]));
diagrams.push_back(ffg->evaluate(QCDScale_,p1_v1,p2_v2,g[khel]));
diagrams.push_back(ffv2->evaluate(EWScale_,p1_v1,p2_k,v2[k2hel]));
}
intermediate_t = (!(k1data->id()==24&&k2data->id()==-24)) ? p1data : tc[ix];
SpinorWaveFunction p1_v2 = ffv2->evaluate(EWScale_,5,intermediate_t,q[p1hel],v2[k2hel]);
SpinorBarWaveFunction p2_v1 = ffv1->evaluate(EWScale_,5,intermediate_t,qb[p2hel],v1[k1hel]);
// q+qb->g+v2+v1, q+qb->v2+g+v1, q+qb->v2+v1+g
if(!((k1data->id()==24&&k2data->id()==-24)&&(abs(p1data->id())%2==0))) {
diagrams.push_back(ffv2->evaluate(EWScale_,p1_k,p2_v1,v2[k2hel]));
diagrams.push_back(ffg->evaluate(QCDScale_,p1_v2,p2_v1,g[khel]));
diagrams.push_back(ffv1->evaluate(EWScale_,p1_v2,p2_k,v1[k1hel]));
}
}
// Note: choosing 3 as the second argument in WWWvertex_->evaluate()
// sets option 3 in thepeg/Helicity/Vertex/VertexBase.cc , which
// means the propagator does not contain a width factor (which is
// good re. gauge invariance).
// If W+Z / W-Z calculate the two V+jet-like s-channel diagrams
if(abs(k1data->id())==24&&k2data->id()==23) {
// The off-shell s-channel boson current
VectorWaveFunction k1_k2 =
WWWvertex_->evaluate(EWScale_,3,k1data->CC(),v2[k2hel],v1[k1hel]);
// q+qb->g+v1*->g+v1+v2, q+qb->v1*+g->v1+v2+g
diagrams.push_back(ffv1->evaluate(EWScale_,p1_k,qb[p2hel],k1_k2));
diagrams.push_back(ffv1->evaluate(EWScale_,q[p1hel],p2_k,k1_k2));
}
// If W+W- calculate the four V+jet-like s-channel diagrams
if((k1data->id()==24&&k2data->id()==-24)&&(p1data->id()==-p2data->id())) {
// The off-shell s-channel boson current
VectorWaveFunction k1_k2;
// q+qb->g+Z0*->g+v1+v2,q+qb->Z0*+g->v1+v2+g,
tcPDPtr Z0 = getParticleData(ParticleID::Z0);
k1_k2 = WWWvertex_->evaluate(EWScale_,3,Z0,v2[k2hel],v1[k1hel]);
diagrams.push_back(FFZvertex_->evaluate(EWScale_,p1_k,qb[p2hel],k1_k2));
diagrams.push_back(FFZvertex_->evaluate(EWScale_,q[p1hel],p2_k,k1_k2));
// q+qb->g+gamma*->g+v1+v2,q+qb->gamma*+g->v1+v2+g,
tcPDPtr gamma = getParticleData(ParticleID::gamma);
k1_k2 = WWWvertex_->evaluate(EWScale_,3,gamma,v2[k2hel],v1[k1hel]);
diagrams.push_back(FFPvertex_->evaluate(EWScale_,p1_k,qb[p2hel],k1_k2));
diagrams.push_back(FFPvertex_->evaluate(EWScale_,q[p1hel],p2_k,k1_k2));
}
// Add up all diagrams to get the total amplitude:
Complex hel_amp(0.);
for(unsigned int ix=0;ix<diagrams.size();ix++) hel_amp += diagrams[ix];
// If we need to fill the production ME we do it here:
if(getMatrix) {
if(khel==0)
qqb_hel_amps(p1hel,p2hel,k1hel,k2hel,0) = hel_amp;
else
qqb_hel_amps(p1hel,p2hel,k1hel,k2hel,2) = hel_amp;
}
sum_hel_amps_sqr += norm(hel_amp);
}
}
}
}
}
// Fill up the remaining bits of the production ME, corresponding
// to longitudinal gluon polarization, with (0.,0.).
if(getMatrix) {
for(unsigned int p1hel=0;p1hel<2;++p1hel) {
for(unsigned int p2hel=0;p2hel<2;++p2hel) {
for(unsigned int k1hel=0;k1hel<3;++k1hel) {
for(unsigned int k2hel=0;k2hel<3;++k2hel) {
qqb_hel_amps(p1hel,p2hel,k1hel,k2hel,1) = Complex(0.,0.);
}
}
}
}
}
// Calculate the production density matrix:
if(getMatrix) {
for(unsigned int k1hel=0;k1hel<3;++k1hel) {
for(unsigned int k1helpr=0;k1helpr<3;++k1helpr) {
for(unsigned int k2hel=0;k2hel<3;++k2hel) {
for(unsigned int k2helpr=0;k2helpr<3;++k2helpr) {
Complex theElement(0.,0.);
// For each k1hel, k1helpr, k2hel, k2helpr sum over fermion and gluon spins...
for(unsigned int p1hel=0;p1hel<2;++p1hel) {
for(unsigned int p2hel=0;p2hel<2;++p2hel) {
for(unsigned int khel=0;khel<3;khel+=2) {
theElement += qqb_hel_amps(p1hel,p2hel,k1hel ,k2hel ,khel)
*conj(qqb_hel_amps(p1hel,p2hel,k1helpr,k2helpr,khel));
}
}
}
// ...and then set the production matrix element to the sum:
productionMatrix_[k1hel][k1helpr][k2hel][k2helpr] = theElement;
}
}
}
}
}
// Spin and colour averaging factors = 1/4 * CF * 1/3 = 1/9
sum_hel_amps_sqr /= 9.;
// Symmetry factor for identical Z bosons in the final state
if(k1data->id()==23&&k2data->id()==23) sum_hel_amps_sqr /= 2.;
return sum_hel_amps_sqr*R.tkr()*R.ukr()*UnitRemoval::InvE2;
}
/***************************************************************************/
// This is identical to the code in the Powheg matrix element. It should
// equal t_u_M_R_qg in there, which is supposed to be the real emission ME
// times tk*uk.
Energy2 MEPP2VVPowheg::t_u_M_R_qg_hel_amp(realVVKinematics R, bool getMatrix) const {
using namespace ThePEG::Helicity;
ProductionMatrixElement qg_hel_amps(PDT::Spin1Half,PDT::Spin1,
PDT::Spin1,PDT::Spin1,
PDT::Spin1Half);
double sum_hel_amps_sqr(0.);
tcPDPtr p1data(showerQuark_->dataPtr());
tcPDPtr p2data(getParticleData(ParticleID::g));
tcPDPtr k1data(V1_->dataPtr());
tcPDPtr k2data(V2_->dataPtr());
tcPDPtr kdata (showerAntiquark_->dataPtr()->CC());
if(k1data->id()==-24&&k2data->id()==24) swap(k1data,k2data);
SpinorWaveFunction qinSpinor(R.p1r(),p1data,incoming);
SpinorBarWaveFunction qoutSpinor(R.kr(),kdata,outgoing);
vector<SpinorWaveFunction> qin;
vector<SpinorBarWaveFunction> qout;
for(unsigned int ix=0;ix<2;ix++) {
qinSpinor.reset(ix);
qoutSpinor.reset(ix);
qin.push_back(qinSpinor);
qout.push_back(qoutSpinor);
}
VectorWaveFunction v1Polarization(R.k1r(),k1data,outgoing);
VectorWaveFunction v2Polarization(R.k2r(),k2data,outgoing);
vector<VectorWaveFunction> v1;
vector<VectorWaveFunction> v2;
for(unsigned int ix=0;ix<3;ix++) {
v1Polarization.reset(ix);
v2Polarization.reset(ix);
v1.push_back(v1Polarization);
v2.push_back(v2Polarization);
}
VectorWaveFunction gPolarization(R.p2r(),p2data,incoming);
vector<VectorWaveFunction> g;
for(unsigned int ix=0;ix<3;ix+=2) {
gPolarization.reset(ix);
g.push_back(gPolarization);
}
AbstractFFVVertexPtr ffg = FFGvertex_;
AbstractFFVVertexPtr ffv1 = k1data->id()==23 ? FFZvertex_ : FFWvertex_;
AbstractFFVVertexPtr ffv2 = k2data->id()==23 ? FFZvertex_ : FFWvertex_;
// Collecting information for intermediate fermions
vector<tcPDPtr> tc;
if(abs(k1data->id())==24&&abs(k2data->id())==24) {
if(abs(p1data->id())%2==0)
for(int ix=0;ix<3;++ix) tc.push_back(getParticleData(1+2*ix));
else
for(int ix=0;ix<3;++ix) tc.push_back(getParticleData(2+2*ix));
}
else if(k1data->id()==23&&k2data->id()==23) tc.push_back(p1data);
else if(abs(k1data->id())==24&&k2data->id()==23) tc.push_back(kdata->CC());
// Loop over helicities summing the relevant diagrams
for(unsigned int p1hel=0;p1hel<2;++p1hel) {
for(unsigned int p2hel=0;p2hel<2;++p2hel) {
for(unsigned int khel=0;khel<2;++khel) {
SpinorWaveFunction p1_p2 = ffg->evaluate(QCDScale_,5,p1data,qin[p1hel],g[p2hel]);
SpinorBarWaveFunction p2_k = ffg->evaluate(QCDScale_,5,kdata->CC(),qout[khel],g[p2hel]);
for(unsigned int k1hel=0;k1hel<3;++k1hel) {
for(unsigned int k2hel=0;k2hel<3;++k2hel) {
// If helicity is exactly conserved (massless quarks) skip if p1hel!=khel
// but if the production ME is required first fill it with (0.,0.).
if((p1hel!=khel)&&helicityConservation_) {
if(getMatrix) {
if(p2hel==0)
qg_hel_amps(p1hel,0,k1hel,k2hel,khel) = Complex(0.,0.);
else
qg_hel_amps(p1hel,2,k1hel,k2hel,khel) = Complex(0.,0.);
}
continue;
}
vector<Complex> diagrams;
// Get all t-channel diagram contributions
tcPDPtr intermediate_q;
for(unsigned int ix=0;ix<tc.size();ix++) {
intermediate_q = (!(k1data->id()==24&&k2data->id()==-24)) ? showerAntiquark_->dataPtr() : tc[ix];
SpinorWaveFunction p1_v1 = ffv1->evaluate(EWScale_,5,intermediate_q,qin[p1hel],v1[k1hel]);
SpinorBarWaveFunction k_v2 = ffv2->evaluate(EWScale_,5,intermediate_q,qout[khel],v2[k2hel]);
// First calculate all the off-shell fermion currents
// Now calculate the 6 abelian diagrams
// q+g->v1+v2+q with 2 t-channel propagators, 1 s- and 1 t-channel and 2 t-channel ones.
if(!((k1data->id()==24&&k2data->id()==-24)&&(abs(p1data->id())%2==1))) {
diagrams.push_back(ffv2->evaluate(EWScale_,p1_v1,p2_k,v2[k2hel]));
diagrams.push_back(ffg->evaluate(QCDScale_,p1_v1,k_v2,g[p2hel]));
diagrams.push_back(ffv1->evaluate(EWScale_,p1_p2,k_v2,v1[k1hel]));
}
intermediate_q = (!(k1data->id()==24&&k2data->id()==-24)) ? p1data : tc[ix];
SpinorWaveFunction p1_v2 = ffv2->evaluate(EWScale_,5,intermediate_q,qin[p1hel],v2[k2hel]);
SpinorBarWaveFunction k_v1 = ffv1->evaluate(EWScale_,5,intermediate_q,qout[khel],v1[k1hel]);
// q+g->v2+v1+q, with 2 t-channel propagators, 1 s- and 1 t-channel and 2 t-channel ones.
if(!((k1data->id()==24&&k2data->id()==-24)&&(abs(p1data->id())%2==0))) {
diagrams.push_back(ffv1->evaluate(EWScale_,p1_v2,p2_k,v1[k1hel]));
diagrams.push_back(ffg->evaluate(QCDScale_,p1_v2,k_v1,g[p2hel]));
diagrams.push_back(ffv2->evaluate(EWScale_,p1_p2,k_v1,v2[k2hel]));
}
}
// Note: choosing 3 as the second argument in WWWvertex_->evaluate()
// sets option 3 in thepeg/Helicity/Vertex/VertexBase.cc , which
// means the propagator does not contain a width factor (which is
// good re. gauge invariance).
// If W+Z / W-Z calculate the two V+jet-like s-channel diagrams
if(abs(k1data->id())==24&&k2data->id()==23) {
// The off-shell s-channel boson current
VectorWaveFunction k1_k2 =
WWWvertex_->evaluate(EWScale_,3,k1data->CC(),v2[k2hel],v1[k1hel]);
// q+qb->g+v1*->g+v1+v2, q+qb->v1*+g->v1+v2+g
diagrams.push_back(ffv1->evaluate(EWScale_,p1_p2,qout[khel],k1_k2));
diagrams.push_back(ffv1->evaluate(EWScale_,qin[p1hel],p2_k,k1_k2));
}
// If W+W- calculate the four V+jet-like s-channel diagrams
if((k1data->id()==24&&k2data->id()==-24)&&(p1data->id()==kdata->id())) {
// The off-shell s-channel boson current
VectorWaveFunction k1_k2;
// q+qb->g+Z0*->g+v1+v2,q+qb->Z0*+g->v1+v2+g,
tcPDPtr Z0 = getParticleData(ParticleID::Z0);
k1_k2 = WWWvertex_->evaluate(EWScale_,3,Z0,v2[k2hel],v1[k1hel]);
diagrams.push_back(FFZvertex_->evaluate(EWScale_,p1_p2,qout[khel],k1_k2));
diagrams.push_back(FFZvertex_->evaluate(EWScale_,qin[p1hel],p2_k,k1_k2));
// q+qb->g+gamma*->g+v1+v2,q+qb->gamma*+g->v1+v2+g,
tcPDPtr gamma = getParticleData(ParticleID::gamma);
k1_k2 = WWWvertex_->evaluate(EWScale_,3,gamma,v2[k2hel],v1[k1hel]);
diagrams.push_back(FFPvertex_->evaluate(EWScale_,p1_p2,qout[khel],k1_k2));
diagrams.push_back(FFPvertex_->evaluate(EWScale_,qin[p1hel],p2_k,k1_k2));
}
// Add up all diagrams to get the total amplitude:
Complex hel_amp(0.);
for(unsigned int ix=0;ix<diagrams.size();ix++) hel_amp += diagrams[ix];
// If we need to fill the production ME we do it here:
if(getMatrix) {
if(p2hel==0)
qg_hel_amps(p1hel,0,k1hel,k2hel,khel) = hel_amp;
else
qg_hel_amps(p1hel,2,k1hel,k2hel,khel) = hel_amp;
}
sum_hel_amps_sqr += norm(hel_amp);
}
}
}
}
}
// Fill up the remaining bits of the production ME, corresponding
// to longitudinal gluon polarization, with (0.,0.).
if(getMatrix) {
for(unsigned int p1hel=0;p1hel<2;++p1hel) {
for(unsigned int k1hel=0;k1hel<3;++k1hel) {
for(unsigned int k2hel=0;k2hel<3;++k2hel) {
for(unsigned int khel=0;khel<2;++khel) {
qg_hel_amps(p1hel,1,k1hel,k2hel,khel) = Complex(0.,0.);
}
}
}
}
}
// Calculate the production density matrix:
if(getMatrix) {
for(unsigned int k1hel=0;k1hel<3;++k1hel) {
for(unsigned int k1helpr=0;k1helpr<3;++k1helpr) {
for(unsigned int k2hel=0;k2hel<3;++k2hel) {
for(unsigned int k2helpr=0;k2helpr<3;++k2helpr) {
Complex theElement(0.,0.);
// For each k1hel, k1helpr, k2hel, k2helpr sum over fermion and gluon spins...
for(unsigned int p1hel=0;p1hel<2;++p1hel) {
for(unsigned int p2hel=0;p2hel<3;p2hel+=2) {
for(unsigned int khel=0;khel<2;++khel) {
theElement += qg_hel_amps(p1hel,p2hel,k1hel ,k2hel ,khel)
*conj(qg_hel_amps(p1hel,p2hel,k1helpr,k2helpr,khel));
}
}
}
// ...and then set the production matrix element to the sum:
productionMatrix_[k1hel][k1helpr][k2hel][k2helpr] = theElement;
}
}
}
}
}
// Spin and colour averaging factors = 1/4 * TR * 1/3 = 1/24
sum_hel_amps_sqr /= 24.;
// Symmetry factor for identical Z bosons in the final state
if(k1data->id()==23&&k2data->id()==23) sum_hel_amps_sqr /= 2.;
return sum_hel_amps_sqr*R.tkr()*R.ukr()*UnitRemoval::InvE2;
}
/***************************************************************************/
// This is identical to the code in the Powheg matrix element. It should
// equal t_u_M_R_gqb in there, which is supposed to be the real emission ME
// times tk*uk.
Energy2 MEPP2VVPowheg::t_u_M_R_gqb_hel_amp(realVVKinematics R, bool getMatrix) const {
using namespace ThePEG::Helicity;
ProductionMatrixElement gqb_hel_amps(PDT::Spin1,PDT::Spin1Half,
PDT::Spin1,PDT::Spin1,
PDT::Spin1Half);
double sum_hel_amps_sqr(0.);
tcPDPtr p1data(getParticleData(ParticleID::g));
tcPDPtr p2data(showerAntiquark_->dataPtr());
tcPDPtr k1data(V1_->dataPtr());
tcPDPtr k2data(V2_->dataPtr());
tcPDPtr kdata (showerQuark_->dataPtr()->CC());
if(k1data->id()==-24&&k2data->id()==24) swap(k1data,k2data);
SpinorBarWaveFunction qbinSpinor(R.p2r(),p2data,incoming);
SpinorWaveFunction qboutSpinor(R.kr(),kdata,outgoing);
vector<SpinorBarWaveFunction> qbin;
vector<SpinorWaveFunction> qbout;
for(unsigned int ix=0;ix<2;ix++) {
qbinSpinor.reset(ix);
qboutSpinor.reset(ix);
qbin.push_back(qbinSpinor);
qbout.push_back(qboutSpinor);
}
VectorWaveFunction v1Polarization(R.k1r(),k1data,outgoing);
VectorWaveFunction v2Polarization(R.k2r(),k2data,outgoing);
vector<VectorWaveFunction> v1;
vector<VectorWaveFunction> v2;
for(unsigned int ix=0;ix<3;ix++) {
v1Polarization.reset(ix);
v2Polarization.reset(ix);
v1.push_back(v1Polarization);
v2.push_back(v2Polarization);
}
VectorWaveFunction gPolarization(R.p1r(),p1data,incoming);
vector<VectorWaveFunction> g;
for(unsigned int ix=0;ix<3;ix+=2) {
gPolarization.reset(ix);
g.push_back(gPolarization);
}
AbstractFFVVertexPtr ffg = FFGvertex_;
AbstractFFVVertexPtr ffv1 = k1data->id()==23 ? FFZvertex_ : FFWvertex_;
AbstractFFVVertexPtr ffv2 = k2data->id()==23 ? FFZvertex_ : FFWvertex_;
// Collecting information for intermediate fermions
vector<tcPDPtr> tc;
if(abs(k1data->id())==24&&abs(k2data->id())==24) {
if(abs(p2data->id())%2==0)
for(int ix=0;ix<3;++ix) tc.push_back(getParticleData(1+2*ix));
else
for(int ix=0;ix<3;++ix) tc.push_back(getParticleData(2+2*ix));
}
else if(k1data->id()==23&&k2data->id()==23) tc.push_back(p2data);
else if(abs(k1data->id())==24&&k2data->id()==23) tc.push_back(kdata->CC());
// Loop over helicities summing the relevant diagrams
for(unsigned int p1hel=0;p1hel<2;++p1hel) {
for(unsigned int p2hel=0;p2hel<2;++p2hel) {
for(unsigned int khel=0;khel<2;++khel) {
SpinorBarWaveFunction p1_p2 = ffg->evaluate(QCDScale_,5,p2data,qbin[p2hel],g[p1hel]);
SpinorWaveFunction p1_k = ffg->evaluate(QCDScale_,5,kdata->CC(),qbout[khel],g[p1hel]);
for(unsigned int k1hel=0;k1hel<3;++k1hel) {
for(unsigned int k2hel=0;k2hel<3;++k2hel) {
// If helicity is exactly conserved (massless quarks) skip if p2hel!=khel
// but if the production ME is required first fill it with (0.,0.).
if((p2hel!=khel)&&helicityConservation_) {
if(getMatrix) {
if(p1hel==0)
gqb_hel_amps(0,p2hel,k1hel,k2hel,khel) = Complex(0.,0.);
else
gqb_hel_amps(2,p2hel,k1hel,k2hel,khel) = Complex(0.,0.);
}
continue;
}
vector<Complex> diagrams;
// Get all t-channel diagram contributions
tcPDPtr intermediate_q;
for(unsigned int ix=0;ix<tc.size();ix++) {
intermediate_q = (!(k1data->id()==24&&k2data->id()==-24)) ? showerQuark_->dataPtr() : tc[ix];
SpinorBarWaveFunction p2_v1 = ffv1->evaluate(EWScale_,5,intermediate_q,qbin[p2hel],v1[k1hel]);
SpinorWaveFunction k_v2 = ffv2->evaluate(EWScale_,5,intermediate_q,qbout[khel],v2[k2hel]);
// First calculate all the off-shell fermion currents
// Now calculate the 6 abelian diagrams q+g->v1+v2+q
// with 2 t-channel propagators, 1 s- and 1 t-channel
// and 2 t-channel ones.
if(!((k1data->id()==24&&k2data->id()==-24)&&(abs(p2data->id())%2==0))) {
diagrams.push_back(ffv2->evaluate(EWScale_,p1_k,p2_v1,v2[k2hel]));
diagrams.push_back(ffg->evaluate(QCDScale_,k_v2,p2_v1,g[p1hel]));
diagrams.push_back(ffv1->evaluate(EWScale_,k_v2,p1_p2,v1[k1hel]));
}
intermediate_q = (!(k1data->id()==24&&k2data->id()==-24)) ? p2data : tc[ix];
SpinorBarWaveFunction p2_v2 = ffv2->evaluate(EWScale_,5,intermediate_q,qbin[p2hel],v2[k2hel]);
SpinorWaveFunction k_v1 = ffv1->evaluate(EWScale_,5,intermediate_q,qbout[khel],v1[k1hel]);
// q+g->v2+v1+q, with 2 t-channel propagators, 1 s- and 1 t-channel and 2 t-channel ones.
if(!((k1data->id()==24&&k2data->id()==-24)&&(abs(p2data->id())%2==1))) {
diagrams.push_back(ffv1->evaluate(EWScale_,p1_k,p2_v2,v1[k1hel]));
diagrams.push_back(ffg->evaluate(QCDScale_,k_v1,p2_v2,g[p1hel]));
diagrams.push_back(ffv2->evaluate(EWScale_,k_v1,p1_p2,v2[k2hel]));
}
}
// Note: choosing 3 as the second argument in WWWvertex_->evaluate()
// sets option 3 in thepeg/Helicity/Vertex/VertexBase.cc , which
// means the propagator does not contain a width factor (which is
// good re. gauge invariance).
// If W+Z / W-Z calculate the two V+jet-like s-channel diagrams
if(abs(k1data->id())==24&&k2data->id()==23) {
// The off-shell s-channel boson current
VectorWaveFunction k1_k2 =
WWWvertex_->evaluate(EWScale_,3,k1data->CC(),v2[k2hel],v1[k1hel]);
// q+qb->g+v1*->g+v1+v2, q+qb->v1*+g->v1+v2+g
diagrams.push_back(ffv1->evaluate(EWScale_,qbout[khel],p1_p2,k1_k2));
diagrams.push_back(ffv1->evaluate(EWScale_,p1_k,qbin[p2hel],k1_k2));
}
// If W+W- calculate the four V+jet-like s-channel diagrams
if((k1data->id()==24&&k2data->id()==-24)&&(p2data->id()==kdata->id())) {
// The off-shell s-channel boson current
VectorWaveFunction k1_k2;
// q+qb->g+Z0*->g+v1+v2,q+qb->Z0*+g->v1+v2+g,
tcPDPtr Z0 = getParticleData(ParticleID::Z0);
k1_k2 = WWWvertex_->evaluate(EWScale_,3,Z0,v2[k2hel],v1[k1hel]);
diagrams.push_back(FFZvertex_->evaluate(EWScale_,qbout[khel],p1_p2,k1_k2));
diagrams.push_back(FFZvertex_->evaluate(EWScale_,p1_k,qbin[p2hel],k1_k2));
// q+qb->g+gamma*->g+v1+v2,q+qb->gamma*+g->v1+v2+g,
tcPDPtr gamma = getParticleData(ParticleID::gamma);
k1_k2 = WWWvertex_->evaluate(EWScale_,3,gamma,v2[k2hel],v1[k1hel]);
diagrams.push_back(FFPvertex_->evaluate(EWScale_,qbout[khel],p1_p2,k1_k2));
diagrams.push_back(FFPvertex_->evaluate(EWScale_,p1_k,qbin[p2hel],k1_k2));
}
// Add up all diagrams to get the total amplitude:
Complex hel_amp(0.);
for(unsigned int ix=0;ix<diagrams.size();ix++) hel_amp += diagrams[ix];
// If we need to fill the production ME we do it here:
if(getMatrix) {
if(p1hel==0)
gqb_hel_amps(0,p2hel,k1hel,k2hel,khel) = hel_amp;
else
gqb_hel_amps(2,p2hel,k1hel,k2hel,khel) = hel_amp;
}
sum_hel_amps_sqr += norm(hel_amp);
}
}
}
}
}
// Fill up the remaining bits of the production ME, corresponding
// to longitudinal gluon polarization, with (0.,0.).
if(getMatrix) {
for(unsigned int p2hel=0;p2hel<2;++p2hel) {
for(unsigned int k1hel=0;k1hel<3;++k1hel) {
for(unsigned int k2hel=0;k2hel<3;++k2hel) {
for(unsigned int khel=0;khel<2;++khel) {
gqb_hel_amps(1,p2hel,k1hel,k2hel,khel) = Complex(0.,0.);
}
}
}
}
}
// Calculate the production density matrix:
if(getMatrix) {
for(unsigned int k1hel=0;k1hel<3;++k1hel) {
for(unsigned int k1helpr=0;k1helpr<3;++k1helpr) {
for(unsigned int k2hel=0;k2hel<3;++k2hel) {
for(unsigned int k2helpr=0;k2helpr<3;++k2helpr) {
Complex theElement(0.,0.);
// For each k1hel, k1helpr, k2hel, k2helpr sum over fermion and gluon spins...
for(unsigned int p1hel=0;p1hel<3;p1hel+=2) {
for(unsigned int p2hel=0;p2hel<2;++p2hel) {
for(unsigned int khel=0;khel<2;++khel) {
theElement += gqb_hel_amps(p1hel,p2hel,k1hel ,k2hel ,khel)
*conj(gqb_hel_amps(p1hel,p2hel,k1helpr,k2helpr,khel));
}
}
}
// ...and then set the production matrix element to the sum:
productionMatrix_[k1hel][k1helpr][k2hel][k2helpr] = theElement;
}
}
}
}
}
// Spin and colour averaging factors = 1/4 * TR * 1/3 = 1/24
sum_hel_amps_sqr /= 24.;
// Symmetry factor for identical Z bosons in the final state
if(k1data->id()==23&&k2data->id()==23) sum_hel_amps_sqr /= 2.;
return sum_hel_amps_sqr*R.tkr()*R.ukr()*UnitRemoval::InvE2;
}
/***************************************************************************/
// This returns exactly the same value as lo_me2_ when you put it in MEPP2VVPowheg.cc
double MEPP2VVPowheg::lo_me(bool getMatrix) const {
using namespace ThePEG::Helicity;
ProductionMatrixElement lo_hel_amps(PDT::Spin1Half,PDT::Spin1Half,
PDT::Spin1 ,PDT::Spin1);
double sum_hel_amps_sqr(0.);
tcPDPtr p1data(showerQuark_->dataPtr());
tcPDPtr p2data(showerAntiquark_->dataPtr());
tcPDPtr k1data(V1_->dataPtr());
tcPDPtr k2data(V2_->dataPtr());
if(k1data->id()==-24&&k2data->id()==24) swap(k1data,k2data); // Should never actually occur.
// If you want to reproduce the spin correlations of MEPP2VV
// you should evaluate this ME using the lab frame momenta
// instead of the bornVVKinematics ones (partonic C.O.M. frame).
SpinorWaveFunction qSpinor;
SpinorBarWaveFunction qbSpinor;
if(!getMatrix) {
qSpinor=SpinorWaveFunction(B_.p1b(),p1data,incoming);
qbSpinor=SpinorBarWaveFunction(B_.p2b(),p2data,incoming);
} else {
qSpinor=SpinorWaveFunction(showerQuark_->momentum(),p1data,incoming);
qbSpinor=SpinorBarWaveFunction(showerAntiquark_->momentum(),p2data,incoming);
}
vector<SpinorWaveFunction> q;
vector<SpinorBarWaveFunction> qb;
for(unsigned int ix=0;ix<2;ix++) {
qSpinor.reset(ix);
qbSpinor.reset(ix);
q.push_back(qSpinor);
qb.push_back(qbSpinor);
}
// If you want to reproduce the spin correlations of MEPP2VV
// you should evaluate this ME using the lab frame momenta
// instead of the bornVVKinematics ones (partonic C.O.M. frame).
VectorWaveFunction v1Polarization;
VectorWaveFunction v2Polarization;
if(!getMatrix) {
v1Polarization=VectorWaveFunction(B_.k1b(),k1data,outgoing);
v2Polarization=VectorWaveFunction(B_.k2b(),k2data,outgoing);
} else {
v1Polarization=VectorWaveFunction(V1_->momentum(),k1data,outgoing);
v2Polarization=VectorWaveFunction(V2_->momentum(),k2data,outgoing);
}
vector<VectorWaveFunction> v1;
vector<VectorWaveFunction> v2;
for(unsigned int ix=0;ix<3;ix++) {
v1Polarization.reset(ix);
v2Polarization.reset(ix);
v1.push_back(v1Polarization);
v2.push_back(v2Polarization);
}
AbstractFFVVertexPtr ffv1 = k1data->id()==23 ? FFZvertex_ : FFWvertex_;
AbstractFFVVertexPtr ffv2 = k2data->id()==23 ? FFZvertex_ : FFWvertex_;
// Collecting information for intermediate fermions
vector<tcPDPtr> tc;
if(abs(k1data->id())==24&&abs(k2data->id())==24) {
if(abs(p1data->id())%2==0)
for(int ix=0;ix<3;++ix) tc.push_back(getParticleData(1+2*ix));
else
for(int ix=0;ix<3;++ix) tc.push_back(getParticleData(2+2*ix));
}
else if(k1data->id()==23&&k2data->id()==23) tc.push_back(p1data);
else if(abs(k1data->id())==24&&k2data->id()==23) tc.push_back(p2data);
// Loop over helicities summing the relevant diagrams
for(unsigned int p1hel=0;p1hel<2;++p1hel) {
for(unsigned int p2hel=0;p2hel<2;++p2hel) {
for(unsigned int k1hel=0;k1hel<3;++k1hel) {
for(unsigned int k2hel=0;k2hel<3;++k2hel) {
if((p1hel==p2hel)&&helicityConservation_) {
lo_hel_amps(p1hel,p2hel,k1hel,k2hel) = Complex(0.,0.);
continue;
}
vector<Complex> diagrams;
// Get all t-channel diagram contributions
tcPDPtr intermediate_t;
for(unsigned int ix=0;ix<tc.size();ix++) {
intermediate_t = (!(k1data->id()==24&&k2data->id()==-24)) ? p2data : tc[ix];
SpinorWaveFunction p1_v1 = ffv1->evaluate(EWScale_,5,intermediate_t,q[p1hel],v1[k1hel]);
// First calculate all the off-shell fermion currents
// Now calculate the 6 t-channel diagrams
// q+qb->v1+v2
if(!((k1data->id()==24&&k2data->id()==-24)&&(abs(p1data->id())%2==1)))
diagrams.push_back(ffv2->evaluate(EWScale_,p1_v1,qb[p2hel],v2[k2hel]));
intermediate_t = (!(k1data->id()==24&&k2data->id()==-24)) ? p1data : tc[ix];
SpinorWaveFunction p1_v2 = ffv2->evaluate(EWScale_,5,intermediate_t,q[p1hel],v2[k2hel]);
// q+qb->v2+v1
if(!((k1data->id()==24&&k2data->id()==-24)&&(abs(p1data->id())%2==0)))
diagrams.push_back(ffv1->evaluate(EWScale_,p1_v2,qb[p2hel],v1[k1hel]));
}
// Note: choosing 3 as the second argument in WWWvertex_->evaluate()
// sets option 3 in thepeg/Helicity/Vertex/VertexBase.cc , which
// means the propagator does not contain a width factor (which is
// good re. gauge invariance).
// If W+Z / W-Z calculate the two V+jet-like s-channel diagrams
if(abs(k1data->id())==24&&k2data->id()==23) {
// The off-shell s-channel boson current
VectorWaveFunction k1_k2 =
WWWvertex_->evaluate(EWScale_,3,k1data->CC(),v2[k2hel],v1[k1hel]);
// q+qb->v1*->v1+v2
diagrams.push_back(ffv1->evaluate(EWScale_,q[p1hel],qb[p2hel],k1_k2));
}
// If W+W- calculate the four V+jet-like s-channel diagrams
if((k1data->id()==24&&k2data->id()==-24)&&(p1data->id()==-p2data->id())) {
// The off-shell s-channel boson current
VectorWaveFunction k1_k2;
// q+qb->Z0*->v1+v2
tcPDPtr Z0 = getParticleData(ParticleID::Z0);
k1_k2 = WWWvertex_->evaluate(EWScale_,3,Z0,v2[k2hel],v1[k1hel]);
diagrams.push_back(FFZvertex_->evaluate(EWScale_,q[p1hel],qb[p2hel],k1_k2));
// q+qb->gamma*->v1+v2
tcPDPtr gamma = getParticleData(ParticleID::gamma);
k1_k2 = WWWvertex_->evaluate(EWScale_,3,gamma,v2[k2hel],v1[k1hel]);
diagrams.push_back(FFPvertex_->evaluate(EWScale_,q[p1hel],qb[p2hel],k1_k2));
}
// Add up all diagrams to get the total amplitude:
Complex hel_amp(0.);
for(unsigned int ix=0;ix<diagrams.size();ix++) hel_amp += diagrams[ix];
// If we need to fill the production ME we do it here:
if(getMatrix) lo_hel_amps(p1hel,p2hel,k1hel,k2hel) = hel_amp;
sum_hel_amps_sqr += norm(hel_amp);
}
}
}
}
// Calculate the production density matrix:
if(getMatrix) {
for(unsigned int k1hel=0;k1hel<3;++k1hel) {
for(unsigned int k1helpr=0;k1helpr<3;++k1helpr) {
for(unsigned int k2hel=0;k2hel<3;++k2hel) {
for(unsigned int k2helpr=0;k2helpr<3;++k2helpr) {
Complex theElement(0.,0.);
// For each k1hel, k1helpr, k2hel, k2helpr sum over the fermion spins...
for(unsigned int p1hel=0;p1hel<2;++p1hel) {
for(unsigned int p2hel=0;p2hel<2;++p2hel) {
if((p1hel==p2hel)&&helicityConservation_) continue;
theElement += lo_hel_amps(p1hel,p2hel,k1hel ,k2hel )
*conj(lo_hel_amps(p1hel,p2hel,k1helpr,k2helpr));
}
}
// ...and then set the production matrix element to the sum:
productionMatrix_[k1hel][k1helpr][k2hel][k2helpr] = theElement;
}
}
}
}
}
// Spin and colour averaging factors = 1/4 * 1/3 = 1/12
sum_hel_amps_sqr /= 12.;
// Symmetry factor for identical Z bosons in the final state
if(k1data->id()==23&&k2data->id()==23) sum_hel_amps_sqr /= 2.;
return sum_hel_amps_sqr;
}
/***************************************************************************/
// This member selects a [2-body] decay mode and assigns children to the
// vector bosons with momenta which are isotropic in their rest frames.
bool MEPP2VVPowheg::isotropicDecayer() {
using namespace ThePEG::Helicity;
// Generate the children's momenta isotropically in
// the rest frames of V1 and V2:
double cth,phi;
// First V1's children:
cth = UseRandom::rnd()*2.-1.;
phi = UseRandom::rnd()*2.*Constants::pi;
Energy m1(V1_->momentum().m());
Energy m3(children_[0]->data().constituentMass());
Energy m4(children_[1]->data().constituentMass());
Energy p34(triangleFn(sqr(m1),sqr(m3),sqr(m4))
/2./m1);
if(isnan(p34/GeV)||cth>1.||cth<-1.) return false;
Energy pT34(p34*sqrt(1.-cth)*sqrt(1.+cth));
Lorentz5Momentum k3(pT34*sin(phi),pT34*cos(phi),p34 *cth,
sqrt(p34*p34+sqr(m3)),m3);
Lorentz5Momentum k4(-k3);
k4.setE(sqrt(p34*p34+sqr(m4)));
k4.setTau(m4);
Boost boostToV1RF(R_.k1r().boostVector());
k3.boost(boostToV1RF);
k3.rescaleRho();
k4.boost(boostToV1RF);
k4.rescaleRho();
// Second V2's children:
cth = UseRandom::rnd()*2.-1.;
phi = UseRandom::rnd()*2.*Constants::pi;
Energy m2(V2_->momentum().m());
Energy m5(children_[2]->data().constituentMass());
Energy m6(children_[3]->data().constituentMass());
Energy p56(triangleFn(sqr(m2),sqr(m5),sqr(m6))
/2./m2);
if(isnan(p56/GeV)||cth>1.||cth<-1.) return false;
Energy pT56(p56*sqrt(1.-cth)*sqrt(1.+cth));
Lorentz5Momentum k5(pT56*sin(phi),pT56*cos(phi),p56*cth,
sqrt(p56*p56+sqr(m5)),m5);
Lorentz5Momentum k6(-k5);
k6.setE(sqrt(p56*p56+sqr(m6)));
k6.setTau(m6);
Boost boostToV2RF(R_.k2r().boostVector());
k5.boost(boostToV2RF);
k5.rescaleRho();
k6.boost(boostToV2RF);
k6.rescaleRho();
// Assign the momenta to the children:
children_[0]->set5Momentum(k3);
children_[1]->set5Momentum(k4);
children_[2]->set5Momentum(k5);
children_[3]->set5Momentum(k6);
return true;
}
// Override 2->2 production matrix here:
void MEPP2VVPowheg::recalculateVertex() {
// Zero the squared amplitude; this equals sum_hel_amps_sqr if all
// is working as it should:
Complex productionMatrix2(0.,0.);
for(unsigned int k1hel=0;k1hel<3;++k1hel)
for(unsigned int k2hel=0;k2hel<3;++k2hel)
productionMatrix2 += productionMatrix_[k1hel][k1hel][k2hel][k2hel];
// Get the vector wavefunctions:
VectorWaveFunction v1Polarization;
VectorWaveFunction v2Polarization;
v1Polarization=VectorWaveFunction(R_.k1r(),V1_->dataPtr(),outgoing);
v2Polarization=VectorWaveFunction(R_.k2r(),V2_->dataPtr(),outgoing);
vector<VectorWaveFunction> v1;
vector<VectorWaveFunction> v2;
for(unsigned int ix=0;ix<3;ix++) {
v1Polarization.reset(ix);
v2Polarization.reset(ix);
v1.push_back(v1Polarization);
v2.push_back(v2Polarization);
}
AbstractFFVVertexPtr ffv1 = V1_->id()==23 ? FFZvertex_ : FFWvertex_;
AbstractFFVVertexPtr ffv2 = V2_->id()==23 ? FFZvertex_ : FFWvertex_;
bool vetoed(true);
while(vetoed) {
// Decay the bosons isotropically in their rest frames:
isotropicDecayer();
// Get the spinor wavefunctions:
SpinorWaveFunction k3Spinor(children_[0]->momentum(),children_[0]->dataPtr(),outgoing);
SpinorBarWaveFunction k4Spinor(children_[1]->momentum(),children_[1]->dataPtr(),outgoing);
SpinorWaveFunction k5Spinor(children_[2]->momentum(),children_[2]->dataPtr(),outgoing);
SpinorBarWaveFunction k6Spinor(children_[3]->momentum(),children_[3]->dataPtr(),outgoing);
vector<SpinorWaveFunction> k3,k5;
vector<SpinorBarWaveFunction> k4,k6;
for(unsigned int ix=0;ix<2;ix++) {
k3Spinor.reset(ix);
k4Spinor.reset(ix);
k3.push_back(k3Spinor);
k4.push_back(k4Spinor);
k5Spinor.reset(ix);
k6Spinor.reset(ix);
k5.push_back(k5Spinor);
k6.push_back(k6Spinor);
}
DecayMatrixElement decayAmps(PDT::Spin1,PDT::Spin1Half,PDT::Spin1Half);
for(unsigned int k1hel=0;k1hel<3;++k1hel) {
for(unsigned int k3hel=0;k3hel<2;++k3hel) {
for(unsigned int k4hel=0;k4hel<2;++k4hel) {
decayAmps(k1hel,k3hel,k4hel) =
ffv1->evaluate(EWScale_,k3[k3hel],k4[k4hel],v1[k1hel]);
}
}
}
Complex V1decayMatrix[3][3];
for(unsigned int k1hel=0;k1hel<3;++k1hel) {
for(unsigned int k1helpr=0;k1helpr<3;++k1helpr) {
Complex theElement(0.,0.);
for(unsigned int k3hel=0;k3hel<2;++k3hel) {
for(unsigned int k4hel=0;k4hel<2;++k4hel) {
theElement += decayAmps(k1hel,k3hel,k4hel)
*conj(decayAmps(k1helpr,k3hel,k4hel));
}
}
V1decayMatrix[k1hel][k1helpr] = theElement;
}
}
Complex V1decayMatrix2(0.,0.);
for(unsigned int k1hel=0;k1hel<3;++k1hel) V1decayMatrix2 += V1decayMatrix[k1hel][k1hel];
for(unsigned int k2hel=0;k2hel<3;++k2hel) {
for(unsigned int k5hel=0;k5hel<2;++k5hel) {
for(unsigned int k6hel=0;k6hel<2;++k6hel) {
decayAmps(k2hel,k5hel,k6hel) =
ffv2->evaluate(EWScale_,k5[k5hel],k6[k6hel],v2[k2hel]);
}
}
}
Complex V2decayMatrix[3][3];
for(unsigned int k2hel=0;k2hel<3;++k2hel) {
for(unsigned int k2helpr=0;k2helpr<3;++k2helpr) {
Complex theElement(0.,0.);
for(unsigned int k5hel=0;k5hel<2;++k5hel) {
for(unsigned int k6hel=0;k6hel<2;++k6hel) {
theElement += decayAmps(k2hel,k5hel,k6hel)
*conj(decayAmps(k2helpr,k5hel,k6hel));
}
}
V2decayMatrix[k2hel][k2helpr] = theElement;
}
}
Complex V2decayMatrix2(0.,0.);
for(unsigned int k2hel=0;k2hel<3;++k2hel) V2decayMatrix2 += V2decayMatrix[k2hel][k2hel];
// Contract the production matrix and the decay matrices:
Complex meTimesV1V2denominators(0.,0.);
for(unsigned int k1hel=0;k1hel<3;++k1hel) {
for(unsigned int k1helpr=0;k1helpr<3;++k1helpr) {
for(unsigned int k2hel=0;k2hel<3;++k2hel) {
for(unsigned int k2helpr=0;k2helpr<3;++k2helpr) {
meTimesV1V2denominators +=
productionMatrix_[k1hel][k1helpr][k2hel][k2helpr]
*V1decayMatrix[k1hel][k1helpr]
*V2decayMatrix[k2hel][k2helpr];
}
}
}
}
if(imag(meTimesV1V2denominators)/real(meTimesV1V2denominators)>1.e-7)
cout << "MEPP2VVPowheg warning\n"
<< "the matrix element's imaginary part is large "
<< meTimesV1V2denominators << endl;
if(imag(productionMatrix2)/real(productionMatrix2)>1.e-7)
cout << "MEPP2VVPowheg warning\n"
<< "the production matrix element's imaginary part is large "
<< productionMatrix2 << endl;
if(imag(V1decayMatrix2)/real(V1decayMatrix2)>1.e-7)
cout << "MEPP2VVPowheg warning\n"
<< "the V1 decay matrix element's imaginary part is large "
<< V1decayMatrix2 << endl;
if(imag(V2decayMatrix2)/real(V2decayMatrix2)>1.e-7)
cout << "MEPP2VVPowheg warning\n"
<< "the V2 decay matrix element's imaginary part is large "
<< V2decayMatrix2 << endl;
// Need branching ratio at least in here I would think --->
double decayWeight( real(meTimesV1V2denominators)
/ real(productionMatrix2*V1decayMatrix2*V2decayMatrix2));
if(decayWeight>1.)
cout << "MEPP2VVPowheg::recalculateVertex decayWeight > 1., decayWeight = "
<< decayWeight << endl;
if(decayWeight<0.)
cout << "MEPP2VVPowheg::recalculateVertex decayWeight < 0., decayWeight = "
<< decayWeight << endl;
if(UseRandom::rnd()<decayWeight) vetoed = false;
else vetoed = true;
}
return;
}
Energy2 MEPP2VVPowheg::triangleFn(Energy2 m12,Energy2 m22, Energy2 m32) {
Energy4 lambda2(m12*m12+m22*m22+m32*m32-2.*m12*m22-2.*m12*m32-2.*m22*m32);
if(lambda2>=ZERO) {
return sqrt(lambda2);
} else {
generator()->log()
<< "MEPP2VVPowheg::triangleFn "
<< "kinematic instability, imaginary triangle function\n";
return -999999.*GeV2;
}
}
diff --git a/MatrixElement/Powheg/MEPP2ZHPowheg.cc b/MatrixElement/Powheg/MEPP2ZHPowheg.cc
--- a/MatrixElement/Powheg/MEPP2ZHPowheg.cc
+++ b/MatrixElement/Powheg/MEPP2ZHPowheg.cc
@@ -1,389 +1,388 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MEPP2ZHPowheg class.
//
#include "MEPP2ZHPowheg.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Handlers/StandardXComb.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/PDT/DecayMode.h"
using namespace Herwig;
MEPP2ZHPowheg::MEPP2ZHPowheg()
: _gluon(), TR_(0.5), CF_(4./3.),
_contrib(1) ,_nlo_alphaS_opt(0), _fixed_alphaS(0.115895),
_a(0.5) ,_p(0.7) , _eps(1.0e-8), _scaleopt(1),
_fixedScale(100.*GeV), _scaleFact(1.)
{}
void MEPP2ZHPowheg::persistentOutput(PersistentOStream & os) const {
os << _contrib << _nlo_alphaS_opt << _fixed_alphaS
<< _a << _p << _gluon
<< _scaleopt
<< ounit(_fixedScale,GeV) << _scaleFact;
}
void MEPP2ZHPowheg::persistentInput(PersistentIStream & is, int) {
is >> _contrib >> _nlo_alphaS_opt >> _fixed_alphaS
>> _a >> _p >> _gluon
>> _scaleopt
>> iunit(_fixedScale,GeV) >> _scaleFact;
}
ClassDescription<MEPP2ZHPowheg> MEPP2ZHPowheg::initMEPP2ZHPowheg;
// Definition of the static class description member.
void MEPP2ZHPowheg::Init() {
static ClassDocumentation<MEPP2ZHPowheg> documentation
("The MEPP2ZHPowheg class implements the matrix element for q qbar -> Z H",
"The PP$\\to$Z Higgs POWHEG matrix element is described in \\cite{Hamilton:2009za}.",
- "%\\cite{Hamilton:2009za}\n"
"\\bibitem{Hamilton:2009za}\n"
" K.~Hamilton, P.~Richardson and J.~Tully,\n"
" %``A Positive-Weight Next-to-Leading Order Monte Carlo Simulation for Higgs\n"
" %Boson Production,''\n"
" JHEP {\\bf 0904} (2009) 116\n"
" [arXiv:0903.4345 [hep-ph]].\n"
" %%CITATION = JHEPA,0904,116;%%\n"
);
static Switch<MEPP2ZHPowheg,unsigned int> interfaceContribution
("Contribution",
"Which contributions to the cross section to include",
&MEPP2ZHPowheg::_contrib, 1, false, false);
static SwitchOption interfaceContributionLeadingOrder
(interfaceContribution,
"LeadingOrder",
"Just generate the leading order cross section",
0);
static SwitchOption interfaceContributionPositiveNLO
(interfaceContribution,
"PositiveNLO",
"Generate the positive contribution to the full NLO cross section",
1);
static SwitchOption interfaceContributionNegativeNLO
(interfaceContribution,
"NegativeNLO",
"Generate the negative contribution to the full NLO cross section",
2);
static Switch<MEPP2ZHPowheg,unsigned int> interfaceNLOalphaSopt
("NLOalphaSopt",
"Whether to use a fixed or a running QCD coupling for the NLO weight",
&MEPP2ZHPowheg::_nlo_alphaS_opt, 0, false, false);
static SwitchOption interfaceNLOalphaSoptRunningAlphaS
(interfaceNLOalphaSopt,
"RunningAlphaS",
"Use the usual running QCD coupling evaluated at scale scale()",
0);
static SwitchOption interfaceNLOalphaSoptFixedAlphaS
(interfaceNLOalphaSopt,
"FixedAlphaS",
"Use a constant QCD coupling for comparison/debugging purposes",
1);
static Parameter<MEPP2ZHPowheg,double> interfaceFixedNLOalphaS
("FixedNLOalphaS",
"The value of alphaS to use for the nlo weight if _nlo_alphaS_opt=1",
&MEPP2ZHPowheg::_fixed_alphaS, 0.115895, 0., 1.0,
false, false, Interface::limited);
static Parameter<MEPP2ZHPowheg,double> interfaceCorrectionCoefficient
("CorrectionCoefficient",
"The magnitude of the correction term to reduce the negative contribution",
&MEPP2ZHPowheg::_a, 0.5, -10., 10.0,
false, false, Interface::limited);
static Parameter<MEPP2ZHPowheg,double> interfaceCorrectionPower
("CorrectionPower",
"The power of the correction term to reduce the negative contribution",
&MEPP2ZHPowheg::_p, 0.7, 0.0, 1.0,
false, false, Interface::limited);
static Switch<MEPP2ZHPowheg,unsigned int> interfaceFactorizationScaleOption
("FactorizationScaleOption",
"Option for the scale to be used",
&MEPP2ZHPowheg::_scaleopt, 1, false, false);
static SwitchOption interfaceScaleOptionFixed
(interfaceFactorizationScaleOption,
"Fixed",
"Use a fixed scale",
0);
static SwitchOption interfaceScaleOptionsHat
(interfaceFactorizationScaleOption,
"Dynamic",
"Use the mass of the vector boson-Higgs boson system",
1);
static Parameter<MEPP2ZHPowheg,Energy> interfaceFactorizationScaleValue
("FactorizationScaleValue",
"The fixed scale to use if required",
&MEPP2ZHPowheg::_fixedScale, GeV, 100.0*GeV, 10.0*GeV, 1000.0*GeV,
false, false, Interface::limited);
static Parameter<MEPP2ZHPowheg,double> interfaceScaleFactor
("ScaleFactor",
"The factor used before sHat if using a running scale",
&MEPP2ZHPowheg::_scaleFact, 1.0, 0.0, 10.0,
false, false, Interface::limited);
}
void MEPP2ZHPowheg::doinit() {
// gluon ParticleData object
_gluon = getParticleData(ParticleID::g);
MEPP2ZH::doinit();
}
Energy2 MEPP2ZHPowheg::scale() const {
return _scaleopt == 0 ? sqr(_fixedScale) : _scaleFact*sHat();
}
int MEPP2ZHPowheg::nDim() const {
return 7;
}
bool MEPP2ZHPowheg::generateKinematics(const double * r) {
_xt=*(r+5);
_v =*(r+6);
return MEPP2ZH::generateKinematics(r);
}
CrossSection MEPP2ZHPowheg::dSigHatDR() const {
// Get Born momentum fractions xbar_a and xbar_b:
_xb_a = lastX1();
_xb_b = lastX2();
return MEPP2ZH::dSigHatDR()*NLOweight();
}
double MEPP2ZHPowheg::NLOweight() const {
// If only leading order is required return 1:
if(_contrib==0) return 1.;
useMe();
// Get particle data for QCD particles:
_parton_a=mePartonData()[0];
_parton_b=mePartonData()[1];
// get BeamParticleData objects for PDF's
_hadron_A=dynamic_ptr_cast<Ptr<BeamParticleData>::transient_const_pointer>
(lastParticles().first->dataPtr());
_hadron_B=dynamic_ptr_cast<Ptr<BeamParticleData>::transient_const_pointer>
(lastParticles().second->dataPtr());
// If necessary swap the particle data vectors so that _xb_a,
// mePartonData[0], beam[0] relate to the inbound quark:
if(!(lastPartons().first ->dataPtr()==_parton_a&&
lastPartons().second->dataPtr()==_parton_b)) {
swap(_xb_a ,_xb_b);
swap(_hadron_A,_hadron_B);
}
// calculate the PDF's for the Born process
_oldq = _hadron_A->pdf()->xfx(_hadron_A,_parton_a,scale(),_xb_a)/_xb_a;
_oldqbar = _hadron_B->pdf()->xfx(_hadron_B,_parton_b,scale(),_xb_b)/_xb_b;
// Calculate alpha_S
_alphaS2Pi = _nlo_alphaS_opt==1 ? _fixed_alphaS : SM().alphaS(scale());
_alphaS2Pi /= 2.*Constants::pi;
// Calculate the invariant mass of the dilepton pair
_mll2 = sHat();
_mu2 = scale();
// Calculate the integrand
// q qbar contribution
double wqqvirt = Vtilde_qq();
double wqqcollin = Ctilde_qq(x(_xt,1.),1.) + Ctilde_qq(x(_xt,0.),0.);
double wqqreal = Ftilde_qq(_xt,_v);
double wqq = wqqvirt+wqqcollin+wqqreal;
// q g contribution
double wqgcollin = Ctilde_qg(x(_xt,0.),0.);
double wqgreal = Ftilde_qg(_xt,_v);
double wqg = wqgreal+wqgcollin;
// g qbar contribution
double wgqbarcollin = Ctilde_gq(x(_xt,1.),1.);
double wgqbarreal = Ftilde_gq(_xt,_v);
double wgqbar = wgqbarreal+wgqbarcollin;
// total
double wgt = 1.+(wqq+wqg+wgqbar);
// KMH - 06/08 - This seems to give wrong NLO results for
// associated Higgs so I'm omitting it.
// //trick to try and reduce neg wgt contribution
// if(_xt<1.-_eps)
// wgt += _a*(1./pow(1.-_xt,_p)-(1.-pow(_eps,1.-_p))/(1.-_p)/(1.-_eps));
// return the answer
assert(!isinf(wgt)&&!isnan(wgt));
return _contrib==1 ? max(0.,wgt) : max(0.,-wgt);
}
double MEPP2ZHPowheg::x(double xt, double v) const {
double x0(xbar(v));
return x0+(1.-x0)*xt;
}
double MEPP2ZHPowheg::x_a(double x, double v) const {
if(x==1.) return _xb_a;
if(v==0.) return _xb_a;
if(v==1.) return _xb_a/x;
return (_xb_a/sqrt(x))*sqrt((1.-(1.-x)*(1.-v))/(1.-(1.-x)*v));
}
double MEPP2ZHPowheg::x_b(double x, double v) const {
if(x==1.) return _xb_b;
if(v==0.) return _xb_b/x;
if(v==1.) return _xb_b;
return (_xb_b/sqrt(x))*sqrt((1.-(1.-x)*v)/(1.-(1.-x)*(1.-v)));
}
double MEPP2ZHPowheg::xbar(double v) const {
double xba2(sqr(_xb_a)), xbb2(sqr(_xb_b)), omv(-999.);
double xbar1(-999.), xbar2(-999.);
if(v==1.) return _xb_a;
if(v==0.) return _xb_b;
omv = 1.-v;
xbar1=4.* v*xba2/
(sqrt(sqr(1.+xba2)*4.*sqr(omv)+16.*(1.-2.*omv)*xba2)+2.*omv*(1.-_xb_a)*(1.+_xb_a));
xbar2=4.*omv*xbb2/
(sqrt(sqr(1.+xbb2)*4.*sqr( v)+16.*(1.-2.* v)*xbb2)+2.* v*(1.-_xb_b)*(1.+_xb_b));
return max(xbar1,xbar2);
}
double MEPP2ZHPowheg::Ltilde_qq(double x, double v) const {
if(x==1.) return 1.;
double xa(x_a(x,v)),xb(x_b(x,v));
double newq = (_hadron_A->pdf()->xfx(_hadron_A,_parton_a,scale(), xa)/ xa);
double newqbar = (_hadron_B->pdf()->xfx(_hadron_B,_parton_b,scale(), xb)/ xb);
return( newq * newqbar / _oldq / _oldqbar );
}
double MEPP2ZHPowheg::Ltilde_qg(double x, double v) const {
double xa(x_a(x,v)),xb(x_b(x,v));
double newq = (_hadron_A->pdf()->xfx(_hadron_A,_parton_a,scale(), xa)/ xa);
double newg2 = (_hadron_B->pdf()->xfx(_hadron_B,_gluon ,scale(), xb)/ xb);
return( newq * newg2 / _oldq / _oldqbar );
}
double MEPP2ZHPowheg::Ltilde_gq(double x, double v) const {
double xa(x_a(x,v)),xb(x_b(x,v));
double newg1 = (_hadron_A->pdf()->xfx(_hadron_A,_gluon ,scale(), xa)/ xa);
double newqbar = (_hadron_B->pdf()->xfx(_hadron_B,_parton_b,scale(), xb)/ xb);
return( newg1 * newqbar / _oldq / _oldqbar );
}
double MEPP2ZHPowheg::Vtilde_qq() const {
return _alphaS2Pi*CF_*(-3.*log(_mu2/_mll2)+(2.*sqr(Constants::pi)/3.)-8.);
}
double MEPP2ZHPowheg::Ccalbar_qg(double x) const {
return (sqr(x)+sqr(1.-x))*(log(_mll2/(_mu2*x))+2.*log(1.-x))+2.*x*(1.-x);
}
double MEPP2ZHPowheg::Ctilde_qg(double x, double v) const {
return _alphaS2Pi*TR_ * ((1.-xbar(v))/x) * Ccalbar_qg(x)*Ltilde_qg(x,v);
}
double MEPP2ZHPowheg::Ctilde_gq(double x, double v) const {
return _alphaS2Pi*TR_ * ((1.-xbar(v))/x) * Ccalbar_qg(x)*Ltilde_gq(x,v);
}
double MEPP2ZHPowheg::Ctilde_qq(double x, double v) const {
double wgt
= ((1.-x)/x+(1.+x*x)/(1.-x)/x*(2.*log(1.-x)-log(x)))*Ltilde_qq(x,v)
- 4.*log(1.-x)/(1.-x)
+ 2./(1.-xbar(v))*log(1.-xbar(v))*log(1.-xbar(v))
+ (2./(1.-xbar(v))*log(1.-xbar(v))-2./(1.-x)+(1.+x*x)/x/(1.-x)*Ltilde_qq(x,v))
*log(_mll2/_mu2);
return _alphaS2Pi*CF_*(1.-xbar(v))*wgt;
}
double MEPP2ZHPowheg::Fcal_qq(double x, double v) const {
return (sqr(1.-x)*(1.-2.*v*(1.-v))+2.*x)/x*Ltilde_qq(x,v);
}
double MEPP2ZHPowheg::Fcal_qg(double x, double v) const {
return ((1.-xbar(v))/x)*
(2.*x*(1.-x)*v+sqr((1.-x)*v)+sqr(x)+sqr(1.-x))*Ltilde_qg(x,v);
}
double MEPP2ZHPowheg::Fcal_gq(double x, double v) const {
return ((1.-xbar(v))/x)*
(2.*x*(1.-x)*(1.-v)+sqr((1.-x)*(1.-v))+sqr(x)+sqr(1.-x))*Ltilde_gq(x,v);
}
double MEPP2ZHPowheg::Ftilde_qg(double xt, double v) const {
return _alphaS2Pi*TR_*
( Fcal_qg(x(xt,v),v) - Fcal_qg(x(xt,0.),0.) )/v;
}
double MEPP2ZHPowheg::Ftilde_gq(double xt, double v) const {
return _alphaS2Pi*TR_*
( Fcal_gq(x(xt,v),v) - Fcal_gq(x(xt,1.),1.) )/(1.-v);
}
double MEPP2ZHPowheg::Ftilde_qq(double xt, double v) const {
double eps(1e-10);
// is emission into regular or singular region?
if(xt>=0. && xt<1.-eps && v>eps && v<1.-eps) {
// x<1, v>0, v<1 (regular emission, neither soft or collinear):
return _alphaS2Pi*CF_*
(( ( Fcal_qq(x(xt, v), v) - Fcal_qq(x(xt,1.),1.) ) / (1.-v)+
( Fcal_qq(x(xt, v), v) - Fcal_qq(x(xt,0.),0.) ) / v )/(1.-xt)
+ ( log(1.-xbar(v)) - log(1.-_xb_a))*2./(1.-v)
+ ( log(1.-xbar(v)) - log(1.-_xb_b))*2./v);
}
else {
// make sure emission is actually in the allowed phase space:
if(!(v>=0. && v<=1. && xt>=0. && xt<=1.)) {
ostringstream s;
s << "MEPP2ZHPowheg::Ftilde_qq : \n" << "xt(" << xt << ") and / or v("
<< v << ") not in the phase space.";
generator()->logWarning(Exception(s.str(),Exception::warning));
return 0.;
}
// is emission soft singular?
if(xt>=1.-eps) {
// x=1:
if(v<=eps) {
// x==1, v=0 (soft and collinear with particle b):
return _alphaS2Pi*CF_*
( ( log(1.-xbar(v)) - log(1.-_xb_a))*2./(1.-v)
);
} else if(v>=1.-eps) {
// x==1, v=1 (soft and collinear with particle a):
return _alphaS2Pi*CF_*
( ( log(1.-xbar(v)) - log(1.-_xb_b))*2./v
);
} else {
// x==1, 0<v<1 (soft wide angle emission):
return _alphaS2Pi*CF_*
( ( log(1.-xbar(v)) - log(1.-_xb_a))*2./(1.-v)
+ ( log(1.-xbar(v)) - log(1.-_xb_b))*2./v
);
}
} else {
// x<1:
if(v<=eps) {
// x<1 but v=0 (collinear with particle b, but not soft):
return _alphaS2Pi*CF_*
( ( ( Fcal_qq(x(xt, v), v) - Fcal_qq(x(xt,1.),1.) ) / (1.-v)
)/(1.-xt)
+ ( log(1.-xbar(v)) - log(1.-_xb_a))*2./(1.-v)
);
} else if(v>=1.-eps) {
// x<1 but v=1 (collinear with particle a, but not soft):
return _alphaS2Pi*CF_*
( ( ( Fcal_qq(x(xt, v), v) - Fcal_qq(x(xt,0.),0.) ) / v
)/(1.-xt)
+ ( log(1.-xbar(v)) - log(1.-_xb_b))*2./v
);
}
}
}
return 0.;
}
diff --git a/MatrixElement/Powheg/VVKinematics.h b/MatrixElement/Powheg/VVKinematics.h
--- a/MatrixElement/Powheg/VVKinematics.h
+++ b/MatrixElement/Powheg/VVKinematics.h
@@ -1,436 +1,684 @@
// -*- C++ -*-
#ifndef HERWIG_VVKinematics_H
#define HERWIG_VVKinematics_H
//
// This is the declaration of the VVKinematics class.
//
#include "ThePEG/Vectors/Lorentz5Vector.h"
namespace Herwig {
using namespace ThePEG;
/** \ingroup VVKinematics
* The bornVVKinematics class is used to store information on the
* the kinematics of the real emission processes needed for the
* evaluation of matrix elements in the real part of the NLO process.
*/
class bornVVKinematics {
public:
/**
* Default constructor
*/
bornVVKinematics();
/**
* Meaningful constructor: takes the momenta
* and Bjorken x values of the partons involved
* in the 2->2 scattering of the leading order
* / virtual process and calculates all interesting
* Mandelstam and Born variables.
*/
bornVVKinematics(vector<Lorentz5Momentum> Momenta, double x1, double x2);
public:
/**
* Read-only access to all of the above member variables.
*/
/**
* @name Leading order momentum fractions and associated etabar's:
*/
//@{
/**
* Leading order momentum fraction for first particle
*/
double x1b() const { return x1b_; }
/**
* Leading order etabar for first particle
*/
double eta1b() const { return eta1b_; }
/**
* Leading order momentum fraction for second particle
*/
double x2b() const { return x2b_; }
/**
* Leading order etabar for second particle
*/
double eta2b() const { return eta2b_; }
//@}
/**
* @name The Born momenta according to the notation of the FMNR papers,
* in the diboson centre of mass frame:
*/
//@{
/**
* Momentum \f$p_1\f$
*/
Lorentz5Momentum p1b() const { return p1b_; }
/**
* Momentum \f$p_2\f$
*/
Lorentz5Momentum p2b() const { return p2b_; }
/**
* Momentum \f$k_1\f$
*/
Lorentz5Momentum k1b() const { return k1b_; }
/**
* Momentum \f$k_2\f$
*/
Lorentz5Momentum k2b() const { return k2b_; }
//@}
/**
* @name The diboson invariant mass / shat, that and uhat:
*/
//@{
/**
* \f$\hat s\f$
*/
Energy2 sb() const { return sb_; }
/**
* \f$\hat t\f$
*/
Energy2 tb() const { return tb_; }
/**
* \f$\hat u\f$
*/
Energy2 ub() const { return ub_; }
//@}
/**
* The diboson rapidity:
* Note Yb_ = + lastY() if flipped = false
* but Yb_ = - lastY() if flipped = true.
* Yb_ is always defined with the quark travelling in the +z direction!
*/
double Yb() const { return Yb_; }
/**
* @name Masses of the final state bosons:
*/
//@{
/**
* Mass squared og the first boson
*/
Energy2 k12b() const { return k12b_; }
/**
* Mass squared og the second boson
*/
Energy2 k22b() const { return k22b_; }
//@}
/**
* Polar and azimuthal angles of the dibosons in their rest frame:
*/
double theta1b() const { return theta1b_; }
/**
* A check to make sure that the momenta calculated from
* the energies and angles are equal to those of meMomenta().
*/
void sanityCheck() const;
private:
/**
* Invariants required for the evaluation of 2-> 2 next-to-leading
* order quantities (Frixione et al. NPB.383 WZ production at colliders).
*/
/**
* @name Leading order momentum fractions and associated etabar's:
*/
//@{
/**
* Leading order momentum fraction for first particle
*/
double x1b_;
/**
* Leading order etabar for first particle
*/
double eta1b_;
/**
* Leading order momentum fraction for second particle
*/
double x2b_;
/**
* Leading order etabar for second particle
*/
double eta2b_;
//@}
/**
* @name The Born momenta according to the notation of the FMNR papers,
* in the diboson centre of mass frame:
*/
//@{
/**
* Momentum \f$p_1\f$
*/
Lorentz5Momentum p1b_;
/**
* Momentum \f$p_2\f$
*/
Lorentz5Momentum p2b_;
/**
* Momentum \f$k_1\f$
*/
Lorentz5Momentum k1b_;
/**
* Momentum \f$k_2\f$
*/
Lorentz5Momentum k2b_;
//@}
/**
* @name The diboson invariant mass / shat, that and uhat:
*/
//@{
/**
* \f$\hat s\f$
*/
Energy2 sb_;
/**
* \f$\hat t\f$
*/
Energy2 tb_;
/**
* \f$\hat u\f$
*/
Energy2 ub_;
//@}
/**
* The diboson rapidity:
* Note Yb_ = + lastY() if flipped = false
* but Yb_ = - lastY() if flipped = true.
* Yb_ is always defined with the quark travelling in the +z direction!
*/
double Yb_;
/**
* @name Masses of the final state bosons:
*/
//@{
/**
* Mass squared og the first boson
*/
Energy2 k12b_;
/**
* Mass squared og the second boson
*/
Energy2 k22b_;
//@}
/**
* Polar angle of the dibosons in their rest frame:
*/
double theta1b_;
};
/** \ingroup VVKinematics
* The realVVKinematics class is used to store information on the
* the kinematics of the real emission processes needed for the
* evaluation of matrix elements in the real part of the NLO process.
*/
class realVVKinematics {
public:
/**
* Default constructor
*/
realVVKinematics();
/**
* Meaningful constructor: takes the Born variables
* from the leading order /virtual 2->2 process and
* the raw \f$\tilde{x}, y\f$ radiative variables and turns
* these into a set of 2->3 momenta with associated
* Mandelstam variables, Bjorken x values etc.
+ * @param bornVariables The object for the Born kinematics
* @param xt The \f$\tilde{x}\f$ radiative variable.
* @param y The angular radiative variable (the cosine
- * of the polar angle of the emitted gluon in the partonic
+ * of the polar angle of the emitted gluon in the partonic
+ * @param theta2 The angle \f$\theta_2\f$
* CMS frame).
*/
realVVKinematics(bornVVKinematics bornVariables,double xt, double y, double theta2);
/**
* A check to make sure that the momenta calculated from
* the energies and angles are equal to those of meMomenta().
*/
void sanityCheck() const;
public:
/**
* Read-only access to all of the above member variables.
*/
/**
* The bornVVKinematics underlying the 2->3 kinematics
*/
bornVVKinematics bornVariables() const { return bornVariables_; }
/**
* The lower bound on the x integration:
*/
double xbar() const { return xbar_; }
/**
* @name The `raw' radiative variables.
*/
//@{
/**
* The \f$\tilde{x}\f$ radiative variable
*/
double xt() const { return xt_; }
/**
* The \f$y\f$ radiative variable
*/
double y() const { return y_; }
/**
* The \f$x_r\f$ radiative variable
*/
double xr() const { return xr_; }
//@}
/**
* The momentum fraction of the parton incident from the +z direction.
*/
double x1r() const { return x1r_; }
/**
* The momentum fraction of the parton incident from the -z direction.
*/
double x2r() const { return x2r_; }
/**
* Invariants required for the evaluation of next-to-leading order
* quantities (Frixione et al. NPB.383 WZ production at colliders).
*/
- // First the Born variables:
+ /**
+ * @name First the Born variables:
+ */
+ //@{
+ /**
+ * \f$s_2\f$ variable from Frixione et al. NPB.383,3
+ */
Energy2 s2r() const { return s2r_; }
+
+ /**
+ * \f$k_1^2\f$ mass of first vector boson
+ */
Energy2 k12r() const { return k12r_; }
+
+ /**
+ * \f$k_2^2\f$ mass of second vector boson
+ */
Energy2 k22r() const { return k22r_; }
+
+ /**
+ * \f$\theta_1\f$ angle from Frixione et al. NPB.383,3
+ */
double theta1r() const { return theta1r_; }
+
+ /**
+ * \f$\theta_2\f$ angle from Frixione et al. NPB.383,3
+ */
double theta2r() const { return theta2r_; }
+ //@}
- // Then the rest:
+ /**
+ * @name Then the rest:
+ */
+ //@{
+ /**
+ * \f$p_T^2\f$ in the lab frame
+ */
Energy2 pT2_in_lab() const { return tkr_*ukr_/sr_; }
+
+ /**
+ * \f$s\f$ from Frixione et al. NPB.383,3
+ */
Energy2 sr() const { return sr_; }
+
+ /**
+ * \f$t_k\f$ from Frixione et al. NPB.383,3
+ */
Energy2 tkr() const { return tkr_; }
+
+ /**
+ * \f$u_k\f$ from Frixione et al. NPB.383,3
+ */
Energy2 ukr() const { return ukr_; }
+
+ /**
+ * \f$\cos\psi\f$ from Frixione et al. NPB.383,3
+ */
double cpsir() const { return cpsir_; }
+
+ /**
+ * \f$\cos\psi'\f$ from Frixione et al. NPB.383,3
+ */
double cpsipr() const { return cpsiprr_; }
+
+ /**
+ * \f$\beta_x\f$ from Frixione et al. NPB.383,3
+ */
double betaxr() const { return betaxr_; }
+
+ /**
+ * \f$v_1\f$ variable from Frixione et al. NPB.383,3
+ */
double v1r() const { return v1r_; }
+
+ /**
+ * \f$v_2\f$ variable from Frixione et al. NPB.383,3
+ */
double v2r() const { return v2r_; }
+
+ /**
+ * \f$q_1\f$ variable from Frixione et al. NPB.383,3
+ */
Energy2 q1r() const { return q1r_; }
+
+ /**
+ * \f$q_2\f$ variable from Frixione et al. NPB.383,3
+ */
Energy2 q2r() const { return q2r_; }
+
+ /**
+ * \f$\hat q_1\f$ variable from Frixione et al. NPB.383,3
+ */
Energy2 q1hatr() const { return q1hatr_; }
+
+ /**
+ * \f$\hat q_2\f$ variable from Frixione et al. NPB.383,3
+ */
Energy2 q2hatr() const { return q2hatr_; }
+
+ /**
+ * \f$\hat w_1\f$ variable from Frixione et al. NPB.383,3
+ */
Energy2 w1r() const { return w1r_; }
+
+ /**
+ * \f$\hat w_2\f$ variable from Frixione et al. NPB.383,3
+ */
Energy2 w2r() const { return w2r_; }
+
+ /**
+ * 4-momentum \f$p_1\f$ from Frixione et al. NPB.383,3
+ */
Lorentz5Momentum p1r() const { return p1r_; }
+
+ /**
+ * 4-momentum \f$p_2\f$ from Frixione et al. NPB.383,3
+ */
Lorentz5Momentum p2r() const { return p2r_; }
+
+ /**
+ * 4-momentum \f$k\f$ from Frixione et al. NPB.383,3
+ */
Lorentz5Momentum kr() const { return kr_ ; }
+
+ /**
+ * 4-momentum \f$k_1\f$ from Frixione et al. NPB.383,3
+ */
Lorentz5Momentum k1r() const { return k1r_; }
+
+ /**
+ * 4-momentum \f$k_2\f$ from Frixione et al. NPB.383,3
+ */
Lorentz5Momentum k2r() const { return k2r_; }
+
+ /**
+ * Set 4-momentum \f$p_1\f$ from Frixione et al. NPB.383,3
+ */
void p1r(Lorentz5Momentum p1r) { p1r_ = p1r; }
+
+ /**
+ * Set 4-momentum \f$p_2\f$ from Frixione et al. NPB.383,3
+ */
void p2r(Lorentz5Momentum p2r) { p2r_ = p2r; }
+
+ /**
+ * Set 4-momentum \f$k\f$ from Frixione et al. NPB.383,3
+ */
void kr (Lorentz5Momentum kr ) { kr_ = kr ; }
+
+ /**
+ * Set 4-momentum \f$k_1\f$ from Frixione et al. NPB.383,3
+ */
void k1r(Lorentz5Momentum k1r) { k1r_ = k1r; }
+
+ /**
+ * Set 4-momentum \f$k_2\f$ from Frixione et al. NPB.383,3
+ */
void k2r(Lorentz5Momentum k2r) { k2r_ = k2r; }
-
+ //@}
private:
+
/**
* The bornVVKinematics object underlying the 2->3 kinematics.
*/
bornVVKinematics bornVariables_;
/**
* The lower bound on the x integration.
*/
double xbar_;
// The `raw' radiative variables.
+ /**
+ * @name The `raw' radiative variables.
+ */
+ //@{
+ /**
+ * The \f$\tilde{x}\f$ radiative variable
+ */
double xt_;
+
+ /**
+ * The \f$y\f$ radiative variable
+ */
double y_;
+
+ /**
+ * The \f$x_r\f$ radiative variable
+ */
double xr_;
+ //@}
/**
* The momentum fraction of the parton incident from the +z direction.
*/
double x1r_;
/**
* The momentum fraction of the parton incident from the -z direction.
*/
double x2r_;
/**
* Invariants required for the evaluation of next-to-leading order
* quantities (Frixione et al. NPB.383 WZ production at colliders).
*/
- // First the Born variables:
+
+ /**
+ * @name First the Born variables:
+ */
+ //@{
+ /**
+ * \f$s_2\f$ variable from Frixione et al. NPB.383,3
+ */
Energy2 s2r_;
+
+ /**
+ * \f$k_1^2\f$ mass of first vector boson
+ */
Energy2 k12r_;
+
+ /**
+ * \f$k_2^2\f$ mass of second vector boson
+ */
Energy2 k22r_;
+
+ /**
+ * \f$\theta_1\f$ angle from Frixione et al. NPB.383,3
+ */
double theta1r_;
+
+ /**
+ * \f$\theta_2\f$ angle from Frixione et al. NPB.383,3
+ */
double theta2r_;
- // Then the rest:
+ //@}
+
+ /**
+ * @name Then the rest:
+ */
+ //@{
+ /**
+ * \f$s\f$ from Frixione et al. NPB.383,3
+ */
Energy2 sr_;
+
+ /**
+ * \f$t_k\f$ from Frixione et al. NPB.383,3
+ */
Energy2 tkr_;
+
+ /**
+ * \f$u_k\f$ from Frixione et al. NPB.383,3
+ */
Energy2 ukr_;
+
+ /**
+ * \f$\cos\psi\f$ from Frixione et al. NPB.383,3
+ */
double cpsir_;
+
+ /**
+ * \f$\cos\psi'\f$ from Frixione et al. NPB.383,3
+ */
double cpsiprr_;
+
+ /**
+ * \f$\beta_x\f$ from Frixione et al. NPB.383,3
+ */
double betaxr_;
+
+ /**
+ * \f$v_1\f$ variable from Frixione et al. NPB.383,3
+ */
double v1r_;
+
+ /**
+ * \f$v_2\f$ variable from Frixione et al. NPB.383,3
+ */
double v2r_;
+
+ /**
+ * \f$q_1\f$ variable from Frixione et al. NPB.383,3
+ */
Energy2 q1r_;
+
+ /**
+ * \f$q_2\f$ variable from Frixione et al. NPB.383,3
+ */
Energy2 q2r_;
+
+ /**
+ * \f$\hat q_1\f$ variable from Frixione et al. NPB.383,3
+ */
Energy2 q1hatr_;
+
+ /**
+ * \f$\hat q_2\f$ variable from Frixione et al. NPB.383,3
+ */
Energy2 q2hatr_;
+
+ /**
+ * \f$\hat w_1\f$ variable from Frixione et al. NPB.383,3
+ */
Energy2 w1r_;
+
+ /**
+ * \f$\hat w_2\f$ variable from Frixione et al. NPB.383,3
+ */
Energy2 w2r_;
+
+ /**
+ * 4-momentum \f$p_1\f$ from Frixione et al. NPB.383,3
+ */
Lorentz5Momentum p1r_;
+
+ /**
+ * 4-momentum \f$p_2\f$ from Frixione et al. NPB.383,3
+ */
Lorentz5Momentum p2r_;
+
+ /**
+ * 4-momentum \f$k\f$ from Frixione et al. NPB.383,3
+ */
Lorentz5Momentum kr_;
+
+ /**
+ * 4-momentum \f$k_1\f$ from Frixione et al. NPB.383,3
+ */
Lorentz5Momentum k1r_;
+
+ /**
+ * 4-momentum \f$k_2\f$ from Frixione et al. NPB.383,3
+ */
Lorentz5Momentum k2r_;
+ //@}
};
}
#endif /* HERWIG_VVKinematics_H */
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Apr 24, 6:38 AM (1 d, 21 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4887794
Default Alt Text
(255 KB)
Attached To
rHERWIGHG herwighg
Event Timeline
Log In to Comment