Page MenuHomeHEPForge

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/MatrixElement/Makefile.am b/MatrixElement/Makefile.am
--- a/MatrixElement/Makefile.am
+++ b/MatrixElement/Makefile.am
@@ -1,18 +1,18 @@
-SUBDIRS = General Lepton Hadron DIS Powheg Gamma Matchbox Reweighters
+SUBDIRS = General Lepton Hadron DIS Powheg Gamma Matchbox Reweighters Onium
if WANT_LIBFASTJET
SUBDIRS += FxFx
endif
noinst_LTLIBRARIES = libHwME.la
libHwME_la_SOURCES = \
HwMEBase.h HwMEBase.fh HwMEBase.cc \
MEMultiChannel.h MEMultiChannel.cc \
MEfftoVH.h MEfftoVH.cc \
MEfftoffH.h MEfftoffH.cc \
HardVertex.fh HardVertex.h HardVertex.cc \
ProductionMatrixElement.h ProductionMatrixElement.cc \
DrellYanBase.h DrellYanBase.cc \
BlobME.h BlobME.cc \
MEMinBias.h MEMinBias.cc
diff --git a/MatrixElement/Onium/GammaGamma2Onium1D2Amplitude.cc b/MatrixElement/Onium/GammaGamma2Onium1D2Amplitude.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/GammaGamma2Onium1D2Amplitude.cc
@@ -0,0 +1,238 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the GammaGamma2Onium1D2Amplitude class.
+//
+
+#include "GammaGamma2Onium1D2Amplitude.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/Utilities/EnumIO.h"
+#include "ThePEG/Helicity/epsilon.h"
+#include "Herwig/Models/StandardModel/StandardModel.h"
+#include "ThePEG/Helicity/WaveFunction/TensorWaveFunction.h"
+#include "ThePEG/Handlers/EventHandler.h"
+
+using namespace Herwig;
+
+IBPtr GammaGamma2Onium1D2Amplitude::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr GammaGamma2Onium1D2Amplitude::fullclone() const {
+ return new_ptr(*this);
+}
+
+void GammaGamma2Onium1D2Amplitude::persistentOutput(PersistentOStream & os) const {
+ os << params_ << ounit(O1_,GeV*GeV2*GeV2*GeV2) << oenum(state_)
+ << n_ << ounit(Lambda2_,GeV2) << mOpt_ << massGen_;
+}
+
+void GammaGamma2Onium1D2Amplitude::persistentInput(PersistentIStream & is, int) {
+ is >> params_ >> iunit(O1_,GeV*GeV2*GeV2*GeV2) >> ienum(state_)
+ >> n_ >> iunit(Lambda2_,GeV2) >> mOpt_ >> massGen_;
+}
+
+void GammaGamma2Onium1D2Amplitude::doinit() {
+ GammaGammaAmplitude::doinit();
+ // get the non-perturbative ME
+ O1_ = params_->singletMEProduction<2>(state_,n_,0,2);
+ // get the mass generator of the onium state
+ unsigned int iq = 4+state_;
+ long id = iq*110+10005 + (n_-1)*100000;
+ tcPDPtr ps = getParticleData(id);
+ if(!ps)
+ throw Exception() << "No onium particle with id " << id << " in " << fullName();
+ if(ps->massGenerator())
+ massGen_=dynamic_ptr_cast<GenericMassGeneratorPtr>(ps->massGenerator());
+ if(!massGen_) mOpt_=0;
+}
+
+// The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<GammaGamma2Onium1D2Amplitude,GammaGammaAmplitude>
+describeHerwigGammaGamma2Onium1D2Amplitude("Herwig::GammaGamma2Onium1D2Amplitude",
+ "HwOniumParameters.so HwMEGammaGamma.so HwMEGammaGammaOnium.so");
+
+void GammaGamma2Onium1D2Amplitude::Init() {
+
+ static ClassDocumentation<GammaGamma2Onium1D2Amplitude> documentation
+ ("The GammaGamma2Onium1D2Amplitude class implements the amplitude for gamma gamma -> 1D2");
+
+ static Reference<GammaGamma2Onium1D2Amplitude,OniumParameters> interfaceParameters
+ ("Parameters",
+ "Quarkonium parameters",
+ &GammaGamma2Onium1D2Amplitude::params_, false, false, true, false, false);
+
+ static Switch<GammaGamma2Onium1D2Amplitude,OniumState> interfaceState
+ ("State",
+ "The type of onium state",
+ &GammaGamma2Onium1D2Amplitude::state_, ccbar, false, false);
+ static SwitchOption interfaceStateccbar
+ (interfaceState,
+ "ccbar",
+ "Charmonium state",
+ ccbar);
+ static SwitchOption interfaceStatebbbar
+ (interfaceState,
+ "bbbar",
+ "Bottomonium state",
+ bbbar);
+
+ static Parameter<GammaGamma2Onium1D2Amplitude,unsigned int> interfacePrincipalQuantumNumber
+ ("PrincipalQuantumNumber",
+ "The principle quantum number of the states",
+ &GammaGamma2Onium1D2Amplitude::n_, 1, 1, 10,
+ false, false, Interface::limited);
+
+ static Parameter<GammaGamma2Onium1D2Amplitude,Energy2> interfaceLambda2
+ ("Lambda2",
+ "The value of Lambda^2 for the form-factor",
+ &GammaGamma2Onium1D2Amplitude::Lambda2_, GeV2, sqr(3.0969*GeV), 0.0*GeV2, 200.0*GeV2,
+ false, false, Interface::limited);
+
+ static Switch<GammaGamma2Onium1D2Amplitude,unsigned int> interfaceMassOption
+ ("MassOption",
+ "Option for the generation of the onium mass",
+ &GammaGamma2Onium1D2Amplitude::mOpt_, 0, false, false);
+ static SwitchOption interfaceMassOptionOnShell
+ (interfaceMassOption,
+ "OnShell",
+ "Generate the onium state on-shell",
+ 0);
+ static SwitchOption interfaceMassOptionOffShell
+ (interfaceMassOption,
+ "OffShell",
+ "Generate an off-shell onium state using the nass generator",
+ 1);
+
+}
+
+vector<DiagPtr> GammaGamma2Onium1D2Amplitude::getDiagrams(unsigned int iopt) const {
+ // construct the meson PDG code from quark ids
+ unsigned int iq = 4+state_;
+ tcPDPtr ps = getParticleData(long(iq*110+10005 + (n_-1)*100000));
+ // construct the diagrams
+ vector<DiagPtr> output;
+ output.reserve(1);
+ tcPDPtr g = getParticleData(ParticleID::gamma );
+ if(iopt==0) {
+ output.push_back(new_ptr((Tree2toNDiagram(2), g, g, 1, ps, -1)));
+ }
+ else {
+ cPDPair in = generator()->eventHandler()->incoming();
+ if(in.first->charged() && in.second->charged())
+ output.push_back(new_ptr((Tree2toNDiagram(4), in.first, g, g, in.second,
+ 1, in.first, 3, in.second, 2, ps, -1)));
+ }
+ return output;
+}
+
+ProductionMatrixElement GammaGamma2Onium1D2Amplitude::
+helicityAmplitude(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ const vector<TensorWaveFunction> & ten,
+ const Energy & M, double & output) const {
+ Lorentz5Momentum pG1 = v1[0].momentum();
+ Lorentz5Momentum pG2 = v2[0].momentum();
+ // compute the tensor term
+ Lorentz5Momentum pDiff = pG1-pG2;
+ vector<Complex> tamp(5);
+ for(unsigned int i=0;i<5;++i) {
+ tamp[i] = ten[i].wave().trace()+2./sqr(M)*(ten[i].wave().preDot(pDiff)*pDiff);
+ }
+ // calculate the matrix element
+ vector<unsigned int> ihMax(4,0);
+ ProductionMatrixElement me = bookME(ihMax,v1.size(),v2.size(),vector<PDT::Spin>(1,PDT::Spin2));
+ output = 0;
+ for(unsigned int ih1A=0;ih1A<ihMax[0];++ih1A) {
+ for(unsigned int ih1B=0;ih1B<ihMax[1];++ih1B) {
+ unsigned int ih1 = 2*ih1A+ih1B;
+ auto vOff1 = Helicity::epsilon(v1[ih1].wave(),pG1,pG2);
+ for(unsigned int ih2A=0;ih2A<ihMax[2];++ih2A) {
+ for(unsigned int ih2B=0;ih2B<ihMax[3];++ih2B) {
+ unsigned int ih2 = 2*ih2A+ih2B;
+ Complex vamp = (vOff1*v2[ih2].wave())/sqr(M);
+ auto vOff2 = Helicity::epsilon(v2[ih2].wave(),pG1,pG2);
+ auto vOff3 = Helicity::epsilon(pG1+pG2,v1[ih1].wave(),v2[ih2].wave());
+ for(unsigned int ix=0;ix<5;++ix) {
+ Complex amp = vamp*tamp[ix];
+ Complex ampNew = (0.125*(ten[ix].wave().preDot (pDiff)*vOff3)+
+ 0.125*(ten[ix].wave().postDot(pDiff)*vOff3)+
+ 0.25*ten[ix].wave().preDot (v1[ih1].wave())*vOff2-
+ 0.25*ten[ix].wave().preDot (v2[ih2].wave())*vOff1+
+ 0.25*ten[ix].wave().postDot(v1[ih1].wave())*vOff2-
+ 0.25*ten[ix].wave().postDot(v2[ih2].wave())*vOff1)/sqr(M);
+ amp +=ampNew;
+ output += norm(amp);
+ if(v1.size()==2 && v2.size()==2) me(2*ih1B,2*ih2B,ix) = amp;
+ else if(v1.size()==2) me(2*ih1B,ih2A,ih2B,ix) = amp;
+ else if(v2.size()==2) me(ih1A,ih1B,2*ih2B,ix) = amp;
+ else me(ih1A,ih1B,ih2A,ih2B,ix) = amp;
+ }
+ }
+ }
+ }
+ }
+ return me;
+}
+
+double GammaGamma2Onium1D2Amplitude::me2(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ const Energy2 & t1, const Energy2 & t2,
+ const Energy2 & scale,
+ const vector<Lorentz5Momentum> & momenta,
+ const cPDVector & partons, DVector & ) const {
+ Energy M = momenta.back().mass();
+ double output(0.);
+ vector<TensorWaveFunction> t3(5);
+ for(unsigned int i=0;i<5;++i) {
+ TensorWaveFunction ten(momenta.back(), partons.back(),i,outgoing);
+ t3[i]=ten;
+ }
+ helicityAmplitude(v1,v2,t3,M,output);
+ // coupling factors
+ double eQ = state_==ccbar ? 2./3. : -1./3.;
+ double alpha = generator()->standardModel()->alphaEM();
+ return 512./5.*output*O1_/scale/pow<5,1>(M)*sqr(Constants::pi*alpha*sqr(eQ)/(1.-t1/Lambda2_)/(1.-t2/Lambda2_));
+}
+
+Energy GammaGamma2Onium1D2Amplitude::generateW(double r, const tcPDVector & partons, Energy Wmin,
+ Energy Wmax,Energy2 & jacW, Energy2 scale) {
+ Wmin = max(Wmin,partons.back()->massMin());
+ Wmax = min(Wmax,partons.back()->massMax());
+ double wgt(0.);
+ Energy output = massGen_->mass(wgt,*partons.back(),Wmin,Wmax,r);
+ jacW = scale*wgt;
+ return output;
+}
+
+ProductionMatrixElement GammaGamma2Onium1D2Amplitude::me(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ tParticleVector & particles) const {
+ vector<TensorWaveFunction> t3;
+ TensorWaveFunction(t3,particles[0],outgoing,true,false);
+ double output(0);
+ return helicityAmplitude(v1,v2,t3,particles[0]->mass(),output);
+}
+
+double GammaGamma2Onium1D2Amplitude::
+generateKinematics(const double * ,
+ const Energy2 & scale,
+ vector<Lorentz5Momentum> & momenta,
+ const tcPDVector & ) {
+ Energy M = sqrt(scale);
+ double jac = scale*massGen_->BreitWignerWeight(M)/pow(Constants::twopi,3);
+ momenta[0].setVect(Momentum3(ZERO,ZERO,ZERO));
+ momenta[0].setE(M);
+ momenta[0].rescaleMass();
+ return jac;
+}
diff --git a/MatrixElement/Onium/GammaGamma2Onium1D2Amplitude.h b/MatrixElement/Onium/GammaGamma2Onium1D2Amplitude.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/GammaGamma2Onium1D2Amplitude.h
@@ -0,0 +1,225 @@
+// -*- C++ -*-
+#ifndef Herwig_GammaGamma2Onium1D2Amplitude_H
+#define Herwig_GammaGamma2Onium1D2Amplitude_H
+//
+// This is the declaration of the GammaGamma2Onium1D2Amplitude class.
+//
+
+#include "Herwig/MatrixElement/Gamma/GammaGammaAmplitude.h"
+#include "OniumParameters.h"
+#include "Herwig/PDT/GenericMassGenerator.h"
+#include "Herwig/Models/StandardModel/StandardModel.h"
+#include "ThePEG/Helicity/WaveFunction/TensorWaveFunction.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * The GammaGamma2Onium1D2Amplitude class implements the matrix element for \f$\gamma\gamma\to^{1}\!\!D_2\f$ quarkonium
+ * states.
+ *
+ * @see \ref GammaGamma2Onium1D2AmplitudeInterfaces "The interfaces"
+ * defined for GammaGamma2Onium1D2Amplitude.
+ */
+class GammaGamma2Onium1D2Amplitude: public GammaGammaAmplitude {
+
+public:
+
+ /** @name Standard constructors and destructors. */
+ //@{
+ /**
+ * The default constructor.
+ */
+ GammaGamma2Onium1D2Amplitude() : O1_(ZERO), state_(ccbar), n_(1),
+ Lambda2_(sqr(3.0969*GeV)), mOpt_(0)
+ {}
+ //@}
+
+public:
+
+ /** @name Virtual functions required by GammaGammaAmplitude class. */
+ //@{
+ /**
+ * Return the order in \f$\alpha_S\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaS() const {
+ return 0;
+ }
+
+ /**
+ * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaEW() const {
+ return 2;
+ }
+
+ /**
+ * The number of internal degrees of freedom used in the matrix
+ * element.
+ */
+ virtual int nDim(unsigned int) const {
+ return mOpt_;
+ }
+
+ /**
+ * The Feynman diagrams (iopt=0 gamma gamma, iopt=1, e+e-)
+ */
+ virtual vector<DiagPtr> getDiagrams(unsigned int iopt) const;
+
+ /**
+ * The matrix element
+ */
+ virtual double me2(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ const Energy2 & t1, const Energy2 & t2,
+ const Energy2 & scale,
+ const vector<Lorentz5Momentum> & momenta,
+ const cPDVector & partons,
+ DVector & dweights ) const;
+
+ /**
+ * Matrix element for spin correlations
+ */
+ virtual ProductionMatrixElement me(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ tParticleVector & particles) const;
+
+ /**
+ * Generate the mass of the \f$\gamma\gamma\f$ system
+ */
+ virtual Energy generateW(double r, const tcPDVector & partons, Energy Wmin,
+ Energy Wmax, Energy2 & jacW, Energy2 scale);
+
+ /**
+ * Generate internal degrees of freedom given 'nDim()' uniform
+ * random numbers in the interval ]0,1[. To help the phase space
+ * generator, the 'dSigHatDR()' should be a smooth function of these
+ * numbers, although this is not strictly necessary. Return
+ * false if the chosen points failed the kinematical cuts.
+ */
+ virtual double generateKinematics(const double * r,
+ const Energy2 & scale,
+ vector<Lorentz5Momentum> & momenta,
+ const tcPDVector & partons);
+
+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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+protected:
+
+ /**
+ * Calculation of the helicity amplitudes for the process
+ */
+ ProductionMatrixElement helicityAmplitude(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ const vector<TensorWaveFunction> & ten,
+ const Energy & M, double & output) const;
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ GammaGamma2Onium1D2Amplitude & operator=(const GammaGamma2Onium1D2Amplitude &) = delete;
+
+private:
+
+ /**
+ * Parameters for the form-factors
+ */
+ //@{
+ /**
+ * Access to the parameters for the quarkonium states
+ */
+ OniumParametersPtr params_;
+
+ /**
+ * The \f$O_1\f$ colour-singlet coefficient
+ */
+ Energy7 O1_;
+
+ /**
+ * Type of state
+ */
+ OniumState state_;
+
+ /**
+ * Principal quantum number
+ */
+ unsigned int n_;
+ /**
+ * Pole mass squared parameter for the form factors
+ */
+ Energy2 Lambda2_;
+
+ /**
+ * Option for the mass generation
+ */
+ unsigned int mOpt_;
+
+ /**
+ * The mass generator for the Higgs
+ */
+ GenericMassGeneratorPtr massGen_;
+ //@}
+};
+
+}
+
+#endif /* Herwig_GammaGamma2Onium1D2Amplitude_H */
diff --git a/MatrixElement/Onium/GammaGamma2Onium1S0Amplitude.cc b/MatrixElement/Onium/GammaGamma2Onium1S0Amplitude.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/GammaGamma2Onium1S0Amplitude.cc
@@ -0,0 +1,186 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the GammaGamma2Onium1S0Amplitude class.
+//
+
+#include "GammaGamma2Onium1S0Amplitude.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/Utilities/EnumIO.h"
+#include "ThePEG/Helicity/epsilon.h"
+#include "Herwig/Models/StandardModel/StandardModel.h"
+#include "ThePEG/Handlers/EventHandler.h"
+
+using namespace Herwig;
+
+IBPtr GammaGamma2Onium1S0Amplitude::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr GammaGamma2Onium1S0Amplitude::fullclone() const {
+ return new_ptr(*this);
+}
+
+void GammaGamma2Onium1S0Amplitude::persistentOutput(PersistentOStream & os) const {
+ os << params_ << ounit(O1_,GeV*GeV2) << oenum(state_) << n_ << ounit(Lambda2_,GeV2) << mOpt_ << massGen_;
+}
+
+void GammaGamma2Onium1S0Amplitude::persistentInput(PersistentIStream & is, int) {
+ is >> params_ >> iunit(O1_,GeV*GeV2) >> ienum(state_) >> n_ >> iunit(Lambda2_,GeV2) >> mOpt_ >> massGen_;
+}
+
+void GammaGamma2Onium1S0Amplitude::doinit() {
+ GammaGammaAmplitude::doinit();
+ // get the non-perturbative ME
+ O1_ = params_->singletMEProduction<0>(state_,n_,0,0);
+ // get the mass generator of the onium state
+ unsigned int iq = 4+state_;
+ long id = iq*110+1 + (n_-1)*100000;
+ tcPDPtr ps = getParticleData(id);
+ if(!ps)
+ throw Exception() << "No onium particle with id " << id
+ << "in " << fullName();
+ if(ps->massGenerator())
+ massGen_=dynamic_ptr_cast<GenericMassGeneratorPtr>(ps->massGenerator());
+ if(!massGen_) mOpt_=0;
+}
+
+// The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<GammaGamma2Onium1S0Amplitude,GammaGammaAmplitude>
+describeHerwigGammaGamma2Onium1S0Amplitude("Herwig::GammaGamma2Onium1S0Amplitude",
+ "HwOniumParameters.so HwMEGammaGamma.so HwMEGammaGammaOnium.so");
+
+void GammaGamma2Onium1S0Amplitude::Init() {
+
+ static ClassDocumentation<GammaGamma2Onium1S0Amplitude> documentation
+ ("The GammaGamma2Onium1S0Amplitude class implements the amplitude for gamma gamma -> 1S0");
+
+ static Reference<GammaGamma2Onium1S0Amplitude,OniumParameters> interfaceParameters
+ ("Parameters",
+ "Quarkonium parameters",
+ &GammaGamma2Onium1S0Amplitude::params_, false, false, true, false, false);
+
+ static Switch<GammaGamma2Onium1S0Amplitude,OniumState> interfaceState
+ ("State",
+ "The type of onium state",
+ &GammaGamma2Onium1S0Amplitude::state_, ccbar, false, false);
+ static SwitchOption interfaceStateccbar
+ (interfaceState,
+ "ccbar",
+ "Charmonium state",
+ ccbar);
+ static SwitchOption interfaceStatebbbar
+ (interfaceState,
+ "bbbar",
+ "Bottomonium state",
+ bbbar);
+
+ static Parameter<GammaGamma2Onium1S0Amplitude,unsigned int> interfacePrincipalQuantumNumber
+ ("PrincipalQuantumNumber",
+ "The principle quantum number of the states",
+ &GammaGamma2Onium1S0Amplitude::n_, 1, 1, 10,
+ false, false, Interface::limited);
+
+ static Parameter<GammaGamma2Onium1S0Amplitude,Energy2> interfaceLambda2
+ ("Lambda2",
+ "The value of Lambda^2 for the form-factor",
+ &GammaGamma2Onium1S0Amplitude::Lambda2_, GeV2, sqr(3.0969*GeV), 0.0*GeV2, 200.0*GeV2,
+ false, false, Interface::limited);
+
+ static Switch<GammaGamma2Onium1S0Amplitude,unsigned int> interfaceMassOption
+ ("MassOption",
+ "Option for the generation of the onium mass",
+ &GammaGamma2Onium1S0Amplitude::mOpt_, 0, false, false);
+ static SwitchOption interfaceMassOptionOnShell
+ (interfaceMassOption,
+ "OnShell",
+ "Generate the onium state on-shell",
+ 0);
+ static SwitchOption interfaceMassOptionOffShell
+ (interfaceMassOption,
+ "OffShell",
+ "Generate an off-shell onium state using the mass generator",
+ 1);
+
+}
+
+vector<DiagPtr> GammaGamma2Onium1S0Amplitude::getDiagrams(unsigned int iopt) const {
+ // construct the meson PDG code from quark ids
+ unsigned int iq = 4+state_;
+ tcPDPtr ps = getParticleData(long(iq*110+1 + (n_-1)*100000));
+ // construct the diagrams
+ vector<DiagPtr> output;
+ output.reserve(1);
+ tcPDPtr g = getParticleData(ParticleID::gamma );
+ if(iopt==0) {
+ output.push_back(new_ptr((Tree2toNDiagram(2), g, g, 1, ps, -1)));
+ }
+ else {
+ cPDPair in = generator()->eventHandler()->incoming();
+ if(in.first->charged() && in.second->charged())
+ output.push_back(new_ptr((Tree2toNDiagram(4), in.first, g, g, in.second,
+ 1, in.first, 3, in.second, 2, ps, -1)));
+ }
+ return output;
+}
+
+ProductionMatrixElement GammaGamma2Onium1S0Amplitude::
+helicityAmplitude(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ const Energy & M, double & output) const {
+ vector<unsigned int> ihMax(4,0);
+ ProductionMatrixElement me = bookME(ihMax,v1.size(),v2.size(),vector<PDT::Spin>(1,PDT::Spin0));
+ // calculate the matrix element
+ output = 0;
+ Lorentz5Momentum pG1 = v1[0].momentum();
+ Lorentz5Momentum pG2 = v2[0].momentum();
+ for(unsigned int ih1A=0;ih1A<ihMax[0];++ih1A) {
+ for(unsigned int ih1B=0;ih1B<ihMax[1];++ih1B) {
+ auto vOff = Helicity::epsilon(v1[2*ih1A+ih1B].wave(),pG1,pG2);
+ for(unsigned int ih2A=0;ih2A<ihMax[2];++ih2A) {
+ for(unsigned int ih2B=0;ih2B<ihMax[3];++ih2B) {
+ Complex amp = (vOff*v2[2*ih2A+ih2B].wave())/sqr(M);
+ output += norm(amp);
+ if(v1.size()==2 && v2.size()==2) me(2*ih1B,2*ih2B,0) = amp;
+ else if(v1.size()==2) me(2*ih1B,ih2A,ih2B,0) = amp;
+ else if(v2.size()==2) me(ih1A,ih1B,2*ih2B,0) = amp;
+ else me(ih1A,ih1B,ih2A,ih2B,0) = amp;
+ }
+ }
+ }
+ }
+ return me;
+}
+
+Energy GammaGamma2Onium1S0Amplitude::generateW(double r, const tcPDVector & partons, Energy Wmin,
+ Energy Wmax,Energy2 & jacW, Energy2 scale) {
+ Wmin = max(Wmin,partons.back()->massMin());
+ Wmax = min(Wmax,partons.back()->massMax());
+ double wgt(0.);
+ Energy output = massGen_->mass(wgt,*partons.back(),Wmin,Wmax,r);
+ jacW = scale*wgt;
+ return output;
+}
+
+double GammaGamma2Onium1S0Amplitude::
+generateKinematics(const double * ,
+ const Energy2 & scale,
+ vector<Lorentz5Momentum> & momenta,
+ const tcPDVector & ) {
+ Energy M = sqrt(scale);
+ double jac = scale*massGen_->BreitWignerWeight(M)/pow(Constants::twopi,3);
+ momenta[0].setVect(Momentum3(ZERO,ZERO,ZERO));
+ momenta[0].setE(M);
+ momenta[0].rescaleMass();
+ return jac;
+}
diff --git a/MatrixElement/Onium/GammaGamma2Onium1S0Amplitude.h b/MatrixElement/Onium/GammaGamma2Onium1S0Amplitude.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/GammaGamma2Onium1S0Amplitude.h
@@ -0,0 +1,235 @@
+// -*- C++ -*-
+#ifndef Herwig_GammaGamma2Onium1S0Amplitude_H
+#define Herwig_GammaGamma2Onium1S0Amplitude_H
+//
+// This is the declaration of the GammaGamma2Onium1S0Amplitude class.
+//
+
+#include "Herwig/MatrixElement/Gamma/GammaGammaAmplitude.h"
+#include "OniumParameters.h"
+#include "Herwig/PDT/GenericMassGenerator.h"
+#include "Herwig/Models/StandardModel/StandardModel.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * The GammaGamma2Onium1S0Amplitude class implements the matrix element for \f$\gamma\gamma\to^{1}\!\!S_0\f$ quarkonium.
+ * states.
+ *
+ * @see \ref GammaGamma2Onium1S0AmplitudeInterfaces "The interfaces"
+ * defined for GammaGamma2Onium1S0Amplitude.
+ */
+class GammaGamma2Onium1S0Amplitude: public GammaGammaAmplitude {
+
+public:
+
+ /** @name Standard constructors and destructors. */
+ //@{
+ /**
+ * The default constructor.
+ */
+ GammaGamma2Onium1S0Amplitude() : O1_(ZERO), state_(ccbar), n_(1),
+ Lambda2_(sqr(3.0969*GeV)), mOpt_(0)
+ {}
+ //@}
+
+public:
+
+ /** @name Virtual functions required by GammaGammaAmplitude class. */
+ //@{
+ /**
+ * Return the order in \f$\alpha_S\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaS() const {
+ return 0;
+ }
+
+ /**
+ * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaEW() const {
+ return 2;
+ }
+
+ /**
+ * The number of internal degrees of freedom used in the matrix
+ * element.
+ */
+ virtual int nDim(unsigned int) const {
+ return mOpt_;
+ }
+
+ /**
+ * The Feynman diagrams (iopt=0 gamma gamma, iopt=1, e+e-)
+ */
+ virtual vector<DiagPtr> getDiagrams(unsigned int iopt) const;
+
+ /**
+ * The matrix element
+ */
+ virtual double me2(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ const Energy2 & t1, const Energy2 & t2,
+ const Energy2 & scale,
+ const vector<Lorentz5Momentum> & momenta,
+ const cPDVector & , DVector & ) const {
+ Energy M = momenta.back().mass();
+ double output(0.);
+ helicityAmplitude(v1,v2,M,output);
+ // coupling factors
+ double eQ = state_==ccbar ? 2./3. : -1./3.;
+ double alpha = generator()->standardModel()->alphaEM();
+ return 128.*output*O1_/M/scale*sqr(Constants::pi*alpha*sqr(eQ)/(1.-t1/Lambda2_)/(1.-t2/Lambda2_));
+ }
+
+ /**
+ * Matrix element for spin correlations
+ */
+ virtual ProductionMatrixElement me(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ tParticleVector & particles) const {
+ ScalarWaveFunction(particles[0],outgoing,true);
+ double output(0);
+ return helicityAmplitude(v1,v2,particles[0]->mass(),output);
+ }
+
+ /**
+ * Generate the mass of the \f$\gamma\gamma\f$ system
+ */
+ virtual Energy generateW(double r, const tcPDVector & partons, Energy Wmin,
+ Energy Wmax, Energy2 & jacW, Energy2 scale);
+
+ /**
+ * Generate internal degrees of freedom given 'nDim()' uniform
+ * random numbers in the interval ]0,1[. To help the phase space
+ * generator, the 'dSigHatDR()' should be a smooth function of these
+ * numbers, although this is not strictly necessary. Return
+ * false if the chosen points failed the kinematical cuts.
+ */
+ virtual double generateKinematics(const double * r,
+ const Energy2 & scale,
+ vector<Lorentz5Momentum> & momenta,
+ const tcPDVector & partons);
+
+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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+protected:
+
+ /**
+ * Calculation of the helicity amplitudes for the process
+ */
+ ProductionMatrixElement helicityAmplitude(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ const Energy & M, double & output) const;
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ GammaGamma2Onium1S0Amplitude & operator=(const GammaGamma2Onium1S0Amplitude &) = delete;
+
+private:
+
+ /**
+ * Parameters for the form-factors
+ */
+ //@{
+ /**
+ * Access to the parameters for the quarkonium states
+ */
+ OniumParametersPtr params_;
+
+ /**
+ * The \f$O_1\f$ colour-singlet coefficient
+ */
+ Energy3 O1_;
+
+ /**
+ * Type of state
+ */
+ OniumState state_;
+
+ /**
+ * Principal quantum number
+ */
+ unsigned int n_;
+ /**
+ * Pole mass squared parameter for the form factors
+ */
+ Energy2 Lambda2_;
+
+ /**
+ * Option for the mass generation
+ */
+ unsigned int mOpt_;
+
+ /**
+ * The mass generator for the onium state
+ */
+ GenericMassGeneratorPtr massGen_;
+ //@}
+
+};
+
+}
+
+#endif /* Herwig_GammaGamma2Onium1S0Amplitude_H */
diff --git a/MatrixElement/Onium/GammaGamma2Onium3P0Amplitude.cc b/MatrixElement/Onium/GammaGamma2Onium3P0Amplitude.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/GammaGamma2Onium3P0Amplitude.cc
@@ -0,0 +1,186 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the GammaGamma2Onium3P0Amplitude class.
+//
+
+#include "GammaGamma2Onium3P0Amplitude.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/Utilities/EnumIO.h"
+#include "Herwig/Models/StandardModel/StandardModel.h"
+#include "ThePEG/Handlers/EventHandler.h"
+
+using namespace Herwig;
+
+IBPtr GammaGamma2Onium3P0Amplitude::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr GammaGamma2Onium3P0Amplitude::fullclone() const {
+ return new_ptr(*this);
+}
+
+void GammaGamma2Onium3P0Amplitude::persistentOutput(PersistentOStream & os) const {
+ os << params_ << ounit(O1_,GeV*GeV2*GeV2) << oenum(state_) << n_ << ounit(Lambda2_,GeV2) << mOpt_ << massGen_;
+}
+
+void GammaGamma2Onium3P0Amplitude::persistentInput(PersistentIStream & is, int) {
+ is >> params_ >> iunit(O1_,GeV*GeV2*GeV2) >> ienum(state_) >> n_ >> iunit(Lambda2_,GeV2) >> mOpt_ >> massGen_;
+}
+
+void GammaGamma2Onium3P0Amplitude::doinit() {
+ GammaGammaAmplitude::doinit();
+ // get the non-perturbative ME
+ O1_ = params_->singletMEProduction<1>(state_,n_,1,0);
+ // get the mass generator of the onium state
+ unsigned int iq = 4+state_;
+ long id = iq*110+10001 + (n_-1)*100000;
+ tcPDPtr ps = getParticleData(id);
+ if(!ps)
+ throw Exception() << "No onium particle with id " << id << " in " << fullName();
+ if(ps->massGenerator())
+ massGen_=dynamic_ptr_cast<GenericMassGeneratorPtr>(ps->massGenerator());
+ if(!massGen_) mOpt_=0;
+}
+
+// The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<GammaGamma2Onium3P0Amplitude,GammaGammaAmplitude>
+describeHerwigGammaGamma2Onium3P0Amplitude("Herwig::GammaGamma2Onium3P0Amplitude",
+ "HwOniumParameters.so HwMEGammaGamma.so HwMEGammaGammaOnium.so");
+
+void GammaGamma2Onium3P0Amplitude::Init() {
+
+ static ClassDocumentation<GammaGamma2Onium3P0Amplitude> documentation
+ ("The GammaGamma2Onium3P0Amplitude class implements the amplitude for gamma gamma -> 3P0");
+
+ static Reference<GammaGamma2Onium3P0Amplitude,OniumParameters> interfaceParameters
+ ("Parameters",
+ "Quarkonium parameters",
+ &GammaGamma2Onium3P0Amplitude::params_, false, false, true, false, false);
+
+ static Switch<GammaGamma2Onium3P0Amplitude,OniumState> interfaceState
+ ("State",
+ "The type of onium state",
+ &GammaGamma2Onium3P0Amplitude::state_, ccbar, false, false);
+ static SwitchOption interfaceStateccbar
+ (interfaceState,
+ "ccbar",
+ "Charmonium state",
+ ccbar);
+ static SwitchOption interfaceStatebbbar
+ (interfaceState,
+ "bbbar",
+ "Bottomonium state",
+ bbbar);
+
+ static Parameter<GammaGamma2Onium3P0Amplitude,unsigned int> interfacePrincipalQuantumNumber
+ ("PrincipalQuantumNumber",
+ "The principle quantum number of the states",
+ &GammaGamma2Onium3P0Amplitude::n_, 1, 1, 10,
+ false, false, Interface::limited);
+
+ static Parameter<GammaGamma2Onium3P0Amplitude,Energy2> interfaceLambda2
+ ("Lambda2",
+ "The value of Lambda^2 for the form-factor",
+ &GammaGamma2Onium3P0Amplitude::Lambda2_, GeV2, sqr(3.0969*GeV), 0.0*GeV2, 200.0*GeV2,
+ false, false, Interface::limited);
+
+ static Switch<GammaGamma2Onium3P0Amplitude,unsigned int> interfaceMassOption
+ ("MassOption",
+ "Option for the generation of the onium mass",
+ &GammaGamma2Onium3P0Amplitude::mOpt_, 0, false, false);
+ static SwitchOption interfaceMassOptionOnShell
+ (interfaceMassOption,
+ "OnShell",
+ "Generate the onium state on-shell",
+ 0);
+ static SwitchOption interfaceMassOptionOffShell
+ (interfaceMassOption,
+ "OffShell",
+ "Generate an off-shell onium state using the nass generator",
+ 1);
+
+}
+
+vector<DiagPtr> GammaGamma2Onium3P0Amplitude::getDiagrams(unsigned int iopt) const {
+ // construct the meson PDG code from quark ids
+ unsigned int iq = 4+state_;
+ tcPDPtr ps = getParticleData(long(iq*110+10001 + (n_-1)*100000));
+ // construct the diagrams
+ vector<DiagPtr> output;
+ output.reserve(1);
+ tcPDPtr g = getParticleData(ParticleID::gamma );
+ if(iopt==0) {
+ output.push_back(new_ptr((Tree2toNDiagram(2), g, g, 1, ps, -1)));
+ }
+ else {
+ cPDPair in = generator()->eventHandler()->incoming();
+ if(in.first->charged() && in.second->charged())
+ output.push_back(new_ptr((Tree2toNDiagram(4), in.first, g, g, in.second,
+ 1, in.first, 3, in.second, 2, ps, -1)));
+ }
+ return output;
+}
+
+ProductionMatrixElement GammaGamma2Onium3P0Amplitude::
+helicityAmplitude(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ const Energy & M, double & output) const {
+ Lorentz5Momentum pG1 = v1[0].momentum();
+ Lorentz5Momentum pG2 = v2[0].momentum();
+ vector<unsigned int> ihMax(4,0);
+ ProductionMatrixElement me = bookME(ihMax,v1.size(),v2.size(),vector<PDT::Spin>(1,PDT::Spin0));
+ // calculate the matrix element
+ output = 0;
+ for(unsigned int ih1A=0;ih1A<ihMax[0];++ih1A) {
+ for(unsigned int ih1B=0;ih1B<ihMax[1];++ih1B) {
+ unsigned int ih1 = 2*ih1A+ih1B;
+ complex<Energy> d1 = v1[ih1].wave()*pG2;
+ for(unsigned int ih2A=0;ih2A<ihMax[2];++ih2A) {
+ for(unsigned int ih2B=0;ih2B<ihMax[3];++ih2B) {
+ unsigned int ih2 = 2*ih2A+ih2B;
+ Complex amp = v1[ih1].wave()*v2[ih2].wave() -2./sqr(M)*d1*(v2[ih2].wave()*pG1);
+ output += norm(amp);
+ if(v1.size()==2 && v2.size()==2) me(2*ih1B,2*ih2B,0) = amp;
+ else if(v1.size()==2) me(2*ih1B,ih2A,ih2B,0) = amp;
+ else if(v2.size()==2) me(ih1A,ih1B,2*ih2B,0) = amp;
+ else me(ih1A,ih1B,ih2A,ih2B,0) = amp;
+ }
+ }
+ }
+ }
+ return me;
+}
+
+Energy GammaGamma2Onium3P0Amplitude::generateW(double r, const tcPDVector & partons, Energy Wmin,
+ Energy Wmax,Energy2 & jacW, Energy2 scale) {
+ Wmin = max(Wmin,partons.back()->massMin());
+ Wmax = min(Wmax,partons.back()->massMax());
+ double wgt(0.);
+ Energy output = massGen_->mass(wgt,*partons.back(),Wmin,Wmax,r);
+ jacW = scale*wgt;
+ return output;
+}
+
+double GammaGamma2Onium3P0Amplitude::
+generateKinematics(const double * ,
+ const Energy2 & scale,
+ vector<Lorentz5Momentum> & momenta,
+ const tcPDVector & ) {
+ Energy M = sqrt(scale);
+ double jac = scale*massGen_->BreitWignerWeight(M)/pow(Constants::twopi,3);
+ momenta[0].setVect(Momentum3(ZERO,ZERO,ZERO));
+ momenta[0].setE(M);
+ momenta[0].rescaleMass();
+ return jac;
+}
diff --git a/MatrixElement/Onium/GammaGamma2Onium3P0Amplitude.h b/MatrixElement/Onium/GammaGamma2Onium3P0Amplitude.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/GammaGamma2Onium3P0Amplitude.h
@@ -0,0 +1,236 @@
+// -*- C++ -*-
+#ifndef Herwig_GammaGamma2Onium3P0Amplitude_H
+#define Herwig_GammaGamma2Onium3P0Amplitude_H
+//
+// This is the declaration of the GammaGamma2Onium3P0Amplitude class.
+//
+
+#include "Herwig/MatrixElement/Gamma/GammaGammaAmplitude.h"
+#include "OniumParameters.h"
+#include "Herwig/PDT/GenericMassGenerator.h"
+#include "Herwig/Models/StandardModel/StandardModel.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * The GammaGamma2Onium3P0Amplitude class implements the matrix element for \f$\gamma\gamma\to^{3}\!\!P_0\f$ quarkonium.
+ *
+ * @see \ref GammaGamma2Onium3P0AmplitudeInterfaces "The interfaces"
+ * defined for GammaGamma2Onium3P0Amplitude.
+ */
+class GammaGamma2Onium3P0Amplitude: public GammaGammaAmplitude {
+
+public:
+
+ /** @name Standard constructors and destructors. */
+ //@{
+ /**
+ * The default constructor.
+ */
+ GammaGamma2Onium3P0Amplitude() : O1_(ZERO), state_(ccbar), n_(1),
+ Lambda2_(sqr(3.0969*GeV)), mOpt_(0)
+ {}
+ //@}
+
+public:
+
+ /** @name Virtual functions required by GammaGammaAmplitude class. */
+ //@{
+ /**
+ * Return the order in \f$\alpha_S\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaS() const {
+ return 0;
+ }
+
+ /**
+ * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaEW() const {
+ return 2;
+ }
+
+ /**
+ * The number of internal degrees of freedom used in the matrix
+ * element.
+ */
+ virtual int nDim(unsigned int) const {
+ return mOpt_;
+ }
+
+ /**
+ * The Feynman diagrams (iopt=0 gamma gamma, iopt=1, e+e-)
+ */
+ virtual vector<DiagPtr> getDiagrams(unsigned int iopt) const;
+
+ /**
+ * The matrix element
+ */
+ virtual double me2(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ const Energy2 & t1, const Energy2 & t2,
+ const Energy2 & scale,
+ const vector<Lorentz5Momentum> & momenta,
+ const cPDVector & , DVector & ) const {
+ // calculate the matrix element
+ Energy M = momenta.back().mass();
+ double output(0.);
+ helicityAmplitude(v1,v2,M,output);
+ // coupling factors
+ double eQ = state_==ccbar ? 2./3. : -1./3.;
+ double alpha = generator()->standardModel()->alphaEM();
+ return 384.*output/pow<3,1>(M)/scale*O1_*sqr(Constants::pi*alpha*sqr(eQ)/(1.-t1/Lambda2_)/(1.-t2/Lambda2_));
+ }
+
+ /**
+ * Matrix element for spin correlations
+ */
+ virtual ProductionMatrixElement me(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ tParticleVector & particles) const {
+ ScalarWaveFunction(particles[0],outgoing,true);
+ double output(0);
+ return helicityAmplitude(v1,v2,particles[0]->mass(),output);
+ }
+
+ /**
+ * Generate the mass of the \f$\gamma\gamma\f$ system
+ */
+ virtual Energy generateW(double r, const tcPDVector & partons, Energy Wmin,
+ Energy Wmax, Energy2 & jacW, Energy2 scale);
+
+ /**
+ * Generate internal degrees of freedom given 'nDim()' uniform
+ * random numbers in the interval ]0,1[. To help the phase space
+ * generator, the 'dSigHatDR()' should be a smooth function of these
+ * numbers, although this is not strictly necessary. Return
+ * false if the chosen points failed the kinematical cuts.
+ */
+ virtual double generateKinematics(const double * r,
+ const Energy2 & scale,
+ vector<Lorentz5Momentum> & momenta,
+ const tcPDVector & partons);
+
+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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+protected:
+
+ /**
+ * Calculation of the helicity amplitudes for the process
+ */
+ ProductionMatrixElement helicityAmplitude(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ const Energy & M, double & output) const;
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ GammaGamma2Onium3P0Amplitude & operator=(const GammaGamma2Onium3P0Amplitude &) = delete;
+
+private:
+
+ /**
+ * Parameters for the form-factors
+ */
+ //@{
+ /**
+ * Access to the parameters for the quarkonium states
+ */
+ OniumParametersPtr params_;
+
+ /**
+ * The \f$O_1\f$ colour-singlet coefficient
+ */
+ Energy5 O1_;
+
+ /**
+ * Type of state
+ */
+ OniumState state_;
+
+ /**
+ * Principal quantum number
+ */
+ unsigned int n_;
+
+ /**
+ * Pole mass squared parameter for the form factors
+ */
+ Energy2 Lambda2_;
+
+ /**
+ * Option for the mass generation
+ */
+ unsigned int mOpt_;
+
+ /**
+ * The mass generator for the Higgs
+ */
+ GenericMassGeneratorPtr massGen_;
+ //@}
+
+};
+
+}
+
+#endif /* Herwig_GammaGamma2Onium3P0Amplitude_H */
diff --git a/MatrixElement/Onium/GammaGamma2Onium3P2Amplitude.cc b/MatrixElement/Onium/GammaGamma2Onium3P2Amplitude.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/GammaGamma2Onium3P2Amplitude.cc
@@ -0,0 +1,232 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the GammaGamma2Onium3P2Amplitude class.
+//
+
+#include "GammaGamma2Onium3P2Amplitude.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/Utilities/EnumIO.h"
+#include "Herwig/Models/StandardModel/StandardModel.h"
+#include "ThePEG/Helicity/WaveFunction/TensorWaveFunction.h"
+#include "ThePEG/Handlers/EventHandler.h"
+
+using namespace Herwig;
+
+IBPtr GammaGamma2Onium3P2Amplitude::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr GammaGamma2Onium3P2Amplitude::fullclone() const {
+ return new_ptr(*this);
+}
+
+void GammaGamma2Onium3P2Amplitude::persistentOutput(PersistentOStream & os) const {
+ os << params_ << ounit(O1_,GeV*GeV2*GeV2) << oenum(state_)
+ << n_ << ounit(Lambda2_,GeV2) << mOpt_ << massGen_;
+}
+
+void GammaGamma2Onium3P2Amplitude::persistentInput(PersistentIStream & is, int) {
+ is >> params_ >> iunit(O1_,GeV*GeV2*GeV2) >> ienum(state_)
+ >> n_ >> iunit(Lambda2_,GeV2) >> mOpt_ >> massGen_;
+}
+
+void GammaGamma2Onium3P2Amplitude::doinit() {
+ GammaGammaAmplitude::doinit();
+ // get the non-perturbative ME
+ O1_ = params_->singletMEProduction<1>(state_,n_,1,2);
+ // get the mass generator of the onium state
+ unsigned int iq = 4+state_;
+ long id = iq*110+5 + (n_-1)*100000;
+ tcPDPtr ps = getParticleData(id);
+ if(!ps)
+ throw Exception() << "No onium particle with id " << id << " in " << fullName();
+ if(ps->massGenerator())
+ massGen_=dynamic_ptr_cast<GenericMassGeneratorPtr>(ps->massGenerator());
+ if(!massGen_) mOpt_=0;
+}
+
+// The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<GammaGamma2Onium3P2Amplitude,GammaGammaAmplitude>
+describeHerwigGammaGamma2Onium3P2Amplitude("Herwig::GammaGamma2Onium3P2Amplitude",
+ "HwOniumParameters.so HwMEGammaGamma.so HwMEGammaGammaOnium.so");
+
+void GammaGamma2Onium3P2Amplitude::Init() {
+
+ static ClassDocumentation<GammaGamma2Onium3P2Amplitude> documentation
+ ("The GammaGamma2Onium3P2Amplitude class implements the amplitude for gamma gamma -> 3P2");
+
+
+ static Reference<GammaGamma2Onium3P2Amplitude,OniumParameters> interfaceParameters
+ ("Parameters",
+ "Quarkonium parameters",
+ &GammaGamma2Onium3P2Amplitude::params_, false, false, true, false, false);
+
+ static Switch<GammaGamma2Onium3P2Amplitude,OniumState> interfaceState
+ ("State",
+ "The type of onium state",
+ &GammaGamma2Onium3P2Amplitude::state_, ccbar, false, false);
+ static SwitchOption interfaceStateccbar
+ (interfaceState,
+ "ccbar",
+ "Charmonium state",
+ ccbar);
+ static SwitchOption interfaceStatebbbar
+ (interfaceState,
+ "bbbar",
+ "Bottomonium state",
+ bbbar);
+
+ static Parameter<GammaGamma2Onium3P2Amplitude,unsigned int> interfacePrincipalQuantumNumber
+ ("PrincipalQuantumNumber",
+ "The principle quantum number of the states",
+ &GammaGamma2Onium3P2Amplitude::n_, 1, 1, 10,
+ false, false, Interface::limited);
+
+ static Parameter<GammaGamma2Onium3P2Amplitude,Energy2> interfaceLambda2
+ ("Lambda2",
+ "The value of Lambda^2 for the form-factor",
+ &GammaGamma2Onium3P2Amplitude::Lambda2_, GeV2, sqr(3.0969*GeV), 0.0*GeV2, 200.0*GeV2,
+ false, false, Interface::limited);
+
+ static Switch<GammaGamma2Onium3P2Amplitude,unsigned int> interfaceMassOption
+ ("MassOption",
+ "Option for the generation of the onium mass",
+ &GammaGamma2Onium3P2Amplitude::mOpt_, 0, false, false);
+ static SwitchOption interfaceMassOptionOnShell
+ (interfaceMassOption,
+ "OnShell",
+ "Generate the onium state on-shell",
+ 0);
+ static SwitchOption interfaceMassOptionOffShell
+ (interfaceMassOption,
+ "OffShell",
+ "Generate an off-shell onium state using the nass generator",
+ 1);
+
+}
+
+vector<DiagPtr> GammaGamma2Onium3P2Amplitude::getDiagrams(unsigned int iopt) const {
+ // construct the meson PDG code from quark ids
+ unsigned int iq = 4+state_;
+ tcPDPtr ps = getParticleData(long(iq*110+5 + (n_-1)*100000));
+ // construct the diagrams
+ vector<DiagPtr> output;
+ output.reserve(1);
+ tcPDPtr g = getParticleData(ParticleID::gamma );
+ if(iopt==0) {
+ output.push_back(new_ptr((Tree2toNDiagram(2), g, g, 1, ps, -1)));
+ }
+ else {
+ cPDPair in = generator()->eventHandler()->incoming();
+ if(in.first->charged() && in.second->charged())
+ output.push_back(new_ptr((Tree2toNDiagram(4), in.first, g, g, in.second,
+ 1, in.first, 3, in.second, 2, ps, -1)));
+ }
+ return output;
+}
+
+ProductionMatrixElement GammaGamma2Onium3P2Amplitude::
+helicityAmplitude(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ const vector<TensorWaveFunction> & twave,
+ const Energy & M, double & output) const {
+ vector<unsigned int> ihMax(4,0);
+ ProductionMatrixElement me = bookME(ihMax,v1.size(),v2.size(),vector<PDT::Spin>(1,PDT::Spin2));
+ Lorentz5Momentum pG1 = v1[0].momentum();
+ Lorentz5Momentum pG2 = v2[0].momentum();
+ Lorentz5Momentum pDiff = pG1-pG2;
+ // calculate the amplitudes
+ for(unsigned int ix=0;ix<5;++ix) {
+ auto vPre = twave[ix].wave().preDot (pDiff);
+ auto vPost = twave[ix].wave().postDot(pDiff);
+ complex<Energy2> v1v2=vPre*pDiff;
+ for(unsigned int ih1A=0;ih1A<ihMax[0];++ih1A) {
+ for(unsigned int ih1B=0;ih1B<ihMax[1];++ih1B) {
+ unsigned int ih1 = 2*ih1A+ih1B;
+ auto vEps1 = twave[ix].wave().preDot(v1[ih1].wave())+twave[ix].wave().postDot(v1[ih1].wave());
+ complex<Energy> dPreEps1 = vPre*v1[ih1].wave();
+ complex<Energy> dPostEps1 = vPost*v1[ih1].wave();
+ complex<Energy> d1 = v1[ih1].wave()*pG2;
+ for(unsigned int ih2A=0;ih2A<ihMax[2];++ih2A) {
+ for(unsigned int ih2B=0;ih2B<ihMax[3];++ih2B) {
+ unsigned int ih2 = 2*ih2A+ih2B;
+ complex<Energy> d2 = v2[ih2].wave()*pG1;
+ Complex d12 = v1[ih1].wave()*v2[ih2].wave();
+ Complex amp = ((dPreEps1+dPostEps1)*d2 -(vPre*v2[ih2].wave()+vPost*v2[ih2].wave())*d1-v1v2*d12)/sqr(M) + vEps1*v2[ih2].wave();
+ output += norm(amp);
+ if(v1.size()==2 && v2.size()==2) me(2*ih1B,2*ih2B,ix) = amp;
+ else if(v1.size()==2) me(2*ih1B,ih2A,ih2B,ix) = amp;
+ else if(v2.size()==2) me(ih1A,ih1B,2*ih2B,ix) = amp;
+ else me(ih1A,ih1B,ih2A,ih2B,ix) = amp;
+ }
+ }
+ }
+ }
+ }
+ return me;
+}
+
+double GammaGamma2Onium3P2Amplitude::me2(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ const Energy2 & t1, const Energy2 & t2,
+ const Energy2 & scale,
+ const vector<Lorentz5Momentum> & momenta,
+ const cPDVector & partons, DVector & ) const {
+ double output(0.);
+ Energy M = momenta.back().mass();
+ // wavefunction for the tensor meson
+ vector<TensorWaveFunction> twave(5);
+ for(unsigned int i=0;i<5;++i) {
+ twave[i] = TensorWaveFunction(momenta.back(), partons.back(),i,outgoing);
+ }
+ // calculate the matrix element
+ helicityAmplitude(v1,v2,twave,M,output);
+ // coupling factors
+ double eQ = state_==ccbar ? 2./3. : -1./3.;
+ double alpha = generator()->standardModel()->alphaEM();
+ return 128./5.*output*O1_/pow<3,1>(M)/scale*sqr(Constants::pi*alpha*sqr(eQ)/(1.-t1/Lambda2_)/(1.-t2/Lambda2_));
+}
+
+Energy GammaGamma2Onium3P2Amplitude::generateW(double r, const tcPDVector & partons, Energy Wmin,
+ Energy Wmax,Energy2 & jacW, Energy2 scale) {
+ Wmin = max(Wmin,partons.back()->massMin());
+ Wmax = min(Wmax,partons.back()->massMax());
+ double wgt(0.);
+ Energy output = massGen_->mass(wgt,*partons.back(),Wmin,Wmax,r);
+ jacW = scale*wgt;
+ return output;
+}
+
+ProductionMatrixElement GammaGamma2Onium3P2Amplitude::me(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ tParticleVector & particles) const {
+ vector<TensorWaveFunction> t3;
+ TensorWaveFunction(t3,particles[0],outgoing,true,false);
+ double output(0);
+ return helicityAmplitude(v1,v2,t3,particles[0]->mass(),output);
+}
+
+
+double GammaGamma2Onium3P2Amplitude::
+generateKinematics(const double * ,
+ const Energy2 & scale,
+ vector<Lorentz5Momentum> & momenta,
+ const tcPDVector & ) {
+ Energy M = sqrt(scale);
+ double jac = scale*massGen_->BreitWignerWeight(M)/pow(Constants::twopi,3);
+ momenta[0].setVect(Momentum3(ZERO,ZERO,ZERO));
+ momenta[0].setE(M);
+ momenta[0].rescaleMass();
+ return jac;
+}
diff --git a/MatrixElement/Onium/GammaGamma2Onium3P2Amplitude.h b/MatrixElement/Onium/GammaGamma2Onium3P2Amplitude.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/GammaGamma2Onium3P2Amplitude.h
@@ -0,0 +1,225 @@
+// -*- C++ -*-
+#ifndef Herwig_GammaGamma2Onium3P2Amplitude_H
+#define Herwig_GammaGamma2Onium3P2Amplitude_H
+//
+// This is the declaration of the GammaGamma2Onium3P2Amplitude class.
+//
+
+#include "Herwig/MatrixElement/Gamma/GammaGammaAmplitude.h"
+#include "OniumParameters.h"
+#include "Herwig/PDT/GenericMassGenerator.h"
+#include "Herwig/Models/StandardModel/StandardModel.h"
+#include "ThePEG/Helicity/WaveFunction/TensorWaveFunction.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * The GammaGamma2Onium3P2Amplitude class implements the matrix element for \f$\gamma\gamma\to^{3}\!\!P_2\f$ quarkonium.
+ *
+ * @see \ref GammaGamma2Onium3P2AmplitudeInterfaces "The interfaces"
+ * defined for GammaGamma2Onium3P2Amplitude.
+ */
+class GammaGamma2Onium3P2Amplitude: public GammaGammaAmplitude {
+
+public:
+
+ /** @name Standard constructors and destructors. */
+ //@{
+ /**
+ * The default constructor.
+ */
+ GammaGamma2Onium3P2Amplitude() : O1_(ZERO), state_(ccbar), n_(1),
+ Lambda2_(sqr(3.0969*GeV)), mOpt_(0)
+ {}
+ //@}
+
+public:
+
+ /** @name Virtual functions required by GammaGammaAmplitude class. */
+ //@{
+ /**
+ * Return the order in \f$\alpha_S\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaS() const {
+ return 0;
+ }
+
+ /**
+ * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaEW() const {
+ return 2;
+ }
+
+ /**
+ * The number of internal degrees of freedom used in the matrix
+ * element.
+ */
+ virtual int nDim(unsigned int) const {
+ return mOpt_;
+ }
+
+ /**
+ * The Feynman diagrams (iopt=0 gamma gamma, iopt=1, e+e-)
+ */
+ virtual vector<DiagPtr> getDiagrams(unsigned int iopt) const;
+
+ /**
+ * The matrix element
+ */
+ virtual double me2(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ const Energy2 & t1, const Energy2 & t2,
+ const Energy2 & scale,
+ const vector<Lorentz5Momentum> & momenta,
+ const cPDVector & partons,
+ DVector & dweights ) const;
+
+ /**
+ * Matrix element for spin correlations
+ */
+ virtual ProductionMatrixElement me(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ tParticleVector & particles) const;
+
+ /**
+ * Generate the mass of the \f$\gamma\gamma\f$ system
+ */
+ virtual Energy generateW(double r, const tcPDVector & partons, Energy Wmin,
+ Energy Wmax, Energy2 & jacW, Energy2 scale);
+
+ /**
+ * Generate internal degrees of freedom given 'nDim()' uniform
+ * random numbers in the interval ]0,1[. To help the phase space
+ * generator, the 'dSigHatDR()' should be a smooth function of these
+ * numbers, although this is not strictly necessary. Return
+ * false if the chosen points failed the kinematical cuts.
+ */
+ virtual double generateKinematics(const double * r,
+ const Energy2 & scale,
+ vector<Lorentz5Momentum> & momenta,
+ const tcPDVector & partons);
+
+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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+protected:
+
+ /**
+ * Calculation of the helicity amplitudes for the process
+ */
+ ProductionMatrixElement helicityAmplitude(const vector<VectorWaveFunction> & v1,
+ const vector<VectorWaveFunction> & v2,
+ const vector<TensorWaveFunction> & ten,
+ const Energy & M, double & output) const;
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ GammaGamma2Onium3P2Amplitude & operator=(const GammaGamma2Onium3P2Amplitude &) = delete;
+
+private:
+
+ /**
+ * Parameters for the form-factors
+ */
+ //@{
+ /**
+ * Access to the parameters for the quarkonium states
+ */
+ OniumParametersPtr params_;
+
+ /**
+ * The \f$O_1\f$ colour-singlet coefficient
+ */
+ Energy5 O1_;
+
+ /**
+ * Type of state
+ */
+ OniumState state_;
+
+ /**
+ * Principal quantum number
+ */
+ unsigned int n_;
+
+ /**
+ * Pole mass squared parameter for the form factors
+ */
+ Energy2 Lambda2_;
+
+ /**
+ * Option for the mass generation
+ */
+ unsigned int mOpt_;
+
+ /**
+ * The mass generator for the Higgs
+ */
+ GenericMassGeneratorPtr massGen_;
+ //@}
+};
+
+}
+
+#endif /* Herwig_GammaGamma2Onium3P2Amplitude_H */
diff --git a/MatrixElement/Onium/MEGGto1D2.cc b/MatrixElement/Onium/MEGGto1D2.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEGGto1D2.cc
@@ -0,0 +1,196 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the MEGGto1D2 class.
+//
+
+#include "MEGGto1D2.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/PDT/EnumParticles.h"
+#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
+#include "ThePEG/Utilities/EnumIO.h"
+#include "ThePEG/Cuts/Cuts.h"
+#include "ThePEG/StandardModel/StandardModelBase.h"
+#include "Herwig/MatrixElement/HardVertex.h"
+#include "ThePEG/Helicity/epsilon.h"
+#include "ThePEG/Helicity/WaveFunction/TensorWaveFunction.h"
+
+using namespace Herwig;
+
+void MEGGto1D2::doinit() {
+ HwMEBase::doinit();
+ // get the non-perturbative ME
+ O1_ = params_->singletMEProduction<2>(state_,n_,0,2);
+ // get the mass generator of the onium state
+ unsigned int iq = 4+state_;
+ long id = iq*110+10005 + (n_-1)*100000;
+ tcPDPtr ps = getParticleData(id);
+ if(!ps)
+ throw Exception() << "No onium particle with id " << id
+ << "in " << fullName();
+ if(ps->massGenerator())
+ massGen_=dynamic_ptr_cast<GenericMassGeneratorPtr>(ps->massGenerator());
+ if(!massGen_)
+ throw Exception() << "Must have mass generator for " << ps->PDGName()
+ << "in " << fullName();
+}
+
+IBPtr MEGGto1D2::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr MEGGto1D2::fullclone() const {
+ return new_ptr(*this);
+}
+
+void MEGGto1D2::persistentOutput(PersistentOStream & os) const {
+ os << params_ << ounit(O1_,GeV*GeV2*GeV2*GeV2) << oenum(state_) << n_ << massGen_;
+}
+
+void MEGGto1D2::persistentInput(PersistentIStream & is, int) {
+ is >> params_ >> iunit(O1_,GeV*GeV2*GeV2*GeV2) >> ienum(state_) >> n_ >> massGen_;
+}
+
+
+// The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<MEGGto1D2,HwMEBase>
+describeHerwigMEGGto1D2("Herwig::MEGGto1D2",
+ "HwOniumParameters.so HwMEHadronOnium.so");
+
+void MEGGto1D2::Init() {
+
+ static ClassDocumentation<MEGGto1D2> documentation
+ ("The MEGGto1D2 class implements the colour singlet matrix element for g g -> 1D2");
+
+ static Reference<MEGGto1D2,OniumParameters> interfaceParameters
+ ("Parameters",
+ "Quarkonium parameters",
+ &MEGGto1D2::params_, false, false, true, false, false);
+
+ static Switch<MEGGto1D2,OniumState> interfaceState
+ ("State",
+ "The type of onium state",
+ &MEGGto1D2::state_, ccbar, false, false);
+ static SwitchOption interfaceStateccbar
+ (interfaceState,
+ "ccbar",
+ "Charmonium state",
+ ccbar);
+ static SwitchOption interfaceStatebbbar
+ (interfaceState,
+ "bbbar",
+ "Bottomonium state",
+ bbbar);
+
+ static Parameter<MEGGto1D2,unsigned int> interfacePrincipalQuantumNumber
+ ("PrincipalQuantumNumber",
+ "The principle quantum number of the states",
+ &MEGGto1D2::n_, 1, 1, 10,
+ false, false, Interface::limited);
+}
+
+void MEGGto1D2::getDiagrams() const {
+ // construct the meson PDG code from quark ids
+ unsigned int iq = 4+state_;
+ tcPDPtr ps = getParticleData(long(iq*110+10005 + (n_-1)*100000));
+ tcPDPtr g = getParticleData(ParticleID::g);
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, ps, -1)));
+}
+
+Energy2 MEGGto1D2::scale() const {
+ return sHat();
+}
+
+int MEGGto1D2::nDim() const {
+ return 0;
+}
+
+Selector<MEBase::DiagramIndex>
+MEGGto1D2::diagrams(const DiagramVector & diags) const {
+ Selector<DiagramIndex> sel;
+ for ( DiagramIndex i = 0; i < diags.size(); ++i ) sel.insert(1.0, i);
+ return sel;
+}
+
+Selector<const ColourLines *>
+MEGGto1D2::colourGeometries(tcDiagPtr) const {
+ static ColourLines cFlow("1 -2, 2 -1");
+ Selector<const ColourLines *> sel;
+ sel.insert(1.0, &cFlow);
+ return sel;
+}
+
+bool MEGGto1D2::generateKinematics(const double * ) {
+ Lorentz5Momentum pout = meMomenta()[0] + meMomenta()[1];
+ pout.rescaleMass();
+ meMomenta()[2].setMass(pout.mass());
+ meMomenta()[2] = LorentzMomentum(pout.x(),pout.y(),pout.z(),pout.t());
+ jacobian(1.0);
+ // check whether it passes all the cuts: returns true if it does
+ vector<LorentzMomentum> out(1,meMomenta()[2]);
+ tcPDVector tout(1,mePartonData()[2]);
+ return lastCuts().passCuts(tout, out, mePartonData()[0], mePartonData()[1]);
+}
+
+CrossSection MEGGto1D2::dSigHatDR() const {
+ return Constants::pi*sqr(hbarc)*me2()*jacobian()*massGen_->BreitWignerWeight(sqrt(sHat()));
+}
+
+double MEGGto1D2::me2() const {
+ return 64./135.*sqr(Constants::pi)*O1_/pow<7,2>(sHat())*sqr(standardModel()->alphaS(scale()));
+}
+
+void MEGGto1D2::constructVertex(tSubProPtr sub) {
+ using namespace ThePEG::Helicity;
+ // extract the particles in the hard process
+ ParticleVector hard;
+ hard.push_back(sub->incoming().first);
+ hard.push_back(sub->incoming().second);
+ hard.push_back(sub->outgoing()[0]);
+ // gluon wave functions (remove zero longitudinal polarization
+ vector<VectorWaveFunction> g1,g2;
+ VectorWaveFunction (g1,hard[0],incoming,false,true,true);
+ g1[1] = g1[2];
+ VectorWaveFunction (g2,hard[1],incoming,false,true,true);
+ g2[1] = g2[2];
+ // 1D2 wavefunction
+ vector<TensorWaveFunction> twave;
+ TensorWaveFunction(twave,hard[2],outgoing,true,false);
+ // matrix element
+ ProductionMatrixElement me(PDT::Spin1,PDT::Spin1,PDT::Spin2);
+
+ Lorentz5Momentum pDiff = hard[0]->momentum()-hard[1]->momentum();
+ Energy M = hard[2]->mass();
+ vector<Complex> tamp(5);
+ for(unsigned int i=0;i<5;++i) {
+ tamp[i] = twave[i].wave().trace()+2./sqr(M)*(twave[i].wave().preDot(pDiff)*pDiff);
+ }
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // auto vOff = epsilon(g1[ih1].wave(),hard[0]->momentum(),hard[1]->momentum());
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // Complex vamp = (vOff*g2[ih2].wave())/sqr(M);
+ // for(unsigned int ih3=0;ih3<5;++ih3) {
+ // me(2*ih1,2*ih2,ih3) = tamp[ih3]*vamp*Complex(0,1)*sqrt(1.5);
+ // }
+ // }
+ // }
+ me(0,0,2) = -1.;
+ me(2,2,2) = 1.;
+ // construct the vertex
+ HardVertexPtr hardvertex = new_ptr(HardVertex());
+ // // set the matrix element for the vertex
+ hardvertex->ME(me);
+ // set the pointers and to and from the vertex
+ for(unsigned int i = 0; i < 3; ++i)
+ hard[i]->spinInfo()->productionVertex(hardvertex);
+}
diff --git a/MatrixElement/Onium/MEGGto1D2.h b/MatrixElement/Onium/MEGGto1D2.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEGGto1D2.h
@@ -0,0 +1,224 @@
+// -*- C++ -*-
+#ifndef Herwig_MEGGto1D2_H
+#define Herwig_MEGGto1D2_H
+//
+// This is the declaration of the MEGGto1D2 class.
+//
+
+#include "Herwig/MatrixElement/HwMEBase.h"
+#include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
+#include "Herwig/PDT/GenericMassGenerator.h"
+#include "Herwig/MatrixElement/ProductionMatrixElement.h"
+#include "OniumParameters.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * The MEGGto1D2 class implements the colour singlet matrix element for \f$gg\to^1\!\!D_2\f$ quarkonium.
+ *
+ * @see \ref MEGGto1D2Interfaces "The interfaces"
+ * defined for MEGGto1D2.
+ */
+class MEGGto1D2: public HwMEBase {
+
+public:
+
+ /** @name Standard constructors and destructors. */
+ //@{
+ /**
+ * The default constructor.
+ */
+ MEGGto1D2() : O1_(ZERO), state_(ccbar), n_(1)
+ {}
+ //@}
+
+public:
+
+ /** @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 2;
+ }
+
+ /**
+ * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaEW() const {
+ return 0;
+ }
+
+ /**
+ * 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;
+
+ /**
+ * The number of internal degrees of freedom used in the matrix
+ * element.
+ */
+ virtual int nDim() const;
+
+ /**
+ * Generate internal degrees of freedom given nDim() uniform
+ * random numbers in the interval \f$ ]0,1[ \f$. To help the phase space
+ * generator, the dSigHatDR should be a smooth function of these
+ * numbers, although this is not strictly necessary.
+ * @param r a pointer to the first of nDim() consecutive random numbers.
+ * @return true if the generation succeeded, otherwise false.
+ */
+ virtual bool generateKinematics(const double * r);
+
+ /**
+ * Return the matrix element squared differential in the variables
+ * given by the last call to generateKinematics().
+ */
+ virtual CrossSection dSigHatDR() 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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ MEGGto1D2 & operator=(const MEGGto1D2 &) = delete;
+
+private:
+
+ /**
+ * Parameters for the form-factors
+ */
+ //@{
+ /**
+ * Access to the parameters for the quarkonium states
+ */
+ OniumParametersPtr params_;
+
+ /**
+ * The \f$O_1\f$ colour-singlet coefficient
+ */
+ Energy7 O1_;
+
+ /**
+ * Type of state
+ */
+ OniumState state_;
+
+ /**
+ * Principal quantum number
+ */
+ unsigned int n_;
+
+ /**
+ * The mass generator for the Higgs
+ */
+ GenericMassGeneratorPtr massGen_;
+ //@}
+};
+
+}
+
+#endif /* Herwig_MEGGto1D2_H */
diff --git a/MatrixElement/Onium/MEGGto1S0.cc b/MatrixElement/Onium/MEGGto1S0.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEGGto1S0.cc
@@ -0,0 +1,184 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the MEGGto1S0 class.
+//
+
+#include "MEGGto1S0.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/PDT/EnumParticles.h"
+#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
+#include "ThePEG/Utilities/EnumIO.h"
+#include "ThePEG/Cuts/Cuts.h"
+#include "ThePEG/StandardModel/StandardModelBase.h"
+#include "Herwig/MatrixElement/HardVertex.h"
+#include "ThePEG/Helicity/epsilon.h"
+
+using namespace Herwig;
+
+void MEGGto1S0::doinit() {
+ HwMEBase::doinit();
+ // get the non-perturbative ME
+ O1_ = params_->singletMEProduction<0>(state_,n_,0,0);
+ // get the mass generator of the onium state
+ unsigned int iq = 4+state_;
+ long id = iq*110+1 + (n_-1)*100000;
+ tcPDPtr ps = getParticleData(id);
+ if(!ps)
+ throw Exception() << "No onium particle with id " << id
+ << "in " << fullName();
+ if(ps->massGenerator())
+ massGen_=dynamic_ptr_cast<GenericMassGeneratorPtr>(ps->massGenerator());
+ if(!massGen_)
+ throw Exception() << "Must have mass generator for " << ps->PDGName()
+ << "in " << fullName();
+}
+
+IBPtr MEGGto1S0::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr MEGGto1S0::fullclone() const {
+ return new_ptr(*this);
+}
+
+void MEGGto1S0::persistentOutput(PersistentOStream & os) const {
+ os << params_ << ounit(O1_,GeV*GeV2) << oenum(state_) << n_ << massGen_;
+}
+
+void MEGGto1S0::persistentInput(PersistentIStream & is, int) {
+ is >> params_ >> iunit(O1_,GeV*GeV2) >> ienum(state_) >> n_ >> massGen_;
+}
+
+
+// The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<MEGGto1S0,HwMEBase>
+describeHerwigMEGGto1S0("Herwig::MEGGto1S0",
+ "HwOniumParameters.so HwMEHadronOnium.so");
+
+void MEGGto1S0::Init() {
+
+ static ClassDocumentation<MEGGto1S0> documentation
+ ("The MEGGto1S0 class implements the colour singlet matrix element for g g -> 1S0");
+
+ static Reference<MEGGto1S0,OniumParameters> interfaceParameters
+ ("Parameters",
+ "Quarkonium parameters",
+ &MEGGto1S0::params_, false, false, true, false, false);
+
+ static Switch<MEGGto1S0,OniumState> interfaceState
+ ("State",
+ "The type of onium state",
+ &MEGGto1S0::state_, ccbar, false, false);
+ static SwitchOption interfaceStateccbar
+ (interfaceState,
+ "ccbar",
+ "Charmonium state",
+ ccbar);
+ static SwitchOption interfaceStatebbbar
+ (interfaceState,
+ "bbbar",
+ "Bottomonium state",
+ bbbar);
+
+ static Parameter<MEGGto1S0,unsigned int> interfacePrincipalQuantumNumber
+ ("PrincipalQuantumNumber",
+ "The principle quantum number of the states",
+ &MEGGto1S0::n_, 1, 1, 10,
+ false, false, Interface::limited);
+}
+
+void MEGGto1S0::getDiagrams() const {
+ // construct the meson PDG code from quark ids
+ unsigned int iq = 4+state_;
+ tcPDPtr ps = getParticleData(long(iq*110+1 + (n_-1)*100000));
+ tcPDPtr g = getParticleData(ParticleID::g);
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, ps, -1)));
+}
+
+Energy2 MEGGto1S0::scale() const {
+ return sHat();
+}
+
+int MEGGto1S0::nDim() const {
+ return 0;
+}
+
+Selector<MEBase::DiagramIndex>
+MEGGto1S0::diagrams(const DiagramVector & diags) const {
+ Selector<DiagramIndex> sel;
+ for ( DiagramIndex i = 0; i < diags.size(); ++i ) sel.insert(1.0, i);
+ return sel;
+}
+
+Selector<const ColourLines *>
+MEGGto1S0::colourGeometries(tcDiagPtr) const {
+ static ColourLines cFlow("1 -2, 2 -1");
+ Selector<const ColourLines *> sel;
+ sel.insert(1.0, &cFlow);
+ return sel;
+}
+
+bool MEGGto1S0::generateKinematics(const double * ) {
+ Lorentz5Momentum pout = meMomenta()[0] + meMomenta()[1];
+ pout.rescaleMass();
+ meMomenta()[2].setMass(pout.mass());
+ meMomenta()[2] = LorentzMomentum(pout.x(),pout.y(),pout.z(),pout.t());
+ jacobian(1.0);
+ // check whether it passes all the cuts: returns true if it does
+ vector<LorentzMomentum> out(1,meMomenta()[2]);
+ tcPDVector tout(1,mePartonData()[2]);
+ return lastCuts().passCuts(tout, out, mePartonData()[0], mePartonData()[1]);
+}
+
+CrossSection MEGGto1S0::dSigHatDR() const {
+ return Constants::pi*sqr(hbarc)*me2()*jacobian()*massGen_->BreitWignerWeight(sqrt(sHat()));
+}
+
+double MEGGto1S0::me2() const {
+ return 2.*sqr(Constants::pi)*O1_/9./sHat()/sqrt(sHat())*sqr(standardModel()->alphaS(scale()));
+}
+
+void MEGGto1S0::constructVertex(tSubProPtr sub) {
+ using namespace ThePEG::Helicity;
+ // extract the particles in the hard process
+ ParticleVector hard;
+ hard.push_back(sub->incoming().first);
+ hard.push_back(sub->incoming().second);
+ hard.push_back(sub->outgoing()[0]);
+ // gluon wave functions (remove zero longitudinal polarization
+ vector<VectorWaveFunction> g1,g2;
+ VectorWaveFunction (g1,hard[0],incoming,false,true,true);
+ g1[1] = g1[2];
+ VectorWaveFunction (g2,hard[1],incoming,false,true,true);
+ g2[1] = g2[2];
+ // 1S0 wavefunction
+ ScalarWaveFunction out(hard[2],outgoing,true);
+ // matrix element
+ ProductionMatrixElement me(PDT::Spin1,PDT::Spin1,PDT::Spin0);
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // auto vOff = Helicity::epsilon(g1[ih1].wave(),hard[0]->momentum(),hard[1]->momentum());
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // me(2*ih1,2*ih2,0) = Complex(0,-2.)*(vOff*g2[ih2].wave())/sqr(hard[2]->mass());
+ // }
+ // }
+ me(0,0,0) = 1.;
+ me(2,2,0) = -1.;
+ // construct the vertex
+ HardVertexPtr hardvertex = new_ptr(HardVertex());
+ // // set the matrix element for the vertex
+ hardvertex->ME(me);
+ // set the pointers and to and from the vertex
+ for(unsigned int i = 0; i < 3; ++i)
+ hard[i]->spinInfo()->productionVertex(hardvertex);
+}
diff --git a/MatrixElement/Onium/MEGGto1S0.h b/MatrixElement/Onium/MEGGto1S0.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEGGto1S0.h
@@ -0,0 +1,225 @@
+// -*- C++ -*-
+#ifndef Herwig_MEGGto1S0_H
+#define Herwig_MEGGto1S0_H
+//
+// This is the declaration of the MEGGto1S0 class.
+//
+
+#include "Herwig/MatrixElement/HwMEBase.h"
+#include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
+#include "Herwig/PDT/GenericMassGenerator.h"
+#include "Herwig/MatrixElement/ProductionMatrixElement.h"
+#include "OniumParameters.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * The MEGGto1S0 class implements the colour singlet matrix element for
+ * \f$gg\to^1\!\!S_0\f$.
+ *
+ * @see \ref MEGGto1S0Interfaces "The interfaces"
+ * defined for MEGGto1S0.
+ */
+class MEGGto1S0: public HwMEBase {
+
+public:
+
+ /** @name Standard constructors and destructors. */
+ //@{
+ /**
+ * The default constructor.
+ */
+ MEGGto1S0() : O1_(ZERO), state_(ccbar), n_(1)
+ {}
+ //@}
+
+public:
+
+ /** @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 2;
+ }
+
+ /**
+ * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaEW() const {
+ return 0;
+ }
+
+ /**
+ * 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;
+
+ /**
+ * The number of internal degrees of freedom used in the matrix
+ * element.
+ */
+ virtual int nDim() const;
+
+ /**
+ * Generate internal degrees of freedom given nDim() uniform
+ * random numbers in the interval \f$ ]0,1[ \f$. To help the phase space
+ * generator, the dSigHatDR should be a smooth function of these
+ * numbers, although this is not strictly necessary.
+ * @param r a pointer to the first of nDim() consecutive random numbers.
+ * @return true if the generation succeeded, otherwise false.
+ */
+ virtual bool generateKinematics(const double * r);
+
+ /**
+ * Return the matrix element squared differential in the variables
+ * given by the last call to generateKinematics().
+ */
+ virtual CrossSection dSigHatDR() 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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ MEGGto1S0 & operator=(const MEGGto1S0 &) = delete;
+
+private:
+
+ /**
+ * Parameters for the form-factors
+ */
+ //@{
+ /**
+ * Access to the parameters for the quarkonium states
+ */
+ OniumParametersPtr params_;
+
+ /**
+ * The \f$O_1\f$ colour-singlet coefficient
+ */
+ Energy3 O1_;
+
+ /**
+ * Type of state
+ */
+ OniumState state_;
+
+ /**
+ * Principal quantum number
+ */
+ unsigned int n_;
+
+ /**
+ * The mass generator for the onium state
+ */
+ GenericMassGeneratorPtr massGen_;
+ //@}
+};
+
+}
+
+#endif /* Herwig_MEGGto1S0_H */
diff --git a/MatrixElement/Onium/MEGGto3P0.cc b/MatrixElement/Onium/MEGGto3P0.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEGGto3P0.cc
@@ -0,0 +1,183 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the MEGGto3P0 class.
+//
+
+#include "MEGGto3P0.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/PDT/EnumParticles.h"
+#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
+#include "ThePEG/Utilities/EnumIO.h"
+#include "ThePEG/Cuts/Cuts.h"
+#include "ThePEG/StandardModel/StandardModelBase.h"
+#include "Herwig/MatrixElement/HardVertex.h"
+
+using namespace Herwig;
+
+void MEGGto3P0::doinit() {
+ HwMEBase::doinit();
+ // get the non-perturbative ME
+ O1_ = params_->singletMEProduction<1>(state_,n_,1,0);
+ // get the mass generator of the onium state
+ unsigned int iq = 4+state_;
+ long id = iq*110+10001 + (n_-1)*100000;
+ tcPDPtr ps = getParticleData(id);
+ if(!ps)
+ throw Exception() << "No onium particle with id " << id
+ << "in " << fullName();
+ if(ps->massGenerator())
+ massGen_=dynamic_ptr_cast<GenericMassGeneratorPtr>(ps->massGenerator());
+ if(!massGen_)
+ throw Exception() << "Must have mass generator for " << ps->PDGName()
+ << "in " << fullName();
+}
+
+IBPtr MEGGto3P0::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr MEGGto3P0::fullclone() const {
+ return new_ptr(*this);
+}
+
+void MEGGto3P0::persistentOutput(PersistentOStream & os) const {
+ os << params_ << ounit(O1_,GeV*GeV2*GeV2) << oenum(state_) << n_ << massGen_;
+}
+
+void MEGGto3P0::persistentInput(PersistentIStream & is, int) {
+ is >> params_ >> iunit(O1_,GeV*GeV2*GeV2) >> ienum(state_) >> n_ >> massGen_;
+}
+
+
+// The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<MEGGto3P0,HwMEBase>
+describeHerwigMEGGto3P0("Herwig::MEGGto3P0",
+ "HwOniumParameters.so HwMEHadronOnium.so");
+
+void MEGGto3P0::Init() {
+
+ static ClassDocumentation<MEGGto3P0> documentation
+ ("The MEGGto3P0 class implements the colour singlet matrix element for g g -> 3P0");
+
+ static Reference<MEGGto3P0,OniumParameters> interfaceParameters
+ ("Parameters",
+ "Quarkonium parameters",
+ &MEGGto3P0::params_, false, false, true, false, false);
+
+ static Switch<MEGGto3P0,OniumState> interfaceState
+ ("State",
+ "The type of onium state",
+ &MEGGto3P0::state_, ccbar, false, false);
+ static SwitchOption interfaceStateccbar
+ (interfaceState,
+ "ccbar",
+ "Charmonium state",
+ ccbar);
+ static SwitchOption interfaceStatebbbar
+ (interfaceState,
+ "bbbar",
+ "Bottomonium state",
+ bbbar);
+
+ static Parameter<MEGGto3P0,unsigned int> interfacePrincipalQuantumNumber
+ ("PrincipalQuantumNumber",
+ "The principle quantum number of the states",
+ &MEGGto3P0::n_, 1, 1, 10,
+ false, false, Interface::limited);
+}
+
+void MEGGto3P0::getDiagrams() const {
+ // construct the meson PDG code from quark ids
+ unsigned int iq = 4+state_;
+ tcPDPtr ps = getParticleData(long(iq*110+10001 + (n_-1)*100000));
+ tcPDPtr g = getParticleData(ParticleID::g);
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, ps, -1)));
+}
+
+Energy2 MEGGto3P0::scale() const {
+ return sHat();
+}
+
+int MEGGto3P0::nDim() const {
+ return 0;
+}
+
+Selector<MEBase::DiagramIndex>
+MEGGto3P0::diagrams(const DiagramVector & diags) const {
+ Selector<DiagramIndex> sel;
+ for ( DiagramIndex i = 0; i < diags.size(); ++i ) sel.insert(1.0, i);
+ return sel;
+}
+
+Selector<const ColourLines *>
+MEGGto3P0::colourGeometries(tcDiagPtr) const {
+ static ColourLines cFlow("1 -2, 2 -1");
+ Selector<const ColourLines *> sel;
+ sel.insert(1.0, &cFlow);
+ return sel;
+}
+
+bool MEGGto3P0::generateKinematics(const double * ) {
+ Lorentz5Momentum pout = meMomenta()[0] + meMomenta()[1];
+ pout.rescaleMass();
+ meMomenta()[2].setMass(pout.mass());
+ meMomenta()[2] = LorentzMomentum(pout.x(),pout.y(),pout.z(),pout.t());
+ jacobian(1.0);
+ // check whether it passes all the cuts: returns true if it does
+ vector<LorentzMomentum> out(1,meMomenta()[2]);
+ tcPDVector tout(1,mePartonData()[2]);
+ return lastCuts().passCuts(tout, out, mePartonData()[0], mePartonData()[1]);
+}
+
+CrossSection MEGGto3P0::dSigHatDR() const {
+ return Constants::pi*sqr(hbarc)*me2()*jacobian()*massGen_->BreitWignerWeight(sqrt(sHat()));
+}
+
+double MEGGto3P0::me2() const {
+ return 8.*sqr(Constants::pi)*O1_/3./sqr(sHat())/sqrt(sHat())*sqr(standardModel()->alphaS(scale()));
+}
+
+void MEGGto3P0::constructVertex(tSubProPtr sub) {
+ using namespace ThePEG::Helicity;
+ // extract the particles in the hard process
+ ParticleVector hard;
+ hard.push_back(sub->incoming().first);
+ hard.push_back(sub->incoming().second);
+ hard.push_back(sub->outgoing()[0]);
+ // gluon wave functions (remove zero longitudinal polarization
+ vector<VectorWaveFunction> g1,g2;
+ VectorWaveFunction (g1,hard[0],incoming,false,true,true);
+ g1[1] = g1[2];
+ VectorWaveFunction (g2,hard[1],incoming,false,true,true);
+ g2[1] = g2[2];
+ // 1S0 wavefunction
+ ScalarWaveFunction out(hard[2],outgoing,true);
+ // matrix element
+ ProductionMatrixElement me(PDT::Spin1,PDT::Spin1,PDT::Spin0);
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // complex<Energy> d1 = g1[ih1].wave()*hard[1]->momentum();
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // me(2*ih1,2*ih2,0) = g1[ih1].wave()*g2[ih2].wave() -2./sqr(hard[2]->mass())*d1*(g2[ih2].wave()*hard[0]->momentum());
+ // }
+ // }
+ me(0,0,0) = 1.;
+ me(2,2,0) = -1.;
+ // construct the vertex
+ HardVertexPtr hardvertex = new_ptr(HardVertex());
+ // // set the matrix element for the vertex
+ hardvertex->ME(me);
+ // set the pointers and to and from the vertex
+ for(unsigned int i = 0; i < 3; ++i)
+ hard[i]->spinInfo()->productionVertex(hardvertex);
+}
diff --git a/MatrixElement/Onium/MEGGto3P0.h b/MatrixElement/Onium/MEGGto3P0.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEGGto3P0.h
@@ -0,0 +1,224 @@
+// -*- C++ -*-
+#ifndef Herwig_MEGGto3P0_H
+#define Herwig_MEGGto3P0_H
+//
+// This is the declaration of the MEGGto3P0 class.
+//
+
+#include "Herwig/MatrixElement/HwMEBase.h"
+#include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
+#include "Herwig/PDT/GenericMassGenerator.h"
+#include "Herwig/MatrixElement/ProductionMatrixElement.h"
+#include "OniumParameters.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * The MEGGto3P0 class implements the colour singlet matrix element for \f$gg\to^3\!\!P_0\f$ quarkonium.
+ *
+ * @see \ref MEGGto3P0Interfaces "The interfaces"
+ * defined for MEGGto3P0.
+ */
+class MEGGto3P0: public HwMEBase {
+
+public:
+
+ /** @name Standard constructors and destructors. */
+ //@{
+ /**
+ * The default constructor.
+ */
+ MEGGto3P0() : O1_(ZERO), state_(ccbar), n_(1)
+ {}
+ //@}
+
+public:
+
+ /** @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 2;
+ }
+
+ /**
+ * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaEW() const {
+ return 0;
+ }
+
+ /**
+ * 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;
+
+ /**
+ * The number of internal degrees of freedom used in the matrix
+ * element.
+ */
+ virtual int nDim() const;
+
+ /**
+ * Generate internal degrees of freedom given nDim() uniform
+ * random numbers in the interval \f$ ]0,1[ \f$. To help the phase space
+ * generator, the dSigHatDR should be a smooth function of these
+ * numbers, although this is not strictly necessary.
+ * @param r a pointer to the first of nDim() consecutive random numbers.
+ * @return true if the generation succeeded, otherwise false.
+ */
+ virtual bool generateKinematics(const double * r);
+
+ /**
+ * Return the matrix element squared differential in the variables
+ * given by the last call to generateKinematics().
+ */
+ virtual CrossSection dSigHatDR() 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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ MEGGto3P0 & operator=(const MEGGto3P0 &) = delete;
+
+private:
+
+ /**
+ * Parameters for the form-factors
+ */
+ //@{
+ /**
+ * Access to the parameters for the quarkonium states
+ */
+ OniumParametersPtr params_;
+
+ /**
+ * The \f$O_1\f$ colour-singlet coefficient
+ */
+ Energy5 O1_;
+
+ /**
+ * Type of state
+ */
+ OniumState state_;
+
+ /**
+ * Principal quantum number
+ */
+ unsigned int n_;
+
+ /**
+ * The mass generator for the Higgs
+ */
+ GenericMassGeneratorPtr massGen_;
+ //@}
+};
+
+}
+
+#endif /* Herwig_MEGGto3P0_H */
diff --git a/MatrixElement/Onium/MEGGto3P2.cc b/MatrixElement/Onium/MEGGto3P2.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEGGto3P2.cc
@@ -0,0 +1,208 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the MEGGto3P2 class.
+//
+
+#include "MEGGto3P2.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/PDT/EnumParticles.h"
+#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
+#include "ThePEG/Utilities/EnumIO.h"
+#include "ThePEG/Cuts/Cuts.h"
+#include "ThePEG/StandardModel/StandardModelBase.h"
+#include "Herwig/MatrixElement/HardVertex.h"
+#include "ThePEG/Helicity/WaveFunction/TensorWaveFunction.h"
+
+using namespace Herwig;
+
+void MEGGto3P2::doinit() {
+ HwMEBase::doinit();
+ // get the non-perturbative ME
+ O1_ = params_->singletMEProduction<1>(state_,n_,1,2);
+ // get the mass generator of the onium state
+ unsigned int iq = 4+state_;
+ long id = iq*110+5 + (n_-1)*100000;
+ tcPDPtr ps = getParticleData(id);
+ if(!ps)
+ throw Exception() << "No onium particle with id " << id
+ << "in " << fullName();
+ if(ps->massGenerator())
+ massGen_=dynamic_ptr_cast<GenericMassGeneratorPtr>(ps->massGenerator());
+ if(!massGen_)
+ throw Exception() << "Must have mass generator for " << ps->PDGName()
+ << "in " << fullName();
+}
+
+IBPtr MEGGto3P2::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr MEGGto3P2::fullclone() const {
+ return new_ptr(*this);
+}
+
+void MEGGto3P2::persistentOutput(PersistentOStream & os) const {
+ os << params_ << ounit(O1_,GeV*GeV2*GeV2) << oenum(state_) << n_ << massGen_;
+}
+
+void MEGGto3P2::persistentInput(PersistentIStream & is, int) {
+ is >> params_ >> iunit(O1_,GeV*GeV2*GeV2) >> ienum(state_) >> n_ >> massGen_;
+}
+
+
+// The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<MEGGto3P2,HwMEBase>
+describeHerwigMEGGto3P2("Herwig::MEGGto3P2",
+ "HwOniumParameters.so HwMEHadronOnium.so");
+
+void MEGGto3P2::Init() {
+
+ static ClassDocumentation<MEGGto3P2> documentation
+ ("The MEGGto3P2 class implements the colour singlet matrix element for g g -> 3P2");
+
+ static Reference<MEGGto3P2,OniumParameters> interfaceParameters
+ ("Parameters",
+ "Quarkonium parameters",
+ &MEGGto3P2::params_, false, false, true, false, false);
+
+ static Switch<MEGGto3P2,OniumState> interfaceState
+ ("State",
+ "The type of onium state",
+ &MEGGto3P2::state_, ccbar, false, false);
+ static SwitchOption interfaceStateccbar
+ (interfaceState,
+ "ccbar",
+ "Charmonium state",
+ ccbar);
+ static SwitchOption interfaceStatebbbar
+ (interfaceState,
+ "bbbar",
+ "Bottomonium state",
+ bbbar);
+
+ static Parameter<MEGGto3P2,unsigned int> interfacePrincipalQuantumNumber
+ ("PrincipalQuantumNumber",
+ "The principle quantum number of the states",
+ &MEGGto3P2::n_, 1, 1, 10,
+ false, false, Interface::limited);
+}
+
+void MEGGto3P2::getDiagrams() const {
+ // construct the meson PDG code from quark ids
+ unsigned int iq = 4+state_;
+ tcPDPtr ps = getParticleData(long(iq*110+5 + (n_-1)*100000));
+ tcPDPtr g = getParticleData(ParticleID::g);
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, ps, -1)));
+}
+
+Energy2 MEGGto3P2::scale() const {
+ return sHat();
+}
+
+int MEGGto3P2::nDim() const {
+ return 0;
+}
+
+Selector<MEBase::DiagramIndex>
+MEGGto3P2::diagrams(const DiagramVector & diags) const {
+ Selector<DiagramIndex> sel;
+ for ( DiagramIndex i = 0; i < diags.size(); ++i ) sel.insert(1.0, i);
+ return sel;
+}
+
+Selector<const ColourLines *>
+MEGGto3P2::colourGeometries(tcDiagPtr) const {
+ static ColourLines cFlow("1 -2, 2 -1");
+ Selector<const ColourLines *> sel;
+ sel.insert(1.0, &cFlow);
+ return sel;
+}
+
+bool MEGGto3P2::generateKinematics(const double * ) {
+ Lorentz5Momentum pout = meMomenta()[0] + meMomenta()[1];
+ pout.rescaleMass();
+ meMomenta()[2].setMass(pout.mass());
+ meMomenta()[2] = LorentzMomentum(pout.x(),pout.y(),pout.z(),pout.t());
+ jacobian(1.0);
+ // check whether it passes all the cuts: returns true if it does
+ vector<LorentzMomentum> out(1,meMomenta()[2]);
+ tcPDVector tout(1,mePartonData()[2]);
+ return lastCuts().passCuts(tout, out, mePartonData()[0], mePartonData()[1]);
+}
+
+CrossSection MEGGto3P2::dSigHatDR() const {
+ return Constants::pi*sqr(hbarc)*me2()*jacobian()*massGen_->BreitWignerWeight(sqrt(sHat()));
+}
+
+double MEGGto3P2::me2() const {
+ return 32./45.*sqr(Constants::pi)*O1_/sqr(sHat())/sqrt(sHat())*sqr(standardModel()->alphaS(scale()));
+}
+
+void MEGGto3P2::constructVertex(tSubProPtr sub) {
+ using namespace ThePEG::Helicity;
+ // extract the particles in the hard process
+ ParticleVector hard;
+ hard.push_back(sub->incoming().first);
+ hard.push_back(sub->incoming().second);
+ hard.push_back(sub->outgoing()[0]);
+ // gluon wave functions (remove zero longitudinal polarization
+ vector<VectorWaveFunction> g1,g2;
+ VectorWaveFunction (g1,hard[0],incoming,false,true,true);
+ g1[1] = g1[2];
+ VectorWaveFunction (g2,hard[1],incoming,false,true,true);
+ g2[1] = g2[2];
+ // 3P2 wavefunction
+ vector<TensorWaveFunction> twave;
+ TensorWaveFunction(twave,hard[2],outgoing,true,false);
+ // matrix element
+ ProductionMatrixElement me(PDT::Spin1,PDT::Spin1,PDT::Spin2);
+ if(hard[2]->momentum().z()>ZERO) {
+ me(0,2,0) = 1.;
+ me(2,0,4) = 1.;
+ }
+ else {
+ me(0,2,4) = 1.;
+ me(2,0,0) = 1.;
+ }
+ // Lorentz5Momentum pDiff = hard[0]->momentum()-hard[1]->momentum();
+ // Energy M = hard[2]->mass();
+ // for(unsigned int ih3=0;ih3<5;++ih3) {
+ // auto vPre = twave[ih3].wave().preDot (pDiff);
+ // auto vPost = twave[ih3].wave().postDot(pDiff);
+ // complex<Energy2> g1g2=vPre*pDiff;
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // auto vEps1 = twave[ih3].wave().preDot(g1[ih1].wave())+twave[ih3].wave().postDot(g1[ih1].wave());
+ // complex<Energy> dPreEps1 = vPre*g1[ih1].wave();
+ // complex<Energy> dPostEps1 = vPost*g1[ih1].wave();
+ // complex<Energy> d1 = g1[ih1].wave()*hard[1]->momentum();
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // complex<Energy> d2 = g2[ih2].wave()*hard[0]->momentum();
+ // Complex d12 = g1[ih1].wave()*g2[ih2].wave();
+ // Complex amp = 0.5*(((dPreEps1+dPostEps1)*d2 -(vPre*g2[ih2].wave()+vPost*g2[ih2].wave())*d1-g1g2*d12)/sqr(M) + vEps1*g2[ih2].wave());
+ // if(norm(amp)>1e-10) {
+ // Complex diff = amp-me(2*ih1,2*ih2,ih3);
+ // if(abs(diff)>1e-10)
+ // cerr << "testing me " << ih1 << " " << ih2 << " " << ih3 << " " << diff << "\n";
+ // }
+ // }
+ // }
+ // }
+ // construct the vertex
+ HardVertexPtr hardvertex = new_ptr(HardVertex());
+ // // set the matrix element for the vertex
+ hardvertex->ME(me);
+ // set the pointers and to and from the vertex
+ for(unsigned int i = 0; i < 3; ++i)
+ hard[i]->spinInfo()->productionVertex(hardvertex);
+}
diff --git a/MatrixElement/Onium/MEGGto3P2.h b/MatrixElement/Onium/MEGGto3P2.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEGGto3P2.h
@@ -0,0 +1,224 @@
+// -*- C++ -*-
+#ifndef Herwig_MEGGto3P2_H
+#define Herwig_MEGGto3P2_H
+//
+// This is the declaration of the MEGGto3P2 class.
+//
+
+#include "Herwig/MatrixElement/HwMEBase.h"
+#include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
+#include "Herwig/PDT/GenericMassGenerator.h"
+#include "Herwig/MatrixElement/ProductionMatrixElement.h"
+#include "OniumParameters.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * The MEGGto3P2 class implements the colour singlet matrix element for \f$gg\to^3\!\!P_2\f$ quarkonium.
+ *
+ * @see \ref MEGGto3P2Interfaces "The interfaces"
+ * defined for MEGGto3P2.
+ */
+class MEGGto3P2: public HwMEBase {
+
+public:
+
+ /** @name Standard constructors and destructors. */
+ //@{
+ /**
+ * The default constructor.
+ */
+ MEGGto3P2() : O1_(ZERO), state_(ccbar), n_(1)
+ {}
+ //@}
+
+public:
+
+ /** @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 2;
+ }
+
+ /**
+ * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaEW() const {
+ return 0;
+ }
+
+ /**
+ * 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;
+
+ /**
+ * The number of internal degrees of freedom used in the matrix
+ * element.
+ */
+ virtual int nDim() const;
+
+ /**
+ * Generate internal degrees of freedom given nDim() uniform
+ * random numbers in the interval \f$ ]0,1[ \f$. To help the phase space
+ * generator, the dSigHatDR should be a smooth function of these
+ * numbers, although this is not strictly necessary.
+ * @param r a pointer to the first of nDim() consecutive random numbers.
+ * @return true if the generation succeeded, otherwise false.
+ */
+ virtual bool generateKinematics(const double * r);
+
+ /**
+ * Return the matrix element squared differential in the variables
+ * given by the last call to generateKinematics().
+ */
+ virtual CrossSection dSigHatDR() 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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ MEGGto3P2 & operator=(const MEGGto3P2 &) = delete;
+
+private:
+
+ /**
+ * Parameters for the form-factors
+ */
+ //@{
+ /**
+ * Access to the parameters for the quarkonium states
+ */
+ OniumParametersPtr params_;
+
+ /**
+ * The \f$O_1\f$ colour-singlet coefficient
+ */
+ Energy5 O1_;
+
+ /**
+ * Type of state
+ */
+ OniumState state_;
+
+ /**
+ * Principal quantum number
+ */
+ unsigned int n_;
+
+ /**
+ * The mass generator for the Higgs
+ */
+ GenericMassGeneratorPtr massGen_;
+ //@}
+};
+
+}
+
+#endif /* Herwig_MEGGto3P2_H */
diff --git a/MatrixElement/Onium/MEPPto1D2Jet.cc b/MatrixElement/Onium/MEPPto1D2Jet.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto1D2Jet.cc
@@ -0,0 +1,852 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the MEPPto1D2Jet class.
+//
+
+#include "MEPPto1D2Jet.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/PDT/EnumParticles.h"
+#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
+#include "ThePEG/Utilities/EnumIO.h"
+#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/TensorWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
+#include "ThePEG/Helicity/epsilon.h"
+#include "ThePEG/StandardModel/StandardModelBase.h"
+#include "Herwig/MatrixElement/ProductionMatrixElement.h"
+#include "Herwig/MatrixElement/HardVertex.h"
+
+using namespace Herwig;
+
+void MEPPto1D2Jet::doinit() {
+ HwMEBase::doinit();
+ // get the non-perturbative ME
+ O1_ = params_->singletMEProduction<2>(state_,n_,0,2);
+ // set the mass option
+ massOption(vector<unsigned int>({mOpt_+1,0}));
+}
+
+IBPtr MEPPto1D2Jet::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr MEPPto1D2Jet::fullclone() const {
+ return new_ptr(*this);
+}
+
+void MEPPto1D2Jet::persistentOutput(PersistentOStream & os) const {
+ os << params_ << ounit(O1_,GeV*GeV2*GeV2*GeV2) << oenum(state_) << n_ << process_ << mOpt_;
+}
+
+void MEPPto1D2Jet::persistentInput(PersistentIStream & is, int) {
+ is >> params_ >> iunit(O1_,GeV*GeV2*GeV2*GeV2) >> ienum(state_) >> n_ >> process_ >> mOpt_;
+}
+
+// The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<MEPPto1D2Jet,HwMEBase>
+describeHerwigMEPPto1D2Jet("Herwig::MEPPto1D2Jet",
+ "HwOniumParameters.so HwMEHadronOnium.so");
+
+void MEPPto1D2Jet::Init() {
+
+ static ClassDocumentation<MEPPto1D2Jet> documentation
+ ("The MEPPto1D2Jet class implements the q qbar -> 1D2 g, g q to 1D2 q"
+ " and g g to 1D2 g processes");
+
+ static Reference<MEPPto1D2Jet,OniumParameters> interfaceParameters
+ ("Parameters",
+ "Quarkonium parameters",
+ &MEPPto1D2Jet::params_, false, false, true, false, false);
+
+ static Switch<MEPPto1D2Jet,OniumState> interfaceState
+ ("State",
+ "The type of onium state",
+ &MEPPto1D2Jet::state_, ccbar, false, false);
+ static SwitchOption interfaceStateccbar
+ (interfaceState,
+ "ccbar",
+ "Charmonium state",
+ ccbar);
+ static SwitchOption interfaceStatebbbar
+ (interfaceState,
+ "bbbar",
+ "Bottomonium state",
+ bbbar);
+
+ static Parameter<MEPPto1D2Jet,unsigned int> interfacePrincipalQuantumNumber
+ ("PrincipalQuantumNumber",
+ "The principle quantum number of the states",
+ &MEPPto1D2Jet::n_, 1, 1, 10,
+ false, false, Interface::limited);
+
+ static Switch<MEPPto1D2Jet,unsigned int> interfaceProcess
+ ("Process",
+ "Which processes to generate",
+ &MEPPto1D2Jet::process_, 0, false, false);
+ static SwitchOption interfaceProcessAll
+ (interfaceProcess,
+ "All",
+ "Generate all the processes",
+ 0);
+ static SwitchOption interfaceProcessGQto1D2Q
+ (interfaceProcess,
+ "GQto1D2Q",
+ "The g q -> 1D2 q process",
+ 1);
+ static SwitchOption interfaceProcessGQbarto1D2Qbar
+ (interfaceProcess,
+ "GQbarto1D2Qbar",
+ "The g qbar -> 1D2 qbar process",
+ 2);
+ static SwitchOption interfaceProcessQQbarto1D2G
+ (interfaceProcess,
+ "QQbarto1D2G",
+ "The q qbar -> 1D2 g process",
+ 3);
+ static SwitchOption interfaceProcessGGto1D2G
+ (interfaceProcess,
+ "GGto1D2G",
+ "The g g -> 1D2 g process",
+ 4);
+
+ static Switch<MEPPto1D2Jet,unsigned int> interfaceMassOption
+ ("MassOption",
+ "Mass of the treatment of the 1D2 mass",
+ &MEPPto1D2Jet::mOpt_, 0, false, false);
+ static SwitchOption interfaceMassOptionOnShell
+ (interfaceMassOption,
+ "OnShell",
+ "Use the on-shell mass",
+ 0);
+ static SwitchOption interfaceMassOptionOffShell
+ (interfaceMassOption,
+ "OffShell",
+ "Use an off-shell mass generated by the MassGenerator object for the 1D2 state.",
+ 1);
+
+}
+
+void MEPPto1D2Jet::getDiagrams() const {
+ // construct the meson PDG code from quark ids
+ unsigned int iq = 4+state_;
+ tcPDPtr ps = getParticleData(long(iq*110+10005 + (n_-1)*100000));
+ tcPDPtr g = getParticleData(ParticleID::g);
+ // processes involving quarks
+ for ( int i = 1; i <= 3; ++i ) {
+ tcPDPtr q = getParticleData(i);
+ tcPDPtr qb = q->CC();
+ if(process_ == 0 || process_ == 1)
+ add(new_ptr((Tree2toNDiagram(3), g, g, q , 1, ps, 2, q , -1)));
+ if(process_ == 0 || process_ == 2)
+ add(new_ptr((Tree2toNDiagram(3), g, g, qb, 1, ps, 2, qb, -2)));
+ if(process_ == 0 || process_ == 3)
+ add(new_ptr((Tree2toNDiagram(2), q, qb, 1, g, 3, ps, 3, g, -3)));
+ }
+ // g g -> 1D2 g (s,t,u 4-point)
+ if(process_ == 0 || process_ == 4) {
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, g, 3, ps, 3, g , -4)));
+ add(new_ptr((Tree2toNDiagram(3), g, g, g, 1, ps, 2, g , -5)));
+ add(new_ptr((Tree2toNDiagram(3), g, g, g, 2, ps, 1, g , -6)));
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, ps, 1, g , -7)));
+ }
+}
+
+Selector<MEBase::DiagramIndex>
+MEPPto1D2Jet::diagrams(const DiagramVector & diags) const {
+ Energy M=meMomenta()[3].mass();
+ Energy2 M2(sqr(M));
+ Selector<DiagramIndex> sel;
+ DVector save(4);
+ if(mePartonData()[1]->id()==ParticleID::g &&
+ mePartonData()[1]->id()==ParticleID::g ) {
+ save[0] = 256*M2*tHat()*uHat()/(3.*sHat()*sqr(tHat()+uHat()));
+ save[1] = 256*M2*tHat()*(sqr(M2)*sqr(sHat())-2*M2*pow<3,1>(sHat())+2*pow<4,1>(sHat())
+ +sqr(M2)*sHat()*tHat()-M2*sqr(sHat())*tHat()+2*pow<3,1>(sHat())*tHat()
+ +sqr(M2)*sqr(tHat())-M2*sHat()*sqr(tHat())+sqr(sHat())*sqr(tHat()))
+ /(3.*sHat()*sqr(M2-uHat())*uHat()*sqr(tHat()+uHat()));
+ save[2] = 256*M2*uHat()*(sqr(M2)*sqr(sHat())-2*M2*pow<3,1>(sHat())+2*pow<4,1>(sHat())
+ +sqr(M2)*sHat()*uHat()-M2*sqr(sHat())*uHat()+2*pow<3,1>(sHat())*uHat()
+ +sqr(M2)*sqr(uHat())-M2*sHat()*sqr(uHat())+sqr(sHat())*sqr(uHat()))
+ /(3.*sHat()*sqr(M2-tHat())*tHat()*sqr(tHat()+uHat()));
+ save[3] = 128*M2*(3*pow<10,1>(M2)*sqr(tHat())-24*pow<9,1>(M2)*pow<3,1>(tHat())+81*pow<8,1>(M2)*pow<4,1>(tHat())
+ -153*pow<7,1>(M2)*pow<5,1>(tHat())+180*pow<6,1>(M2)*pow<6,1>(tHat())-135*pow<5,1>(M2)*pow<7,1>(tHat())
+ +60*pow<4,1>(M2)*pow<8,1>(tHat())-12*pow<3,1>(M2)*pow<9,1>(tHat())+8*pow<10,1>(M2)*tHat()*uHat()
+ -66*pow<9,1>(M2)*sqr(tHat())*uHat()+250*pow<8,1>(M2)*pow<3,1>(tHat())*uHat()
+ -540*pow<7,1>(M2)*pow<4,1>(tHat())*uHat()+731*pow<6,1>(M2)*pow<5,1>(tHat())*uHat()
+ -650*pow<5,1>(M2)*pow<6,1>(tHat())*uHat()+375*pow<4,1>(M2)*pow<7,1>(tHat())*uHat()
+ -126*pow<3,1>(M2)*pow<8,1>(tHat())*uHat()+18*sqr(M2)*pow<9,1>(tHat())*uHat()
+ +3*pow<10,1>(M2)*sqr(uHat())-66*pow<9,1>(M2)*tHat()*sqr(uHat())+358*pow<8,1>(M2)*sqr(tHat())*sqr(uHat())
+ -953*pow<7,1>(M2)*pow<3,1>(tHat())*sqr(uHat())+1439*pow<6,1>(M2)*pow<4,1>(tHat())*sqr(uHat())
+ -1312*pow<5,1>(M2)*pow<5,1>(tHat())*sqr(uHat())+760*pow<4,1>(M2)*pow<6,1>(tHat())*sqr(uHat())
+ -295*pow<3,1>(M2)*pow<7,1>(tHat())*sqr(uHat())+72*sqr(M2)*pow<8,1>(tHat())*sqr(uHat())
+ -6*M2*pow<9,1>(tHat())*sqr(uHat())-24*pow<9,1>(M2)*pow<3,1>(uHat())
+ +250*pow<8,1>(M2)*tHat()*pow<3,1>(uHat())-953*pow<7,1>(M2)*sqr(tHat())*pow<3,1>(uHat())
+ +1930*pow<6,1>(M2)*pow<3,1>(tHat())*pow<3,1>(uHat())-2209*pow<5,1>(M2)*pow<4,1>(tHat())*pow<3,1>(uHat())
+ +1479*pow<4,1>(M2)*pow<5,1>(tHat())*pow<3,1>(uHat())-626*pow<3,1>(M2)*pow<6,1>(tHat())*pow<3,1>(uHat())
+ +161*sqr(M2)*pow<7,1>(tHat())*pow<3,1>(uHat())-6*M2*pow<8,1>(tHat())*pow<3,1>(uHat())
+ +81*pow<8,1>(M2)*pow<4,1>(uHat())-540*pow<7,1>(M2)*tHat()*pow<4,1>(uHat())
+ +1439*pow<6,1>(M2)*sqr(tHat())*pow<4,1>(uHat())-2209*pow<5,1>(M2)*pow<3,1>(tHat())*pow<4,1>(uHat())
+ +1996*pow<4,1>(M2)*pow<4,1>(tHat())*pow<4,1>(uHat())-1115*pow<3,1>(M2)*pow<5,1>(tHat())*pow<4,1>(uHat())
+ +352*sqr(M2)*pow<6,1>(tHat())*pow<4,1>(uHat())-4*M2*pow<7,1>(tHat())*pow<4,1>(uHat())
+ -153*pow<7,1>(M2)*pow<5,1>(uHat())+731*pow<6,1>(M2)*tHat()*pow<5,1>(uHat())
+ -1312*pow<5,1>(M2)*sqr(tHat())*pow<5,1>(uHat())+1479*pow<4,1>(M2)*pow<3,1>(tHat())*pow<5,1>(uHat())
+ -1115*pow<3,1>(M2)*pow<4,1>(tHat())*pow<5,1>(uHat())+490*sqr(M2)*pow<5,1>(tHat())*pow<5,1>(uHat())
+ -24*M2*pow<6,1>(tHat())*pow<5,1>(uHat())+4*pow<7,1>(tHat())*pow<5,1>(uHat())
+ +180*pow<6,1>(M2)*pow<6,1>(uHat())-650*pow<5,1>(M2)*tHat()*pow<6,1>(uHat())
+ +760*pow<4,1>(M2)*sqr(tHat())*pow<6,1>(uHat())-626*pow<3,1>(M2)*pow<3,1>(tHat())*pow<6,1>(uHat())
+ +352*sqr(M2)*pow<4,1>(tHat())*pow<6,1>(uHat())-24*M2*pow<5,1>(tHat())*pow<6,1>(uHat())
+ +8*pow<6,1>(tHat())*pow<6,1>(uHat())-135*pow<5,1>(M2)*pow<7,1>(uHat())
+ +375*pow<4,1>(M2)*tHat()*pow<7,1>(uHat())-295*pow<3,1>(M2)*sqr(tHat())*pow<7,1>(uHat())
+ +161*sqr(M2)*pow<3,1>(tHat())*pow<7,1>(uHat())-4*M2*pow<4,1>(tHat())*pow<7,1>(uHat())
+ +4*pow<5,1>(tHat())*pow<7,1>(uHat())+60*pow<4,1>(M2)*pow<8,1>(uHat())
+ -126*pow<3,1>(M2)*tHat()*pow<8,1>(uHat())+72*sqr(M2)*sqr(tHat())*pow<8,1>(uHat())
+ -6*M2*pow<3,1>(tHat())*pow<8,1>(uHat())-12*pow<3,1>(M2)*pow<9,1>(uHat())
+ +18*sqr(M2)*tHat()*pow<9,1>(uHat())-6*M2*sqr(tHat())*pow<9,1>(uHat()))
+ /(3.*sHat()*pow<4,1>(M2-tHat())*pow<4,1>(M2-uHat())*pow<4,1>(tHat()+uHat()));
+ }
+ for ( DiagramIndex i = 0; i < diags.size(); ++i )
+ if ( diags[i]->id() == -1 ||
+ diags[i]->id() == -2 ||
+ diags[i]->id() == -3 ) sel.insert(1.0, i);
+ else
+ sel.insert(save[abs(diags[i]->id())-4],i);
+ return sel;
+}
+
+Selector<const ColourLines *>
+MEPPto1D2Jet::colourGeometries(tcDiagPtr diag) const {
+ // g q -> 1D2 q
+ static ColourLines cgq ("1 2 5, -1 -2 3");
+ // g qbar -> 1D2 qbar
+ static ColourLines cgqbar("1 2 -3, -1 -2 -5");
+ // q qbar -> 1D2 g
+ static ColourLines cqqbar("1 3 5, -2 -3 -5");
+ // g g -> 1D2 g
+ static ColourLines cs[2]={ColourLines("1 3 5, -1 2, -2 -3 -5"),
+ ColourLines("1 -2, -1 -3 -5, 2 3 5")};
+ static ColourLines ct[2]={ColourLines("1 2 5, -1 -2 3, -3 -5"),
+ ColourLines("1 2 -3, -1 -2 -5, 3 5")};
+ static ColourLines cu[2]={ColourLines("1 5, -1 -2 3, -3 2 -5"),
+ ColourLines("1 2 -3, -1 -5, 3 -2 5")};
+ // 4 point
+ static ColourLines c4[2]={ColourLines("1 -2, 2 4, -1 -4"),
+ ColourLines("1 4, -4 -2, 2 -1")};
+ // create the selector
+ Selector<const ColourLines *> sel;
+ if (diag->id() == -1) sel.insert(1.0, &cgq );
+ else if (diag->id() == -2) sel.insert(1.0, &cgqbar);
+ else if (diag->id() == -3) sel.insert(1.0, &cqqbar);
+ else if (diag->id() == -4) {
+ sel.insert(0.5, &cs[0]);
+ sel.insert(0.5, &cs[1]);
+ }
+ else if (diag->id() == -5) {
+ sel.insert(0.5, &ct[0]);
+ sel.insert(0.5, &ct[1]);
+ }
+ else if (diag->id() == -6) {
+ sel.insert(0.5, &cu[0]);
+ sel.insert(0.5, &cu[1]);
+ }
+ else if (diag->id() == -7) {
+ sel.insert(0.5, &c4[0]);
+ sel.insert(0.5, &c4[1]);
+ }
+ return sel;
+}
+
+Energy2 MEPPto1D2Jet::scale() const {
+ return sHat();
+}
+
+double MEPPto1D2Jet::me2() const {
+ // return value
+ double output(0.);
+ // mass of the 1D2 state
+ Energy M = meMomenta()[2].mass();
+ Energy2 M2 = sqr(meMomenta()[2].mass());
+ if(mePartonData()[0]->id()==ParticleID::g) {
+ // g g -> 1D2 g
+ if(mePartonData()[1]->id()==ParticleID::g) {
+ output = 4.*O1_*pow(Constants::pi*standardModel()->alphaS(scale()),3)
+ /(15.*pow<7,1>(M))/(3.*sHat()*pow<4,1>(M2-tHat())*tHat()*pow<4,1>(M2-uHat())*uHat()*pow<4,1>(tHat()+uHat()))*128*M2*
+ (2*sqr(tHat())*sqr(uHat())*sqr(tHat()+uHat())*pow<4,1>(sqr(tHat())+tHat()*uHat()+sqr(uHat()))
+ +pow<10,1>(M2)*(sqr(tHat())+sqr(uHat()))*(2*sqr(tHat())+3*tHat()*uHat()+2*sqr(uHat()))
+ -4*M2*tHat()*uHat()*pow<3,1>(tHat()+uHat())*sqr(sqr(tHat())+tHat()*uHat()+sqr(uHat()))*
+ (pow<4,1>(tHat())+4*pow<3,1>(tHat())*uHat()-7*sqr(tHat())*sqr(uHat())
+ +4*tHat()*pow<3,1>(uHat())+pow<4,1>(uHat()))-6*pow<9,1>(M2)*(tHat()+uHat())*
+ (2*pow<4,1>(tHat())+2*pow<3,1>(tHat())*uHat()+7*sqr(tHat())*sqr(uHat())+2*tHat()*pow<3,1>(uHat())+2*pow<4,1>(uHat()))
+ +pow<8,1>(M2)*(34*pow<6,1>(tHat())+91*pow<5,1>(tHat())*uHat()+260*pow<4,1>(tHat())*sqr(uHat())+330*pow<3,1>(tHat())*pow<3,1>(uHat())
+ +260*sqr(tHat())*pow<4,1>(uHat())+91*tHat()*pow<5,1>(uHat())+34*pow<6,1>(uHat()))-pow<7,1>(M2)*(tHat()+uHat())*
+ (60*pow<6,1>(tHat())+155*pow<5,1>(tHat())*uHat()+561*pow<4,1>(tHat())*sqr(uHat())+574*pow<3,1>(tHat())*pow<3,1>(uHat())+561*sqr(tHat())*pow<4,1>(uHat())
+ +155*tHat()*pow<5,1>(uHat())+60*pow<6,1>(uHat()))-pow<5,1>(M2)*(tHat()+uHat())*
+ (60*pow<8,1>(tHat())+307*pow<7,1>(tHat())*uHat()+1241*pow<6,1>(tHat())*sqr(uHat())+2043*pow<5,1>(tHat())*pow<3,1>(uHat())+2340*pow<4,1>(tHat())*pow<4,1>(uHat())
+ +2043*pow<3,1>(tHat())*pow<5,1>(uHat())+1241*sqr(tHat())*pow<6,1>(uHat())+307*tHat()*pow<7,1>(uHat())+60*pow<8,1>(uHat()))+pow<6,1>(M2)*
+ (72*pow<8,1>(tHat())+340*pow<7,1>(tHat())*uHat()+1281*pow<6,1>(tHat())*sqr(uHat())+2425*pow<5,1>(tHat())*pow<3,1>(uHat())
+ +2882*pow<4,1>(tHat())*pow<4,1>(uHat())+2425*pow<3,1>(tHat())*pow<5,1>(uHat())+1281*sqr(tHat())*pow<6,1>(uHat())+340*tHat()*pow<7,1>(uHat())
+ +72*pow<8,1>(uHat()))+sqr(M2)*sqr(tHat()+uHat())*(2*pow<10,1>(tHat())+32*pow<9,1>(tHat())*uHat()+164*pow<8,1>(tHat())*sqr(uHat())+190*pow<7,1>(tHat())*pow<3,1>(uHat())
+ +133*pow<6,1>(tHat())*pow<4,1>(uHat())-4*pow<5,1>(tHat())*pow<5,1>(uHat())+133*pow<4,1>(tHat())*pow<6,1>(uHat())
+ +190*pow<3,1>(tHat())*pow<7,1>(uHat())+164*sqr(tHat())*pow<8,1>(uHat())+32*tHat()*pow<9,1>(uHat())+2*pow<10,1>(uHat()))
+ -pow<3,1>(M2)*(tHat()+uHat())*(12*pow<10,1>(tHat())+118*pow<9,1>(tHat())*uHat()+582*pow<8,1>(tHat())*sqr(uHat())
+ +1033*pow<7,1>(tHat())*pow<3,1>(uHat())+1115*pow<6,1>(tHat())*pow<4,1>(uHat())
+ +934*pow<5,1>(tHat())*pow<5,1>(uHat())+1115*pow<4,1>(tHat())*pow<6,1>(uHat())
+ +1033*pow<3,1>(tHat())*pow<7,1>(uHat())+582*sqr(tHat())*pow<8,1>(uHat())+118*tHat()*pow<9,1>(uHat())+12*pow<10,1>(uHat()))
+ +pow<4,1>(M2)*(34*pow<10,1>(tHat())+270*pow<9,1>(tHat())*uHat()+1277*pow<8,1>(tHat())*sqr(uHat())+2868*pow<7,1>(tHat())*pow<3,1>(uHat())
+ +3973*pow<6,1>(tHat())*pow<4,1>(uHat())+4220*pow<5,1>(tHat())*pow<5,1>(uHat())+3973*pow<4,1>(tHat())*pow<6,1>(uHat())
+ +2868*pow<3,1>(tHat())*pow<7,1>(uHat())+1277*sqr(tHat())*pow<8,1>(uHat())+270*tHat()*pow<9,1>(uHat())+34*pow<10,1>(uHat())));
+ // test vs PRD 45, 116
+ // Energy7 R02 = params_->secondDerivativeRadialWaveFunctionSquared(state_,n_);
+ // Energy6 Q(sHat()*tHat()*uHat());
+ // Energy4 P(sHat()*tHat()+tHat()*uHat()+uHat()*sHat());
+ // double test =-16.*Constants::pi*sqr(sHat())*
+ // 40.*Constants::pi*pow(standardModel()->alphaS(scale()),3)*R02/pow<5,1>(M)/Q/sqr(sHat())/pow<4,1>(Q-M2*P)*
+ // (M2*sqr(P)*Q*(5*pow<6,1>(M2)-45*pow<3,1>(M2)*Q+48*sqr(Q)) -
+ // 2*pow<4,1>(P)*(pow<6,1>(M2)-pow<3,1>(M2)*Q+sqr(Q)) +
+ // pow<3,1>(M2)*P*sqr(Q)*(28*pow<3,1>(M2) - 31*Q)-
+ // sqr(M2*P)*P*(13*pow<3,1>(M2)-18*Q)*Q + 4*M2*pow<5,1>(P)*(pow<3,1>(M2)+Q) -
+ // sqr(M2)*(2*pow<6,1>(P) - 33*pow<4,1>(Q)) - 2*pow<8,1>(M2)*sqr(Q) + 43*pow<5,1>(M2)*pow<3,1>(Q));
+ // cerr << "testing matrix element " << output << " " << test << " "
+ // << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ // g qbar -> 1D2 qbar
+ else if(mePartonData()[1]->id()<0) {
+ // helicity amplitude version of ME
+ // VectorWaveFunction g1w(meMomenta()[0],mePartonData()[0],incoming);
+ // SpinorBarWaveFunction q2w(meMomenta()[1],mePartonData()[1],incoming);
+ // TensorWaveFunction t3w(meMomenta()[2],mePartonData()[2],outgoing);
+ // SpinorWaveFunction q4w(meMomenta()[3],mePartonData()[3],outgoing);
+ // vector<VectorWaveFunction> g1;
+ // vector<SpinorBarWaveFunction> q2;
+ // vector<TensorWaveFunction> t3;
+ // vector<SpinorWaveFunction> q4;
+ // for(unsigned int ix=0;ix<2;++ix) {
+ // g1w.reset(2*ix);
+ // g1.push_back(g1w);
+ // q2w.reset(ix);
+ // q2.push_back(q2w);
+ // q4w.reset(ix);
+ // q4.push_back(q4w);
+ // }
+ // for(unsigned int ix=0;ix<5;++ix) {
+ // t3w.reset(ix,tensor_phase);
+ // t3.push_back(t3w);
+ // }
+ // ProductionMatrixElement me(PDT::Spin1,PDT::Spin1Half,PDT::Spin2,PDT::Spin1Half);
+ // double phi = meMomenta()[2].phi();
+ // Complex phase = exp(Complex(0.,phi));
+ // Energy2 th(tHat()),uh(uHat()),sh(sHat()),sm(sHat()-M2),tm(tHat()-M2),um(uHat()-M2);
+ // me(0,0,0,0)=(Complex(0,-8)*sqrt(2)*M*sqr(phase)*sqr(sh)*sqrt(-th)*uh)/(sqr(sm)*sqr(tm));
+ // me(0,0,1,0)=(Complex(0,8)*sqrt(2)*phase*sh*sqrt(sh)*sqrt(-uh)*(-(sm*th)+M2*(-th+uh)))/(sqr(sm)*sqr(tm));
+ // me(0,0,2,0)=(Complex(0,8)*sh*(sqr(sm)*sqr(th)+2*M2*sm*th*(th-2*uh)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))))/(sqrt(3)*M*sqr(sm)*sqrt(-th)*sqr(tm));
+ // me(0,0,3,0)=(Complex(0,-8)*sqrt(2)*sh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(phase*sqr(sm)*sqr(tm));
+ // me(0,0,4,0)=(Complex(0,-8)*sqrt(2)*M*sqr(sh)*sqrt(-th)*uh)/(sqr(phase)*sqr(sm)*sqr(tm));
+ // me(0,1,0,1)=(Complex(0,8)*sqrt(2)*M*sh*sqrt(-th)*sqr(uh))/(sqr(sm)*sqr(tm));
+ // me(0,1,1,1)=(Complex(0,-8)*sqrt(2)*uh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(phase*sqr(sm)*sqr(tm));
+ // me(0,1,2,1)=(Complex(0,-8)*uh*(sqr(sm)*sqr(th)+2*M2*sm*th*(th-2*uh)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))))/(sqrt(3)*M*sqr(phase)*sqr(sm)*sqrt(-th)*sqr(tm));
+ // me(0,1,3,1)=(Complex(0,8)*sqrt(2)*uh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(pow(phase,3)*sqr(sm)*sqr(tm));
+ // me(0,1,4,1)=(Complex(0,8)*sqrt(2)*M*sh*sqrt(-th)*sqr(uh))/(pow(phase,4)*sqr(sm)*sqr(tm));
+ // me(2,0,0,0)=(Complex(0,8)*sqrt(2)*M*pow(phase,4)*sh*sqrt(-th)*sqr(uh))/(sqr(sm)*sqr(tm));
+ // me(2,0,1,0)=(Complex(0,-8)*sqrt(2)*pow(phase,3)*uh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(sqr(sm)*sqr(tm));
+ // me(2,0,2,0)=(Complex(0,-8)*sqr(phase)*uh*(sqr(sm)*sqr(th)+2*M2*sm*th*(th-2*uh)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))))/(sqrt(3)*M*sqr(sm)*sqrt(-th)*sqr(tm));
+ // me(2,0,3,0)=(Complex(0,8)*sqrt(2)*phase*sh*uh*sqrt(-(uh/sh))*(-(sm*th)+M2*(-th+uh)))/(sqr(sm)*sqr(tm));
+ // me(2,0,4,0)=(Complex(0,8)*sqrt(2)*M*sh*sqrt(-th)*sqr(uh))/(sqr(sm)*sqr(tm));
+ // me(2,1,0,1)=(Complex(0,-8)*sqrt(2)*M*sqr(phase)*sqr(sh)*sqrt(-th)*uh)/(sqr(sm)*sqr(tm));
+ // me(2,1,1,1)=(Complex(0,8)*sqrt(2)*phase*sh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(sqr(sm)*sqr(tm));
+ // me(2,1,2,1)=(Complex(0,8)*sh*(sqr(sm)*sqr(th)+2*M2*sm*th*(th-2*uh)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))))/(sqrt(3)*M*sqr(sm)*sqrt(-th)*sqr(tm));
+ // me(2,1,3,1)=(Complex(0,-8)*sqrt(2)*sh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(phase*sqr(sm)*sqr(tm));
+ // me(2,1,4,1)=(Complex(0,-8)*sqrt(2)*M*sqr(sh)*sqrt(-th)*uh)/(sqr(phase)*sqr(sm)*sqr(tm));
+ // double totalB(0.);
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // LorentzPolarizationVectorE fCurrent = q4[ih4].dimensionedWave().vectorCurrent(q2[ih2].dimensionedWave());
+ // for(unsigned int ih3=0;ih3<5;++ih3) {
+ // auto vp1Pre = t3[ih3].wave().preDot(meMomenta()[0]);
+ // complex<Energy2> d11 = vp1Pre*meMomenta()[0];
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // auto eSub1 = epsilon(meMomenta()[0],meMomenta()[2],g1[ih1].wave());
+ // Complex amp = 32.*M*d11/sqr(tHat()-M2)*(fCurrent*eSub1)/tHat();
+ // double test = norm(amp/me(2*ih1,ih2,ih3,ih4)-1.);
+ // if(norm(me(2*ih1,ih2,ih3,ih4))>1e-10 && test>1e-10)
+ // cerr << "testing in hel loop A " << ih1 << " " << ih2 << " " << ih3 << " " << ih4 << " "
+ // << amp << " " << me(2*ih1,ih2,ih3,ih4) << " " << test << "\n";
+ // totalB+= norm(amp);
+ // }
+ // }
+ // }
+ // }
+ // spin sum version
+ double total = -128.*(sqr(sHat())+sqr(uHat()))/3./M2/tHat();
+ // final factors
+ output = 16.*O1_*pow<3,1>(Constants::pi*standardModel()->alphaS(scale())/M)/(135.*sqr(tHat()-M2))*total;
+ // analytic test
+ // Energy7 R02 = params_->secondDerivativeRadialWaveFunctionSquared(state_,n_);
+ // double test = -2560.*sqr(Constants::pi)*R02*pow(standardModel()->alphaS(scale()),3)*
+ // (sqr(sHat())+sqr(uHat()))/(9.*pow<5,1>(M)*tHat()*sqr(tHat()-M2));
+ // cerr << "testing matrix element " << output << " " << test << " " << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ // g q -> 1D2 q
+ else if(mePartonData()[1]->id()<6) {
+ // helicity amplitude version of ME
+ // VectorWaveFunction g1w(meMomenta()[0],mePartonData()[0],incoming);
+ // SpinorWaveFunction q2w(meMomenta()[1],mePartonData()[1],incoming);
+ // TensorWaveFunction t3w(meMomenta()[2],mePartonData()[2],outgoing);
+ // SpinorBarWaveFunction q4w(meMomenta()[3],mePartonData()[3],outgoing);
+ // vector<VectorWaveFunction> g1;
+ // vector<SpinorWaveFunction> q2;
+ // vector<TensorWaveFunction> t3;
+ // vector<SpinorBarWaveFunction> q4;
+ // for(unsigned int ix=0;ix<2;++ix) {
+ // g1w.reset(2*ix);
+ // g1.push_back(g1w);
+ // q2w.reset(ix);
+ // q2.push_back(q2w);
+ // q4w.reset(ix);
+ // q4.push_back(q4w);
+ // }
+ // for(unsigned int ix=0;ix<5;++ix) {
+ // t3w.reset(ix,tensor_phase);
+ // t3.push_back(t3w);
+ // }
+ // ProductionMatrixElement me(PDT::Spin1,PDT::Spin1Half,PDT::Spin2,PDT::Spin1Half);
+ // double phi = meMomenta()[2].phi();
+ // Complex phase = exp(Complex(0.,phi));
+ // me(0,0,0,0)=(Complex(0,8)*sqrt(2)*M*sqr(phase)*sqrt(-(pow<4,1>(sHat())*tHat()))*uHat())/(sqr(M2-tHat())*sqr(tHat()+uHat()));
+ // me(0,0,1,0)=(Complex(0,-8)*sqrt(2)*phase*sHat()*sqrt(-(sHat()*uHat()))*(M2*(-tHat()+uHat())+tHat()*(tHat()+uHat())))/(sqr(M2-tHat())*sqr(tHat()+uHat()));
+ // me(0,0,2,0)=(Complex(0,-8)*sHat()*(-2*M2*tHat()*(tHat()-2*uHat())*(tHat()+uHat())+sqr(tHat())*sqr(tHat()+uHat())+sqr(M2)*(sqr(tHat())-4*tHat()*uHat()+sqr(uHat()))))/(sqrt(3)*M*sqr(M2-tHat())*sqrt(-tHat())*sqr(tHat()+uHat()));
+ // me(0,0,3,0)=(Complex(0,8)*sqrt(2)*sHat()*sqrt(-(sHat()*uHat()))*(M2*(-tHat()+uHat())+tHat()*(tHat()+uHat())))/(phase*sqr(M2-tHat())*sqr(tHat()+uHat()));
+ // me(0,0,4,0)=(Complex(0,8)*sqrt(2)*M*sqrt(-(pow<4,1>(sHat())*tHat()))*uHat())/(sqr(phase)*sqr(M2-tHat())*sqr(tHat()+uHat()));
+ // me(0,1,0,1)=(Complex(0,-8)*sqrt(2)*M*sHat()*sqrt(-tHat())*sqr(uHat()))/(sqr(M2-tHat())*sqr(tHat()+uHat()));
+ // me(0,1,1,1)=(Complex(0,8)*sqrt(2)*uHat()*sqrt(-(sHat()*uHat()))*(M2*(-tHat()+uHat())+tHat()*(tHat()+uHat())))/(phase*sqr(M2-tHat())*sqr(tHat()+uHat()));
+ // me(0,1,2,1)=(Complex(0,8)*uHat()*(-2*M2*tHat()*(tHat()-2*uHat())*(tHat()+uHat())+sqr(tHat())*sqr(tHat()+uHat())+sqr(M2)*(sqr(tHat())-4*tHat()*uHat()+sqr(uHat()))))/(sqrt(3)*M*sqr(phase)*sqr(M2-tHat())*sqrt(-tHat())*sqr(tHat()+uHat()));
+ // me(0,1,3,1)=(Complex(0,-8)*sqrt(2)*uHat()*sqrt(-(sHat()*uHat()))*(M2*(-tHat()+uHat())+tHat()*(tHat()+uHat())))/(pow(phase,3)*sqr(M2-tHat())*sqr(tHat()+uHat()));
+ // me(0,1,4,1)=(Complex(0,-8)*sqrt(2)*M*sHat()*sqrt(-tHat())*sqr(uHat()))/(pow(phase,4)*sqr(M2-tHat())*sqr(tHat()+uHat()));
+ // me(2,0,0,0)=(Complex(0,-8)*sqrt(2)*M*pow(phase,4)*sHat()*sqrt(-tHat())*sqr(uHat()))/(sqr(M2-tHat())*sqr(tHat()+uHat()));
+ // me(2,0,1,0)=(Complex(0,8)*sqrt(2)*pow(phase,3)*uHat()*sqrt(-(sHat()*uHat()))*(M2*(-tHat()+uHat())+tHat()*(tHat()+uHat())))/(sqr(M2-tHat())*sqr(tHat()+uHat()));
+ // me(2,0,2,0)=(Complex(0,8)*sqr(phase)*uHat()*(-2*M2*tHat()*(tHat()-2*uHat())*(tHat()+uHat())+sqr(tHat())*sqr(tHat()+uHat())+sqr(M2)*(sqr(tHat())-4*tHat()*uHat()+sqr(uHat()))))/(sqrt(3)*M*sqr(M2-tHat())*sqrt(-tHat())*sqr(tHat()+uHat()));
+ // me(2,0,3,0)=(Complex(0,-8)*sqrt(2)*phase*uHat()*sqrt(-(sHat()*uHat()))*(M2*(-tHat()+uHat())+tHat()*(tHat()+uHat())))/(sqr(M2-tHat())*sqr(tHat()+uHat()));
+ // me(2,0,4,0)=(Complex(0,-8)*sqrt(2)*M*sHat()*sqrt(-tHat())*sqr(uHat()))/(sqr(M2-tHat())*sqr(tHat()+uHat()));
+ // me(2,1,0,1)=(Complex(0,8)*sqrt(2)*M*sqr(phase)*sqrt(-(pow<4,1>(sHat())*tHat()))*uHat())/(sqr(M2-tHat())*sqr(tHat()+uHat()));
+ // me(2,1,1,1)=(Complex(0,-8)*sqrt(2)*phase*sHat()*sqrt(-(sHat()*uHat()))*(M2*(-tHat()+uHat())+tHat()*(tHat()+uHat())))/(sqr(M2-tHat())*sqr(tHat()+uHat()));
+ // me(2,1,2,1)=(Complex(0,-8)*sHat()*(-2*M2*tHat()*(tHat()-2*uHat())*(tHat()+uHat())+sqr(tHat())*sqr(tHat()+uHat())+sqr(M2)*(sqr(tHat())-4*tHat()*uHat()+sqr(uHat()))))/(sqrt(3)*M*sqr(M2-tHat())*sqrt(-tHat())*sqr(tHat()+uHat()));
+ // me(2,1,3,1)=(Complex(0,8)*sqrt(2)*sHat()*sqrt(-(sHat()*uHat()))*(M2*(-tHat()+uHat())+tHat()*(tHat()+uHat())))/(phase*sqr(M2-tHat())*sqr(tHat()+uHat()));
+ // me(2,1,4,1)=(Complex(0,8)*sqrt(2)*M*sqrt(-(pow<4,1>(sHat())*tHat()))*uHat())/(sqr(phase)*sqr(M2-tHat())*sqr(tHat()+uHat()));
+ // double total(0.);
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // LorentzPolarizationVectorE fCurrent = q2[ih2].dimensionedWave().vectorCurrent(q4[ih4].dimensionedWave());
+ // for(unsigned int ih3=0;ih3<5;++ih3) {
+ // auto vp1Pre = t3[ih3].wave().preDot(meMomenta()[0]);
+ // complex<Energy2> d11 = vp1Pre*meMomenta()[0];
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // auto eSub1 = epsilon(meMomenta()[0],meMomenta()[2],g1[ih1].wave());
+ // Complex amp = -32.*M*d11/sqr(tHat()-M2)*(fCurrent*eSub1)/tHat();
+ // double test = norm(amp/me(2*ih1,ih2,ih3,ih4)-1.);
+ // if(norm(me(2*ih1,ih2,ih3,ih4))>1e-10 && test>1e-10)
+ // cerr << "testing in hel loop A " << ih1 << " " << ih2 << " " << ih3 << " " << ih4 << " "
+ // << amp << " " << me(2*ih1,ih2,ih3,ih4) << " " << test << "\n";
+ // total+= norm(amp);
+ // }
+ // }
+ // }
+ // }
+ // spin averaged version
+ double total = -128.*(sqr(sHat())+sqr(uHat()))/(3.*sqr(M)*tHat());
+ // final factors
+ output = 16.*O1_*pow<3,1>(Constants::pi*standardModel()->alphaS(scale())/M)/135./sqr(tHat()-M2)*total;
+ // analytic test
+ // Energy7 R02 = params_->secondDerivativeRadialWaveFunctionSquared(state_,n_);
+ // double test = -2560.*sqr(Constants::pi)*R02*pow(standardModel()->alphaS(scale()),3)*
+ // (sqr(sHat())+sqr(uHat()))/(9.*pow<5,1>(M)*tHat()*sqr(tHat()-M2));
+ // cerr << "testing matrix element " << output << " " << test << " " << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ else assert(false);
+ }
+ // q qbar -> 1D2 g
+ else if(mePartonData()[0]->id()==-mePartonData()[1]->id()) {
+ // helicity amplitude version of matrix element
+ // SpinorWaveFunction q1w(meMomenta()[0],mePartonData()[0],incoming);
+ // SpinorBarWaveFunction q2w(meMomenta()[1],mePartonData()[1],incoming);
+ // TensorWaveFunction t3w(meMomenta()[2],mePartonData()[2],outgoing);
+ // VectorWaveFunction g4w(meMomenta()[3],mePartonData()[3],outgoing);
+ // vector<VectorWaveFunction> g4;
+ // vector<SpinorWaveFunction> q1;
+ // vector<TensorWaveFunction> t3;
+ // vector<SpinorBarWaveFunction> q2;
+ // for(unsigned int ix=0;ix<2;++ix) {
+ // g4w.reset(2*ix,vector_phase);
+ // g4.push_back(g4w);
+ // q1w.reset(ix);
+ // q1.push_back(q1w);
+ // q2w.reset(ix);
+ // q2.push_back(q2w);
+ // }
+ // for(unsigned int ix=0;ix<5;++ix) {
+ // t3w.reset(ix,tensor_phase);
+ // t3.push_back(t3w);
+ // }
+ // ProductionMatrixElement me(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin2,PDT::Spin1);
+ // double phi = meMomenta()[2].phi();
+ // Complex phase = exp(Complex(0.,phi));
+ // Energy2 sh(sHat()),th(tHat()),uh(uHat());
+ // me(0,1,2,0)=(Complex(0,8)*th)/(sqrt(3)*M*sqrt(sh));
+ // me(0,1,2,2)=(Complex(0,-8)*uh)/(sqrt(3)*M*sqr(phase)*sqrt(sh));
+ // me(1,0,2,0)=(Complex(0,-8)*sqr(phase)*uh)/(sqrt(3)*M*sqrt(sh));
+ // me(1,0,2,2)=(Complex(0,8)*th)/(sqrt(3)*M*sqrt(sh));
+ // double totalB(0.);
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // LorentzPolarizationVectorE fCurrent = q1[ih1].dimensionedWave().vectorCurrent(q2[ih2].dimensionedWave());
+ // for(unsigned int ih3=0;ih3<5;++ih3) {
+ // auto vp1Pre = t3[ih3].wave().preDot(meMomenta()[3]);
+ // complex<Energy2> d11 = vp1Pre*meMomenta()[3];
+ // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // auto eSub1 = epsilon(meMomenta()[3],meMomenta()[2],g4[ih4].wave());
+ // Complex amp = 32.*M*d11/sqr(sHat()-M2)*(fCurrent*eSub1)/sHat();
+ // double test = norm(amp/me(ih1,ih2,ih3,2*ih4)-1.);
+ // if(norm(me(ih1,ih2,ih3,2*ih4))>1e-10 && test>1e-10)
+ // cerr << "testing in hel loop A " << ih1 << " " << ih2 << " " << ih3 << " " << 2*ih4 << " "
+ // << amp << " " << me(ih1,ih2,ih3,2*ih4) << " " << test << "\n";
+ // totalB+= norm(amp);
+ // }
+ // }
+ // }
+ // }
+ // spin sum version
+ double total = 128.*(sqr(tHat())+sqr(uHat()))/3./M2/sHat();
+ // final factors
+ output = 128.*O1_*pow<3,1>(Constants::pi*standardModel()->alphaS(scale())/M)/(405.*sqr(sHat()-M2))*total;
+ // analytic test
+ // Energy7 R02 = params_->secondDerivativeRadialWaveFunctionSquared(state_,n_);
+ // double test = 20480.*sqr(Constants::pi)*R02*pow(standardModel()->alphaS(scale()),3)*
+ // (sqr(tHat())+sqr(uHat()))/(27.*pow<5,1>(M)*sHat()*sqr(sHat()-M2));
+ // cerr << "testing matrix element " << output << " " << test << " " << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ else
+ assert(false);
+ return output;
+}
+
+void MEPPto1D2Jet::constructVertex(tSubProPtr sub) {
+ // extract the particles in the hard process
+ ParticleVector hard;
+ hard.reserve(4);
+ hard.push_back(sub->incoming().first);
+ hard.push_back(sub->incoming().second);
+ hard.push_back(sub->outgoing()[0]);
+ hard.push_back(sub->outgoing()[1]);
+ // get them in the right order
+ bool swapped(false);
+ if(hard[0]->id()==-hard[1]->id()) {
+ if(hard[0]->id()<0) swapped = true;
+ }
+ else if(hard[0]->id()!=ParticleID::g) {
+ swapped=true;
+ }
+ if(swapped) {
+ swap(hard[0],hard[1]);
+ swap(hard[2],hard[3]);
+ }
+ // boost to partonic CMS
+ Lorentz5Momentum pcms = hard[0]->momentum()+hard[1]->momentum();
+ LorentzRotation boost(-pcms.boostVector());
+ for(PPtr part : hard) part->transform(boost);
+ // extract kinematic variables
+ Energy M = hard[2]->mass();
+ Energy2 M2 = sqr(M);
+ double phi = hard[2]->momentum().phi();
+ Energy2 sh = (hard[0]->momentum()+hard[1]->momentum()).m2();
+ Energy2 th = (hard[0]->momentum()-hard[2]->momentum()).m2();
+ Energy2 uh = (hard[0]->momentum()-hard[3]->momentum()).m2();
+ Energy2 um(uh-M2),tm(th-M2),sm(sh-M2);
+ Complex phase = exp(Complex(0.,phi));
+ // set basis states and compute the matrix element
+ ProductionMatrixElement me;
+ vector<TensorWaveFunction> twave;
+ TensorWaveFunction(twave,hard[2],outgoing,true, false,true,tensor_phase);
+ if(hard[0]->id()==ParticleID::g) {
+ // g g -> 1D2 g
+ if(hard[1]->id()==ParticleID::g) {
+ vector<VectorWaveFunction> g1,g2,g4;
+ VectorWaveFunction( g1,hard[0],incoming,false, true,true,vector_phase);
+ VectorWaveFunction( g2,hard[1],incoming,false, true,true,vector_phase);
+ VectorWaveFunction( g4,hard[3],outgoing,true , true,true,vector_phase);
+ ProductionMatrixElement me(PDT::Spin1,PDT::Spin1,PDT::Spin2,PDT::Spin1);
+ auto pre = 1./pow<3,1>((M2-sh)*(M2-th)*(M2-uh));
+ Energy10 f1 = pow<5,1>(th)+pow<4,1>(th)*uh+th*pow<4,1>(uh)+pow<5,1>(uh)
+ -pow<3,1>(M2)*(sqr(th)-th*uh+sqr(uh))+3*sqr(M2)*(pow<3,1>(th)+pow<3,1>(uh))
+ -M2*(3*pow<4,1>(th)+2*pow<3,1>(th)*uh-sqr(th)*sqr(uh)+2*th*pow<3,1>(uh)+3*pow<4,1>(uh));
+
+ me(0,0,0,0)=Complex(pre*Complex(0,8)*sqrt(2)*pow<3,1>(M)*pow(phase,3)*sh*sqrt(sh)*sqrt(th*uh)*f1);
+ me(0,0,0,2)=Complex(pre*Complex(0,8)*sqrt(2)*pow<7,1>(M)*phase*sqrt(sh)*sqrt(th*uh)*(pow<4,1>(sh)+3*pow<3,1>(sh)*uh+sqr(M2)*sqr(uh)+4*sqr(sh)*sqr(uh)+2*sh*pow<3,1>(uh)+pow<4,1>(uh)-M2*(pow<3,1>(sh)+3*sqr(sh)*uh+2*sh*sqr(uh)+2*pow<3,1>(uh))));
+ me(0,0,1,0)=Complex(pre*Complex(0,-4)*sqrt(2)*M2*sqr(phase)*sh*(th-uh)*(pow<4,1>(M2)*sqr(sh+uh)-sqr(sh)*uh*(2*pow<3,1>(sh)+3*sqr(sh)*uh+2*sh*sqr(uh)+pow<3,1>(uh))-pow<3,1>(M2)*(3*pow<3,1>(sh)+7*sqr(sh)*uh+6*sh*sqr(uh)+2*pow<3,1>(uh))+sqr(M2)*(4*pow<4,1>(sh)+12*pow<3,1>(sh)*uh+9*sqr(sh)*sqr(uh)+6*sh*pow<3,1>(uh)+pow<4,1>(uh))-M2*sh*(2*pow<4,1>(sh)+5*pow<3,1>(sh)*uh+7*sqr(sh)*sqr(uh)+2*sh*pow<3,1>(uh)+2*pow<4,1>(uh))));
+ me(0,0,1,2)=Complex(pre*Complex(0,-4)*sqrt(2)*pow<3,1>(M2)*(th-uh)*(pow<3,1>(M2)*uh*(sh+uh)-2*sqr(M2)*(pow<3,1>(sh)+3*sqr(sh)*uh+sh*sqr(uh)+pow<3,1>(uh))+sh*uh*(2*pow<3,1>(sh)+3*sqr(sh)*uh+2*sh*sqr(uh)+pow<3,1>(uh))+M2*(2*pow<4,1>(sh)+3*pow<3,1>(sh)*uh+4*sqr(sh)*sqr(uh)+pow<4,1>(uh))));
+ me(0,0,2,0)=Complex(pre*(Complex(0,8)*M*phase*sqr(sh)*sqrt(sh)*(pow<4,1>(M2)*(pow<3,1>(th)-2*sqr(th)*uh-2*th*sqr(uh)+pow<3,1>(uh))+sqr(th)*sqr(uh)*(pow<3,1>(th)+2*sqr(th)*uh+2*th*sqr(uh)+pow<3,1>(uh))+pow<3,1>(M2)*(-2*pow<4,1>(th)+7*pow<3,1>(th)*uh+7*th*pow<3,1>(uh)-2*pow<4,1>(uh))+M2*th*uh*(4*pow<4,1>(th)-3*pow<3,1>(th)*uh-8*sqr(th)*sqr(uh)-3*th*pow<3,1>(uh)+4*pow<4,1>(uh))+sqr(M2)*(pow<5,1>(th)-9*pow<4,1>(th)*uh+4*pow<3,1>(th)*sqr(uh)+4*sqr(th)*pow<3,1>(uh)-9*th*pow<4,1>(uh)+pow<5,1>(uh))))/(sqrt(3)*sqrt(th*uh)));
+ me(0,0,2,2)=Complex(pre*(Complex(0,8)*pow<5,1>(M)*(2*sqr(sh)*sqr(uh)*sqr(sh+uh)*(sqr(sh)+sh*uh+sqr(uh))-pow<5,1>(M2)*(pow<3,1>(sh)+sqr(sh)*uh+sh*sqr(uh)+pow<3,1>(uh))+pow<4,1>(M2)*(3*pow<4,1>(sh)+5*pow<3,1>(sh)*uh+7*sqr(sh)*sqr(uh)+2*sh*pow<3,1>(uh)+3*pow<4,1>(uh))-pow<3,1>(M2)*(3*pow<5,1>(sh)+4*pow<4,1>(sh)*uh+6*sqr(sh)*pow<3,1>(uh)-2*sh*pow<4,1>(uh)+3*pow<5,1>(uh))+M2*sh*uh*(3*pow<5,1>(sh)+12*pow<4,1>(sh)*uh+19*pow<3,1>(sh)*sqr(uh)+10*sqr(sh)*pow<3,1>(uh)+3*sh*pow<4,1>(uh)+3*pow<5,1>(uh))+sqr(M2)*(pow<6,1>(sh)-3*pow<5,1>(sh)*uh-20*pow<4,1>(sh)*sqr(uh)-20*pow<3,1>(sh)*pow<3,1>(uh)-5*sqr(sh)*pow<4,1>(uh)-6*sh*pow<5,1>(uh)+pow<6,1>(uh))))/(sqrt(3)*phase*sqrt(sh)*sqrt(th*uh)));
+ me(0,0,3,0)=Complex(pre*Complex(0,-4)*sqrt(2)*M2*sqr(sh)*(th-uh)*(pow<3,1>(M2)*uh*(sh+uh)-2*sqr(M2)*(pow<3,1>(sh)+3*sqr(sh)*uh+sh*sqr(uh)+pow<3,1>(uh))+sh*uh*(2*pow<3,1>(sh)+3*sqr(sh)*uh+2*sh*sqr(uh)+pow<3,1>(uh))+M2*(2*pow<4,1>(sh)+3*pow<3,1>(sh)*uh+4*sqr(sh)*sqr(uh)+pow<4,1>(uh))));
+ me(0,0,3,2)=Complex(pre*(Complex(0,-4)*sqrt(2)*pow<3,1>(M2)*sh*(th-uh)*(pow<3,1>(M2)*(th+uh)-9*M2*th*uh*(th+uh)-sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))+2*th*uh*(2*sqr(th)+3*th*uh+2*sqr(uh))))/sqr(phase));
+ me(0,0,4,0)=Complex(pre*(Complex(0,-8)*sqrt(2)*pow<3,1>(M)*sqr(sh)*sqrt(sh)*sqrt(th*uh)*(pow<4,1>(sh)+3*pow<3,1>(sh)*uh+sqr(M2)*sqr(uh)+4*sqr(sh)*sqr(uh)+2*sh*pow<3,1>(uh)+pow<4,1>(uh)-M2*(pow<3,1>(sh)+3*sqr(sh)*uh+2*sh*sqr(uh)+2*pow<3,1>(uh))))/phase);
+ me(0,0,4,2)=Complex(pre*(Complex(0,-8)*sqrt(2)*pow<5,1>(M)*sh*sqrt(sh)*th*uh*sqrt(th*uh)*(3*sqr(M2)+sqr(th)+th*uh+sqr(uh)-3*M2*(th+uh)))/pow(phase,3));
+ me(0,2,0,0)=Complex(pre*Complex(0,-8)*sqrt(2)*pow<3,1>(M)*phase*sqrt(sh)*th*(-(sh*pow<4,1>(th))+pow<3,1>(M2)*th*(sh+th)-sqr(M2)*(pow<3,1>(sh)+3*sqr(sh)*th+5*sh*sqr(th)+2*pow<3,1>(th))+M2*(pow<4,1>(sh)+3*pow<3,1>(sh)*th+4*sqr(sh)*sqr(th)+5*sh*pow<3,1>(th)+pow<4,1>(th)))*sqrt(th*uh));
+ me(0,2,0,2)=Complex(pre*(Complex(0,-8)*sqrt(2)*pow<3,1>(M)*sh*sqrt(sh)*sqr(uh)*sqrt(th*uh)*(pow<3,1>(sh)+2*sqr(sh)*uh+M2*uh*(-M2+uh)+sh*uh*(-M2+2*uh)))/phase);
+ me(0,2,1,0)=Complex(pre*Complex(0,-4)*sqrt(2)*M2*th*(-(pow<4,1>(sh)*pow<3,1>(th))+sqr(sh)*pow<5,1>(th)+pow<5,1>(M2)*sqr(sh+th)-pow<4,1>(M2)*(4*pow<3,1>(sh)+11*sqr(sh)*th+11*sh*sqr(th)+4*pow<3,1>(th))-M2*sh*th*(2*pow<4,1>(sh)+4*pow<3,1>(sh)*th+6*sqr(sh)*sqr(th)+7*sh*pow<3,1>(th)-pow<4,1>(th))+pow<3,1>(M2)*(5*pow<4,1>(sh)+19*pow<3,1>(sh)*th+23*sqr(sh)*sqr(th)+18*sh*pow<3,1>(th)+5*pow<4,1>(th))-sqr(M2)*(2*pow<5,1>(sh)+8*pow<4,1>(sh)*th+13*pow<3,1>(sh)*sqr(th)+7*sqr(sh)*pow<3,1>(th)+10*sh*pow<4,1>(th)+2*pow<5,1>(th))));
+ me(0,2,1,2)=Complex(pre*(Complex(0,-4)*sqrt(2)*M2*sh*sqr(uh)*(pow<4,1>(M2)*(sh+uh)+sh*sqr(uh)*(sqr(sh)-sqr(uh))-pow<3,1>(M2)*(sqr(sh)-sh*uh+2*sqr(uh))-sqr(M2)*sh*(4*sqr(sh)+9*sh*uh+13*sqr(uh))+M2*(4*pow<4,1>(sh)+11*pow<3,1>(sh)*uh+14*sqr(sh)*sqr(uh)+12*sh*pow<3,1>(uh)+pow<4,1>(uh))))/sqr(phase));
+ me(0,2,2,0)=Complex(pre*(Complex(0,-8)*M*sqr(th)*(sqr(sh)*sqr(uh)*sqr(sh+uh)*(sqr(sh)+sh*uh+sqr(uh))-pow<5,1>(M2)*(pow<3,1>(sh)+sqr(sh)*uh+sh*sqr(uh)+pow<3,1>(uh))+pow<4,1>(M2)*(3*pow<4,1>(sh)+7*pow<3,1>(sh)*uh+11*sqr(sh)*sqr(uh)+4*sh*pow<3,1>(uh)+3*pow<4,1>(uh))+M2*sh*uh*(4*pow<5,1>(sh)+12*pow<4,1>(sh)*uh+11*pow<3,1>(sh)*sqr(uh)-sqr(sh)*pow<3,1>(uh)-6*sh*pow<4,1>(uh)-2*pow<5,1>(uh))-pow<3,1>(M2)*(3*pow<5,1>(sh)+10*pow<4,1>(sh)*uh+15*pow<3,1>(sh)*sqr(uh)+24*sqr(sh)*pow<3,1>(uh)+7*sh*pow<4,1>(uh)+3*pow<5,1>(uh))+sqr(M2)*(pow<6,1>(sh)-2*pow<4,1>(sh)*sqr(uh)+7*pow<3,1>(sh)*pow<3,1>(uh)+19*sqr(sh)*pow<4,1>(uh)+6*sh*pow<5,1>(uh)+pow<6,1>(uh))))/(sqrt(3)*phase*sqrt(sh)*sqrt(th*uh)));
+ me(0,2,2,2)=Complex(pre*(Complex(0,-8)*M*(sqr(sh)*sqr(th)*sqr(sh+th)*(sqr(sh)+sh*th+sqr(th))-pow<5,1>(M2)*(pow<3,1>(sh)+sqr(sh)*th+sh*sqr(th)+pow<3,1>(th))+pow<4,1>(M2)*(3*pow<4,1>(sh)+7*pow<3,1>(sh)*th+11*sqr(sh)*sqr(th)+4*sh*pow<3,1>(th)+3*pow<4,1>(th))+M2*sh*th*(4*pow<5,1>(sh)+12*pow<4,1>(sh)*th+11*pow<3,1>(sh)*sqr(th)-sqr(sh)*pow<3,1>(th)-6*sh*pow<4,1>(th)-2*pow<5,1>(th))-pow<3,1>(M2)*(3*pow<5,1>(sh)+10*pow<4,1>(sh)*th+15*pow<3,1>(sh)*sqr(th)+24*sqr(sh)*pow<3,1>(th)+7*sh*pow<4,1>(th)+3*pow<5,1>(th))+sqr(M2)*(pow<6,1>(sh)-2*pow<4,1>(sh)*sqr(th)+7*pow<3,1>(sh)*pow<3,1>(th)+19*sqr(sh)*pow<4,1>(th)+6*sh*pow<5,1>(th)+pow<6,1>(th)))*sqr(uh))/(sqrt(3)*pow(phase,3)*sqrt(sh)*sqrt(th*uh)));
+ me(0,2,3,0)=Complex(pre*(Complex(0,-4)*sqrt(2)*M2*sh*sqr(th)*(pow<4,1>(M2)*(sh+th)+sh*sqr(th)*(sqr(sh)-sqr(th))-pow<3,1>(M2)*(sqr(sh)-sh*th+2*sqr(th))-sqr(M2)*sh*(4*sqr(sh)+9*sh*th+13*sqr(th))+M2*(4*pow<4,1>(sh)+11*pow<3,1>(sh)*th+14*sqr(sh)*sqr(th)+12*sh*pow<3,1>(th)+pow<4,1>(th))))/sqr(phase));
+ me(0,2,3,2)=Complex(pre*(Complex(0,-4)*sqrt(2)*M2*uh*(-(pow<4,1>(sh)*pow<3,1>(uh))+sqr(sh)*pow<5,1>(uh)+pow<5,1>(M2)*sqr(sh+uh)-pow<4,1>(M2)*(4*pow<3,1>(sh)+11*sqr(sh)*uh+11*sh*sqr(uh)+4*pow<3,1>(uh))-M2*sh*uh*(2*pow<4,1>(sh)+4*pow<3,1>(sh)*uh+6*sqr(sh)*sqr(uh)+7*sh*pow<3,1>(uh)-pow<4,1>(uh))+pow<3,1>(M2)*(5*pow<4,1>(sh)+19*pow<3,1>(sh)*uh+23*sqr(sh)*sqr(uh)+18*sh*pow<3,1>(uh)+5*pow<4,1>(uh))-sqr(M2)*(2*pow<5,1>(sh)+8*pow<4,1>(sh)*uh+13*pow<3,1>(sh)*sqr(uh)+7*sqr(sh)*pow<3,1>(uh)+10*sh*pow<4,1>(uh)+2*pow<5,1>(uh))))/pow(phase,4));
+ me(0,2,4,0)=Complex(pre*(Complex(0,-8)*sqrt(2)*pow<3,1>(M)*sh*sqrt(sh)*sqr(th)*sqrt(th*uh)*(pow<3,1>(sh)+2*sqr(sh)*uh+M2*uh*(-M2+uh)+sh*uh*(-M2+2*uh)))/pow(phase,3));
+ me(0,2,4,2)=Complex(pre*(Complex(0,-8)*sqrt(2)*pow<3,1>(M)*sqrt(sh)*uh*sqrt(th*uh)*(-(sh*pow<4,1>(uh))+pow<3,1>(M2)*uh*(sh+uh)-sqr(M2)*(pow<3,1>(sh)+3*sqr(sh)*uh+5*sh*sqr(uh)+2*pow<3,1>(uh))+M2*(pow<4,1>(sh)+3*pow<3,1>(sh)*uh+4*sqr(sh)*sqr(uh)+5*sh*pow<3,1>(uh)+pow<4,1>(uh))))/pow(phase,5));
+ me(2,0,0,0)=Complex(pre*Complex(0,-8)*sqrt(2)*pow<3,1>(M)*pow(phase,5)*sqrt(sh)*uh*sqrt(th*uh)*(-(sh*pow<4,1>(uh))+pow<3,1>(M2)*uh*(sh+uh)-sqr(M2)*(pow<3,1>(sh)+3*sqr(sh)*uh+5*sh*sqr(uh)+2*pow<3,1>(uh))+M2*(pow<4,1>(sh)+3*pow<3,1>(sh)*uh+4*sqr(sh)*sqr(uh)+5*sh*pow<3,1>(uh)+pow<4,1>(uh))));
+ me(2,0,0,2)=Complex(pre*Complex(0,-8)*sqrt(2)*pow<3,1>(M)*pow(phase,3)*sh*sqrt(sh)*sqr(th)*sqrt(th*uh)*(pow<3,1>(sh)+2*sqr(sh)*uh+M2*uh*(-M2+uh)+sh*uh*(-M2+2*uh)));
+ me(2,0,1,0)=Complex(pre*Complex(0,4)*sqrt(2)*M2*pow(phase,4)*uh*(-(pow<4,1>(sh)*pow<3,1>(uh))+sqr(sh)*pow<5,1>(uh)+pow<5,1>(M2)*sqr(sh+uh)-pow<4,1>(M2)*(4*pow<3,1>(sh)+11*sqr(sh)*uh+11*sh*sqr(uh)+4*pow<3,1>(uh))-M2*sh*uh*(2*pow<4,1>(sh)+4*pow<3,1>(sh)*uh+6*sqr(sh)*sqr(uh)+7*sh*pow<3,1>(uh)-pow<4,1>(uh))+pow<3,1>(M2)*(5*pow<4,1>(sh)+19*pow<3,1>(sh)*uh+23*sqr(sh)*sqr(uh)+18*sh*pow<3,1>(uh)+5*pow<4,1>(uh))-sqr(M2)*(2*pow<5,1>(sh)+8*pow<4,1>(sh)*uh+13*pow<3,1>(sh)*sqr(uh)+7*sqr(sh)*pow<3,1>(uh)+10*sh*pow<4,1>(uh)+2*pow<5,1>(uh))));
+ me(2,0,1,2)=Complex(pre*Complex(0,4)*sqrt(2)*M2*sqr(phase)*sh*sqr(th)*(pow<4,1>(M2)*(sh+th)+sh*sqr(th)*(sqr(sh)-sqr(th))-pow<3,1>(M2)*(sqr(sh)-sh*th+2*sqr(th))-sqr(M2)*sh*(4*sqr(sh)+9*sh*th+13*sqr(th))+M2*(4*pow<4,1>(sh)+11*pow<3,1>(sh)*th+14*sqr(sh)*sqr(th)+12*sh*pow<3,1>(th)+pow<4,1>(th))));
+ me(2,0,2,0)=Complex(pre*(Complex(0,-8)*M*pow(phase,3)*(sqr(sh)*sqr(th)*sqr(sh+th)*(sqr(sh)+sh*th+sqr(th))-pow<5,1>(M2)*(pow<3,1>(sh)+sqr(sh)*th+sh*sqr(th)+pow<3,1>(th))+pow<4,1>(M2)*(3*pow<4,1>(sh)+7*pow<3,1>(sh)*th+11*sqr(sh)*sqr(th)+4*sh*pow<3,1>(th)+3*pow<4,1>(th))+M2*sh*th*(4*pow<5,1>(sh)+12*pow<4,1>(sh)*th+11*pow<3,1>(sh)*sqr(th)-sqr(sh)*pow<3,1>(th)-6*sh*pow<4,1>(th)-2*pow<5,1>(th))-pow<3,1>(M2)*(3*pow<5,1>(sh)+10*pow<4,1>(sh)*th+15*pow<3,1>(sh)*sqr(th)+24*sqr(sh)*pow<3,1>(th)+7*sh*pow<4,1>(th)+3*pow<5,1>(th))+sqr(M2)*(pow<6,1>(sh)-2*pow<4,1>(sh)*sqr(th)+7*pow<3,1>(sh)*pow<3,1>(th)+19*sqr(sh)*pow<4,1>(th)+6*sh*pow<5,1>(th)+pow<6,1>(th)))*sqr(uh))/(sqrt(3)*sqrt(sh)*sqrt(th*uh)));
+ me(2,0,2,2)=Complex(pre*(Complex(0,-8)*M*phase*sqr(th)*(sqr(sh)*sqr(uh)*sqr(sh+uh)*(sqr(sh)+sh*uh+sqr(uh))-pow<5,1>(M2)*(pow<3,1>(sh)+sqr(sh)*uh+sh*sqr(uh)+pow<3,1>(uh))+pow<4,1>(M2)*(3*pow<4,1>(sh)+7*pow<3,1>(sh)*uh+11*sqr(sh)*sqr(uh)+4*sh*pow<3,1>(uh)+3*pow<4,1>(uh))+M2*sh*uh*(4*pow<5,1>(sh)+12*pow<4,1>(sh)*uh+11*pow<3,1>(sh)*sqr(uh)-sqr(sh)*pow<3,1>(uh)-6*sh*pow<4,1>(uh)-2*pow<5,1>(uh))-pow<3,1>(M2)*(3*pow<5,1>(sh)+10*pow<4,1>(sh)*uh+15*pow<3,1>(sh)*sqr(uh)+24*sqr(sh)*pow<3,1>(uh)+7*sh*pow<4,1>(uh)+3*pow<5,1>(uh))+sqr(M2)*(pow<6,1>(sh)-2*pow<4,1>(sh)*sqr(uh)+7*pow<3,1>(sh)*pow<3,1>(uh)+19*sqr(sh)*pow<4,1>(uh)+6*sh*pow<5,1>(uh)+pow<6,1>(uh))))/(sqrt(3)*sqrt(sh)*sqrt(th*uh)));
+ me(2,0,3,0)=Complex(pre*Complex(0,4)*sqrt(2)*M2*sqr(phase)*sh*sqr(uh)*(pow<4,1>(M2)*(sh+uh)+sh*sqr(uh)*(sqr(sh)-sqr(uh))-pow<3,1>(M2)*(sqr(sh)-sh*uh+2*sqr(uh))-sqr(M2)*sh*(4*sqr(sh)+9*sh*uh+13*sqr(uh))+M2*(4*pow<4,1>(sh)+11*pow<3,1>(sh)*uh+14*sqr(sh)*sqr(uh)+12*sh*pow<3,1>(uh)+pow<4,1>(uh))));
+ me(2,0,3,2)=Complex(pre*Complex(0,4)*sqrt(2)*M2*th*(-(pow<4,1>(sh)*pow<3,1>(th))+sqr(sh)*pow<5,1>(th)+pow<5,1>(M2)*sqr(sh+th)-pow<4,1>(M2)*(4*pow<3,1>(sh)+11*sqr(sh)*th+11*sh*sqr(th)+4*pow<3,1>(th))-M2*sh*th*(2*pow<4,1>(sh)+4*pow<3,1>(sh)*th+6*sqr(sh)*sqr(th)+7*sh*pow<3,1>(th)-pow<4,1>(th))+pow<3,1>(M2)*(5*pow<4,1>(sh)+19*pow<3,1>(sh)*th+23*sqr(sh)*sqr(th)+18*sh*pow<3,1>(th)+5*pow<4,1>(th))-sqr(M2)*(2*pow<5,1>(sh)+8*pow<4,1>(sh)*th+13*pow<3,1>(sh)*sqr(th)+7*sqr(sh)*pow<3,1>(th)+10*sh*pow<4,1>(th)+2*pow<5,1>(th))));
+ me(2,0,4,0)=Complex(pre*Complex(0,-8)*sqrt(2)*pow<3,1>(M)*phase*sh*sqrt(sh)*sqr(uh)*sqrt(th*uh)*(pow<3,1>(sh)+2*sqr(sh)*uh+M2*uh*(-M2+uh)+sh*uh*(-M2+2*uh)));
+ me(2,0,4,2)=Complex(pre*(Complex(0,-8)*sqrt(2)*pow<3,1>(M)*sqrt(sh)*th*(-(sh*pow<4,1>(th))+pow<3,1>(M2)*th*(sh+th)-sqr(M2)*(pow<3,1>(sh)+3*sqr(sh)*th+5*sh*sqr(th)+2*pow<3,1>(th))+M2*(pow<4,1>(sh)+3*pow<3,1>(sh)*th+4*sqr(sh)*sqr(th)+5*sh*pow<3,1>(th)+pow<4,1>(th)))*sqrt(th*uh))/phase);
+ me(2,2,0,0)=Complex(pre*Complex(0,-8)*sqrt(2)*pow<5,1>(M)*pow(phase,3)*sh*sqrt(sh)*th*uh*sqrt(th*uh)*(3*sqr(M2)+sqr(th)+th*uh+sqr(uh)-3*M2*(th+uh)));
+ me(2,2,0,2)=Complex(pre*Complex(0,-8)*sqrt(2)*pow<3,1>(M)*phase*sqr(sh)*sqrt(sh)*sqrt(th*uh)*(pow<4,1>(sh)+3*pow<3,1>(sh)*uh+sqr(M2)*sqr(uh)+4*sqr(sh)*sqr(uh)+2*sh*pow<3,1>(uh)+pow<4,1>(uh)-M2*(pow<3,1>(sh)+3*sqr(sh)*uh+2*sh*sqr(uh)+2*pow<3,1>(uh))));
+ me(2,2,1,0)=Complex(pre*Complex(0,4)*sqrt(2)*pow<3,1>(M2)*sqr(phase)*sh*(th-uh)*(pow<3,1>(M2)*(th+uh)-9*M2*th*uh*(th+uh)-sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))+2*th*uh*(2*sqr(th)+3*th*uh+2*sqr(uh))));
+ me(2,2,1,2)=Complex(pre*Complex(0,4)*sqrt(2)*M2*sqr(sh)*(th-uh)*(pow<3,1>(M2)*uh*(sh+uh)-2*sqr(M2)*(pow<3,1>(sh)+3*sqr(sh)*uh+sh*sqr(uh)+pow<3,1>(uh))+sh*uh*(2*pow<3,1>(sh)+3*sqr(sh)*uh+2*sh*sqr(uh)+pow<3,1>(uh))+M2*(2*pow<4,1>(sh)+3*pow<3,1>(sh)*uh+4*sqr(sh)*sqr(uh)+pow<4,1>(uh))));
+ me(2,2,2,0)=Complex(pre*(Complex(0,8)*pow<5,1>(M)*phase*(2*sqr(sh)*sqr(uh)*sqr(sh+uh)*(sqr(sh)+sh*uh+sqr(uh))-pow<5,1>(M2)*(pow<3,1>(sh)+sqr(sh)*uh+sh*sqr(uh)+pow<3,1>(uh))+pow<4,1>(M2)*(3*pow<4,1>(sh)+5*pow<3,1>(sh)*uh+7*sqr(sh)*sqr(uh)+2*sh*pow<3,1>(uh)+3*pow<4,1>(uh))-pow<3,1>(M2)*(3*pow<5,1>(sh)+4*pow<4,1>(sh)*uh+6*sqr(sh)*pow<3,1>(uh)-2*sh*pow<4,1>(uh)+3*pow<5,1>(uh))+M2*sh*uh*(3*pow<5,1>(sh)+12*pow<4,1>(sh)*uh+19*pow<3,1>(sh)*sqr(uh)+10*sqr(sh)*pow<3,1>(uh)+3*sh*pow<4,1>(uh)+3*pow<5,1>(uh))+sqr(M2)*(pow<6,1>(sh)-3*pow<5,1>(sh)*uh-20*pow<4,1>(sh)*sqr(uh)-20*pow<3,1>(sh)*pow<3,1>(uh)-5*sqr(sh)*pow<4,1>(uh)-6*sh*pow<5,1>(uh)+pow<6,1>(uh))))/(sqrt(3)*sqrt(sh)*sqrt(th*uh)));
+ me(2,2,2,2)=Complex(pre*(Complex(0,8)*M*sqr(sh)*sqrt(sh)*(pow<4,1>(M2)*(pow<3,1>(th)-2*sqr(th)*uh-2*th*sqr(uh)+pow<3,1>(uh))+sqr(th)*sqr(uh)*(pow<3,1>(th)+2*sqr(th)*uh+2*th*sqr(uh)+pow<3,1>(uh))+pow<3,1>(M2)*(-2*pow<4,1>(th)+7*pow<3,1>(th)*uh+7*th*pow<3,1>(uh)-2*pow<4,1>(uh))+M2*th*uh*(4*pow<4,1>(th)-3*pow<3,1>(th)*uh-8*sqr(th)*sqr(uh)-3*th*pow<3,1>(uh)+4*pow<4,1>(uh))+sqr(M2)*(pow<5,1>(th)-9*pow<4,1>(th)*uh+4*pow<3,1>(th)*sqr(uh)+4*sqr(th)*pow<3,1>(uh)-9*th*pow<4,1>(uh)+pow<5,1>(uh))))/(sqrt(3)*phase*sqrt(th*uh)));
+ me(2,2,3,0)=Complex(pre*Complex(0,4)*sqrt(2)*pow<3,1>(M2)*(th-uh)*(pow<3,1>(M2)*uh*(sh+uh)-2*sqr(M2)*(pow<3,1>(sh)+3*sqr(sh)*uh+sh*sqr(uh)+pow<3,1>(uh))+sh*uh*(2*pow<3,1>(sh)+3*sqr(sh)*uh+2*sh*sqr(uh)+pow<3,1>(uh))+M2*(2*pow<4,1>(sh)+3*pow<3,1>(sh)*uh+4*sqr(sh)*sqr(uh)+pow<4,1>(uh))));
+ me(2,2,3,2)=Complex(pre*(Complex(0,4)*sqrt(2)*M2*sh*(th-uh)*(pow<4,1>(M2)*sqr(sh+uh)-sqr(sh)*uh*(2*pow<3,1>(sh)+3*sqr(sh)*uh+2*sh*sqr(uh)+pow<3,1>(uh))-pow<3,1>(M2)*(3*pow<3,1>(sh)+7*sqr(sh)*uh+6*sh*sqr(uh)+2*pow<3,1>(uh))+sqr(M2)*(4*pow<4,1>(sh)+12*pow<3,1>(sh)*uh+9*sqr(sh)*sqr(uh)+6*sh*pow<3,1>(uh)+pow<4,1>(uh))-M2*sh*(2*pow<4,1>(sh)+5*pow<3,1>(sh)*uh+7*sqr(sh)*sqr(uh)+2*sh*pow<3,1>(uh)+2*pow<4,1>(uh))))/sqr(phase));
+ me(2,2,4,0)=Complex(pre*(Complex(0,8)*sqrt(2)*pow<7,1>(M)*sqrt(sh)*sqrt(th*uh)*(pow<4,1>(sh)+3*pow<3,1>(sh)*uh+sqr(M2)*sqr(uh)+4*sqr(sh)*sqr(uh)+2*sh*pow<3,1>(uh)+pow<4,1>(uh)-M2*(pow<3,1>(sh)+3*sqr(sh)*uh+2*sh*sqr(uh)+2*pow<3,1>(uh))))/phase);
+ me(2,2,4,2)=Complex(pre*(Complex(0,8)*sqrt(2)*pow<3,1>(M)*sh*sqrt(sh)*sqrt(th*uh)*f1)/pow(phase,3));
+
+ // test the average result
+ // double aver = me.average();
+ // Energy6 Q(sh*th*uh);
+ // Energy4 P(sh*th+th*uh+uh*sh);
+ // double test =-128.*M2/3./Q/pow<4,1>(Q-M2*P)*
+ // (M2*sqr(P)*Q*(5*pow<6,1>(M2)-45*pow<3,1>(M2)*Q+48*sqr(Q)) -
+ // 2*pow<4,1>(P)*(pow<6,1>(M2)-pow<3,1>(M2)*Q+sqr(Q)) +
+ // pow<3,1>(M2)*P*sqr(Q)*(28*pow<3,1>(M2) - 31*Q)-
+ // sqr(M2*P)*P*(13*pow<3,1>(M2)-18*Q)*Q + 4*M2*pow<5,1>(P)*(pow<3,1>(M2)+Q) -
+ // sqr(M2)*(2*pow<6,1>(P) - 33*pow<4,1>(Q)) - 2*pow<8,1>(M2)*sqr(Q) + 43*pow<5,1>(M2)*pow<3,1>(Q));
+ // cerr << "testing spin correlations " << test << " " << me.average() << " "
+ // << abs(test-aver)/(test+aver) << "\n";
+ }
+ // g qbar -> 1D2 qbar
+ else if(hard[1]->id()<0) {
+ vector<VectorWaveFunction> g1;
+ vector<SpinorBarWaveFunction> q2;
+ vector<SpinorWaveFunction> q4;
+ VectorWaveFunction( g1,hard[0],incoming,false,true,true,vector_phase);
+ SpinorBarWaveFunction(q2,hard[1],incoming,false,true);
+ SpinorWaveFunction( q4,hard[3],outgoing,true ,true);
+ g1[1]=g1[2];
+ // matrix element
+ me = ProductionMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin2,PDT::Spin1Half);
+ if(!swapped) {
+ me(0,0,0,0)=(Complex(0,-8)*sqrt(2)*M*sqr(phase)*sqr(sh)*sqrt(-th)*uh)/(sqr(sm)*sqr(tm));
+ me(0,0,1,0)=(Complex(0,8)*sqrt(2)*phase*sh*sqrt(sh)*sqrt(-uh)*(-(sm*th)+M2*(-th+uh)))/(sqr(sm)*sqr(tm));
+ me(0,0,2,0)=(Complex(0,8)*sh*(sqr(sm)*sqr(th)+2*M2*sm*th*(th-2*uh)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))))/(sqrt(3)*M*sqr(sm)*sqrt(-th)*sqr(tm));
+ me(0,0,3,0)=(Complex(0,-8)*sqrt(2)*sh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(phase*sqr(sm)*sqr(tm));
+ me(0,0,4,0)=(Complex(0,-8)*sqrt(2)*M*sqr(sh)*sqrt(-th)*uh)/(sqr(phase)*sqr(sm)*sqr(tm));
+ me(0,1,0,1)=(Complex(0,8)*sqrt(2)*M*sh*sqrt(-th)*sqr(uh))/(sqr(sm)*sqr(tm));
+ me(0,1,1,1)=(Complex(0,-8)*sqrt(2)*uh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(phase*sqr(sm)*sqr(tm));
+ me(0,1,2,1)=(Complex(0,-8)*uh*(sqr(sm)*sqr(th)+2*M2*sm*th*(th-2*uh)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))))/(sqrt(3)*M*sqr(phase)*sqr(sm)*sqrt(-th)*sqr(tm));
+ me(0,1,3,1)=(Complex(0,8)*sqrt(2)*uh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(pow(phase,3)*sqr(sm)*sqr(tm));
+ me(0,1,4,1)=(Complex(0,8)*sqrt(2)*M*sh*sqrt(-th)*sqr(uh))/(pow(phase,4)*sqr(sm)*sqr(tm));
+ me(2,0,0,0)=(Complex(0,8)*sqrt(2)*M*pow(phase,4)*sh*sqrt(-th)*sqr(uh))/(sqr(sm)*sqr(tm));
+ me(2,0,1,0)=(Complex(0,-8)*sqrt(2)*pow(phase,3)*uh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(sqr(sm)*sqr(tm));
+ me(2,0,2,0)=(Complex(0,-8)*sqr(phase)*uh*(sqr(sm)*sqr(th)+2*M2*sm*th*(th-2*uh)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))))/(sqrt(3)*M*sqr(sm)*sqrt(-th)*sqr(tm));
+ me(2,0,3,0)=(Complex(0,8)*sqrt(2)*phase*sh*uh*sqrt(-(uh/sh))*(-(sm*th)+M2*(-th+uh)))/(sqr(sm)*sqr(tm));
+ me(2,0,4,0)=(Complex(0,8)*sqrt(2)*M*sh*sqrt(-th)*sqr(uh))/(sqr(sm)*sqr(tm));
+ me(2,1,0,1)=(Complex(0,-8)*sqrt(2)*M*sqr(phase)*sqr(sh)*sqrt(-th)*uh)/(sqr(sm)*sqr(tm));
+ me(2,1,1,1)=(Complex(0,8)*sqrt(2)*phase*sh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(sqr(sm)*sqr(tm));
+ me(2,1,2,1)=(Complex(0,8)*sh*(sqr(sm)*sqr(th)+2*M2*sm*th*(th-2*uh)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))))/(sqrt(3)*M*sqr(sm)*sqrt(-th)*sqr(tm));
+ me(2,1,3,1)=(Complex(0,-8)*sqrt(2)*sh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(phase*sqr(sm)*sqr(tm));
+ me(2,1,4,1)=(Complex(0,-8)*sqrt(2)*M*sqr(sh)*sqrt(-th)*uh)/(sqr(phase)*sqr(sm)*sqr(tm));
+ }
+ else {
+ phase*=-1.;
+ me(0,0,0,0)=(Complex(0,8)*sqrt(2)*M*pow(phase,3)*sqr(sh)*sqrt(-th)*uh)/(sqr(sm)*sqr(tm));
+ me(0,0,1,0)=(Complex(0,8)*sqrt(2)*sqr(phase)*sh*sqrt(-(sh/uh))*uh*(M2*(-th+uh)+th*(th+uh)))/(sqr(sm)*sqr(tm));
+ me(0,0,2,0)=(Complex(0,-8)*phase*sh*(sqr(th)*sqr(sm)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))+2*M2*th*(-sqr(th)+th*uh+2*sqr(uh))))/(sqrt(3)*M*sqr(sm)*sqrt(-th)*sqr(tm));
+ me(0,0,3,0)=(Complex(0,8)*sqrt(2)*sqr(sh)*sqrt(th*uh)*(M2*(-th+uh)+th*(th+uh)))/(sqr(sm)*sqrt(-(sh*th))*sqr(tm));
+ me(0,0,4,0)=(Complex(0,8)*sqrt(2)*M*sqr(sh)*sqrt(-th)*uh)/(phase*sqr(sm)*sqr(tm));
+ me(0,1,0,1)=(Complex(0,-8)*sqrt(2)*M*pow(phase,3)*sh*sqrt(-th)*sqr(uh))/(sqr(sm)*sqr(tm));
+ me(0,1,1,1)=(Complex(0,8)*sqrt(2)*sqr(phase)*sh*uh*sqrt(-(uh/sh))*(M2*(-th+uh)+th*(th+uh)))/(sqr(sm)*sqr(tm));
+ me(0,1,2,1)=(Complex(0,8)*phase*uh*(sqr(th)*sqr(sm)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))+2*M2*th*(-sqr(th)+th*uh+2*sqr(uh))))/(sqrt(3)*M*sqr(sm)*sqrt(-th)*sqr(tm));
+ me(0,1,3,1)=(Complex(0,-8)*sqrt(2)*sh*uh*sqrt(-(uh/sh))*(M2*(-th+uh)+th*(th+uh)))/(sqr(sm)*sqr(tm));
+ me(0,1,4,1)=(Complex(0,-8)*sqrt(2)*M*sh*sqrt(-th)*sqr(uh))/(phase*sqr(sm)*sqr(tm));
+ me(2,0,0,0)=(Complex(0,-8)*sqrt(2)*M*phase*sh*sqrt(-th)*sqr(uh))/(sqr(sm)*sqr(tm));
+ me(2,0,1,0)=(Complex(0,8)*sqrt(2)*sh*uh*sqrt(th*uh)*(M2*(-th+uh)+th*(th+uh)))/(sqr(sm)*sqrt(-(sh*th))*sqr(tm));
+ me(2,0,2,0)=(Complex(0,8)*uh*(sqr(th)*sqr(sm)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))+2*M2*th*(-sqr(th)+th*uh+2*sqr(uh))))/(sqrt(3)*M*phase*sqr(sm)*sqrt(-th)*sqr(tm));
+ me(2,0,3,0)=(Complex(0,-8)*sqrt(2)*sh*uh*sqrt(th*uh)*(M2*(-th+uh)+th*(th+uh)))/(sqr(phase)*sqr(sm)*sqrt(-(sh*th))*sqr(tm));
+ me(2,0,4,0)=(Complex(0,-8)*sqrt(2)*M*sh*sqrt(-th)*sqr(uh))/(pow(phase,3)*sqr(sm)*sqr(tm));
+ me(2,1,0,1)=(Complex(0,8)*sqrt(2)*M*phase*sqr(sh)*sqrt(-th)*uh)/(sqr(sm)*sqr(tm));
+ me(2,1,1,1)=(Complex(0,-8)*sqrt(2)*sqr(sh)*sqrt(th*uh)*(M2*(-th+uh)+th*(th+uh)))/(sqr(sm)*sqrt(-(sh*th))*sqr(tm));
+ me(2,1,2,1)=(Complex(0,-8)*sh*(sqr(th)*sqr(sm)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))+2*M2*th*(-sqr(th)+th*uh+2*sqr(uh))))/(sqrt(3)*M*phase*sqr(sm)*sqrt(-th)*sqr(tm));
+ me(2,1,3,1)=(Complex(0,8)*sqrt(2)*sqr(sh)*sqrt(th*uh)*(M2*(-th+uh)+th*(th+uh)))/(sqr(phase)*sqr(sm)*sqrt(-(sh*th))*sqr(tm));
+ me(2,1,4,1)=(Complex(0,8)*sqrt(2)*M*sqr(sh)*sqrt(-th)*uh)/(pow(phase,3)*sqr(sm)*sqr(tm));
+ }
+ // helicity version
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // LorentzPolarizationVectorE fCurrent = q4[ih4].dimensionedWave().vectorCurrent(q2[ih4].dimensionedWave());
+ // for(unsigned int ih3=0;ih3<5;++ih3) {
+ // auto vp1Pre = twave[ih3].wave().preDot(hard[0]->momentum());
+ // complex<Energy2> d11 = vp1Pre*hard[0]->momentum();
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // auto eSub1 = epsilon(hard[0]->momentum(),hard[2]->momentum(),g1[ih1].wave());
+ // Complex amp = 32.*M*d11/sqr(tHat()-M2)*(fCurrent*eSub1)/tHat();
+ // double test = norm(amp/me(2*ih1,ih2,ih3,ih4)-1.);
+ // if(norm(me(2*ih1,ih2,ih3,ih4))>1e-10 && test>1e-10)
+ // cerr << "testing in hel loop B " << ih1 << " " << ih2 << " " << ih3 << " " << ih4 << " "
+ // << amp << " " << me(2*ih1,ih2,ih3,ih4) << " " << test << "\n";
+ // }
+ // }
+ // }
+ // }
+ }
+ // g q -> 1D2 q
+ else if(hard[1]->id()<6) {
+ vector<VectorWaveFunction> g1;
+ vector<SpinorWaveFunction> q2;
+ vector<SpinorBarWaveFunction> q4;
+ VectorWaveFunction( g1,hard[0],incoming,false,true,true,vector_phase);
+ SpinorWaveFunction( q2,hard[1],incoming,false,true);
+ SpinorBarWaveFunction(q4,hard[3],outgoing,true ,true);
+ g1[1]=g1[2];
+ // matrix element
+ me = ProductionMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin2,PDT::Spin1Half);
+ if(!swapped) {
+ me(0,0,0,0)=(Complex(0,8)*sqrt(2)*M*sqr(phase)*sqrt(-(pow<4,1>(sh)*th))*uh)/(sqr(sm)*sqr(tm));
+ me(0,0,1,0)=(Complex(0,-8)*sqrt(2)*phase*sh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(sqr(sm)*sqr(tm));
+ me(0,0,2,0)=(Complex(0,-8)*sh*(sqr(sm)*sqr(th)+2*M2*sm*th*(th-2*uh)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))))/(sqrt(3)*M*sqr(sm)*sqrt(-th)*sqr(tm));
+ me(0,0,3,0)=(Complex(0,8)*sqrt(2)*sh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(phase*sqr(sm)*sqr(tm));
+ me(0,0,4,0)=(Complex(0,8)*sqrt(2)*M*sqrt(-(pow<4,1>(sh)*th))*uh)/(sqr(phase)*sqr(sm)*sqr(tm));
+ me(0,1,0,1)=(Complex(0,-8)*sqrt(2)*M*sh*sqrt(-th)*sqr(uh))/(sqr(sm)*sqr(tm));
+ me(0,1,1,1)=(Complex(0,8)*sqrt(2)*uh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(phase*sqr(sm)*sqr(tm));
+ me(0,1,2,1)=(Complex(0,8)*uh*(sqr(sm)*sqr(th)+2*M2*sm*th*(th-2*uh)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))))/(sqrt(3)*M*sqr(phase)*sqr(sm)*sqrt(-th)*sqr(tm));
+ me(0,1,3,1)=(Complex(0,-8)*sqrt(2)*uh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(pow(phase,3)*sqr(sm)*sqr(tm));
+ me(0,1,4,1)=(Complex(0,-8)*sqrt(2)*M*sh*sqrt(-th)*sqr(uh))/(pow(phase,4)*sqr(sm)*sqr(tm));
+ me(2,0,0,0)=(Complex(0,-8)*sqrt(2)*M*pow(phase,4)*sh*sqrt(-th)*sqr(uh))/(sqr(sm)*sqr(tm));
+ me(2,0,1,0)=(Complex(0,8)*sqrt(2)*pow(phase,3)*uh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(sqr(sm)*sqr(tm));
+ me(2,0,2,0)=(Complex(0,8)*sqr(phase)*uh*(sqr(sm)*sqr(th)+2*M2*sm*th*(th-2*uh)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))))/(sqrt(3)*M*sqr(sm)*sqrt(-th)*sqr(tm));
+ me(2,0,3,0)=(Complex(0,-8)*sqrt(2)*phase*uh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(sqr(sm)*sqr(tm));
+ me(2,0,4,0)=(Complex(0,-8)*sqrt(2)*M*sh*sqrt(-th)*sqr(uh))/(sqr(sm)*sqr(tm));
+ me(2,1,0,1)=(Complex(0,8)*sqrt(2)*M*sqr(phase)*sqrt(-(pow<4,1>(sh)*th))*uh)/(sqr(sm)*sqr(tm));
+ me(2,1,1,1)=(Complex(0,-8)*sqrt(2)*phase*sh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(sqr(sm)*sqr(tm));
+ me(2,1,2,1)=(Complex(0,-8)*sh*(sqr(sm)*sqr(th)+2*M2*sm*th*(th-2*uh)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))))/(sqrt(3)*M*sqr(sm)*sqrt(-th)*sqr(tm));
+ me(2,1,3,1)=(Complex(0,8)*sqrt(2)*sh*sqrt(-(sh*uh))*(-(sm*th)+M2*(-th+uh)))/(phase*sqr(sm)*sqr(tm));
+ me(2,1,4,1)=(Complex(0,8)*sqrt(2)*M*sqrt(-(pow<4,1>(sh)*th))*uh)/(sqr(phase)*sqr(sm)*sqr(tm));
+ }
+ else {
+ phase *=-1.;me(0,0,0,0)=(Complex(0,-8)*sqrt(2)*M*pow(phase,3)*sqr(sh)*sqrt(-th)*uh)/(sqr(sm)*sqr(tm));
+ me(0,0,1,0)=(Complex(0,8)*sqrt(2)*sqr(phase)*sh*sqrt(sh)*sqrt(-uh)*(M2*(-th+uh)+th*(th+uh)))/(sqr(sm)*sqr(tm));
+ me(0,0,2,0)=(Complex(0,8)*phase*sh*(sqr(th)*sqr(sh-M2)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))+2*M2*th*(-sqr(th)+th*uh+2*sqr(uh))))/(sqrt(3)*M*sqr(sm)*sqrt(-th)*sqr(tm));
+ me(0,0,3,0)=(Complex(0,-8)*sqrt(2)*sqr(sh)*sqrt(th*uh)*(M2*(-th+uh)+th*(th+uh)))/(sqr(sm)*sqrt(-(sh*th))*sqr(tm));
+ me(0,0,4,0)=(Complex(0,-8)*sqrt(2)*M*sqr(sh)*sqrt(-th)*uh)/(phase*sqr(sm)*sqr(tm));
+ me(0,1,0,1)=(Complex(0,8)*sqrt(2)*M*pow(phase,3)*sh*sqrt(-th)*sqr(uh))/(sqr(sm)*sqr(tm));
+ me(0,1,1,1)=(Complex(0,-8)*sqrt(2)*sqr(phase)*sh*uh*sqrt(-(uh/sh))*(M2*(-th+uh)+th*(th+uh)))/(sqr(sm)*sqr(tm));
+ me(0,1,2,1)=(Complex(0,-8)*phase*uh*(sqr(th)*sqr(sh-M2)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))+2*M2*th*(-sqr(th)+th*uh+2*sqr(uh))))/(sqrt(3)*M*sqr(sm)*sqrt(-th)*sqr(tm));
+ me(0,1,3,1)=(Complex(0,8)*sqrt(2)*sh*uh*sqrt(-(uh/sh))*(M2*(-th+uh)+th*(th+uh)))/(sqr(sm)*sqr(tm));
+ me(0,1,4,1)=(Complex(0,8)*sqrt(2)*M*sh*sqrt(-th)*sqr(uh))/(phase*sqr(sm)*sqr(tm));
+ me(2,0,0,0)=(Complex(0,8)*sqrt(2)*M*phase*sh*sqrt(-th)*sqr(uh))/(sqr(sm)*sqr(tm));
+ me(2,0,1,0)=(Complex(0,-8)*sqrt(2)*sh*uh*sqrt(th*uh)*(M2*(-th+uh)+th*(th+uh)))/(sqr(sm)*sqrt(-(sh*th))*sqr(tm));
+ me(2,0,2,0)=(Complex(0,-8)*uh*(sqr(th)*sqr(sh-M2)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))+2*M2*th*(-sqr(th)+th*uh+2*sqr(uh))))/(sqrt(3)*M*phase*sqr(sm)*sqrt(-th)*sqr(tm));
+ me(2,0,3,0)=(Complex(0,8)*sqrt(2)*sh*uh*sqrt(th*uh)*(M2*(-th+uh)+th*(th+uh)))/(sqr(phase)*sqr(sm)*sqrt(-(sh*th))*sqr(tm));
+ me(2,0,4,0)=(Complex(0,8)*sqrt(2)*M*sh*sqrt(-th)*sqr(uh))/(pow(phase,3)*sqr(sm)*sqr(tm));
+ me(2,1,0,1)=(Complex(0,-8)*sqrt(2)*M*phase*sqr(sh)*sqrt(-th)*uh)/(sqr(sm)*sqr(tm));
+ me(2,1,1,1)=(Complex(0,8)*sqrt(2)*sqr(sh)*sqrt(th*uh)*(M2*(-th+uh)+th*(th+uh)))/(sqr(sm)*sqrt(-(sh*th))*sqr(tm));
+ me(2,1,2,1)=(Complex(0,8)*sh*(sqr(th)*sqr(sh-M2)+sqr(M2)*(sqr(th)-4*th*uh+sqr(uh))+2*M2*th*(-sqr(th)+th*uh+2*sqr(uh))))/(sqrt(3)*M*phase*sqr(sm)*sqrt(-th)*sqr(tm));
+ me(2,1,3,1)=(Complex(0,-8)*sqrt(2)*sqr(sh)*sqrt(th*uh)*(M2*(-th+uh)+th*(th+uh)))/(sqr(phase)*sqr(sm)*sqrt(-(sh*th))*sqr(tm));
+ me(2,1,4,1)=(Complex(0,-8)*sqrt(2)*M*sqr(sh)*sqrt(-th)*uh)/(pow(phase,3)*sqr(sm)*sqr(tm));
+ }
+ // Helicity code version
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // LorentzPolarizationVectorE fCurrent = q2[ih2].dimensionedWave().vectorCurrent(q4[ih4].dimensionedWave());
+ // for(unsigned int ih3=0;ih3<5;++ih3) {
+ // auto vp1Pre = twave[ih3].wave().preDot(hard[0]->momentum());
+ // complex<Energy2> d11 = vp1Pre*hard[0]->momentum();
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // auto eSub1 = epsilon(hard[0]->momentum(),hard[2]->momentum(),g1[ih1].wave());
+ // Complex amp = -32.*M*d11/sqr(tHat()-M2)*(fCurrent*eSub1)/tHat();
+ // double test = norm(amp/me(2*ih1,ih2,ih3,ih4)-1.);
+ // if(norm(me(2*ih1,ih2,ih3,ih4))>1e-10 && test>1e-10)
+ // cerr << "testing in hel loop B " << ih1 << " " << ih2 << " " << ih3 << " " << ih4 << " "
+ // << amp << " " << me(2*ih1,ih2,ih3,ih4) << " " << test << "\n";
+ // }
+ // }
+ // }
+ // }
+ }
+ else
+ assert(false);
+ }
+ else if(hard[0]->id()==-hard[1]->id()) {
+ vector<SpinorWaveFunction> q1;
+ vector<SpinorBarWaveFunction> q2;
+ vector<VectorWaveFunction> g4;
+ SpinorWaveFunction( q1,hard[0],incoming,false,true);
+ SpinorBarWaveFunction(q2,hard[1],incoming,false,true);
+ VectorWaveFunction( g4,hard[3],outgoing,true,true,true,vector_phase);
+ g4[1]=g4[2];
+ // matrix element
+ me = ProductionMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin2,PDT::Spin1);
+ if(!swapped) {
+ me(0,1,2,0)=(Complex(0,8)*th)/(sqrt(3)*M*sqrt(sh));
+ me(0,1,2,2)=(Complex(0,-8)*uh)/(sqrt(3)*M*sqr(phase)*sqrt(sh));
+ me(1,0,2,0)=(Complex(0,-8)*sqr(phase)*uh)/(sqrt(3)*M*sqrt(sh));
+ me(1,0,2,2)=(Complex(0,8)*th)/(sqrt(3)*M*sqrt(sh));
+ }
+ else {
+ me(0,1,2,0)=(Complex(0,-8)*sqr(phase)*th)/(sqrt(3)*M*sqrt(sh));
+ me(0,1,2,2)=(Complex(0,8)*uh)/(sqrt(3)*M*sqrt(sh));
+ me(1,0,2,0)=(Complex(0,8)*uh)/(sqrt(3)*M*sqrt(sh));
+ me(1,0,2,2)=(Complex(0,-8)*th)/(sqrt(3)*M*sqr(phase)*sqrt(sh));
+ }
+ // Helicity code version
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // LorentzPolarizationVectorE fCurrent = q1[ih1].dimensionedWave().
+ // vectorCurrent(q2[ih2].dimensionedWave());
+ // for(unsigned int ih3=0;ih3<5;++ih3) {
+ // auto vp1Pre = twave[ih3].wave().preDot(hard[3]->momentum());
+ // complex<Energy2> d11 = vp1Pre*hard[3]->momentum();
+ // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // auto eSub1 = epsilon(hard[3]->momentum(),hard[2]->momentum(),g4[ih4].wave());
+ // Complex amp = 32.*M*d11/sqr(sHat()-M2)*(fCurrent*eSub1)/sHat();
+ // double test = norm(amp/me(ih1,ih2,ih3,2*ih4)-1.);
+ // if(norm(me(ih1,ih2,ih3,2*ih4))>1e-10 && test>1e-10)
+ // cerr << "testing in hel loop B " << ih1 << " " << ih2 << " " << ih3 << " " << 2*ih4 << " "
+ // << amp << " " << me(ih1,ih2,ih3,2*ih4) << " " << test << "\n";
+ // }
+ // }
+ // }
+ // }
+ }
+ else
+ assert(false);
+ // construct the vertex
+ HardVertexPtr hardvertex = new_ptr(HardVertex());
+ // set the matrix element for the vertex
+ hardvertex->ME(me);
+ // set the pointers and to and from the vertex
+ for(unsigned int i = 0; i < hard.size(); ++i)
+ hard[i]->spinInfo()->productionVertex(hardvertex);
+ // boost back to lab
+ boost = LorentzRotation(pcms.boostVector());
+ for(PPtr part : hard)
+ part->transform(boost);
+}
diff --git a/MatrixElement/Onium/MEPPto1D2Jet.h b/MatrixElement/Onium/MEPPto1D2Jet.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto1D2Jet.h
@@ -0,0 +1,197 @@
+// -*- C++ -*-
+#ifndef Herwig_MEPPto1D2Jet_H
+#define Herwig_MEPPto1D2Jet_H
+//
+// This is the declaration of the MEPPto1D2Jet class.
+//
+
+#include "Herwig/MatrixElement/HwMEBase.h"
+#include "OniumParameters.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * The MEPPto1D2Jet class implements the colour singlet processes for
+ * \f$gq\to^1\!\!D_2 q\f$, \f$q\bar{q}\to^1\!\!D_2 g\f$ and
+ * \f$gg\to^1\!\!D_2 g\f$.
+ *
+ * @see \ref MEPPto1D2JetInterfaces "The interfaces"
+ * defined for MEPPto1D2Jet.
+ */
+class MEPPto1D2Jet: public HwMEBase {
+
+public:
+
+ /**
+ * The default constructor.
+ */
+ MEPPto1D2Jet() : O1_(ZERO), state_(ccbar), n_(1), process_(0), mOpt_(0)
+ {}
+
+public:
+
+ /** @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 3;
+ }
+
+ /**
+ * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaEW() const {
+ return 0;
+ }
+
+ /**
+ * 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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ MEPPto1D2Jet & operator=(const MEPPto1D2Jet &) = delete;
+
+private:
+
+ /**
+ * Access to the parameters for the quarkonium states
+ */
+ OniumParametersPtr params_;
+
+ /**
+ * The \f$O_1\f$ colour-singlet coefficient
+ */
+ Energy7 O1_;
+
+ /**
+ * Type of state
+ */
+ OniumState state_;
+
+ /**
+ * Principal quantum number
+ */
+ unsigned int n_;
+
+ /**
+ * Which processes to generate
+ */
+ unsigned int process_;
+
+ /**
+ * Option for the onium mass
+ */
+ unsigned int mOpt_;
+};
+
+}
+
+#endif /* Herwig_MEPPto1D2Jet_H */
diff --git a/MatrixElement/Onium/MEPPto1P1Jet.cc b/MatrixElement/Onium/MEPPto1P1Jet.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto1P1Jet.cc
@@ -0,0 +1,263 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the MEPPto1P1Jet class.
+//
+
+#include "MEPPto1P1Jet.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/PDT/EnumParticles.h"
+#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
+#include "ThePEG/Utilities/EnumIO.h"
+#include "ThePEG/StandardModel/StandardModelBase.h"
+#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
+#include "Herwig/MatrixElement/ProductionMatrixElement.h"
+#include "Herwig/MatrixElement/HardVertex.h"
+
+using namespace Herwig;
+
+void MEPPto1P1Jet::doinit() {
+ HwMEBase::doinit();
+ // get the non-perturbative ME
+ O1_ = params_->singletMEProduction<1>(state_,n_,0,1);
+ // set the mass option
+ massOption(vector<unsigned int>({mOpt_+1,0}));
+}
+
+IBPtr MEPPto1P1Jet::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr MEPPto1P1Jet::fullclone() const {
+ return new_ptr(*this);
+}
+
+void MEPPto1P1Jet::persistentOutput(PersistentOStream & os) const {
+ os << params_ << ounit(O1_,GeV*GeV2*GeV2) << oenum(state_) << n_ << mOpt_;
+}
+
+void MEPPto1P1Jet::persistentInput(PersistentIStream & is, int) {
+ is >> params_ >> iunit(O1_,GeV*GeV2*GeV2) >> ienum(state_) >> n_ >> mOpt_;
+}
+
+//The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<MEPPto1P1Jet,HwMEBase>
+describeHerwigMEPPto1P1Jet("Herwig::MEPPto1P1Jet",
+ "HwOniumParameters.so HwMEHadronOnium.so");
+
+void MEPPto1P1Jet::Init() {
+
+ static ClassDocumentation<MEPPto1P1Jet> documentation
+ ("The MEPPto1P1Jet class implements the g g to 1P1 g processes");
+
+ static Reference<MEPPto1P1Jet,OniumParameters> interfaceParameters
+ ("Parameters",
+ "Quarkonium parameters",
+ &MEPPto1P1Jet::params_, false, false, true, false, false);
+
+ static Switch<MEPPto1P1Jet,OniumState> interfaceState
+ ("State",
+ "The type of onium state",
+ &MEPPto1P1Jet::state_, ccbar, false, false);
+ static SwitchOption interfaceStateccbar
+ (interfaceState,
+ "ccbar",
+ "Charmonium state",
+ ccbar);
+ static SwitchOption interfaceStatebbbar
+ (interfaceState,
+ "bbbar",
+ "Bottomonium state",
+ bbbar);
+
+ static Parameter<MEPPto1P1Jet,unsigned int> interfacePrincipalQuantumNumber
+ ("PrincipalQuantumNumber",
+ "The principle quantum number of the states",
+ &MEPPto1P1Jet::n_, 1, 1, 10,
+ false, false, Interface::limited);
+
+ static Switch<MEPPto1P1Jet,unsigned int> interfaceMassOption
+ ("MassOption",
+ "Mass of the treatment of the 1P1 mass",
+ &MEPPto1P1Jet::mOpt_, 0, false, false);
+ static SwitchOption interfaceMassOptionOnShell
+ (interfaceMassOption,
+ "OnShell",
+ "Use the on-shell mass",
+ 0);
+ static SwitchOption interfaceMassOptionOffShell
+ (interfaceMassOption,
+ "OffShell",
+ "Use an off-shell mass generated by the MassGenerator object for the 1P1 state.",
+ 1);
+}
+
+void MEPPto1P1Jet::getDiagrams() const {
+ // construct the meson PDG code from quark ids
+ unsigned int iq = 4+state_;
+ tcPDPtr ps = getParticleData(long(iq*110+10003 + (n_-1)*100000));
+ tcPDPtr g = getParticleData(ParticleID::g);
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, ps, 1, g , -1)));
+}
+
+Selector<MEBase::DiagramIndex>
+MEPPto1P1Jet::diagrams(const DiagramVector & diags) const {
+ Selector<DiagramIndex> sel;
+ for ( DiagramIndex i = 0; i < diags.size(); ++i )
+ if ( diags[i]->id() == -1 ) sel.insert(1.0, i);
+ return sel;
+}
+
+Selector<const ColourLines *>
+MEPPto1P1Jet::colourGeometries(tcDiagPtr ) const {
+ static ColourLines c1("1 -2, 2 4, -1 -4");
+ static ColourLines c2("1 4, -4 -2, 2 -1");
+ Selector<const ColourLines *> sel;
+ sel.insert(0.5, &c1);
+ sel.insert(0.5, &c2);
+ return sel;
+}
+
+Energy2 MEPPto1P1Jet::scale() const {
+ return sHat();
+}
+
+double MEPPto1P1Jet::me2() const {
+ Energy M = meMomenta()[2].mass();
+ Energy2 M2=sqr(M);
+ InvEnergy4 me2 = -1024*
+ (pow<6,1>(M2)*(M2 - sHat()) +
+ 2*(M2 - sHat())*tHat()*uHat()*
+ sqr(sqr(tHat()) + tHat()*uHat() + sqr(uHat())) - 2*pow<5,1>(M2)*
+ (sqr(tHat()) + 4*tHat()*uHat() + sqr(uHat())) +
+ 2*pow<4,1>(M2)*(M2 - sHat())*
+ (sqr(tHat()) + 7*tHat()*uHat() + sqr(uHat())) +
+ sqr(M2)*(M2 - sHat())*tHat()*uHat()*
+ (13*sqr(tHat()) + 23*tHat()*uHat() +
+ 13*sqr(uHat())) -
+ pow<3,1>(M2)*(pow<4,1>(tHat()) +
+ 18*pow<3,1>(tHat())*uHat() +
+ 32*sqr(tHat())*sqr(uHat()) +
+ 18*tHat()*pow<3,1>(uHat()) + pow<4,1>(uHat())) -
+ 2*M2*tHat()*uHat()*
+ (3*pow<4,1>(tHat()) + 10*pow<3,1>(tHat())*uHat() +
+ 15*sqr(tHat())*sqr(uHat()) +
+ 10*tHat()*pow<3,1>(uHat()) + 3*pow<4,1>(uHat())))
+ /pow<3,1>((uHat()-M2)*(tHat()-M2)*(sHat()-M2));
+ double output = 5./324.*pow(Constants::pi*standardModel()->alphaS(scale()),3)*O1_/M*me2;
+ // test vs NPB 291 731
+ // Energy5 R02 = params_->firstDerivativeRadialWaveFunctionSquared(state_,n_);
+ // Energy6 Q(sHat()*tHat()*uHat());
+ // Energy4 P(sHat()*tHat()+tHat()*uHat()+uHat()*sHat());
+ // double test = 16.*Constants::pi*sqr(sHat())*
+ // 40*Constants::pi*pow(standardModel()->alphaS(scale()),3)*R02/3./M/sqr(sHat())/pow<3,1>(Q-M2*P)*
+ // (-pow<5,1>(M2)*P + pow<3,1>(M2)*sqr(P) +Q*(-7*sqr(M2)*P+5*pow<4,1>(M2)+2.*sqr(P)) +4.*M2*sqr(Q));
+ // cerr << "testing matrix element " << output << " " << test << " "
+ // << (output-test)/(output+test) << " " << output/test << "\n";
+ return output;
+}
+
+
+void MEPPto1P1Jet::constructVertex(tSubProPtr sub) {
+ using namespace ThePEG::Helicity;
+ // extract the particles in the hard process
+ // only one order
+ ParticleVector hard;
+ hard.reserve(4);
+ hard.push_back(sub->incoming().first);
+ hard.push_back(sub->incoming().second);
+ hard.push_back(sub->outgoing()[0]);
+ hard.push_back(sub->outgoing()[1]);
+ // boost to partonic CMS
+ Lorentz5Momentum pcms = hard[0]->momentum()+hard[1]->momentum();
+ LorentzRotation boost(-pcms.boostVector());
+ for(PPtr part : hard) part->transform(boost);
+ // set the wavefunctions
+ vector<VectorWaveFunction> g1,g2,psi,g4;
+ VectorWaveFunction( g1,hard[0],incoming,false, true,true,vector_phase);
+ VectorWaveFunction( g2,hard[1],incoming,false, true,true,vector_phase);
+ VectorWaveFunction(psi,hard[2],outgoing,true ,false,true,vector_phase);
+ VectorWaveFunction( g4,hard[3],outgoing,true , true,true,vector_phase);
+ // extract kinematic variables
+ Energy M = hard[2]->mass();
+ Energy2 M2 = sqr(hard[2]->mass());
+ double phi = hard[2]->momentum().phi();
+ Energy2 sh = (hard[0]->momentum()+hard[1]->momentum()).m2();
+ Energy2 th = (hard[0]->momentum()-hard[2]->momentum()).m2();
+ Energy2 uh = (hard[0]->momentum()-hard[3]->momentum()).m2();
+ Energy2 um(uh-M2),tm(th-M2),sm(sh-M2);
+ Complex phase = exp(Complex(0.,phi));
+ Energy rstu = sqrt(th*uh/sh);
+ // calculate the matrix element
+ ProductionMatrixElement me(PDT::Spin1,PDT::Spin1,PDT::Spin1,PDT::Spin1);
+ me(0,0,0,0)=-16.*sqr(phase)*sqr(sh)*(pow<3,1>(M2)*(sh + uh) + sqr(sh)*uh*(sh + uh) + M2*sh*uh*(sh + 2*uh)
+ - sqr(M2)*(sqr(sh) + 3*sh*uh + sqr(uh)))/(sqr(sm)*sqr(tm)*sqr(um));
+ me(0,0,0,2)=-16.*sqr(M2)*sh*(M2 + sh)*th*uh/(sqr(sm)*sqr(tm)*sqr(um));
+ me(0,0,1,0)=16.*sqrt(2)*M*phase*rstu*pow<4,1>(sh)*(-th + uh)/(sqr(sm)*sqr(tm)*sqr(um));
+ me(0,0,1,2)=16.*sqrt(2)*pow<5,1>(M)*rstu*sqr(sh)*(th - uh)/(phase*sqr(sm)*sqr(tm)*sqr(um));
+ me(0,0,2,0)=-16.*pow<3,1>(sh)*(M2 + sh)*th*uh/(sqr(sm)*sqr(tm)*sqr(um));
+ me(0,0,2,2)=16.*sqr(M2)*sqr(sh)*(M2*sm + 2*th*uh)/(sqr(phase)*sqr(sm)*sqr(tm)*sqr(um));
+ me(0,2,0,0)=16.*sh*th*(-(M2*sh*th) + sh*sqr(th) + sqr(M2)*(sh + th))*uh/(sqr(sm)*sqr(tm)*sqr(um));
+ me(0,2,0,2)=16.*sqr(sh)*sqr(uh)*(-sqr(M2) + th*uh)/(sqr(phase)*sqr(sm)*sqr(tm)*sqr(um));
+ me(0,2,1,0)=-16.*sqrt(2)*M*sqr(sh)*th*(M2*sh + sqr(th))*sqrt((th*uh)/(sh*sqr(sm)))/(phase*sm*sqr(tm)*sqr(um));
+ me(0,2,1,2)=16.*sqrt(2)*M*sqr(sh)*uh*sqrt((th*uh)/(sh*sqr(sm)))*(M2*sh + sqr(uh))/(pow(phase,3)*sm*sqr(tm)*sqr(um));
+ me(0,2,2,0)=16.*sqr(sh)*sqr(th)*(sqr(M2) - th*uh)/(sqr(phase)*sqr(sm)*sqr(tm)*sqr(um));
+ me(0,2,2,2)=-16.*sh*th*uh*(-(M2*sh*uh) + sh*sqr(uh) + sqr(M2)*(sh + uh))/(pow(phase,4)*sqr(sm)*sqr(tm)*sqr(um));
+ me(2,0,0,0)=16.*pow(phase,4)*sh*th*uh*(-(M2*sh*uh) + sh*sqr(uh) + sqr(M2)*(sh + uh))/(sqr(sm)*sqr(tm)*sqr(um));
+ me(2,0,0,2)=16.*sqr(phase)*sqr(sh)*sqr(th)*(-sqr(M2) + th*uh)/(sqr(sm)*sqr(tm)*sqr(um));
+ me(2,0,1,0)=16.*sqrt(2)*M*pow(phase,3)*sqr(sh)*uh*sqrt((th*uh)/(sh*sqr(sm)))*(M2*sh + sqr(uh))/(sm*sqr(tm)*sqr(um));
+ me(2,0,1,2)=-16.*sqrt(2)*M*phase*sqr(sh)*th*(M2*sh + sqr(th))*sqrt((th*uh)/(sh*sqr(sm)))/(sm*sqr(tm)*sqr(um));
+ me(2,0,2,0)=16.*sqr(phase)*sqr(sh)*sqr(uh)*(sqr(M2) - th*uh)/(sqr(sm)*sqr(tm)*sqr(um));
+ me(2,0,2,2)=-16.*sh*th*(-(M2*sh*th) + sh*sqr(th) + sqr(M2)*(sh + th))*uh/(sqr(sm)*sqr(tm)*sqr(um));
+ me(2,2,0,0)=-16.*sqr(M2)*sqr(phase)*sqr(sh)*(M2*sm + 2*th*uh)/(sqr(sm)*sqr(tm)*sqr(um));
+ me(2,2,0,2)=16.*pow<3,1>(sh)*(M2 + sh)*th*uh/(sqr(sm)*sqr(tm)*sqr(um));
+ me(2,2,1,0)=16.*sqrt(2)*pow<5,1>(M)*phase*rstu*sqr(sh)*(th - uh)/(sqr(sm)*sqr(tm)*sqr(um));
+ me(2,2,1,2)=16.*sqrt(2)*M*rstu*pow<4,1>(sh)*(-th + uh)/(phase*sqr(sm)*sqr(tm)*sqr(um));
+ me(2,2,2,0)=16.*sqr(M2)*sh*(M2 + sh)*th*uh/(sqr(sm)*sqr(tm)*sqr(um));
+ me(2,2,2,2)=16.*sqr(sh)*(pow<3,1>(M2)*(sh + uh) + sqr(sh)*uh*(sh + uh) + M2*sh*uh*(sh + 2*uh)
+ - sqr(M2)*(sqr(sh) + 3*sh*uh + sqr(uh)))/(sqr(phase)*sqr(sm)*sqr(tm)*sqr(um));
+ // test the spin averaged result
+ // double test = -1024*sqr(sh)*
+ // (pow<6,1>(M2)*(M2 - sh) +
+ // 2*(M2 - sh)*th*uh*
+ // sqr(sqr(th) + th*uh + sqr(uh)) - 2*pow<5,1>(M2)*
+ // (sqr(th) + 4*th*uh + sqr(uh)) +
+ // 2*pow<4,1>(M2)*(M2 - sh)*
+ // (sqr(th) + 7*th*uh + sqr(uh)) +
+ // sqr(M2)*(M2 - sh)*th*uh*
+ // (13*sqr(th) + 23*th*uh +
+ // 13*sqr(uh)) -
+ // pow<3,1>(M2)*(pow<4,1>(th) +
+ // 18*pow<3,1>(th)*uh +
+ // 32*sqr(th)*sqr(uh) +
+ // 18*th*pow<3,1>(uh) + pow<4,1>(uh)) -
+ // 2*M2*th*uh*
+ // (3*pow<4,1>(th) + 10*pow<3,1>(th)*uh +
+ // 15*sqr(th)*sqr(uh) +
+ // 10*th*pow<3,1>(uh) + 3*pow<4,1>(uh)))
+ // /pow<3,1>((uh-M2)*(th-M2)*(sh-M2));
+ // double aver = me.average();
+ // cerr << "testing spin correlations " << test << " " << me.average() << " "
+ // << abs(test-aver)/(test+aver) << "\n";
+ // construct the vertex
+ HardVertexPtr hardvertex = new_ptr(HardVertex());
+ // // set the matrix element for the vertex
+ hardvertex->ME(me);
+ // set the pointers and to and from the vertex
+ for(unsigned int i = 0; i < hard.size(); ++i)
+ hard[i]->spinInfo()->productionVertex(hardvertex);
+ // boost back to lab
+ boost = LorentzRotation(pcms.boostVector());
+ for(PPtr part : hard)
+ part->transform(boost);
+}
diff --git a/MatrixElement/Onium/MEPPto1P1Jet.h b/MatrixElement/Onium/MEPPto1P1Jet.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto1P1Jet.h
@@ -0,0 +1,191 @@
+// -*- C++ -*-
+#ifndef Herwig_MEPPto1P1Jet_H
+#define Herwig_MEPPto1P1Jet_H
+//
+// This is the declaration of the MEPPto1P1Jet class.
+//
+
+#include "Herwig/MatrixElement/HwMEBase.h"
+#include "OniumParameters.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * The MEPPto1P1Jet class implements the colour singlet processes for
+ * \f$gg\to^1\!\!P_1 g\f$.
+ *
+ * @see \ref MEPPto1P1JetInterfaces "The interfaces"
+ * defined for MEPPto1P1Jet.
+ */
+class MEPPto1P1Jet: public HwMEBase {
+
+public:
+
+ /**
+ * The default constructor.
+ */
+ MEPPto1P1Jet(): O1_(ZERO), state_(ccbar), n_(1), mOpt_(0)
+ {}
+
+public:
+
+ /** @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 3;
+ }
+
+ /**
+ * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaEW() const {
+ return 0;
+ }
+
+ /**
+ * 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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ MEPPto1P1Jet & operator=(const MEPPto1P1Jet &) = delete;
+
+private:
+
+ /**
+ * Access to the parameters for the quarkonium states
+ */
+ OniumParametersPtr params_;
+
+ /**
+ * The \f$O_1\f$ colour-singlet coefficient
+ */
+ Energy5 O1_;
+
+ /**
+ * Type of state
+ */
+ OniumState state_;
+
+ /**
+ * Principal quantum number
+ */
+ unsigned int n_;
+
+ /**
+ * Option for the onium mass
+ */
+ unsigned int mOpt_;
+};
+
+}
+
+#endif /* Herwig_MEPPto1P1Jet_H */
diff --git a/MatrixElement/Onium/MEPPto1S0Jet.cc b/MatrixElement/Onium/MEPPto1S0Jet.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto1S0Jet.cc
@@ -0,0 +1,492 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the MEPPto1S0Jet class.
+//
+
+#include "MEPPto1S0Jet.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/PDT/EnumParticles.h"
+#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
+#include "ThePEG/Utilities/EnumIO.h"
+#include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
+#include "ThePEG/Helicity/epsilon.h"
+#include "ThePEG/StandardModel/StandardModelBase.h"
+#include "Herwig/MatrixElement/ProductionMatrixElement.h"
+#include "Herwig/MatrixElement/HardVertex.h"
+
+using namespace Herwig;
+
+void MEPPto1S0Jet::doinit() {
+ HwMEBase::doinit();
+ // get the non-perturbative ME
+ O1_ = params_->singletMEProduction<0>(state_,n_,0,0);
+ // set the mass option
+ massOption(vector<unsigned int>({mOpt_+1,0}));
+}
+
+IBPtr MEPPto1S0Jet::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr MEPPto1S0Jet::fullclone() const {
+ return new_ptr(*this);
+}
+
+void MEPPto1S0Jet::persistentOutput(PersistentOStream & os) const {
+ os << params_ << ounit(O1_,GeV*GeV2) << oenum(state_) << n_ << process_ << mOpt_;
+}
+
+void MEPPto1S0Jet::persistentInput(PersistentIStream & is, int) {
+ is >> params_ >> iunit(O1_,GeV*GeV2) >> ienum(state_) >> n_ >> process_ >> mOpt_;
+}
+
+// The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<MEPPto1S0Jet,HwMEBase>
+describeHerwigMEPPto1S0Jet("Herwig::MEPPto1S0Jet",
+ "HwOniumParameters.so HwMEHadronOnium.so");
+
+void MEPPto1S0Jet::Init() {
+
+ static ClassDocumentation<MEPPto1S0Jet> documentation
+ ("The MEPPto1S0Jet class implements the q qbar -> 1S0 g, g q to 1S0 q"
+ " and g g to 1S0 g processes");
+
+ static Reference<MEPPto1S0Jet,OniumParameters> interfaceParameters
+ ("Parameters",
+ "Quarkonium parameters",
+ &MEPPto1S0Jet::params_, false, false, true, false, false);
+
+ static Switch<MEPPto1S0Jet,OniumState> interfaceState
+ ("State",
+ "The type of onium state",
+ &MEPPto1S0Jet::state_, ccbar, false, false);
+ static SwitchOption interfaceStateccbar
+ (interfaceState,
+ "ccbar",
+ "Charmonium state",
+ ccbar);
+ static SwitchOption interfaceStatebbbar
+ (interfaceState,
+ "bbbar",
+ "Bottomonium state",
+ bbbar);
+
+ static Parameter<MEPPto1S0Jet,unsigned int> interfacePrincipalQuantumNumber
+ ("PrincipalQuantumNumber",
+ "The principle quantum number of the states",
+ &MEPPto1S0Jet::n_, 1, 1, 10,
+ false, false, Interface::limited);
+
+ static Switch<MEPPto1S0Jet,unsigned int> interfaceProcess
+ ("Process",
+ "Which processes to generate",
+ &MEPPto1S0Jet::process_, 0, false, false);
+ static SwitchOption interfaceProcessAll
+ (interfaceProcess,
+ "All",
+ "Generate all the processes",
+ 0);
+ static SwitchOption interfaceProcessGQto1S0Q
+ (interfaceProcess,
+ "GQto1S0Q",
+ "The g q -> 1S0 q process",
+ 1);
+ static SwitchOption interfaceProcessGQbarto1S0Qbar
+ (interfaceProcess,
+ "GQbarto1S0Qbar",
+ "The g qbar -> 1S0 qbar process",
+ 2);
+ static SwitchOption interfaceProcessQQbarto1S0G
+ (interfaceProcess,
+ "QQbarto1S0G",
+ "The q qbar -> 1S0 g process",
+ 3);
+ static SwitchOption interfaceProcessGGto1S0G
+ (interfaceProcess,
+ "GGto1S0G",
+ "The g g -> 1S0 g process",
+ 4);
+
+ static Switch<MEPPto1S0Jet,unsigned int> interfaceMassOption
+ ("MassOption",
+ "Mass of the treatment of the 1S0 mass",
+ &MEPPto1S0Jet::mOpt_, 0, false, false);
+ static SwitchOption interfaceMassOptionOnShell
+ (interfaceMassOption,
+ "OnShell",
+ "Use the on-shell mass",
+ 0);
+ static SwitchOption interfaceMassOptionOffShell
+ (interfaceMassOption,
+ "OffShell",
+ "Use an off-shell mass generated by the MassGenerator object for the 1S0 state.",
+ 1);
+
+}
+
+void MEPPto1S0Jet::getDiagrams() const {
+ // construct the meson PDG code from quark ids
+ unsigned int iq = 4+state_;
+ tcPDPtr ps = getParticleData(long(iq*110+1 + (n_-1)*100000));
+ tcPDPtr g = getParticleData(ParticleID::g);
+ // processes involving quarks
+ for ( int i = 1; i <= 3; ++i ) {
+ tcPDPtr q = getParticleData(i);
+ tcPDPtr qb = q->CC();
+ if(process_ == 0 || process_ == 1)
+ add(new_ptr((Tree2toNDiagram(3), g, g, q , 1, ps, 2, q , -1)));
+ if(process_ == 0 || process_ == 2)
+ add(new_ptr((Tree2toNDiagram(3), g, g, qb, 1, ps, 2, qb, -2)));
+ if(process_ == 0 || process_ == 3)
+ add(new_ptr((Tree2toNDiagram(2), q, qb, 1, g, 3, ps, 3, g, -3)));
+ }
+ // g g -> 1S0 g (s,t,u 4-point)
+ if(process_ == 0 || process_ == 4) {
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, g, 3, ps, 3, g , -4)));
+ add(new_ptr((Tree2toNDiagram(3), g, g, g, 1, ps, 2, g , -5)));
+ add(new_ptr((Tree2toNDiagram(3), g, g, g, 2, ps, 1, g , -6)));
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, ps, 1, g , -7)));
+ }
+}
+
+Selector<MEBase::DiagramIndex>
+MEPPto1S0Jet::diagrams(const DiagramVector & diags) const {
+ Selector<DiagramIndex> sel;
+ for ( DiagramIndex i = 0; i < diags.size(); ++i )
+ if ( diags[i]->id() == -1 ||
+ diags[i]->id() == -2 ||
+ diags[i]->id() == -3 ) sel.insert(1.0, i);
+ else
+ sel.insert(meInfo()[abs(diags[i]->id())-4],i);
+ return sel;
+}
+
+Selector<const ColourLines *>
+MEPPto1S0Jet::colourGeometries(tcDiagPtr diag) const {
+ // g q -> 1S0 q
+ static ColourLines cgq ("1 2 5, -1 -2 3");
+ // g qbar -> 1S0 qbar
+ static ColourLines cgqbar("1 2 -3, -1 -2 -5");
+ // q qbar -> 1S0 g
+ static ColourLines cqqbar("1 3 5, -2 -3 -5");
+ // g g -> 1S0 g
+ static ColourLines cs[2]={ColourLines("1 3 5, -1 2, -2 -3 -5"),
+ ColourLines("1 -2, -1 -3 -5, 2 3 5")};
+ static ColourLines ct[2]={ColourLines("1 2 5, -1 -2 3, -3 -5"),
+ ColourLines("1 2 -3, -1 -2 -5, 3 5")};
+ static ColourLines cu[2]={ColourLines("1 5, -1 -2 3, -3 2 -5"),
+ ColourLines("1 2 -3, -1 -5, 3 -2 5")};
+ // 4 point
+ static ColourLines c4[2]={ColourLines("1 -2, 2 4, -1 -4"),
+ ColourLines("1 4, -4 -2, 2 -1")};
+ // create the selector
+ Selector<const ColourLines *> sel;
+ if (diag->id() == -1) sel.insert(1.0, &cgq );
+ else if (diag->id() == -2) sel.insert(1.0, &cgqbar);
+ else if (diag->id() == -3) sel.insert(1.0, &cqqbar);
+ else if (diag->id() == -4) {
+ sel.insert(0.5, &cs[0]);
+ sel.insert(0.5, &cs[1]);
+ }
+ else if (diag->id() == -5) {
+ sel.insert(0.5, &ct[0]);
+ sel.insert(0.5, &ct[1]);
+ }
+ else if (diag->id() == -6) {
+ sel.insert(0.5, &cu[0]);
+ sel.insert(0.5, &cu[1]);
+ }
+ else if (diag->id() == -7) {
+ sel.insert(0.5, &c4[0]);
+ sel.insert(0.5, &c4[1]);
+ }
+ return sel;
+}
+
+Energy2 MEPPto1S0Jet::scale() const {
+ return sHat();
+}
+
+double MEPPto1S0Jet::me2() const {
+ // return value
+ double output(0.);
+ // mass of the 1S0 state
+ Energy M = meMomenta()[2].mass();
+ Energy2 M2 = sqr(meMomenta()[2].mass());
+ if(mePartonData()[0]->id()==ParticleID::g) {
+ // g qbar -> 1S0 qbar
+ if(mePartonData()[1]->id()==ParticleID::g) {
+ // weights for the different diagrams
+ DVector save(4,0.);
+ save[0] = tHat()*uHat()/(2.*sqr(tHat()+uHat()));
+ save[1] = (tHat()*(sqr(M2)*(sqr(sHat()) + sHat()*tHat() + sqr(tHat())) -
+ M2*sHat()*(2*sqr(sHat()) + sHat()*tHat() + sqr(tHat())) +
+ sqr(sHat())*(2*sqr(sHat()) + 2*sHat()*tHat() + sqr(tHat()))))/
+ (2.*sqr(M2 - uHat())*uHat()*sqr(tHat()+uHat()));
+ save[2] = (uHat()*(sqr(M2)*(sqr(sHat()) + sHat()*uHat() + sqr(uHat())) -
+ M2*sHat()*(2*sqr(sHat()) + sHat()*uHat() + sqr(uHat())) +
+ sqr(sHat())*(2*sqr(sHat()) + 2*sHat()*uHat() + sqr(uHat()))))/
+ (2.*sqr(M2 - tHat())*tHat()*sqr(tHat()+uHat()));
+ save[3] = (tHat()*uHat()*(pow<4,1>(M2) + sqr(tHat())*sqr(uHat()) -
+ 2*pow<3,1>(M2)*(tHat() + uHat()) -
+ M2*tHat()*uHat()*(tHat() + uHat()) +
+ sqr(M2)*(sqr(tHat()) +
+ 3*tHat()*uHat() + sqr(uHat()))))/
+ (sqr(M2 - tHat())*sqr(M2 - uHat())*sqr(tHat()+uHat()));
+ meInfo(save);
+ output = 64./3.*O1_*pow(Constants::pi*standardModel()->alphaS(scale()),3)/M*
+ (sqr(-sqr(M2) + M2*sHat() + sqr(tHat()) + tHat()*uHat() + sqr(uHat()))*
+ (pow<4,1>(M2) + pow<4,1>(sHat()) + pow<4,1>(tHat()) + pow<4,1>(uHat())))/
+ (4.*sHat()*tHat()*uHat()*sqr((M2-sHat())*(M2-tHat())*(M2-uHat())));
+ // test vs NPB 291 731
+ // Energy3 R02 = params_->radialWaveFunctionSquared(state_,n_);
+ // Energy6 Q(sHat()*tHat()*uHat());
+ // Energy4 P(sHat()*tHat()+tHat()*uHat()+uHat()*sHat());
+ // double test = 16.*Constants::pi*sqr(sHat())*
+ // Constants::pi*pow(standardModel()->alphaS(scale()),3)*R02/M/sqr(sHat())/Q/sqr(Q-M2*P)*sqr(P)*
+ // (pow<4,1>(M2)-2*sqr(M2)*P+sqr(P)+2.*M2*Q);
+ // cerr << "testing matrix element " << output << " " << test << " "
+ // << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ else if(mePartonData()[1]->id()<0) {
+ // spin sum version
+ double total = 2.*(sqr(sHat())+sqr(uHat()))/pow<4,1>(M);
+ // final factors
+ output = -32.*O1_*pow<3,1>(M*Constants::pi*standardModel()->alphaS(scale()))/(27.*tHat()*sqr(tHat()-M2))*total;
+ // analytic test
+ // Energy3 R02 = params_->radialWaveFunctionSquared(state_,n_);
+ // double test = -32.*sqr(Constants::pi)*pow(standardModel()->alphaS(scale()),3)*R02*(sqr(sHat())+sqr(uHat()))/(9.*M*tHat()*sqr(tHat()-M2));
+ // cerr << "testing matrix element " << output << " " << test << " " << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ // g q -> 1S0 q
+ else if(mePartonData()[1]->id()<6) {
+ // spin sum version
+ double total = 2.*(sqr(sHat())+sqr(uHat()))/pow<4,1>(M);
+ // final factors
+ output = -32.*O1_*pow<3,1>(M*Constants::pi*standardModel()->alphaS(scale()))/(27.*tHat()*sqr(tHat()-M2))*total;
+ // analytic test
+ // Energy3 R02 = params_->radialWaveFunctionSquared(state_,n_);
+ // double test = -32.*sqr(Constants::pi)*pow(standardModel()->alphaS(scale()),3)*R02*(sqr(sHat())+sqr(uHat()))/(9.*M*tHat()*sqr(tHat()-M2));
+ // cerr << "testing matrix element " << output << " " << test << " " << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ else assert(false);
+ }
+ // q qbar -> 1S0 g
+ else if(mePartonData()[0]->id()==-mePartonData()[1]->id()) {
+ // spin sum version
+ double total = 2.*(sqr(tHat())+sqr(uHat()))/pow<4,1>(M);
+ // final factors
+ output = 256.*O1_*pow<3,1>(M*Constants::pi*standardModel()->alphaS(scale()))/(81.*sHat()*sqr(sHat()-M2))*total;
+ // analytic test
+ // Energy3 R02 = params_->radialWaveFunctionSquared(state_,n_);
+ // double test = 256.*sqr(Constants::pi)*pow(standardModel()->alphaS(scale()),3)*
+ // R02*(sqr(tHat())+sqr(uHat()))/(27.*M*sHat()*sqr(sHat()-M2));
+ // cerr << "testing matrix element " << output << " " << test << " " << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ else
+ assert(false);
+ return output;
+}
+
+void MEPPto1S0Jet::constructVertex(tSubProPtr sub) {
+ // extract the particles in the hard process
+ ParticleVector hard;
+ hard.reserve(4);
+ hard.push_back(sub->incoming().first);
+ hard.push_back(sub->incoming().second);
+ hard.push_back(sub->outgoing()[0]);
+ hard.push_back(sub->outgoing()[1]);
+ // get them in the right order
+ bool swapped(false);
+ if(hard[0]->id()==-hard[1]->id()) {
+ if(hard[0]->id()<0) swapped = true;
+ }
+ else if(hard[0]->id()!=ParticleID::g) {
+ swapped=true;
+ }
+ if(swapped) {
+ swap(hard[0],hard[1]);
+ swap(hard[2],hard[3]);
+ }
+ // boost to partonic CMS
+ Lorentz5Momentum pcms = hard[0]->momentum()+hard[1]->momentum();
+ LorentzRotation boost(-pcms.boostVector());
+ for(PPtr part : hard) part->transform(boost);
+ // extract kinematic variables
+ Energy M = hard[2]->mass();
+ Energy2 M2 = sqr(M);
+ double phi = hard[2]->momentum().phi();
+ Energy2 sh = (hard[0]->momentum()+hard[1]->momentum()).m2();
+ Energy2 th = (hard[0]->momentum()-hard[2]->momentum()).m2();
+ Energy2 uh = (hard[0]->momentum()-hard[3]->momentum()).m2();
+ // set basis states and compute the matrix element
+ ProductionMatrixElement me;
+ ScalarWaveFunction( hard[2],outgoing,true);
+ if(hard[0]->id()==ParticleID::g) {
+ // g g -> 1S0 g
+ if(hard[1]->id()==ParticleID::g) {
+ vector<VectorWaveFunction> g1,g2,g4;
+ VectorWaveFunction( g1,hard[0],incoming,false, true,true,vector_phase);
+ VectorWaveFunction( g2,hard[1],incoming,false, true,true,vector_phase);
+ VectorWaveFunction( g4,hard[3],outgoing,true , true,true,vector_phase);
+ ProductionMatrixElement me(PDT::Spin1,PDT::Spin1,PDT::Spin0,PDT::Spin1);
+ Complex phase = exp(Complex(0.,phi));
+ me(0,0,0,0) = phase;
+ me(0,0,0,2) = -sqr(M2)/(phase*sqr(sh));
+ me(0,2,0,0) = sqr(th)/(phase*sqr(sh));
+ me(0,2,0,2) = sqr(uh)/(pow(phase,3)*sqr(sh));
+ me(2,0,0,0) = (pow(phase,3)*sqr(uh))/sqr(sh);
+ me(2,0,0,2) = (phase*sqr(th))/sqr(sh);
+ me(2,2,0,0) = -((sqr(M2)*phase)/sqr(sh));
+ me(2,2,0,2) = 1./phase;
+ // test the average result
+ // double aver = me.average();
+ // double test = 2.*(pow<4,1>(M2)+pow<4,1>(sh)+pow<4,1>(th)+pow<4,1>(uh))/pow<4,1>(sh);
+ // cerr << "testing spin correlations " << test << " " << me.average() << " "
+ // << abs(test-aver)/(test+aver) << "\n";
+ }
+ // g qbar -> 1S0 qbar
+ else if(hard[1]->id()<0) {
+ vector<VectorWaveFunction> g1;
+ vector<SpinorBarWaveFunction> q2;
+ vector<SpinorWaveFunction> q4;
+ VectorWaveFunction( g1,hard[0],incoming,false,true,true,vector_phase);
+ SpinorBarWaveFunction(q2,hard[1],incoming,false,true);
+ SpinorWaveFunction( q4,hard[3],outgoing,true ,true);
+ g1[1]=g1[2];
+ // matrix element
+ me = ProductionMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin0,PDT::Spin1Half);
+ if(!swapped) {
+ me(0,0,0,0) = sh/M2;
+ me(0,1,0,1) =-exp(Complex(0.,-2.*phi))*uh/M2;
+ me(2,1,0,1) = sh/M2;
+ me(2,0,0,0) =-exp(Complex(0., 2.*phi))*uh/M2;
+ }
+ else {
+ me(0,0,0,0) = -exp(Complex(0., phi))*sh/M2;
+ me(0,1,0,1) = exp(Complex(0., phi))*uh/M2;
+ me(2,1,0,1) = -exp(Complex(0.,-phi))*sh/M2;
+ me(2,0,0,0) = exp(Complex(0.,-phi))*uh/M2;
+ }
+ // Helicity code version
+ // complex<InvEnergy3> fact = sqrt(-2/th)/M2*Complex(0.,1.);
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // LorentzPolarizationVectorE fCurrent = q4[ih4].dimensionedWave().vectorCurrent(q2[ih2].dimensionedWave());
+ // LorentzPolarizationVector eps = fact*Helicity::epsilon(fCurrent,hard[2]->momentum(),hard[0]->momentum());
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // Complex amp = eps*g1[ih1].wave();
+ // if(norm(me(2*ih1,ih2,0,ih4))>1e-10) cerr << "testing in hel loop B " << ih1 << " " << ih2 << " " << ih4 << " "
+ // << amp << " " << me(2*ih1,ih2,0,ih4) << " " << amp/me(2*ih1,ih2,0,ih4)
+ // << " " << norm(amp/me(2*ih1,ih2,0,ih4)) << "\n";
+ // }
+ // }
+ // }
+ }
+ // g q -> 1S0 q
+ else if(hard[1]->id()<6) {
+ vector<VectorWaveFunction> g1;
+ vector<SpinorWaveFunction> q2;
+ vector<SpinorBarWaveFunction> q4;
+ VectorWaveFunction( g1,hard[0],incoming,false,true,true,vector_phase);
+ SpinorWaveFunction( q2,hard[1],incoming,false,true);
+ SpinorBarWaveFunction(q4,hard[3],outgoing,true ,true);
+ g1[1]=g1[2];
+ // matrix element
+ me = ProductionMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin0,PDT::Spin1Half);
+ if(!swapped) {
+ me(0,0,0,0) = sh/M2;
+ me(0,1,0,1) =-exp(Complex(0.,-2.*phi))*uh/M2;
+ me(2,1,0,1) = sh/M2;
+ me(2,0,0,0) =-exp(Complex(0., 2.*phi))*uh/M2;
+ }
+ else {
+ me(0,0,0,0) = -exp(Complex(0., phi))*sh/M2;
+ me(0,1,0,1) = exp(Complex(0., phi))*uh/M2;
+ me(2,1,0,1) = -exp(Complex(0.,-phi))*sh/M2;
+ me(2,0,0,0) = exp(Complex(0.,-phi))*uh/M2;
+ }
+ // Helicity code version
+ // complex<InvEnergy3> fact = sqrt(-2/th)/M2*Complex(0.,1.);
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // LorentzPolarizationVectorE fCurrent = q2[ih2].dimensionedWave().vectorCurrent(q4[ih4].dimensionedWave());
+ // LorentzPolarizationVector eps = fact*Helicity::epsilon(fCurrent,hard[2]->momentum(),hard[0]->momentum());
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // Complex amp = eps*g1[ih1].wave();
+ // if(norm(me(2*ih1,ih2,0,ih4))>1e-10) cerr << "testing in hel loop B " << ih1 << " " << ih2 << " " << ih4 << " "
+ // << amp << " " << me(2*ih1,ih2,0,ih4) << " " << amp/me(2*ih1,ih2,0,ih4)
+ // << " " << norm(amp/me(2*ih1,ih2,0,ih4)) << "\n";
+ // }
+ // }
+ // }
+ }
+ else
+ assert(false);
+ }
+ else if(hard[0]->id()==-hard[1]->id()) {
+ vector<SpinorWaveFunction> q1;
+ vector<SpinorBarWaveFunction> q2;
+ vector<VectorWaveFunction> g4;
+ SpinorWaveFunction( q1,hard[0],incoming,false,true);
+ SpinorBarWaveFunction(q2,hard[1],incoming,false,true);
+ VectorWaveFunction( g4,hard[3],outgoing,true,true,true,vector_phase);
+ g4[1]=g4[2];
+ // matrix element
+ me = ProductionMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin0,PDT::Spin1);
+ if(!swapped) {
+ me(0,1,0,0) = -th/M2;
+ me(0,1,0,2) = exp(Complex(0.,-2.*phi))*uh/M2;
+ me(1,0,0,0) = exp(Complex(0., 2.*phi))*uh/M2;
+ me(1,0,0,2) = -th/M2;
+ }
+ else {
+ me(0,1,0,0) = exp(Complex(0., 2.*phi))*th/M2;
+ me(0,1,0,2) = -uh/M2;
+ me(1,0,0,0) = -uh/M2;
+ me(1,0,0,2) = exp(Complex(0.,-2.*phi))*th/M2;
+ }
+ // Helicity code version
+ // complex<InvEnergy3> fact = sqrt(2./sh)/M2*Complex(0.,1.);
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // LorentzPolarizationVectorE fCurrent = q1[ih1].dimensionedWave().vectorCurrent(q2[ih2].dimensionedWave());
+ // LorentzPolarizationVector eps = fact*Helicity::epsilon(fCurrent,hard[2]->momentum(),hard[3]->momentum());
+ // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // Complex amp = eps*g4[ih4].wave();
+ // //if(norm(me(ih1,ih2,0,2*ih4))>1e-10)
+ // cerr << "testing in hel loop B " << ih1 << " " << ih2 << " " << ih4 << " "
+ // << amp << " " << me(ih1,ih2,0,2*ih4) << " " << amp/me(ih1,ih2,0,2*ih4)
+ // << " " << norm(amp/me(ih1,ih2,0,2*ih4)) << "\n";
+ // }
+ // }
+ // }
+ }
+ else
+ assert(false);
+ // construct the vertex
+ HardVertexPtr hardvertex = new_ptr(HardVertex());
+ // // set the matrix element for the vertex
+ hardvertex->ME(me);
+ // set the pointers and to and from the vertex
+ for(unsigned int i = 0; i < hard.size(); ++i)
+ hard[i]->spinInfo()->productionVertex(hardvertex);
+ // boost back to lab
+ boost = LorentzRotation(pcms.boostVector());
+ for(PPtr part : hard)
+ part->transform(boost);
+}
diff --git a/MatrixElement/Onium/MEPPto1S0Jet.h b/MatrixElement/Onium/MEPPto1S0Jet.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto1S0Jet.h
@@ -0,0 +1,197 @@
+// -*- C++ -*-
+#ifndef Herwig_MEPPto1S0Jet_H
+#define Herwig_MEPPto1S0Jet_H
+//
+// This is the declaration of the MEPPto1S0Jet class.
+//
+
+#include "Herwig/MatrixElement/HwMEBase.h"
+#include "OniumParameters.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * The MEPPto1S0Jet class implements the colour singlet processes for
+ * \f$gq\to^1\!\!S_0 q\f$, \f$q\bar{q}\to ^1\!\!S_0 g\f$ and
+ * \f$gg\to^1\!\!S_0 g\f$.
+ *
+ * @see \ref MEPPto1S0JetInterfaces "The interfaces"
+ * defined for MEPPto1S0Jet.
+ */
+class MEPPto1S0Jet: public HwMEBase {
+
+public:
+
+ /**
+ * The default constructor.
+ */
+ MEPPto1S0Jet() : O1_(ZERO), state_(ccbar), n_(1), process_(0), mOpt_(0)
+ {}
+
+public:
+
+ /** @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 3;
+ }
+
+ /**
+ * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaEW() const {
+ return 0;
+ }
+
+ /**
+ * 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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ MEPPto1S0Jet & operator=(const MEPPto1S0Jet &) = delete;
+
+private:
+
+ /**
+ * Access to the parameters for the quarkonium states
+ */
+ OniumParametersPtr params_;
+
+ /**
+ * The \f$O_1\f$ colour-singlet coefficient
+ */
+ Energy3 O1_;
+
+ /**
+ * Type of state
+ */
+ OniumState state_;
+
+ /**
+ * Principal quantum number
+ */
+ unsigned int n_;
+
+ /**
+ * Which processes to generate
+ */
+ unsigned int process_;
+
+ /**
+ * Option for the onium mass
+ */
+ unsigned int mOpt_;
+};
+
+}
+
+#endif /* Herwig_MEPPto1S0Jet_H */
diff --git a/MatrixElement/Onium/MEPPto3D1Jet.cc b/MatrixElement/Onium/MEPPto3D1Jet.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto3D1Jet.cc
@@ -0,0 +1,286 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the MEPPto3D1Jet class.
+//
+
+#include "MEPPto3D1Jet.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/PDT/EnumParticles.h"
+#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
+#include "ThePEG/Utilities/EnumIO.h"
+#include "ThePEG/StandardModel/StandardModelBase.h"
+#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
+#include "Herwig/MatrixElement/ProductionMatrixElement.h"
+#include "Herwig/MatrixElement/HardVertex.h"
+
+using namespace Herwig;
+
+void MEPPto3D1Jet::doinit() {
+ HwMEBase::doinit();
+ // get the non-perturbative ME
+ O1_ = params_->singletMEProduction<2>(state_,n_,1,1);
+ // set the mass option
+ massOption(vector<unsigned int>({mOpt_+1,0}));
+}
+
+IBPtr MEPPto3D1Jet::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr MEPPto3D1Jet::fullclone() const {
+ return new_ptr(*this);
+}
+
+void MEPPto3D1Jet::persistentOutput(PersistentOStream & os) const {
+ os << params_ << ounit(O1_,GeV*GeV2*GeV2*GeV2) << oenum(state_) << n_ << mOpt_;
+}
+
+void MEPPto3D1Jet::persistentInput(PersistentIStream & is, int) {
+ is >> params_ >> iunit(O1_,GeV*GeV2*GeV2*GeV2) >> ienum(state_) >> n_ >> mOpt_;
+}
+
+//The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<MEPPto3D1Jet,HwMEBase>
+describeHerwigMEPPto3D1Jet("Herwig::MEPPto3D1Jet",
+ "HwOniumParameters.so HwMEHadronOnium.so");
+
+void MEPPto3D1Jet::Init() {
+
+ static ClassDocumentation<MEPPto3D1Jet> documentation
+ ("The MEPPto3D1Jet class implements the g g to 3D1 g processes");
+
+ static Reference<MEPPto3D1Jet,OniumParameters> interfaceParameters
+ ("Parameters",
+ "Quarkonium parameters",
+ &MEPPto3D1Jet::params_, false, false, true, false, false);
+
+ static Switch<MEPPto3D1Jet,OniumState> interfaceState
+ ("State",
+ "The type of onium state",
+ &MEPPto3D1Jet::state_, ccbar, false, false);
+ static SwitchOption interfaceStateccbar
+ (interfaceState,
+ "ccbar",
+ "Charmonium state",
+ ccbar);
+ static SwitchOption interfaceStatebbbar
+ (interfaceState,
+ "bbbar",
+ "Bottomonium state",
+ bbbar);
+
+ static Parameter<MEPPto3D1Jet,unsigned int> interfacePrincipalQuantumNumber
+ ("PrincipalQuantumNumber",
+ "The principle quantum number of the states",
+ &MEPPto3D1Jet::n_, 1, 1, 10,
+ false, false, Interface::limited);
+
+ static Switch<MEPPto3D1Jet,unsigned int> interfaceMassOption
+ ("MassOption",
+ "Mass of the treatment of the 3D1 mass",
+ &MEPPto3D1Jet::mOpt_, 0, false, false);
+ static SwitchOption interfaceMassOptionOnShell
+ (interfaceMassOption,
+ "OnShell",
+ "Use the on-shell mass",
+ 0);
+ static SwitchOption interfaceMassOptionOffShell
+ (interfaceMassOption,
+ "OffShell",
+ "Use an off-shell mass generated by the MassGenerator object for the 3D1 state.",
+ 1);
+}
+
+void MEPPto3D1Jet::getDiagrams() const {
+ // construct the meson PDG code from quark ids
+ unsigned int iq = 4+state_;
+ tcPDPtr ps = getParticleData(long(iq*110 + 30003 + (n_-1)*100000));
+ tcPDPtr g = getParticleData(ParticleID::g);
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, ps, 1, g , -1)));
+}
+
+Selector<MEBase::DiagramIndex>
+MEPPto3D1Jet::diagrams(const DiagramVector & diags) const {
+ Selector<DiagramIndex> sel;
+ for ( DiagramIndex i = 0; i < diags.size(); ++i )
+ if ( diags[i]->id() == -1 ) sel.insert(1.0, i);
+ return sel;
+}
+
+Selector<const ColourLines *>
+MEPPto3D1Jet::colourGeometries(tcDiagPtr ) const {
+ static ColourLines c1("1 -2, 2 4, -1 -4");
+ static ColourLines c2("1 4, -4 -2, 2 -1");
+ Selector<const ColourLines *> sel;
+ sel.insert(0.5, &c1);
+ sel.insert(0.5, &c2);
+ return sel;
+}
+
+Energy2 MEPPto3D1Jet::scale() const {
+ return sHat();
+}
+
+double MEPPto3D1Jet::me2() const {
+ Energy M = meMomenta()[2].mass();
+ Energy2 M2=sqr(M);
+ Energy4 um(sqr(uHat()-M2)),tm(sqr(tHat()-M2)),sm(sqr(sHat()-M2));
+ double output = 256*O1_*pow(Constants::pi*standardModel()->alphaS(scale()),3)/
+ (243.*pow<3,1>(M)*pow<5,1>(M2-tHat())*pow<5,1>(M2-uHat())*pow<5,1>(tHat()+uHat()))*
+ ((102*pow<10,1>(M2)*pow<3,1>(tHat())-286*pow<9,1>(M2)*pow<4,1>(tHat())+
+ 275*pow<8,1>(M2)*pow<5,1>(tHat())-227*pow<7,1>(M2)*pow<6,1>(tHat())+
+ 410*pow<6,1>(M2)*pow<7,1>(tHat())-470*pow<5,1>(M2)*pow<8,1>(tHat())+
+ 245*pow<4,1>(M2)*pow<9,1>(tHat())-49*pow<3,1>(M2)*pow<10,1>(tHat())+
+ 302*pow<10,1>(M2)*sqr(tHat())*uHat()-1732*pow<9,1>(M2)*pow<3,1>(tHat())*uHat()+
+ 3840*pow<8,1>(M2)*pow<4,1>(tHat())*uHat()-5004*pow<7,1>(M2)*pow<5,1>(tHat())*uHat()+
+ 5137*pow<6,1>(M2)*pow<6,1>(tHat())*uHat()-4220*pow<5,1>(M2)*pow<7,1>(tHat())*uHat()+
+ 2190*pow<4,1>(M2)*pow<8,1>(tHat())*uHat()-580*pow<3,1>(M2)*pow<9,1>(tHat())*uHat()+
+ 67*sqr(M2)*pow<10,1>(tHat())*uHat()+302*pow<10,1>(M2)*tHat()*sqr(uHat())-
+ 2844*pow<9,1>(M2)*sqr(tHat())*sqr(uHat())+10289*pow<8,1>(M2)*pow<3,1>(tHat())*sqr(uHat())-
+ 19569*pow<7,1>(M2)*pow<4,1>(tHat())*sqr(uHat())+23585*pow<6,1>(M2)*pow<5,1>(tHat())*sqr(uHat())-
+ 19534*pow<5,1>(M2)*pow<6,1>(tHat())*sqr(uHat())+10358*pow<4,1>(M2)*pow<7,1>(tHat())*sqr(uHat())-
+ 2822*pow<3,1>(M2)*pow<8,1>(tHat())*sqr(uHat())+210*sqr(M2)*pow<9,1>(tHat())*sqr(uHat())+
+ 25*M2*pow<10,1>(tHat())*sqr(uHat())+102*pow<10,1>(M2)*pow<3,1>(uHat())-
+ 1732*pow<9,1>(M2)*tHat()*pow<3,1>(uHat())+10289*pow<8,1>(M2)*sqr(tHat())*pow<3,1>(uHat())-
+ 29536*pow<7,1>(M2)*pow<3,1>(tHat())*pow<3,1>(uHat())+
+ 47908*pow<6,1>(M2)*pow<4,1>(tHat())*pow<3,1>(uHat())-
+ 47528*pow<5,1>(M2)*pow<5,1>(tHat())*pow<3,1>(uHat())+
+ 28602*pow<4,1>(M2)*pow<6,1>(tHat())*pow<3,1>(uHat())-
+ 8984*pow<3,1>(M2)*pow<7,1>(tHat())*pow<3,1>(uHat())+774*sqr(M2)*pow<8,1>(tHat())*pow<3,1>(uHat())+
+ 100*M2*pow<9,1>(tHat())*pow<3,1>(uHat())+5*pow<10,1>(tHat())*pow<3,1>(uHat())-
+ 286*pow<9,1>(M2)*pow<4,1>(uHat())+3840*pow<8,1>(M2)*tHat()*pow<4,1>(uHat())-
+ 19569*pow<7,1>(M2)*sqr(tHat())*pow<4,1>(uHat())+47908*pow<6,1>(M2)*pow<3,1>(tHat())*pow<4,1>(uHat())-
+ 63536*pow<5,1>(M2)*pow<4,1>(tHat())*pow<4,1>(uHat())+
+ 47093*pow<4,1>(M2)*pow<5,1>(tHat())*pow<4,1>(uHat())-
+ 17653*pow<3,1>(M2)*pow<6,1>(tHat())*pow<4,1>(uHat())+2006*sqr(M2)*pow<7,1>(tHat())*pow<4,1>(uHat())+
+ 220*M2*pow<8,1>(tHat())*pow<4,1>(uHat())+25*pow<9,1>(tHat())*pow<4,1>(uHat())+
+ 275*pow<8,1>(M2)*pow<5,1>(uHat())-5004*pow<7,1>(M2)*tHat()*pow<5,1>(uHat())+
+ 23585*pow<6,1>(M2)*sqr(tHat())*pow<5,1>(uHat())-47528*pow<5,1>(M2)*pow<3,1>(tHat())*pow<5,1>(uHat())+
+ 47093*pow<4,1>(M2)*pow<4,1>(tHat())*pow<5,1>(uHat())-
+ 21968*pow<3,1>(M2)*pow<5,1>(tHat())*pow<5,1>(uHat())+3147*sqr(M2)*pow<6,1>(tHat())*pow<5,1>(uHat())+
+ 340*M2*pow<7,1>(tHat())*pow<5,1>(uHat())+60*pow<8,1>(tHat())*pow<5,1>(uHat())-
+ 227*pow<7,1>(M2)*pow<6,1>(uHat())+5137*pow<6,1>(M2)*tHat()*pow<6,1>(uHat())-
+ 19534*pow<5,1>(M2)*sqr(tHat())*pow<6,1>(uHat())+28602*pow<4,1>(M2)*pow<3,1>(tHat())*pow<6,1>(uHat())-
+ 17653*pow<3,1>(M2)*pow<4,1>(tHat())*pow<6,1>(uHat())+3147*sqr(M2)*pow<5,1>(tHat())*pow<6,1>(uHat())+
+ 390*M2*pow<6,1>(tHat())*pow<6,1>(uHat())+90*pow<7,1>(tHat())*pow<6,1>(uHat())+
+ 410*pow<6,1>(M2)*pow<7,1>(uHat())-4220*pow<5,1>(M2)*tHat()*pow<7,1>(uHat())+
+ 10358*pow<4,1>(M2)*sqr(tHat())*pow<7,1>(uHat())-8984*pow<3,1>(M2)*pow<3,1>(tHat())*pow<7,1>(uHat())+
+ 2006*sqr(M2)*pow<4,1>(tHat())*pow<7,1>(uHat())+340*M2*pow<5,1>(tHat())*pow<7,1>(uHat())+
+ 90*pow<6,1>(tHat())*pow<7,1>(uHat())-470*pow<5,1>(M2)*pow<8,1>(uHat())+
+ 2190*pow<4,1>(M2)*tHat()*pow<8,1>(uHat())-2822*pow<3,1>(M2)*sqr(tHat())*pow<8,1>(uHat())+
+ 774*sqr(M2)*pow<3,1>(tHat())*pow<8,1>(uHat())+220*M2*pow<4,1>(tHat())*pow<8,1>(uHat())+
+ 60*pow<5,1>(tHat())*pow<8,1>(uHat())+245*pow<4,1>(M2)*pow<9,1>(uHat())-
+ 580*pow<3,1>(M2)*tHat()*pow<9,1>(uHat())+210*sqr(M2)*sqr(tHat())*pow<9,1>(uHat())+
+ 100*M2*pow<3,1>(tHat())*pow<9,1>(uHat())+25*pow<4,1>(tHat())*pow<9,1>(uHat())-
+ 49*pow<3,1>(M2)*pow<10,1>(uHat())+67*sqr(M2)*tHat()*pow<10,1>(uHat())+
+ 25*M2*sqr(tHat())*pow<10,1>(uHat())+5*pow<3,1>(tHat())*pow<10,1>(uHat())));
+ // // test vsPRD 45, 116 PR45, 116
+ // Energy7 R02 = params_->secondDerivativeRadialWaveFunctionSquared(state_,n_);
+ // Energy6 Q(sHat()*tHat()*uHat());
+ // Energy4 P(sHat()*tHat()+tHat()*uHat()+uHat()*sHat());
+ // double test = 16.*Constants::pi*20.*Constants::pi*pow(standardModel()->alphaS(scale()),3)*R02/
+ // (9.*pow<3,1>(M)*pow<5,1>(Q-M2*P))*
+ // (-49*pow<3,1>(M2)*pow<5,1>(P) -
+ // sqr(M2)*pow<4,1>(P)*(20*pow<3,1>(M2) - 67*Q) -
+ // 52*pow<7,1>(M2)*sqr(Q) +
+ // 894*pow<4,1>(M2)*pow<3,1>(Q) -
+ // 5*M2*pow<4,1>(Q) +
+ // sqr(M2)*P*Q*(4*pow<6,1>(M2) -
+ // 1742*pow<3,1>(M2)*Q - 361*sqr(Q)) -
+ // M2*pow<3,1>(P)*
+ // (102*pow<6,1>(M2) + 295*pow<3,1>(M2)*Q -
+ // 25*sqr(Q)) +
+ // sqr(P)*Q*(902*pow<6,1>(M2) + 729*pow<3,1>(M2)*Q +
+ // 5*sqr(Q)));
+ // cerr << "testing matrix element " << output << " " << test << " "
+ // << (output-test)/(output+test) << " " << output/test << "\n";
+ return output;
+}
+
+void MEPPto3D1Jet::constructVertex(tSubProPtr sub) {
+ using namespace ThePEG::Helicity;
+ // extract the particles in the hard process
+ // only one order
+ ParticleVector hard;
+ hard.reserve(4);
+ hard.push_back(sub->incoming().first);
+ hard.push_back(sub->incoming().second);
+ hard.push_back(sub->outgoing()[0]);
+ hard.push_back(sub->outgoing()[1]);
+ // boost to partonic CMS
+ Lorentz5Momentum pcms = hard[0]->momentum()+hard[1]->momentum();
+ LorentzRotation boost(-pcms.boostVector());
+ for(PPtr part : hard) part->transform(boost);
+ // set the wavefunctions
+ vector<VectorWaveFunction> g1,g2,psi,g4;
+ VectorWaveFunction( g1,hard[0],incoming,false, true,true,vector_phase);
+ VectorWaveFunction( g2,hard[1],incoming,false, true,true,vector_phase);
+ VectorWaveFunction(psi,hard[2],outgoing,true ,false,true,vector_phase);
+ VectorWaveFunction( g4,hard[3],outgoing,true , true,true,vector_phase);
+ // extract kinematic variables
+ Energy M = hard[2]->mass();
+ Energy2 M2 = sqr(hard[2]->mass());
+ double phi = hard[2]->momentum().phi();
+ Energy2 sh = (hard[0]->momentum()+hard[1]->momentum()).m2();
+ Energy2 th = (hard[0]->momentum()-hard[2]->momentum()).m2();
+ Energy2 uh = (hard[0]->momentum()-hard[3]->momentum()).m2();
+ Energy2 um(uh-M2),tm(th-M2),sm(sh-M2);
+ Complex phase = exp(Complex(0.,phi));
+ // Energy rstu = sqrt(th*uh/sh);
+ // calculate the matrix element
+ ProductionMatrixElement me(PDT::Spin1,PDT::Spin1,PDT::Spin1,PDT::Spin1);
+ me(0,0,0,0)=(2*M2*sqr(phase)*sh*(10*pow<5,1>(M2)*sm+6*M2*pow<3,1>(sm)*th*uh+sqr(sm)*sqr(th)*sqr(uh)-6*pow<3,1>(M2)*sm*(sqr(th)-13*th*uh+sqr(uh))+pow<4,1>(M2)*(11*sqr(th)+54*th*uh+11*sqr(uh))+sqr(M2)*(-7*pow<4,1>(th)+34*pow<3,1>(th)*uh+66*sqr(th)*sqr(uh)+34*th*pow<3,1>(uh)-7*pow<4,1>(uh))))/(sqrt(15)*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,0,0,2)=(-4*sqrt(1.6666666666666667)*pow<3,1>(M2)*(M2+sh)*th*uh)/(sqr(sm)*sqr(tm)*sqr(um));
+ me(0,0,1,0)=(-4*sqrt(0.13333333333333333)*pow<3,1>(M)*phase*sh*sqrt(sh)*(th-uh)*sqrt(th*uh)*(3*sqr(M2)*(sh-uh)+sh*uh*(sh+uh)+M2*(5*sqr(sh)+2*sh*uh+3*sqr(uh))))/(sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,0,1,2)=(4*sqrt(3.3333333333333335)*pow<7,1>(M)*sqrt(sh)*(th-uh)*sqrt(th*uh))/(phase*sqr(sm)*sqr(tm)*sqr(um));
+ me(0,0,2,0)=(-4*M2*sqr(sh)*th*uh*(16*pow<3,1>(M2)+15*sqr(M2)*sm-sm*th*uh+M2*(5*sqr(th)+2*th*uh+5*sqr(uh))))/(sqrt(15)*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,0,2,2)=(4*sqrt(1.6666666666666667)*pow<3,1>(M2)*sh*(M2*sm+2*th*uh))/(sqr(phase)*sqr(sm)*sqr(tm)*sqr(um));
+ me(0,2,0,0)=(-2*M2*th*(2*pow<4,1>(M2)*(sh+th)+2*sqr(sh)*sqr(th)*(sh+th)+3*pow<3,1>(M2)*(5*sqr(sh)+6*sh*th+5*sqr(th))+M2*sh*th*(7*sqr(sh)+2*sh*th+7*sqr(th))-sqr(M2)*(sh+th)*(15*sqr(sh)+10*sh*th+7*sqr(th)))*uh)/(sqrt(15)*pow<3,1>(sm)*sqr(tm)*pow<3,1>(um));
+ me(0,2,0,2)=(-2*M2*sh*sqr(uh)*(2*pow<4,1>(M2)-sm*sqr(th)*uh+M2*th*(th-uh)*(5*th+6*uh)+pow<3,1>(M2)*(13*th+15*uh)-sqr(M2)*(8*sqr(th)+17*th*uh+7*sqr(uh))))/(sqrt(15)*sqr(phase)*pow<3,1>(sm)*pow<3,1>(tm)*sqr(um));
+ me(0,2,1,0)=(2*sqrt(0.13333333333333333)*pow<3,1>(M)*sqrt(sh)*th*(pow<3,1>(M2)*(8*sh-4*th)-sqr(M2)*(3*sh-11*th)*(sh+th)-sh*th*(sh+th)*(3*sh+th)+M2*(-3*pow<3,1>(sh)+sqr(sh)*th-5*sh*sqr(th)+3*pow<3,1>(th)))*sqrt(th*uh))/(phase*pow<3,1>(sm)*sqr(tm)*pow<3,1>(um));
+ me(0,2,1,2)=(2*sqrt(0.13333333333333333)*pow<3,1>(M)*sqrt(sh)*uh*sqrt(th*uh)*(pow<3,1>(M2)*(8*sh-4*uh)-sqr(M2)*(3*sh-11*uh)*(sh+uh)-sh*uh*(sh+uh)*(3*sh+uh)+M2*(-3*pow<3,1>(sh)+sqr(sh)*uh-5*sh*sqr(uh)+3*pow<3,1>(uh))))/(pow(phase,3)*pow<3,1>(sm)*pow<3,1>(tm)*sqr(um));
+ me(0,2,2,0)=(-2*M2*sh*sqr(th)*(2*pow<4,1>(M2)-sm*th*sqr(uh)+pow<3,1>(M2)*(15*th+13*uh)+M2*uh*(-6*sqr(th)+th*uh+5*sqr(uh))-sqr(M2)*(7*sqr(th)+17*th*uh+8*sqr(uh))))/(sqrt(15)*sqr(phase)*pow<3,1>(sm)*sqr(tm)*pow<3,1>(um));
+ me(0,2,2,2)=(-2*M2*th*uh*(2*pow<4,1>(M2)*(sh+uh)+2*sqr(sh)*sqr(uh)*(sh+uh)+3*pow<3,1>(M2)*(5*sqr(sh)+6*sh*uh+5*sqr(uh))+M2*sh*uh*(7*sqr(sh)+2*sh*uh+7*sqr(uh))-sqr(M2)*(sh+uh)*(15*sqr(sh)+10*sh*uh+7*sqr(uh))))/(sqrt(15)*pow(phase,4)*pow<3,1>(sm)*pow<3,1>(tm)*sqr(um));
+ me(2,0,0,0)=(-2*M2*pow(phase,4)*th*uh*(2*pow<4,1>(M2)*(sh+uh)+2*sqr(sh)*sqr(uh)*(sh+uh)+3*pow<3,1>(M2)*(5*sqr(sh)+6*sh*uh+5*sqr(uh))+M2*sh*uh*(7*sqr(sh)+2*sh*uh+7*sqr(uh))-sqr(M2)*(sh+uh)*(15*sqr(sh)+10*sh*uh+7*sqr(uh))))/(sqrt(15)*pow<3,1>(sm)*pow<3,1>(tm)*sqr(um));
+ me(2,0,0,2)=(-2*M2*sqr(phase)*sh*sqr(th)*(2*pow<4,1>(M2)-sm*th*sqr(uh)+pow<3,1>(M2)*(15*th+13*uh)+M2*uh*(-6*sqr(th)+th*uh+5*sqr(uh))-sqr(M2)*(7*sqr(th)+17*th*uh+8*sqr(uh))))/(sqrt(15)*pow<3,1>(sm)*sqr(tm)*pow<3,1>(um));
+ me(2,0,1,0)=(-2*sqrt(0.13333333333333333)*pow<3,1>(M)*pow(phase,3)*sqrt(sh)*uh*sqrt(th*uh)*(pow<3,1>(M2)*(8*sh-4*uh)-sqr(M2)*(3*sh-11*uh)*(sh+uh)-sh*uh*(sh+uh)*(3*sh+uh)+M2*(-3*pow<3,1>(sh)+sqr(sh)*uh-5*sh*sqr(uh)+3*pow<3,1>(uh))))/(pow<3,1>(sm)*pow<3,1>(tm)*sqr(um));
+ me(2,0,1,2)=(-2*sqrt(0.13333333333333333)*pow<3,1>(M)*phase*sqrt(sh)*th*(pow<3,1>(M2)*(8*sh-4*th)-sqr(M2)*(3*sh-11*th)*(sh+th)-sh*th*(sh+th)*(3*sh+th)+M2*(-3*pow<3,1>(sh)+sqr(sh)*th-5*sh*sqr(th)+3*pow<3,1>(th)))*sqrt(th*uh))/(pow<3,1>(sm)*sqr(tm)*pow<3,1>(um));
+ me(2,0,2,0)=(-2*M2*sqr(phase)*sh*sqr(uh)*(2*pow<4,1>(M2)-sm*sqr(th)*uh+M2*th*(th-uh)*(5*th+6*uh)+pow<3,1>(M2)*(13*th+15*uh)-sqr(M2)*(8*sqr(th)+17*th*uh+7*sqr(uh))))/(sqrt(15)*pow<3,1>(sm)*pow<3,1>(tm)*sqr(um));
+ me(2,0,2,2)=(-2*M2*th*(2*pow<4,1>(M2)*(sh+th)+2*sqr(sh)*sqr(th)*(sh+th)+3*pow<3,1>(M2)*(5*sqr(sh)+6*sh*th+5*sqr(th))+M2*sh*th*(7*sqr(sh)+2*sh*th+7*sqr(th))-sqr(M2)*(sh+th)*(15*sqr(sh)+10*sh*th+7*sqr(th)))*uh)/(sqrt(15)*pow<3,1>(sm)*sqr(tm)*pow<3,1>(um));
+ me(2,2,0,0)=(4*sqrt(1.6666666666666667)*pow<3,1>(M2)*sqr(phase)*sh*(M2*sm+2*th*uh))/(sqr(sm)*sqr(tm)*sqr(um));
+ me(2,2,0,2)=(-4*M2*sqr(sh)*th*uh*(16*pow<3,1>(M2)+15*sqr(M2)*sm-sm*th*uh+M2*(5*sqr(th)+2*th*uh+5*sqr(uh))))/(sqrt(15)*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,2,1,0)=(4*sqrt(3.3333333333333335)*pow<7,1>(M)*phase*sqrt(sh)*sqrt(th*uh)*(-th+uh))/(sqr(sm)*sqr(tm)*sqr(um));
+ me(2,2,1,2)=(4*sqrt(0.13333333333333333)*pow<3,1>(M)*sh*sqrt(sh)*(th-uh)*sqrt(th*uh)*(3*sqr(M2)*(sh-uh)+sh*uh*(sh+uh)+M2*(5*sqr(sh)+2*sh*uh+3*sqr(uh))))/(phase*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,2,2,0)=(-4*sqrt(1.6666666666666667)*pow<3,1>(M2)*(M2+sh)*th*uh)/(sqr(sm)*sqr(tm)*sqr(um));
+ me(2,2,2,2)=(2*M2*sh*(10*pow<5,1>(M2)*sm+6*M2*pow<3,1>(sm)*th*uh+sqr(sm)*sqr(th)*sqr(uh)-6*pow<3,1>(M2)*sm*(sqr(th)-13*th*uh+sqr(uh))+pow<4,1>(M2)*(11*sqr(th)+54*th*uh+11*sqr(uh))+sqr(M2)*(-7*pow<4,1>(th)+34*pow<3,1>(th)*uh+66*sqr(th)*sqr(uh)+34*th*pow<3,1>(uh)-7*pow<4,1>(uh))))/(sqrt(15)*sqr(phase)*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ // test the spin averaged result
+ // Energy6 Q(sh*th*uh);
+ // Energy4 P(sh*th+th*uh+uh*sh);
+ // double test = (16*sqr(M2)*(-49*pow<3,1>(M2)*pow<5,1>(P)-sqr(M2)*pow<4,1>(P)*(20*pow<3,1>(M2)-67*Q)-52*pow<7,1>(M2)*sqr(Q)+894*pow<4,1>(M2)*pow<3,1>(Q)-5*M2*pow<4,1>(Q)+sqr(M2)*P*Q*(4*pow<6,1>(M2)-1742*pow<3,1>(M2)*Q-361*sqr(Q))-M2*pow<3,1>(P)*(102*pow<6,1>(M2)+295*pow<3,1>(M2)*Q-25*sqr(Q))+sqr(P)*Q*(902*pow<6,1>(M2)+729*pow<3,1>(M2)*Q+5*sqr(Q))))/(15.*pow<5,1>(Q-M2*P));
+
+ // double aver = me.average();
+ // cerr << "testing spin correlations " << test << " " << me.average() << " "
+ // << abs(test-aver)/(test+aver) << "\n";
+ // construct the vertex
+ HardVertexPtr hardvertex = new_ptr(HardVertex());
+ // // set the matrix element for the vertex
+ hardvertex->ME(me);
+ // set the pointers and to and from the vertex
+ for(unsigned int i = 0; i < hard.size(); ++i)
+ hard[i]->spinInfo()->productionVertex(hardvertex);
+ // boost back to lab
+ boost = LorentzRotation(pcms.boostVector());
+ for(PPtr part : hard)
+ part->transform(boost);
+}
diff --git a/MatrixElement/Onium/MEPPto3D1Jet.h b/MatrixElement/Onium/MEPPto3D1Jet.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto3D1Jet.h
@@ -0,0 +1,191 @@
+// -*- C++ -*-
+#ifndef Herwig_MEPPto3D1Jet_H
+#define Herwig_MEPPto3D1Jet_H
+//
+// This is the declaration of the MEPPto3D1Jet class.
+//
+
+#include "Herwig/MatrixElement/HwMEBase.h"
+#include "OniumParameters.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * The MEPPto3D1Jet class implements the colour singlet processes for
+ * \f$gg\to^3\!\!D_1 g\f$.
+ *
+ * @see \ref MEPPto3D1JetInterfaces "The interfaces"
+ * defined for MEPPto3D1Jet.
+ */
+class MEPPto3D1Jet: public HwMEBase {
+
+public:
+
+ /**
+ * The default constructor.
+ */
+ MEPPto3D1Jet(): O1_(ZERO), state_(ccbar), n_(1), mOpt_(0)
+ {}
+
+public:
+
+ /** @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 3;
+ }
+
+ /**
+ * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaEW() const {
+ return 0;
+ }
+
+ /**
+ * 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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ MEPPto3D1Jet & operator=(const MEPPto3D1Jet &) = delete;
+
+private:
+
+ /**
+ * Access to the parameters for the quarkonium states
+ */
+ OniumParametersPtr params_;
+
+ /**
+ * The \f$O_1\f$ colour-singlet coefficient
+ */
+ Energy7 O1_;
+
+ /**
+ * Type of state
+ */
+ OniumState state_;
+
+ /**
+ * Principal quantum number
+ */
+ unsigned int n_;
+
+ /**
+ * Option for the onium mass
+ */
+ unsigned int mOpt_;
+};
+
+}
+
+#endif /* Herwig_MEPPto3D1Jet_H */
diff --git a/MatrixElement/Onium/MEPPto3D2Jet.cc b/MatrixElement/Onium/MEPPto3D2Jet.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto3D2Jet.cc
@@ -0,0 +1,278 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the MEPPto3D2Jet class.
+//
+
+#include "MEPPto3D2Jet.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/PDT/EnumParticles.h"
+#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
+#include "ThePEG/Utilities/EnumIO.h"
+#include "ThePEG/StandardModel/StandardModelBase.h"
+#include "ThePEG/Helicity/WaveFunction/TensorWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
+#include "Herwig/MatrixElement/ProductionMatrixElement.h"
+#include "Herwig/MatrixElement/HardVertex.h"
+
+using namespace Herwig;
+
+void MEPPto3D2Jet::doinit() {
+ HwMEBase::doinit();
+ // get the non-perturbative ME
+ O1_ = params_->singletMEProduction<2>(state_,n_,1,2);
+ // set the mass option
+ massOption(vector<unsigned int>({mOpt_+1,0}));
+}
+
+IBPtr MEPPto3D2Jet::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr MEPPto3D2Jet::fullclone() const {
+ return new_ptr(*this);
+}
+
+void MEPPto3D2Jet::persistentOutput(PersistentOStream & os) const {
+ os << params_ << ounit(O1_,GeV*GeV2*GeV2*GeV2) << oenum(state_) << n_ << mOpt_;
+}
+
+void MEPPto3D2Jet::persistentInput(PersistentIStream & is, int) {
+ is >> params_ >> iunit(O1_,GeV*GeV2*GeV2*GeV2) >> ienum(state_) >> n_ >> mOpt_;
+}
+
+//The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<MEPPto3D2Jet,HwMEBase>
+describeHerwigMEPPto3D2Jet("Herwig::MEPPto3D2Jet",
+ "HwOniumParameters.so HwMEHadronOnium.so");
+
+void MEPPto3D2Jet::Init() {
+
+ static ClassDocumentation<MEPPto3D2Jet> documentation
+ ("The MEPPto3D2Jet class implements the g g to 3D2 g processes");
+
+ static Reference<MEPPto3D2Jet,OniumParameters> interfaceParameters
+ ("Parameters",
+ "Quarkonium parameters",
+ &MEPPto3D2Jet::params_, false, false, true, false, false);
+
+ static Switch<MEPPto3D2Jet,OniumState> interfaceState
+ ("State",
+ "The type of onium state",
+ &MEPPto3D2Jet::state_, ccbar, false, false);
+ static SwitchOption interfaceStateccbar
+ (interfaceState,
+ "ccbar",
+ "Charmonium state",
+ ccbar);
+ static SwitchOption interfaceStatebbbar
+ (interfaceState,
+ "bbbar",
+ "Bottomonium state",
+ bbbar);
+
+ static Parameter<MEPPto3D2Jet,unsigned int> interfacePrincipalQuantumNumber
+ ("PrincipalQuantumNumber",
+ "The principle quantum number of the states",
+ &MEPPto3D2Jet::n_, 1, 1, 10,
+ false, false, Interface::limited);
+
+ static Switch<MEPPto3D2Jet,unsigned int> interfaceMassOption
+ ("MassOption",
+ "Mass of the treatment of the 3D2 mass",
+ &MEPPto3D2Jet::mOpt_, 0, false, false);
+ static SwitchOption interfaceMassOptionOnShell
+ (interfaceMassOption,
+ "OnShell",
+ "Use the on-shell mass",
+ 0);
+ static SwitchOption interfaceMassOptionOffShell
+ (interfaceMassOption,
+ "OffShell",
+ "Use an off-shell mass generated by the MassGenerator object for the 3D2 state.",
+ 1);
+}
+
+void MEPPto3D2Jet::getDiagrams() const {
+ // construct the meson PDG code from quark ids
+ unsigned int iq = 4+state_;
+ tcPDPtr ps = getParticleData(long(iq*110 + 20005 + (n_-1)*100000));
+ tcPDPtr g = getParticleData(ParticleID::g);
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, ps, 1, g , -1)));
+}
+
+Selector<MEBase::DiagramIndex>
+MEPPto3D2Jet::diagrams(const DiagramVector & diags) const {
+ Selector<DiagramIndex> sel;
+ for ( DiagramIndex i = 0; i < diags.size(); ++i )
+ if ( diags[i]->id() == -1 ) sel.insert(1.0, i);
+ return sel;
+}
+
+Selector<const ColourLines *>
+MEPPto3D2Jet::colourGeometries(tcDiagPtr ) const {
+ static ColourLines c1("1 -2, 2 4, -1 -4");
+ static ColourLines c2("1 4, -4 -2, 2 -1");
+ Selector<const ColourLines *> sel;
+ sel.insert(0.5, &c1);
+ sel.insert(0.5, &c2);
+ return sel;
+}
+
+Energy2 MEPPto3D2Jet::scale() const {
+ return sHat();
+}
+
+double MEPPto3D2Jet::me2() const {
+ Energy M = meMomenta()[2].mass();
+ Energy2 M2=sqr(M);
+ Energy4 um(sqr(uHat()-M2)),tm(sqr(tHat()-M2)),sm(sqr(sHat()-M2));
+ double output = 16.*O1_*pow(Constants::pi*standardModel()->alphaS(scale()),3)/(27.*pow<7,1>(M))*
+ (32*sqr(M2)*(pow<10,1>(M2)*pow<3,1>(tHat())-3*pow<9,1>(M2)*pow<4,1>(tHat())+5*pow<8,1>(M2)*pow<5,1>(tHat())-11*pow<7,1>(M2)*pow<6,1>(tHat())
+ +20*pow<6,1>(M2)*pow<7,1>(tHat())-20*pow<5,1>(M2)*pow<8,1>(tHat())+10*pow<4,1>(M2)*pow<9,1>(tHat())-2*pow<3,1>(M2)*pow<10,1>(tHat())
+ +9*pow<10,1>(M2)*sqr(tHat())*uHat()-64*pow<9,1>(M2)*pow<3,1>(tHat())*uHat()+180*pow<8,1>(M2)*pow<4,1>(tHat())*uHat()
+ -280*pow<7,1>(M2)*pow<5,1>(tHat())*uHat()+269*pow<6,1>(M2)*pow<6,1>(tHat())*uHat()-144*pow<5,1>(M2)*pow<7,1>(tHat())*uHat()
+ +16*pow<4,1>(M2)*pow<8,1>(tHat())*uHat()+20*pow<3,1>(M2)*pow<9,1>(tHat())*uHat()-6*sqr(M2)*pow<10,1>(tHat())*uHat()
+ +9*pow<10,1>(M2)*tHat()*sqr(uHat())-130*pow<9,1>(M2)*sqr(tHat())*sqr(uHat())+611*pow<8,1>(M2)*pow<3,1>(tHat())*sqr(uHat())
+ -1369*pow<7,1>(M2)*pow<4,1>(tHat())*sqr(uHat())+1716*pow<6,1>(M2)*pow<5,1>(tHat())*sqr(uHat())-1283*pow<5,1>(M2)*pow<6,1>(tHat())*sqr(uHat())
+ +568*pow<4,1>(M2)*pow<7,1>(tHat())*sqr(uHat())-156*pow<3,1>(M2)*pow<8,1>(tHat())*sqr(uHat())+50*sqr(M2)*pow<9,1>(tHat())*sqr(uHat())
+ -16*M2*pow<10,1>(tHat())*sqr(uHat())+pow<10,1>(M2)*pow<3,1>(uHat())-64*pow<9,1>(M2)*tHat()*pow<3,1>(uHat())+611*pow<8,1>(M2)*sqr(tHat())*pow<3,1>(uHat())
+ -2208*pow<7,1>(M2)*pow<3,1>(tHat())*pow<3,1>(uHat())+3927*pow<6,1>(M2)*pow<4,1>(tHat())*pow<3,1>(uHat())-3888*pow<5,1>(M2)*pow<5,1>(tHat())*pow<3,1>(uHat())
+ +2365*pow<4,1>(M2)*pow<6,1>(tHat())*pow<3,1>(uHat())-1072*pow<3,1>(M2)*pow<7,1>(tHat())*pow<3,1>(uHat())+472*sqr(M2)*pow<8,1>(tHat())*pow<3,1>(uHat())
+ -160*M2*pow<9,1>(tHat())*pow<3,1>(uHat())+16*pow<10,1>(tHat())*pow<3,1>(uHat())-3*pow<9,1>(M2)*pow<4,1>(uHat())+180*pow<8,1>(M2)*tHat()*pow<4,1>(uHat())
+ -1369*pow<7,1>(M2)*sqr(tHat())*pow<4,1>(uHat())+3927*pow<6,1>(M2)*pow<3,1>(tHat())*pow<4,1>(uHat())-5450*pow<5,1>(M2)*pow<4,1>(tHat())*pow<4,1>(uHat())
+ +4181*pow<4,1>(M2)*pow<5,1>(tHat())*pow<4,1>(uHat())-2230*pow<3,1>(M2)*pow<6,1>(tHat())*pow<4,1>(uHat())+1172*sqr(M2)*pow<7,1>(tHat())*pow<4,1>(uHat())
+ -496*M2*pow<8,1>(tHat())*pow<4,1>(uHat())+80*pow<9,1>(tHat())*pow<4,1>(uHat())+5*pow<8,1>(M2)*pow<5,1>(uHat())-280*pow<7,1>(M2)*tHat()*pow<5,1>(uHat())
+ +1716*pow<6,1>(M2)*sqr(tHat())*pow<5,1>(uHat())-3888*pow<5,1>(M2)*pow<3,1>(tHat())*pow<5,1>(uHat())+4181*pow<4,1>(M2)*pow<4,1>(tHat())*pow<5,1>(uHat())
+ -2664*pow<3,1>(M2)*pow<5,1>(tHat())*pow<5,1>(uHat())+1570*sqr(M2)*pow<6,1>(tHat())*pow<5,1>(uHat())-832*M2*pow<7,1>(tHat())*pow<5,1>(uHat())
+ +192*pow<8,1>(tHat())*pow<5,1>(uHat())-11*pow<7,1>(M2)*pow<6,1>(uHat())+269*pow<6,1>(M2)*tHat()*pow<6,1>(uHat())-1283*pow<5,1>(M2)*sqr(tHat())*pow<6,1>(uHat())
+ +2365*pow<4,1>(M2)*pow<3,1>(tHat())*pow<6,1>(uHat())-2230*pow<3,1>(M2)*pow<4,1>(tHat())*pow<6,1>(uHat())+1570*sqr(M2)*pow<5,1>(tHat())*pow<6,1>(uHat())
+ -960*M2*pow<6,1>(tHat())*pow<6,1>(uHat())+288*pow<7,1>(tHat())*pow<6,1>(uHat())+20*pow<6,1>(M2)*pow<7,1>(uHat())-144*pow<5,1>(M2)*tHat()*pow<7,1>(uHat())
+ +568*pow<4,1>(M2)*sqr(tHat())*pow<7,1>(uHat())-1072*pow<3,1>(M2)*pow<3,1>(tHat())*pow<7,1>(uHat())+1172*sqr(M2)*pow<4,1>(tHat())*pow<7,1>(uHat())
+ -832*M2*pow<5,1>(tHat())*pow<7,1>(uHat())+288*pow<6,1>(tHat())*pow<7,1>(uHat())-20*pow<5,1>(M2)*pow<8,1>(uHat())+16*pow<4,1>(M2)*tHat()*pow<8,1>(uHat())
+ -156*pow<3,1>(M2)*sqr(tHat())*pow<8,1>(uHat())+472*sqr(M2)*pow<3,1>(tHat())*pow<8,1>(uHat())-496*M2*pow<4,1>(tHat())*pow<8,1>(uHat())
+ +192*pow<5,1>(tHat())*pow<8,1>(uHat())+10*pow<4,1>(M2)*pow<9,1>(uHat())+20*pow<3,1>(M2)*tHat()*pow<9,1>(uHat())+50*sqr(M2)*sqr(tHat())*pow<9,1>(uHat())
+ -160*M2*pow<3,1>(tHat())*pow<9,1>(uHat())+80*pow<4,1>(tHat())*pow<9,1>(uHat())-2*pow<3,1>(M2)*pow<10,1>(uHat())-6*sqr(M2)*tHat()*pow<10,1>(uHat())
+ -16*M2*sqr(tHat())*pow<10,1>(uHat())+16*pow<3,1>(tHat())*pow<10,1>(uHat())))/(3.*pow<5,1>(M2-tHat())*pow<5,1>(M2-uHat())*pow<5,1>(tHat()+uHat()));
+ // test vs PRD 45, 116
+ // Energy7 R02 = params_->secondDerivativeRadialWaveFunctionSquared(state_,n_);
+ // Energy6 Q(sHat()*tHat()*uHat());
+ // Energy4 P(sHat()*tHat()+tHat()*uHat()+uHat()*sHat());
+ // double test = 16.*Constants::pi*200.*Constants::pi*pow(standardModel()->alphaS(scale()),3)*R02/(9.*pow<3,1>(M)*pow<5,1>(Q-M2*P))*
+ // (sqr(P)*Q*(43*pow<6,1>(M2)+110*pow<3,1>(M2)*Q+16*sqr(Q))
+ // -sqr(M2)*P*Q*(6*pow<6,1>(M2)+157*pow<3,1>(M2)*Q+28*sqr(Q))
+ // -M2*pow<3,1>(P)*(pow<6,1>(M2)+26*pow<3,1>(M2)*Q+16*sqr(Q))
+ // +14*pow<7,1>(M2)*sqr(Q)+123*pow<4,1>(M2)*pow<3,1>(Q)
+ // -2*pow<3,1>(M2)*pow<5,1>(P)-6*sqr(M2)*pow<4,1>(P)*Q-64*M2*pow<4,1>(Q));
+ // cerr << "testing matrix element " << output << " " << test << " "
+ // << (output-test)/(output+test) << " " << output/test << "\n";
+ return output;
+}
+
+void MEPPto3D2Jet::constructVertex(tSubProPtr sub) {
+ using namespace ThePEG::Helicity;
+ // extract the particles in the hard process
+ // only one order
+ ParticleVector hard;
+ hard.reserve(4);
+ hard.push_back(sub->incoming().first);
+ hard.push_back(sub->incoming().second);
+ hard.push_back(sub->outgoing()[0]);
+ hard.push_back(sub->outgoing()[1]);
+ // boost to partonic CMS
+ Lorentz5Momentum pcms = hard[0]->momentum()+hard[1]->momentum();
+ LorentzRotation boost(-pcms.boostVector());
+ for(PPtr part : hard) part->transform(boost);
+ // set the wavefunctions
+ vector<VectorWaveFunction> g1,g2,g4;
+ vector<TensorWaveFunction> psi;
+ VectorWaveFunction( g1,hard[0],incoming,false, true,true,vector_phase);
+ VectorWaveFunction( g2,hard[1],incoming,false, true,true,vector_phase);
+ TensorWaveFunction(psi,hard[2],outgoing,true ,false,true,tensor_phase);
+ VectorWaveFunction( g4,hard[3],outgoing,true , true,true,vector_phase);
+ // extract kinematic variables
+ Energy M = hard[2]->mass();
+ Energy2 M2 = sqr(hard[2]->mass());
+ double phi = hard[2]->momentum().phi();
+ Energy2 sh = (hard[0]->momentum()+hard[1]->momentum()).m2();
+ Energy2 th = (hard[0]->momentum()-hard[2]->momentum()).m2();
+ Energy2 uh = (hard[0]->momentum()-hard[3]->momentum()).m2();
+ Energy2 um(uh-M2),tm(th-M2),sm(sh-M2);
+ Complex phase = exp(Complex(0.,phi));
+ // Energy rstu = sqrt(th*uh/sh);
+ // calculate the matrix element
+ ProductionMatrixElement me(PDT::Spin1,PDT::Spin1,PDT::Spin2,PDT::Spin1);
+ me(0,0,0,0)=(8*pow<3,1>(M)*pow(phase,3)*sqrt(sh)*(th-uh)*sqrt(th*uh)*(-(pow<3,1>(M2)*(sh+uh))-sqr(sh)*uh*(sh+uh)+sqr(M2)*(sqr(sh)+4*sh*uh+sqr(uh))-M2*sh*(sqr(sh)+2*sh*uh+3*sqr(uh))))/(sqrt(3)*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,0,0,2)=0;
+ me(0,0,1,0)=(4*M2*sqr(phase)*sh*(2*sqr(th)*sqr(uh)*sqr(th+uh)+2*pow<4,1>(M2)*(sqr(th)-th*uh+sqr(uh))+pow<3,1>(M2)*(-3*pow<3,1>(th)+sqr(th)*uh+th*sqr(uh)-3*pow<3,1>(uh))+M2*th*uh*(3*pow<3,1>(th)-11*sqr(th)*uh-11*th*sqr(uh)+3*pow<3,1>(uh))+sqr(M2)*(pow<4,1>(th)-2*pow<3,1>(th)*uh+12*sqr(th)*sqr(uh)-2*th*pow<3,1>(uh)+pow<4,1>(uh))))/(sqrt(3)*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,0,1,2)=0;
+ me(0,0,2,0)=(4*sqrt(2)*pow<3,1>(M)*phase*sh*sqrt(sh)*(th-uh)*sqrt(th*uh)*(pow<3,1>(M2)-3*M2*th*uh-sqr(M2)*(th+uh)+2*th*uh*(th+uh)))/(sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,0,2,2)=0;
+ me(0,0,3,0)=(8*M2*sqr(sh)*th*uh*(pow<3,1>(M2)-3*M2*th*uh+th*uh*(th+uh)))/(sqrt(3)*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,0,3,2)=0;
+ me(0,0,4,0)=0;
+ me(0,0,4,2)=0;
+ me(0,2,0,0)=(8*pow<3,1>(M)*phase*sqrt(sh)*uh*sqrt(th*uh)*(pow<4,1>(M2)-3*pow<3,1>(M2)*uh+2*sqr(M2)*uh*(th+uh)+2*sqr(th)*uh*(th+uh)-2*M2*th*uh*(2*th+uh)))/(sqrt(3)*pow<3,1>(sm)*sqr(tm)*pow<3,1>(um));
+ me(0,2,0,2)=(-8*pow<3,1>(M)*sh*sqrt(sh)*sqr(uh)*sqrt(th*uh)*(-2*sqr(M2)+M2*uh+th*uh))/(sqrt(3)*phase*pow<3,1>(sm)*pow<3,1>(tm)*sqr(um));
+ me(0,2,1,0)=(4*M2*th*(2*pow<3,1>(M2)*sh*(2*sh-th)+pow<4,1>(M2)*(sh+th)-2*sqr(sh)*sqr(th)*(sh+th)+2*M2*sh*th*(2*sqr(sh)+sh*th-2*sqr(th))-sqr(M2)*(8*pow<3,1>(sh)+14*sqr(sh)*th-sh*sqr(th)+pow<3,1>(th)))*uh)/(sqrt(3)*pow<3,1>(sm)*sqr(tm)*pow<3,1>(um));
+ me(0,2,1,2)=(4*M2*sh*sqr(uh)*(pow<4,1>(M2)-9*pow<3,1>(M2)*th+M2*th*(2*th-3*uh)*uh-2*sqr(th)*uh*(th+uh)+sqr(M2)*(6*sqr(th)+8*th*uh-sqr(uh))))/(sqrt(3)*sqr(phase)*pow<3,1>(sm)*pow<3,1>(tm)*sqr(um));
+ me(0,2,2,0)=(-4*sqrt(2)*pow<3,1>(M)*sqrt(sh)*th*sqrt(th*uh)*(2*sqr(M2)*(sh-uh)*uh+pow<3,1>(M2)*(-sh+uh)+M2*sqr(uh)*(-sh+uh)+2*sh*uh*sqr(sh+uh)))/(phase*pow<3,1>(sm)*sqr(tm)*pow<3,1>(um));
+ me(0,2,2,2)=(4*sqrt(2)*pow<3,1>(M)*sqrt(sh)*(2*sqr(M2)*(sh-th)*th+pow<3,1>(M2)*(-sh+th)+M2*sqr(th)*(-sh+th)+2*sh*th*sqr(sh+th))*uh*sqrt(th*uh))/(pow(phase,3)*pow<3,1>(sm)*pow<3,1>(tm)*sqr(um));
+ me(0,2,3,0)=(-4*M2*sh*sqr(th)*(pow<4,1>(M2)-9*pow<3,1>(M2)*uh-2*th*sqr(uh)*(th+uh)+M2*th*uh*(-3*th+2*uh)+sqr(M2)*(-sqr(th)+8*th*uh+6*sqr(uh))))/(sqrt(3)*sqr(phase)*pow<3,1>(sm)*sqr(tm)*pow<3,1>(um));
+ me(0,2,3,2)=(-4*M2*th*uh*(2*pow<3,1>(M2)*sh*(2*sh-uh)+pow<4,1>(M2)*(sh+uh)-2*sqr(sh)*sqr(uh)*(sh+uh)+2*M2*sh*uh*(2*sqr(sh)+sh*uh-2*sqr(uh))-sqr(M2)*(8*pow<3,1>(sh)+14*sqr(sh)*uh-sh*sqr(uh)+pow<3,1>(uh))))/(sqrt(3)*pow(phase,4)*pow<3,1>(sm)*pow<3,1>(tm)*sqr(um));
+ me(0,2,4,0)=(8*pow<3,1>(M)*sh*sqrt(sh)*sqr(th)*sqrt(th*uh)*(-2*sqr(M2)+M2*th+th*uh))/(sqrt(3)*pow(phase,3)*pow<3,1>(sm)*sqr(tm)*pow<3,1>(um));
+ me(0,2,4,2)=(-8*pow<3,1>(M)*sqrt(sh)*th*sqrt(th*uh)*(pow<4,1>(M2)-3*pow<3,1>(M2)*th+2*sqr(M2)*th*(th+uh)+2*th*sqr(uh)*(th+uh)-2*M2*th*uh*(th+2*uh)))/(sqrt(3)*pow(phase,5)*pow<3,1>(sm)*pow<3,1>(tm)*sqr(um));
+ me(2,0,0,0)=(-8*pow<3,1>(M)*pow(phase,5)*sqrt(sh)*th*sqrt(th*uh)*(pow<4,1>(M2)-3*pow<3,1>(M2)*th+2*sqr(M2)*th*(th+uh)+2*th*sqr(uh)*(th+uh)-2*M2*th*uh*(th+2*uh)))/(sqrt(3)*pow<3,1>(sm)*pow<3,1>(tm)*sqr(um));
+ me(2,0,0,2)=(8*pow<3,1>(M)*pow(phase,3)*sh*sqrt(sh)*sqr(th)*sqrt(th*uh)*(-2*sqr(M2)+M2*th+th*uh))/(sqrt(3)*pow<3,1>(sm)*sqr(tm)*pow<3,1>(um));
+ me(2,0,1,0)=(4*M2*pow(phase,4)*th*uh*(2*pow<3,1>(M2)*sh*(2*sh-uh)+pow<4,1>(M2)*(sh+uh)-2*sqr(sh)*sqr(uh)*(sh+uh)+2*M2*sh*uh*(2*sqr(sh)+sh*uh-2*sqr(uh))-sqr(M2)*(8*pow<3,1>(sh)+14*sqr(sh)*uh-sh*sqr(uh)+pow<3,1>(uh))))/(sqrt(3)*pow<3,1>(sm)*pow<3,1>(tm)*sqr(um));
+ me(2,0,1,2)=(4*M2*sqr(phase)*sh*sqr(th)*(pow<4,1>(M2)-9*pow<3,1>(M2)*uh-2*th*sqr(uh)*(th+uh)+M2*th*uh*(-3*th+2*uh)+sqr(M2)*(-sqr(th)+8*th*uh+6*sqr(uh))))/(sqrt(3)*pow<3,1>(sm)*sqr(tm)*pow<3,1>(um));
+ me(2,0,2,0)=(4*sqrt(2)*pow<3,1>(M)*pow(phase,3)*sqrt(sh)*(2*sqr(M2)*(sh-th)*th+pow<3,1>(M2)*(-sh+th)+M2*sqr(th)*(-sh+th)+2*sh*th*sqr(sh+th))*uh*sqrt(th*uh))/(pow<3,1>(sm)*pow<3,1>(tm)*sqr(um));
+ me(2,0,2,2)=(-4*sqrt(2)*pow<3,1>(M)*phase*sqrt(sh)*th*sqrt(th*uh)*(2*sqr(M2)*(sh-uh)*uh+pow<3,1>(M2)*(-sh+uh)+M2*sqr(uh)*(-sh+uh)+2*sh*uh*sqr(sh+uh)))/(pow<3,1>(sm)*sqr(tm)*pow<3,1>(um));
+ me(2,0,3,0)=(-4*M2*sqr(phase)*sh*sqr(uh)*(pow<4,1>(M2)-9*pow<3,1>(M2)*th+M2*th*(2*th-3*uh)*uh-2*sqr(th)*uh*(th+uh)+sqr(M2)*(6*sqr(th)+8*th*uh-sqr(uh))))/(sqrt(3)*pow<3,1>(sm)*pow<3,1>(tm)*sqr(um));
+ me(2,0,3,2)=(-4*M2*th*(2*pow<3,1>(M2)*sh*(2*sh-th)+pow<4,1>(M2)*(sh+th)-2*sqr(sh)*sqr(th)*(sh+th)+2*M2*sh*th*(2*sqr(sh)+sh*th-2*sqr(th))-sqr(M2)*(8*pow<3,1>(sh)+14*sqr(sh)*th-sh*sqr(th)+pow<3,1>(th)))*uh)/(sqrt(3)*pow<3,1>(sm)*sqr(tm)*pow<3,1>(um));
+ me(2,0,4,0)=(-8*pow<3,1>(M)*phase*sh*sqrt(sh)*sqr(uh)*sqrt(th*uh)*(-2*sqr(M2)+M2*uh+th*uh))/(sqrt(3)*pow<3,1>(sm)*pow<3,1>(tm)*sqr(um));
+ me(2,0,4,2)=(8*pow<3,1>(M)*sqrt(sh)*uh*sqrt(th*uh)*(pow<4,1>(M2)-3*pow<3,1>(M2)*uh+2*sqr(M2)*uh*(th+uh)+2*sqr(th)*uh*(th+uh)-2*M2*th*uh*(2*th+uh)))/(sqrt(3)*phase*pow<3,1>(sm)*sqr(tm)*pow<3,1>(um));
+ me(2,2,0,0)=0;
+ me(2,2,0,2)=0;
+ me(2,2,1,0)=0;
+ me(2,2,1,2)=(-8*M2*sqr(sh)*th*uh*(pow<3,1>(M2)-3*M2*th*uh+th*uh*(th+uh)))/(sqrt(3)*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,2,2,0)=0;
+ me(2,2,2,2)=(4*sqrt(2)*pow<3,1>(M)*sh*sqrt(sh)*(th-uh)*sqrt(th*uh)*(pow<3,1>(M2)-3*M2*th*uh-sqr(M2)*(th+uh)+2*th*uh*(th+uh)))/(phase*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,2,3,0)=0;
+ me(2,2,3,2)=(-4*M2*sh*(2*sqr(th)*sqr(uh)*sqr(th+uh)+2*pow<4,1>(M2)*(sqr(th)-th*uh+sqr(uh))+pow<3,1>(M2)*(-3*pow<3,1>(th)+sqr(th)*uh+th*sqr(uh)-3*pow<3,1>(uh))+M2*th*uh*(3*pow<3,1>(th)-11*sqr(th)*uh-11*th*sqr(uh)+3*pow<3,1>(uh))+sqr(M2)*(pow<4,1>(th)-2*pow<3,1>(th)*uh+12*sqr(th)*sqr(uh)-2*th*pow<3,1>(uh)+pow<4,1>(uh))))/(sqrt(3)*sqr(phase)*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,2,4,0)=0;
+ me(2,2,4,2)=(8*pow<3,1>(M)*sqrt(sh)*(th-uh)*sqrt(th*uh)*(-(pow<3,1>(M2)*(sh+uh))-sqr(sh)*uh*(sh+uh)+sqr(M2)*(sqr(sh)+4*sh*uh+sqr(uh))-M2*sh*(sqr(sh)+2*sh*uh+3*sqr(uh))))/(sqrt(3)*pow(phase,3)*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ // test the spin averaged result
+ // Energy6 Q(sh*th*uh);
+ // Energy4 P(sh*th+th*uh+uh*sh);
+ // double test = 32.*sqr(M2)/3/pow<5,1>(Q-M2*P)*
+ // (sqr(P)*Q*(43*pow<6,1>(M2)+110*pow<3,1>(M2)*Q+16*sqr(Q))
+ // -sqr(M2)*P*Q*(6*pow<6,1>(M2)+157*pow<3,1>(M2)*Q+28*sqr(Q))
+ // -M2*pow<3,1>(P)*(pow<6,1>(M2)+26*pow<3,1>(M2)*Q+16*sqr(Q))
+ // +14*pow<7,1>(M2)*sqr(Q)+123*pow<4,1>(M2)*pow<3,1>(Q)
+ // -2*pow<3,1>(M2)*pow<5,1>(P)-6*sqr(M2)*pow<4,1>(P)*Q-64*M2*pow<4,1>(Q));
+ // double aver = me.average();
+ // cerr << "testing spin correlations " << test << " " << me.average() << " "
+ // << abs(test-aver)/(test+aver) << "\n";
+ // construct the vertex
+ HardVertexPtr hardvertex = new_ptr(HardVertex());
+ // // set the matrix element for the vertex
+ hardvertex->ME(me);
+ // set the pointers and to and from the vertex
+ for(unsigned int i = 0; i < hard.size(); ++i)
+ hard[i]->spinInfo()->productionVertex(hardvertex);
+ // boost back to lab
+ boost = LorentzRotation(pcms.boostVector());
+ for(PPtr part : hard)
+ part->transform(boost);
+}
diff --git a/MatrixElement/Onium/MEPPto3D2Jet.h b/MatrixElement/Onium/MEPPto3D2Jet.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto3D2Jet.h
@@ -0,0 +1,191 @@
+// -*- C++ -*-
+#ifndef Herwig_MEPPto3D2Jet_H
+#define Herwig_MEPPto3D2Jet_H
+//
+// This is the declaration of the MEPPto3D2Jet class.
+//
+
+#include "Herwig/MatrixElement/HwMEBase.h"
+#include "OniumParameters.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * The MEPPto3D2Jet class implements the colour singlet processes for
+ * \f$gg\to^3\!\!D_2 g\f$.
+ *
+ * @see \ref MEPPto3D2JetInterfaces "The interfaces"
+ * defined for MEPPto3D2Jet.
+ */
+class MEPPto3D2Jet: public HwMEBase {
+
+public:
+
+ /**
+ * The default constructor.
+ */
+ MEPPto3D2Jet(): O1_(ZERO), state_(ccbar), n_(1), mOpt_(0)
+ {}
+
+public:
+
+ /** @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 3;
+ }
+
+ /**
+ * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaEW() const {
+ return 0;
+ }
+
+ /**
+ * 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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ MEPPto3D2Jet & operator=(const MEPPto3D2Jet &) = delete;
+
+private:
+
+ /**
+ * Access to the parameters for the quarkonium states
+ */
+ OniumParametersPtr params_;
+
+ /**
+ * The \f$O_1\f$ colour-singlet coefficient
+ */
+ Energy7 O1_;
+
+ /**
+ * Type of state
+ */
+ OniumState state_;
+
+ /**
+ * Principal quantum number
+ */
+ unsigned int n_;
+
+ /**
+ * Option for the onium mass
+ */
+ unsigned int mOpt_;
+};
+
+}
+
+#endif /* Herwig_MEPPto3D2Jet_H */
diff --git a/MatrixElement/Onium/MEPPto3D3Jet.cc b/MatrixElement/Onium/MEPPto3D3Jet.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto3D3Jet.cc
@@ -0,0 +1,291 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the MEPPto3D3Jet class.
+//
+
+#include "MEPPto3D3Jet.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/PDT/EnumParticles.h"
+#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
+#include "ThePEG/Utilities/EnumIO.h"
+#include "ThePEG/StandardModel/StandardModelBase.h"
+#include "ThePEG/Helicity/WaveFunction/Rank3TensorWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
+#include "Herwig/MatrixElement/ProductionMatrixElement.h"
+#include "Herwig/MatrixElement/HardVertex.h"
+
+using namespace Herwig;
+
+void MEPPto3D3Jet::doinit() {
+ HwMEBase::doinit();
+ // get the non-perturbative ME
+ O1_ = params_->singletMEProduction<2>(state_,n_,1,3);
+ // set the mass option
+ massOption(vector<unsigned int>({mOpt_+1,0}));
+}
+
+IBPtr MEPPto3D3Jet::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr MEPPto3D3Jet::fullclone() const {
+ return new_ptr(*this);
+}
+
+void MEPPto3D3Jet::persistentOutput(PersistentOStream & os) const {
+ os << params_ << ounit(O1_,GeV*GeV2*GeV2*GeV2) << oenum(state_) << n_ << mOpt_;
+}
+
+void MEPPto3D3Jet::persistentInput(PersistentIStream & is, int) {
+ is >> params_ >> iunit(O1_,GeV*GeV2*GeV2*GeV2) >> ienum(state_) >> n_ >> mOpt_;
+}
+
+//The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<MEPPto3D3Jet,HwMEBase>
+describeHerwigMEPPto3D3Jet("Herwig::MEPPto3D3Jet",
+ "HwOniumParameters.so HwMEHadronOnium.so");
+
+void MEPPto3D3Jet::Init() {
+
+ static ClassDocumentation<MEPPto3D3Jet> documentation
+ ("The MEPPto3D3Jet class implements the g g to 3D3 g processes");
+
+ static Reference<MEPPto3D3Jet,OniumParameters> interfaceParameters
+ ("Parameters",
+ "Quarkonium parameters",
+ &MEPPto3D3Jet::params_, false, false, true, false, false);
+
+ static Switch<MEPPto3D3Jet,OniumState> interfaceState
+ ("State",
+ "The type of onium state",
+ &MEPPto3D3Jet::state_, ccbar, false, false);
+ static SwitchOption interfaceStateccbar
+ (interfaceState,
+ "ccbar",
+ "Charmonium state",
+ ccbar);
+ static SwitchOption interfaceStatebbbar
+ (interfaceState,
+ "bbbar",
+ "Bottomonium state",
+ bbbar);
+
+ static Parameter<MEPPto3D3Jet,unsigned int> interfacePrincipalQuantumNumber
+ ("PrincipalQuantumNumber",
+ "The principle quantum number of the states",
+ &MEPPto3D3Jet::n_, 1, 1, 10,
+ false, false, Interface::limited);
+
+ static Switch<MEPPto3D3Jet,unsigned int> interfaceMassOption
+ ("MassOption",
+ "Mass of the treatment of the 3D3 mass",
+ &MEPPto3D3Jet::mOpt_, 0, false, false);
+ static SwitchOption interfaceMassOptionOnShell
+ (interfaceMassOption,
+ "OnShell",
+ "Use the on-shell mass",
+ 0);
+ static SwitchOption interfaceMassOptionOffShell
+ (interfaceMassOption,
+ "OffShell",
+ "Use an off-shell mass generated by the MassGenerator object for the 3D3 state.",
+ 1);
+}
+
+void MEPPto3D3Jet::getDiagrams() const {
+ // construct the meson PDG code from quark ids
+ unsigned int iq = 4+state_;
+ tcPDPtr ps = getParticleData(long(iq*110 + 7 + (n_-1)*100000));
+ tcPDPtr g = getParticleData(ParticleID::g);
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, ps, 1, g , -1)));
+}
+
+Selector<MEBase::DiagramIndex>
+MEPPto3D3Jet::diagrams(const DiagramVector & diags) const {
+ Selector<DiagramIndex> sel;
+ for ( DiagramIndex i = 0; i < diags.size(); ++i )
+ if ( diags[i]->id() == -1 ) sel.insert(1.0, i);
+ return sel;
+}
+
+Selector<const ColourLines *>
+MEPPto3D3Jet::colourGeometries(tcDiagPtr ) const {
+ static ColourLines c1("1 -2, 2 4, -1 -4");
+ static ColourLines c2("1 4, -4 -2, 2 -1");
+ Selector<const ColourLines *> sel;
+ sel.insert(0.5, &c1);
+ sel.insert(0.5, &c2);
+ return sel;
+}
+
+Energy2 MEPPto3D3Jet::scale() const {
+ return sHat();
+}
+
+double MEPPto3D3Jet::me2() const {
+ Energy M = meMomenta()[2].mass();
+ Energy2 M2=sqr(M);
+ Energy4 um(sqr(uHat()-M2)),tm(sqr(tHat()-M2)),sm(sqr(sHat()-M2));
+ double output = 80.*O1_*pow(Constants::pi*standardModel()->alphaS(scale()),3)/(189*pow<7,1>(M))*256.*sqr(M2)*
+ (5*pow<3,1>(tHat())*pow<3,1>(uHat())*pow<3,1>(tHat()+uHat())*sqr(sqr(tHat())+tHat()*uHat()+sqr(uHat()))
+ +2*pow<10,1>(M2)*(4*pow<3,1>(tHat())+9*sqr(tHat())*uHat()+9*tHat()*sqr(uHat())+4*pow<3,1>(uHat()))
+ -2*pow<9,1>(M2)*(12*pow<4,1>(tHat())+64*pow<3,1>(tHat())*uHat()+103*sqr(tHat())*sqr(uHat())+64*tHat()*pow<3,1>(uHat())+12*pow<4,1>(uHat()))
+ +pow<8,1>(M2)*(25*pow<5,1>(tHat())+300*pow<4,1>(tHat())*uHat()+826*pow<3,1>(tHat())*sqr(uHat())+826*sqr(tHat())*pow<3,1>(uHat())+300*tHat()*pow<4,1>(uHat())+25*pow<5,1>(uHat()))
+ -5*M2*sqr(tHat())*sqr(uHat())*sqr(tHat()+uHat())*(pow<6,1>(tHat())+8*pow<5,1>(tHat())*uHat()+14*pow<4,1>(tHat())*sqr(uHat())
+ +16*pow<3,1>(tHat())*pow<3,1>(uHat())+14*sqr(tHat())*pow<4,1>(uHat())+8*tHat()*pow<5,1>(uHat())+pow<6,1>(uHat()))
+ -pow<7,1>(M2)*(13*pow<6,1>(tHat())+356*pow<5,1>(tHat())*uHat()+1556*pow<4,1>(tHat())*sqr(uHat())+2424*pow<3,1>(tHat())*pow<3,1>(uHat())
+ +1556*sqr(tHat())*pow<4,1>(uHat())+356*tHat()*pow<5,1>(uHat())+13*pow<6,1>(uHat()))
+ +pow<6,1>(M2)*(10*pow<7,1>(tHat())+283*pow<6,1>(tHat())*uHat()+1680*pow<5,1>(tHat())*sqr(uHat())+3717*pow<4,1>(tHat())*pow<3,1>(uHat())
+ +3717*pow<3,1>(tHat())*pow<4,1>(uHat())+1680*sqr(tHat())*pow<5,1>(uHat())+283*tHat()*pow<6,1>(uHat())+10*pow<7,1>(uHat()))
+ -pow<5,1>(M2)*(10*pow<8,1>(tHat())+180*pow<7,1>(tHat())*uHat()+1201*pow<6,1>(tHat())*sqr(uHat())+3342*pow<5,1>(tHat())*pow<3,1>(uHat())+4624*pow<4,1>(tHat())*pow<4,1>(uHat())
+ +3342*pow<3,1>(tHat())*pow<5,1>(uHat())+1201*sqr(tHat())*pow<6,1>(uHat())+180*tHat()*pow<7,1>(uHat())+10*pow<8,1>(uHat()))
+ +sqr(M2)*tHat()*uHat()*(3*pow<9,1>(tHat())+40*pow<8,1>(tHat())*uHat()+221*pow<7,1>(tHat())*sqr(uHat())+514*pow<6,1>(tHat())*pow<3,1>(uHat())
+ +698*pow<5,1>(tHat())*pow<4,1>(uHat())+698*pow<4,1>(tHat())*pow<5,1>(uHat())+514*pow<3,1>(tHat())*pow<6,1>(uHat())
+ +221*sqr(tHat())*pow<7,1>(uHat())+40*tHat()*pow<8,1>(uHat())+3*pow<9,1>(uHat()))
+ +pow<4,1>(M2)*(5*pow<9,1>(tHat())+80*pow<8,1>(tHat())*uHat()+602*pow<7,1>(tHat())*sqr(uHat())+1943*pow<6,1>(tHat())*pow<3,1>(uHat())
+ +3307*pow<5,1>(tHat())*pow<4,1>(uHat())+3307*pow<4,1>(tHat())*pow<5,1>(uHat())+1943*pow<3,1>(tHat())*pow<6,1>(uHat())
+ +602*sqr(tHat())*pow<7,1>(uHat())+80*tHat()*pow<8,1>(uHat())+5*pow<9,1>(uHat()))
+ -pow<3,1>(M2)*(pow<10,1>(tHat())+20*pow<9,1>(tHat())*uHat()+198*pow<8,1>(tHat())*sqr(uHat())+776*pow<7,1>(tHat())*pow<3,1>(uHat())
+ +1502*pow<6,1>(tHat())*pow<4,1>(uHat())+1812*pow<5,1>(tHat())*pow<5,1>(uHat())+1502*pow<4,1>(tHat())*pow<6,1>(uHat())
+ +776*pow<3,1>(tHat())*pow<7,1>(uHat())+198*sqr(tHat())*pow<8,1>(uHat())+20*tHat()*pow<9,1>(uHat())+pow<10,1>(uHat())))
+ /(15.*pow<5,1>(M2-tHat())*pow<5,1>(M2-uHat())*pow<5,1>(tHat()+uHat()));
+ // test vs PRD 45, 116
+ // Energy7 R02 = params_->secondDerivativeRadialWaveFunctionSquared(state_,n_);
+ // Energy6 Q(sHat()*tHat()*uHat());
+ // Energy4 P(sHat()*tHat()+tHat()*uHat()+uHat()*sHat());
+ // double test = 5120.*sqr(Constants::pi)*pow(standardModel()->alphaS(scale()),3)*R02
+ // /(9.*pow<3,1>(M)*pow<5,1>(Q-M2*P))*
+ // (-pow<3,1>(M2)*pow<5,1>(P) + 3*sqr(M2)*pow<4,1>(P)*Q -
+ // 8*pow<7,1>(M2)*sqr(Q) + 111*pow<4,1>(M2)*pow<3,1>(Q) - 20*M2*pow<4,1>(Q) +
+ // sqr(M2)*P*Q*(6*pow<6,1>(M2) - 173*pow<3,1>(M2)*Q - 14*sqr(Q)) - M2*pow<3,1>(P)*
+ // (8*pow<6,1>(M2) + 25*pow<3,1>(M2)*Q + 5*sqr(Q)) +
+ // sqr(P)*Q*(68*pow<6,1>(M2) + 61*pow<3,1>(M2)*Q + 5*sqr(Q)));
+ // cerr << "testing matrix element " << output << " " << test << " "
+ // << (output-test)/(output+test) << " " << output/test << "\n";
+ return output;
+}
+
+void MEPPto3D3Jet::constructVertex(tSubProPtr sub) {
+ using namespace ThePEG::Helicity;
+ // extract the particles in the hard process
+ // only one order
+ ParticleVector hard;
+ hard.reserve(4);
+ hard.push_back(sub->incoming().first);
+ hard.push_back(sub->incoming().second);
+ hard.push_back(sub->outgoing()[0]);
+ hard.push_back(sub->outgoing()[1]);
+ // boost to partonic CMS
+ Lorentz5Momentum pcms = hard[0]->momentum()+hard[1]->momentum();
+ LorentzRotation boost(-pcms.boostVector());
+ for(PPtr part : hard) part->transform(boost);
+ // set the wavefunctions
+ vector<VectorWaveFunction> g1,g2,g4;
+ vector<Rank3TensorWaveFunction> psi;
+ VectorWaveFunction( g1,hard[0],incoming,false, true,true,vector_phase);
+ VectorWaveFunction( g2,hard[1],incoming,false, true,true,vector_phase);
+ Rank3TensorWaveFunction(psi,hard[2],outgoing,true ,false,true);
+ VectorWaveFunction( g4,hard[3],outgoing,true , true,true,vector_phase);
+ // extract kinematic variables
+ Energy M = hard[2]->mass();
+ Energy2 M2 = sqr(hard[2]->mass());
+ double phi = hard[2]->momentum().phi();
+ Energy2 sh = (hard[0]->momentum()+hard[1]->momentum()).m2();
+ Energy2 th = (hard[0]->momentum()-hard[2]->momentum()).m2();
+ Energy2 uh = (hard[0]->momentum()-hard[3]->momentum()).m2();
+ Energy2 um(uh-M2),tm(th-M2),sm(sh-M2);
+ Complex phase = exp(Complex(0.,phi));
+ // Energy rstu = sqrt(th*uh/sh);
+ // calculate the matrix element
+ ProductionMatrixElement me(PDT::Spin1,PDT::Spin1,PDT::Spin3,PDT::Spin1);
+ me(0,0,0,0)=(8*sqr(M2)*pow(phase,4)*th*uh*(pow<3,1>(M2)*(sh+uh)-sqr(M2)*uh*(2*sh+uh)-M2*sh*(sqr(sh)+2*sh*uh-sqr(uh))+sqr(sh)*(sqr(sh)+3*sh*uh+3*sqr(uh))))/(sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,0,0,2)=0;
+ me(0,0,1,0)=(8*sqrt(0.6666666666666666)*pow<3,1>(M)*pow(phase,3)*sqrt(sh)*(th-uh)*sqrt(th*uh)*(-(pow<3,1>(M2)*(sh+uh))-sqr(sh)*uh*(sh+uh)+sqr(M2)*(sqr(sh)+4*sh*uh+sqr(uh))-M2*sh*(sqr(sh)+2*sh*uh+3*sqr(uh))))/(sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,0,1,2)=0;
+ me(0,0,2,0)=(8*M2*sqr(phase)*sh*(2*sqr(th)*sqr(uh)*sqr(th+uh)+2*pow<4,1>(M2)*(sqr(th)-th*uh+sqr(uh))+pow<3,1>(M2)*(-3*pow<3,1>(th)+sqr(th)*uh+th*sqr(uh)-3*pow<3,1>(uh))+M2*th*uh*(3*pow<3,1>(th)-11*sqr(th)*uh-11*th*sqr(uh)+3*pow<3,1>(uh))+sqr(M2)*(pow<4,1>(th)-2*pow<3,1>(th)*uh+12*sqr(th)*sqr(uh)-2*th*pow<3,1>(uh)+pow<4,1>(uh))))/(sqrt(15)*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,0,2,2)=0;
+ me(0,0,3,0)=(8*pow<3,1>(M)*phase*sh*sqrt(sh)*(th-uh)*sqrt(th*uh)*(pow<3,1>(M2)-3*M2*th*uh-sqr(M2)*(th+uh)+2*th*uh*(th+uh)))/(sqrt(5)*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,0,3,2)=0;
+ me(0,0,4,0)=(8*M2*sqr(sh)*th*uh*(pow<3,1>(M2)-3*M2*th*uh+th*uh*(th+uh)))/(sqrt(15)*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,0,4,2)=0;
+ me(0,0,5,0)=0;
+ me(0,0,5,2)=0;
+ me(0,0,6,0)=0;
+ me(0,0,6,2)=0;
+ me(0,2,0,0)=(8*sqr(M2)*sqr(phase)*sh*sqr(uh)*(pow<4,1>(M2)*(th+uh)+3*sqr(M2)*th*uh*(th+uh)+pow<3,1>(th)*uh*(th+uh)-pow<3,1>(M2)*uh*(4*th+uh)-M2*sqr(th)*uh*(3*th+2*uh)))/(pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,2,0,2)=(8*sqr(M2)*sqr(sh)*th*pow<3,1>(uh)*(3*sqr(M2)+sqr(th)+th*uh+sqr(uh)-3*M2*(th+uh)))/(pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,2,1,0)=(-8*sqrt(0.6666666666666666)*pow<3,1>(M)*phase*sqrt(sh)*(pow<5,1>(M2)*(sh+th)+sqr(sh)*pow<3,1>(th)*(sh+th)-pow<4,1>(M2)*th*(5*sh+3*th)-M2*sh*sqr(th)*(2*sqr(sh)+sh*th-2*sqr(th))+sqr(M2)*sh*th*(5*sqr(sh)+7*sh*th-2*sqr(th))-pow<3,1>(M2)*(pow<3,1>(sh)+sqr(sh)*th-7*sh*sqr(th)-2*pow<3,1>(th)))*uh*sqrt(th*uh))/(pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,2,1,2)=(8*sqrt(0.6666666666666666)*pow<3,1>(M)*sh*sqrt(sh)*sqr(uh)*sqrt(th*uh)*(th*sqr(uh)*(th+uh)+pow<3,1>(M2)*(-7*th+2*uh)+sqr(M2)*(9*sqr(th)+6*th*uh-3*sqr(uh))+M2*(-3*pow<3,1>(th)-4*sqr(th)*uh-3*th*sqr(uh)+pow<3,1>(uh))))/(phase*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,2,2,0)=(8*M2*th*(pow<6,1>(M2)*(sh+th)+pow<3,1>(sh)*pow<3,1>(th)*(sh+th)+M2*sqr(sh)*pow<3,1>(th)*(9*sh+10*th)+pow<5,1>(M2)*(9*sqr(sh)+2*sh*th-sqr(th))-pow<4,1>(M2)*(15*pow<3,1>(sh)+48*sqr(sh)*th+14*sh*sqr(th)+pow<3,1>(th))+sqr(M2)*sh*th*(9*pow<3,1>(sh)-sqr(sh)*th-17*sh*sqr(th)+3*pow<3,1>(th))+pow<3,1>(M2)*(5*pow<4,1>(sh)+36*pow<3,1>(sh)*th+61*sqr(sh)*sqr(th)+8*sh*pow<3,1>(th)+pow<4,1>(th)))*uh)/(sqrt(15)*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,2,2,2)=(8*M2*sh*(2*sqr(sh)*sqr(th)*sqr(sh+th)+pow<4,1>(M2)*(2*sqr(sh)-6*sh*th+7*sqr(th))+M2*sh*th*(3*pow<3,1>(sh)+11*sqr(sh)*th+15*sh*sqr(th)+7*pow<3,1>(th))-pow<3,1>(M2)*(3*pow<3,1>(sh)+5*sqr(sh)*th-16*sh*sqr(th)+12*pow<3,1>(th))+sqr(M2)*(pow<4,1>(sh)+8*pow<3,1>(sh)*th+9*sqr(sh)*sqr(th)-7*sh*pow<3,1>(th)+6*pow<4,1>(th)))*sqr(uh))/(sqrt(15)*sqr(phase)*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,2,3,0)=(-8*pow<3,1>(M)*sqrt(sh)*th*(2*pow<4,1>(M2)*sh*(2*sh-3*th)+pow<5,1>(M2)*(3*sh+th)+2*sqr(sh)*sqr(th)*(sqr(sh)+3*sh*th+2*sqr(th))+M2*sh*sqr(th)*(-7*sqr(sh)-5*sh*th+4*sqr(th))-pow<3,1>(M2)*(15*pow<3,1>(sh)+31*sqr(sh)*th+3*sh*sqr(th)+3*pow<3,1>(th))+2*sqr(M2)*(4*pow<4,1>(sh)+18*pow<3,1>(sh)*th+19*sqr(sh)*sqr(th)+sh*pow<3,1>(th)+pow<4,1>(th)))*sqrt(th*uh))/(sqrt(5)*phase*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,2,3,2)=(-8*pow<3,1>(M)*sqrt(sh)*uh*sqrt(th*uh)*(2*pow<4,1>(M2)*sh*(2*sh-3*uh)+pow<5,1>(M2)*(3*sh+uh)+2*sqr(sh)*sqr(uh)*(sqr(sh)+3*sh*uh+2*sqr(uh))+M2*sh*sqr(uh)*(-7*sqr(sh)-5*sh*uh+4*sqr(uh))-pow<3,1>(M2)*(15*pow<3,1>(sh)+31*sqr(sh)*uh+3*sh*sqr(uh)+3*pow<3,1>(uh))+2*sqr(M2)*(4*pow<4,1>(sh)+18*pow<3,1>(sh)*uh+19*sqr(sh)*sqr(uh)+sh*pow<3,1>(uh)+pow<4,1>(uh))))/(sqrt(5)*pow(phase,3)*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,2,4,0)=(8*M2*sh*sqr(th)*(2*sqr(sh)*sqr(uh)*sqr(sh+uh)+pow<4,1>(M2)*(2*sqr(sh)-6*sh*uh+7*sqr(uh))+M2*sh*uh*(3*pow<3,1>(sh)+11*sqr(sh)*uh+15*sh*sqr(uh)+7*pow<3,1>(uh))-pow<3,1>(M2)*(3*pow<3,1>(sh)+5*sqr(sh)*uh-16*sh*sqr(uh)+12*pow<3,1>(uh))+sqr(M2)*(pow<4,1>(sh)+8*pow<3,1>(sh)*uh+9*sqr(sh)*sqr(uh)-7*sh*pow<3,1>(uh)+6*pow<4,1>(uh))))/(sqrt(15)*sqr(phase)*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,2,4,2)=(8*M2*th*uh*(pow<6,1>(M2)*(sh+uh)+pow<3,1>(sh)*pow<3,1>(uh)*(sh+uh)+M2*sqr(sh)*pow<3,1>(uh)*(9*sh+10*uh)+pow<5,1>(M2)*(9*sqr(sh)+2*sh*uh-sqr(uh))-pow<4,1>(M2)*(15*pow<3,1>(sh)+48*sqr(sh)*uh+14*sh*sqr(uh)+pow<3,1>(uh))+sqr(M2)*sh*uh*(9*pow<3,1>(sh)-sqr(sh)*uh-17*sh*sqr(uh)+3*pow<3,1>(uh))+pow<3,1>(M2)*(5*pow<4,1>(sh)+36*pow<3,1>(sh)*uh+61*sqr(sh)*sqr(uh)+8*sh*pow<3,1>(uh)+pow<4,1>(uh))))/(sqrt(15)*pow(phase,4)*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,2,5,0)=(8*sqrt(0.6666666666666666)*pow<3,1>(M)*sh*sqrt(sh)*sqr(th)*sqrt(th*uh)*(pow<3,1>(M2)*(2*th-7*uh)+sqr(th)*uh*(th+uh)+sqr(M2)*(-3*sqr(th)+6*th*uh+9*sqr(uh))+M2*(pow<3,1>(th)-3*sqr(th)*uh-4*th*sqr(uh)-3*pow<3,1>(uh))))/(pow(phase,3)*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,2,5,2)=(-8*sqrt(0.6666666666666666)*pow<3,1>(M)*sqrt(sh)*th*sqrt(th*uh)*(pow<5,1>(M2)*(sh+uh)+sqr(sh)*pow<3,1>(uh)*(sh+uh)-pow<4,1>(M2)*uh*(5*sh+3*uh)-M2*sh*sqr(uh)*(2*sqr(sh)+sh*uh-2*sqr(uh))+sqr(M2)*sh*uh*(5*sqr(sh)+7*sh*uh-2*sqr(uh))-pow<3,1>(M2)*(pow<3,1>(sh)+sqr(sh)*uh-7*sh*sqr(uh)-2*pow<3,1>(uh))))/(pow(phase,5)*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,2,6,0)=(8*sqr(M2)*sqr(sh)*pow<3,1>(th)*uh*(3*sqr(M2)+sqr(th)+th*uh+sqr(uh)-3*M2*(th+uh)))/(pow(phase,4)*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(0,2,6,2)=(8*sqr(M2)*sh*sqr(th)*(pow<4,1>(M2)*(th+uh)+3*sqr(M2)*th*uh*(th+uh)+th*pow<3,1>(uh)*(th+uh)-M2*th*sqr(uh)*(2*th+3*uh)-pow<3,1>(M2)*th*(th+4*uh)))/(pow(phase,6)*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,0,0,0)=(8*sqr(M2)*pow(phase,6)*sh*sqr(th)*(pow<4,1>(M2)*(th+uh)+3*sqr(M2)*th*uh*(th+uh)+th*pow<3,1>(uh)*(th+uh)-M2*th*sqr(uh)*(2*th+3*uh)-pow<3,1>(M2)*th*(th+4*uh)))/(pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,0,0,2)=(8*sqr(M2)*pow(phase,4)*sqr(sh)*pow<3,1>(th)*uh*(3*sqr(M2)+sqr(th)+th*uh+sqr(uh)-3*M2*(th+uh)))/(pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,0,1,0)=(8*sqrt(0.6666666666666666)*pow<3,1>(M)*pow(phase,5)*sqrt(sh)*th*sqrt(th*uh)*(pow<5,1>(M2)*(sh+uh)+sqr(sh)*pow<3,1>(uh)*(sh+uh)-pow<4,1>(M2)*uh*(5*sh+3*uh)-M2*sh*sqr(uh)*(2*sqr(sh)+sh*uh-2*sqr(uh))+sqr(M2)*sh*uh*(5*sqr(sh)+7*sh*uh-2*sqr(uh))-pow<3,1>(M2)*(pow<3,1>(sh)+sqr(sh)*uh-7*sh*sqr(uh)-2*pow<3,1>(uh))))/(pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,0,1,2)=(-8*sqrt(0.6666666666666666)*pow<3,1>(M)*pow(phase,3)*sh*sqrt(sh)*sqr(th)*sqrt(th*uh)*(pow<3,1>(M2)*(2*th-7*uh)+sqr(th)*uh*(th+uh)+sqr(M2)*(-3*sqr(th)+6*th*uh+9*sqr(uh))+M2*(pow<3,1>(th)-3*sqr(th)*uh-4*th*sqr(uh)-3*pow<3,1>(uh))))/(pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,0,2,0)=(8*M2*pow(phase,4)*th*uh*(pow<6,1>(M2)*(sh+uh)+pow<3,1>(sh)*pow<3,1>(uh)*(sh+uh)+M2*sqr(sh)*pow<3,1>(uh)*(9*sh+10*uh)+pow<5,1>(M2)*(9*sqr(sh)+2*sh*uh-sqr(uh))-pow<4,1>(M2)*(15*pow<3,1>(sh)+48*sqr(sh)*uh+14*sh*sqr(uh)+pow<3,1>(uh))+sqr(M2)*sh*uh*(9*pow<3,1>(sh)-sqr(sh)*uh-17*sh*sqr(uh)+3*pow<3,1>(uh))+pow<3,1>(M2)*(5*pow<4,1>(sh)+36*pow<3,1>(sh)*uh+61*sqr(sh)*sqr(uh)+8*sh*pow<3,1>(uh)+pow<4,1>(uh))))/(sqrt(15)*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,0,2,2)=(8*M2*sqr(phase)*sh*sqr(th)*(2*sqr(sh)*sqr(uh)*sqr(sh+uh)+pow<4,1>(M2)*(2*sqr(sh)-6*sh*uh+7*sqr(uh))+M2*sh*uh*(3*pow<3,1>(sh)+11*sqr(sh)*uh+15*sh*sqr(uh)+7*pow<3,1>(uh))-pow<3,1>(M2)*(3*pow<3,1>(sh)+5*sqr(sh)*uh-16*sh*sqr(uh)+12*pow<3,1>(uh))+sqr(M2)*(pow<4,1>(sh)+8*pow<3,1>(sh)*uh+9*sqr(sh)*sqr(uh)-7*sh*pow<3,1>(uh)+6*pow<4,1>(uh))))/(sqrt(15)*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,0,3,0)=(8*pow<3,1>(M)*pow(phase,3)*sqrt(sh)*uh*sqrt(th*uh)*(2*pow<4,1>(M2)*sh*(2*sh-3*uh)+pow<5,1>(M2)*(3*sh+uh)+2*sqr(sh)*sqr(uh)*(sqr(sh)+3*sh*uh+2*sqr(uh))+M2*sh*sqr(uh)*(-7*sqr(sh)-5*sh*uh+4*sqr(uh))-pow<3,1>(M2)*(15*pow<3,1>(sh)+31*sqr(sh)*uh+3*sh*sqr(uh)+3*pow<3,1>(uh))+2*sqr(M2)*(4*pow<4,1>(sh)+18*pow<3,1>(sh)*uh+19*sqr(sh)*sqr(uh)+sh*pow<3,1>(uh)+pow<4,1>(uh))))/(sqrt(5)*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,0,3,2)=(8*pow<3,1>(M)*phase*sqrt(sh)*th*(2*pow<4,1>(M2)*sh*(2*sh-3*th)+pow<5,1>(M2)*(3*sh+th)+2*sqr(sh)*sqr(th)*(sqr(sh)+3*sh*th+2*sqr(th))+M2*sh*sqr(th)*(-7*sqr(sh)-5*sh*th+4*sqr(th))-pow<3,1>(M2)*(15*pow<3,1>(sh)+31*sqr(sh)*th+3*sh*sqr(th)+3*pow<3,1>(th))+2*sqr(M2)*(4*pow<4,1>(sh)+18*pow<3,1>(sh)*th+19*sqr(sh)*sqr(th)+sh*pow<3,1>(th)+pow<4,1>(th)))*sqrt(th*uh))/(sqrt(5)*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,0,4,0)=(8*M2*sqr(phase)*sh*(2*sqr(sh)*sqr(th)*sqr(sh+th)+pow<4,1>(M2)*(2*sqr(sh)-6*sh*th+7*sqr(th))+M2*sh*th*(3*pow<3,1>(sh)+11*sqr(sh)*th+15*sh*sqr(th)+7*pow<3,1>(th))-pow<3,1>(M2)*(3*pow<3,1>(sh)+5*sqr(sh)*th-16*sh*sqr(th)+12*pow<3,1>(th))+sqr(M2)*(pow<4,1>(sh)+8*pow<3,1>(sh)*th+9*sqr(sh)*sqr(th)-7*sh*pow<3,1>(th)+6*pow<4,1>(th)))*sqr(uh))/(sqrt(15)*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,0,4,2)=(8*M2*th*(pow<6,1>(M2)*(sh+th)+pow<3,1>(sh)*pow<3,1>(th)*(sh+th)+M2*sqr(sh)*pow<3,1>(th)*(9*sh+10*th)+pow<5,1>(M2)*(9*sqr(sh)+2*sh*th-sqr(th))-pow<4,1>(M2)*(15*pow<3,1>(sh)+48*sqr(sh)*th+14*sh*sqr(th)+pow<3,1>(th))+sqr(M2)*sh*th*(9*pow<3,1>(sh)-sqr(sh)*th-17*sh*sqr(th)+3*pow<3,1>(th))+pow<3,1>(M2)*(5*pow<4,1>(sh)+36*pow<3,1>(sh)*th+61*sqr(sh)*sqr(th)+8*sh*pow<3,1>(th)+pow<4,1>(th)))*uh)/(sqrt(15)*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,0,5,0)=(-8*sqrt(0.6666666666666666)*pow<3,1>(M)*phase*sh*sqrt(sh)*sqr(uh)*sqrt(th*uh)*(th*sqr(uh)*(th+uh)+pow<3,1>(M2)*(-7*th+2*uh)+sqr(M2)*(9*sqr(th)+6*th*uh-3*sqr(uh))+M2*(-3*pow<3,1>(th)-4*sqr(th)*uh-3*th*sqr(uh)+pow<3,1>(uh))))/(pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,0,5,2)=(8*sqrt(0.6666666666666666)*pow<3,1>(M)*sqrt(sh)*(pow<5,1>(M2)*(sh+th)+sqr(sh)*pow<3,1>(th)*(sh+th)-pow<4,1>(M2)*th*(5*sh+3*th)-M2*sh*sqr(th)*(2*sqr(sh)+sh*th-2*sqr(th))+sqr(M2)*sh*th*(5*sqr(sh)+7*sh*th-2*sqr(th))-pow<3,1>(M2)*(pow<3,1>(sh)+sqr(sh)*th-7*sh*sqr(th)-2*pow<3,1>(th)))*uh*sqrt(th*uh))/(phase*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,0,6,0)=(8*sqr(M2)*sqr(sh)*th*pow<3,1>(uh)*(3*sqr(M2)+sqr(th)+th*uh+sqr(uh)-3*M2*(th+uh)))/(pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,0,6,2)=(8*sqr(M2)*sh*sqr(uh)*(pow<4,1>(M2)*(th+uh)+3*sqr(M2)*th*uh*(th+uh)+pow<3,1>(th)*uh*(th+uh)-pow<3,1>(M2)*uh*(4*th+uh)-M2*sqr(th)*uh*(3*th+2*uh)))/(sqr(phase)*pow<4,1>(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,2,0,0)=0;
+ me(2,2,0,2)=0;
+ me(2,2,1,0)=0;
+ me(2,2,1,2)=0;
+ me(2,2,2,0)=0;
+ me(2,2,2,2)=(8*M2*sqr(sh)*th*uh*(pow<3,1>(M2)-3*M2*th*uh+th*uh*(th+uh)))/(sqrt(15)*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,2,3,0)=0;
+ me(2,2,3,2)=(-8*pow<3,1>(M)*sh*sqrt(sh)*(th-uh)*sqrt(th*uh)*(pow<3,1>(M2)-3*M2*th*uh-sqr(M2)*(th+uh)+2*th*uh*(th+uh)))/(sqrt(5)*phase*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,2,4,0)=0;
+ me(2,2,4,2)=(8*M2*sh*(2*sqr(th)*sqr(uh)*sqr(th+uh)+2*pow<4,1>(M2)*(sqr(th)-th*uh+sqr(uh))+pow<3,1>(M2)*(-3*pow<3,1>(th)+sqr(th)*uh+th*sqr(uh)-3*pow<3,1>(uh))+M2*th*uh*(3*pow<3,1>(th)-11*sqr(th)*uh-11*th*sqr(uh)+3*pow<3,1>(uh))+sqr(M2)*(pow<4,1>(th)-2*pow<3,1>(th)*uh+12*sqr(th)*sqr(uh)-2*th*pow<3,1>(uh)+pow<4,1>(uh))))/(sqrt(15)*sqr(phase)*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,2,5,0)=0;
+ me(2,2,5,2)=(-8*sqrt(0.6666666666666666)*pow<3,1>(M)*sqrt(sh)*(th-uh)*sqrt(th*uh)*(-(pow<3,1>(M2)*(sh+uh))-sqr(sh)*uh*(sh+uh)+sqr(M2)*(sqr(sh)+4*sh*uh+sqr(uh))-M2*sh*(sqr(sh)+2*sh*uh+3*sqr(uh))))/(pow(phase,3)*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ me(2,2,6,0)=0;
+ me(2,2,6,2)=(8*sqr(M2)*th*uh*(pow<3,1>(M2)*(sh+uh)-sqr(M2)*uh*(2*sh+uh)-M2*sh*(sqr(sh)+2*sh*uh-sqr(uh))+sqr(sh)*(sqr(sh)+3*sh*uh+3*sqr(uh))))/(pow(phase,4)*sqr(sm)*pow<3,1>(tm)*pow<3,1>(um));
+ // test the spin averaged result
+ // Energy6 Q(sh*th*uh);
+ // Energy4 P(sh*th+th*uh+uh*sh);
+ // double test = 256.*sqr(M2)/15./pow<5,1>(Q-M2*P)*
+ // (-pow<3,1>(M2)*pow<5,1>(P) + 3*sqr(M2)*pow<4,1>(P)*Q -
+ // 8*pow<7,1>(M2)*sqr(Q) + 111*pow<4,1>(M2)*pow<3,1>(Q) - 20*M2*pow<4,1>(Q) +
+ // sqr(M2)*P*Q*(6*pow<6,1>(M2) - 173*pow<3,1>(M2)*Q - 14*sqr(Q)) - M2*pow<3,1>(P)*
+ // (8*pow<6,1>(M2) + 25*pow<3,1>(M2)*Q + 5*sqr(Q)) +
+ // sqr(P)*Q*(68*pow<6,1>(M2) + 61*pow<3,1>(M2)*Q + 5*sqr(Q)));
+ // double aver = me.average();
+ // cerr << "testing spin correlations " << test << " " << me.average() << " "
+ // << abs(test-aver)/(test+aver) << "\n";
+ // construct the vertex
+ HardVertexPtr hardvertex = new_ptr(HardVertex());
+ // // set the matrix element for the vertex
+ hardvertex->ME(me);
+ // set the pointers and to and from the vertex
+ for(unsigned int i = 0; i < hard.size(); ++i)
+ hard[i]->spinInfo()->productionVertex(hardvertex);
+ // boost back to lab
+ boost = LorentzRotation(pcms.boostVector());
+ for(PPtr part : hard)
+ part->transform(boost);
+}
diff --git a/MatrixElement/Onium/MEPPto3D3Jet.h b/MatrixElement/Onium/MEPPto3D3Jet.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto3D3Jet.h
@@ -0,0 +1,191 @@
+// -*- C++ -*-
+#ifndef Herwig_MEPPto3D3Jet_H
+#define Herwig_MEPPto3D3Jet_H
+//
+// This is the declaration of the MEPPto3D3Jet class.
+//
+
+#include "Herwig/MatrixElement/HwMEBase.h"
+#include "OniumParameters.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * The MEPPto3D3Jet class implements the colour singlet processes for
+ * \f$gg\to^3\!\!D_3 g\f$.
+ *
+ * @see \ref MEPPto3D3JetInterfaces "The interfaces"
+ * defined for MEPPto3D3Jet.
+ */
+class MEPPto3D3Jet: public HwMEBase {
+
+public:
+
+ /**
+ * The default constructor.
+ */
+ MEPPto3D3Jet(): O1_(ZERO), state_(ccbar), n_(1), mOpt_(0)
+ {}
+
+public:
+
+ /** @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 3;
+ }
+
+ /**
+ * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaEW() const {
+ return 0;
+ }
+
+ /**
+ * 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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ MEPPto3D3Jet & operator=(const MEPPto3D3Jet &) = delete;
+
+private:
+
+ /**
+ * Access to the parameters for the quarkonium states
+ */
+ OniumParametersPtr params_;
+
+ /**
+ * The \f$O_1\f$ colour-singlet coefficient
+ */
+ Energy7 O1_;
+
+ /**
+ * Type of state
+ */
+ OniumState state_;
+
+ /**
+ * Principal quantum number
+ */
+ unsigned int n_;
+
+ /**
+ * Option for the onium mass
+ */
+ unsigned int mOpt_;
+};
+
+}
+
+#endif /* Herwig_MEPPto3D3Jet_H */
diff --git a/MatrixElement/Onium/MEPPto3P0Jet.cc b/MatrixElement/Onium/MEPPto3P0Jet.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto3P0Jet.cc
@@ -0,0 +1,495 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the MEPPto3P0Jet class.
+//
+
+#include "MEPPto3P0Jet.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/PDT/EnumParticles.h"
+#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
+#include "ThePEG/Utilities/EnumIO.h"
+#include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
+#include "ThePEG/StandardModel/StandardModelBase.h"
+#include "Herwig/MatrixElement/ProductionMatrixElement.h"
+#include "Herwig/MatrixElement/HardVertex.h"
+
+using namespace Herwig;
+
+void MEPPto3P0Jet::doinit() {
+ HwMEBase::doinit();
+ // get the non-perturbative ME
+ O1_ = params_->singletMEProduction<1>(state_,n_,1,0);
+ // set the mass option
+ massOption(vector<unsigned int>({mOpt_+1,0}));
+}
+
+IBPtr MEPPto3P0Jet::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr MEPPto3P0Jet::fullclone() const {
+ return new_ptr(*this);
+}
+
+void MEPPto3P0Jet::persistentOutput(PersistentOStream & os) const {
+ os << params_ << ounit(O1_,GeV*GeV2*GeV2) << oenum(state_) << n_ << process_ << mOpt_;
+}
+
+void MEPPto3P0Jet::persistentInput(PersistentIStream & is, int) {
+ is >> params_ >> iunit(O1_,GeV*GeV2*GeV2) >> ienum(state_) >> n_ >> process_ >> mOpt_;
+}
+
+// The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<MEPPto3P0Jet,HwMEBase>
+describeHerwigMEPPto3P0Jet("Herwig::MEPPto3P0Jet",
+ "HwOniumParameters.so HwMEHadronOnium.so");
+
+void MEPPto3P0Jet::Init() {
+
+ static ClassDocumentation<MEPPto3P0Jet> documentation
+ ("The MEPPto3P0Jet class implements the q qbar -> 3P0 g, g q to 3P0 q"
+ " and g g to 3P0 g processes");
+
+ static Reference<MEPPto3P0Jet,OniumParameters> interfaceParameters
+ ("Parameters",
+ "Quarkonium parameters",
+ &MEPPto3P0Jet::params_, false, false, true, false, false);
+
+ static Switch<MEPPto3P0Jet,OniumState> interfaceState
+ ("State",
+ "The type of onium state",
+ &MEPPto3P0Jet::state_, ccbar, false, false);
+ static SwitchOption interfaceStateccbar
+ (interfaceState,
+ "ccbar",
+ "Charmonium state",
+ ccbar);
+ static SwitchOption interfaceStatebbbar
+ (interfaceState,
+ "bbbar",
+ "Bottomonium state",
+ bbbar);
+
+ static Parameter<MEPPto3P0Jet,unsigned int> interfacePrincipalQuantumNumber
+ ("PrincipalQuantumNumber",
+ "The principle quantum number of the states",
+ &MEPPto3P0Jet::n_, 1, 1, 10,
+ false, false, Interface::limited);
+
+ static Switch<MEPPto3P0Jet,unsigned int> interfaceProcess
+ ("Process",
+ "Which processes to generate",
+ &MEPPto3P0Jet::process_, 0, false, false);
+ static SwitchOption interfaceProcessAll
+ (interfaceProcess,
+ "All",
+ "Generate all the processes",
+ 0);
+ static SwitchOption interfaceProcessGQto3P0Q
+ (interfaceProcess,
+ "GQto3P0Q",
+ "The g q -> 3P0 q process",
+ 1);
+ static SwitchOption interfaceProcessGQbarto3P0Qbar
+ (interfaceProcess,
+ "GQbarto3P0Qbar",
+ "The g qbar -> 3P0 qbar process",
+ 2);
+ static SwitchOption interfaceProcessQQbarto3P0G
+ (interfaceProcess,
+ "QQbarto3P0G",
+ "The q qbar -> 3P0 g process",
+ 3);
+ static SwitchOption interfaceProcessGGto3P0G
+ (interfaceProcess,
+ "GGto3P0G",
+ "The g g -> 3P0 g process",
+ 4);
+
+ static Switch<MEPPto3P0Jet,unsigned int> interfaceMassOption
+ ("MassOption",
+ "Mass of the treatment of the 3P0 mass",
+ &MEPPto3P0Jet::mOpt_, 0, false, false);
+ static SwitchOption interfaceMassOptionOnShell
+ (interfaceMassOption,
+ "OnShell",
+ "Use the on-shell mass",
+ 0);
+ static SwitchOption interfaceMassOptionOffShell
+ (interfaceMassOption,
+ "OffShell",
+ "Use an off-shell mass generated by the MassGenerator object for the 3P0 state.",
+ 1);
+
+}
+
+void MEPPto3P0Jet::getDiagrams() const {
+ // construct the meson PDG code from quark ids
+ unsigned int iq = 4+state_;
+ tcPDPtr ps = getParticleData(long(iq*110 + 10001 + (n_-1)*100000));
+ tcPDPtr g = getParticleData(ParticleID::g);
+ // processes involving quarks
+ for ( int i = 1; i <= 3; ++i ) {
+ tcPDPtr q = getParticleData(i);
+ tcPDPtr qb = q->CC();
+ if(process_ == 0 || process_ == 1)
+ add(new_ptr((Tree2toNDiagram(3), g, g, q , 1, ps, 2, q , -1)));
+ if(process_ == 0 || process_ == 2)
+ add(new_ptr((Tree2toNDiagram(3), g, g, qb, 1, ps, 2, qb, -2)));
+ if(process_ == 0 || process_ == 3)
+ add(new_ptr((Tree2toNDiagram(2), q, qb, 1, g, 3, ps, 3, g, -3)));
+ }
+ // g g -> 3P0 g (s,t,u 4-point)
+ if(process_ == 0 || process_ == 4) {
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, g, 3, ps, 3, g , -4)));
+ add(new_ptr((Tree2toNDiagram(3), g, g, g, 1, ps, 2, g , -5)));
+ add(new_ptr((Tree2toNDiagram(3), g, g, g, 2, ps, 1, g , -6)));
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, ps, 1, g , -7)));
+ }
+}
+
+Selector<MEBase::DiagramIndex>
+MEPPto3P0Jet::diagrams(const DiagramVector & diags) const {
+ Selector<DiagramIndex> sel;
+ for ( DiagramIndex i = 0; i < diags.size(); ++i )
+ if ( diags[i]->id() == -1 ||
+ diags[i]->id() == -2 ||
+ diags[i]->id() == -3 ) sel.insert(1.0, i);
+ else
+ sel.insert(meInfo()[abs(diags[i]->id())-4],i);
+ return sel;
+}
+
+Selector<const ColourLines *>
+MEPPto3P0Jet::colourGeometries(tcDiagPtr diag) const {
+ // g q -> 3P0 q
+ static ColourLines cgq ("1 2 5, -1 -2 3");
+ // g qbar -> 3P0 qbar
+ static ColourLines cgqbar("1 2 -3, -1 -2 -5");
+ // q qbar -> 3P0 g
+ static ColourLines cqqbar("1 3 5, -2 -3 -5");
+ // g g -> 3P0 g
+ static ColourLines cs[2]={ColourLines("1 3 5, -1 2, -2 -3 -5"),
+ ColourLines("1 -2, -1 -3 -5, 2 3 5")};
+ static ColourLines ct[2]={ColourLines("1 2 5, -1 -2 3, -3 -5"),
+ ColourLines("1 2 -3, -1 -2 -5, 3 5")};
+ static ColourLines cu[2]={ColourLines("1 5, -1 -2 3, -3 2 -5"),
+ ColourLines("1 2 -3, -1 -5, 3 -2 5")};
+ // 4 point
+ static ColourLines c4[2]={ColourLines("1 -2, 2 4, -1 -4"),
+ ColourLines("1 4, -4 -2, 2 -1")};
+ // create the selector
+ Selector<const ColourLines *> sel;
+ if (diag->id() == -1) sel.insert(1.0, &cgq );
+ else if (diag->id() == -2) sel.insert(1.0, &cgqbar);
+ else if (diag->id() == -3) sel.insert(1.0, &cqqbar);
+ else if (diag->id() == -4) {
+ sel.insert(0.5, &cs[0]);
+ sel.insert(0.5, &cs[1]);
+ }
+ else if (diag->id() == -5) {
+ sel.insert(0.5, &ct[0]);
+ sel.insert(0.5, &ct[1]);
+ }
+ else if (diag->id() == -6) {
+ sel.insert(0.5, &cu[0]);
+ sel.insert(0.5, &cu[1]);
+ }
+ else if (diag->id() == -7) {
+ sel.insert(0.5, &c4[0]);
+ sel.insert(0.5, &c4[1]);
+ }
+ return sel;
+}
+
+Energy2 MEPPto3P0Jet::scale() const {
+ return sHat();
+}
+
+double MEPPto3P0Jet::me2() const {
+ // return value
+ double output(0.);
+ // mass of the 3P0 state
+ Energy M = meMomenta()[2].mass();
+ Energy2 M2 = sqr(meMomenta()[2].mass());
+ if(mePartonData()[0]->id()==ParticleID::g) {
+ // g qbar -> 3P0 qbar
+ if(mePartonData()[1]->id()==ParticleID::g) {
+ // weights for the different diagrams
+ DVector save(4,0.);
+ save[0] = (8*sqr(sHat()-3*M2)*tHat()*uHat())/pow<4,1>(tHat() + uHat());
+ save[1] = (4*tHat()*sqr(uHat()-3*M2)*
+ (pow<4,1>(M2) + pow<4,1>(sHat()) +pow<4,1>(tHat()) -
+ 2*(pow<3,1>(M2) + pow<3,1>(sHat()) - pow<3,1>(tHat()))*uHat() +
+ (sqr(M2) + sqr(sHat()) + sqr(tHat()))*sqr(uHat())))/
+ (pow<4,1>(M2 - uHat())*uHat()*sqr(tHat() + uHat()));
+ save[2] = (4*sqr(-3*M2 + tHat())*uHat()*
+ (pow<4,1>(M2) + pow<4,1>(sHat()) - 2*pow<3,1>(M2)*tHat() -
+ 2*pow<3,1>(sHat())*tHat() + sqr(M2)*sqr(tHat()) +
+ sqr(sHat())*sqr(tHat()) + sqr(uHat())*sqr(tHat() + uHat())))/
+ (pow<4,1>(M2 - tHat())*tHat()*sqr(tHat() + uHat()));
+ save[3]=tHat()*uHat()*(16*pow<10,1>(M2)-32*pow<9,1>(M2)*(tHat()+uHat())
+ +2*sHat()*sqr(tHat())*sqr(tHat()-uHat())*sqr(uHat())*pow<3,1>(tHat()+uHat())
+ +sqr(tHat())*sqr(uHat())*pow<4,1>(tHat()+uHat())*(sqr(tHat())+sqr(uHat()))
+ +2*pow<3,1>(sHat())*(tHat()+uHat())*(sqr(tHat())+sqr(uHat()))*
+ (sqr(tHat())-tHat()*uHat()+sqr(uHat()))*(sqr(tHat())+tHat()*uHat()+sqr(uHat()))
+ +4*pow<8,1>(M2)*(4*sqr(sHat())+5*sqr(tHat())+28*tHat()*uHat()+5*sqr(uHat()))
+ +pow<4,1>(sHat())*sqr(pow<3,1>(tHat())+pow<3,1>(uHat()))
+ +sqr(sHat())*(pow<8,1>(tHat())+2*pow<7,1>(tHat())*uHat()
+ +6*pow<6,1>(tHat())*sqr(uHat())+4*pow<5,1>(tHat())*pow<3,1>(uHat())
+ +14*pow<4,1>(tHat())*pow<4,1>(uHat())+4*pow<3,1>(tHat())*pow<5,1>(uHat())
+ +6*sqr(tHat())*pow<6,1>(uHat())+2*tHat()*pow<7,1>(uHat())+pow<8,1>(uHat()))
+ -4*pow<7,1>(M2)*(16*pow<3,1>(sHat())+26*sqr(sHat())*(tHat()+uHat())
+ +4*sHat()*(2*sqr(tHat())+tHat()*uHat()+2*sqr(uHat()))
+ +(tHat()+uHat())*(7*sqr(tHat())+22*tHat()*uHat()+7*sqr(uHat())))
+ +pow<6,1>(M2)*(64*pow<4,1>(sHat())+280*pow<3,1>(sHat())*(tHat()+uHat())
+ +2*sHat()*(tHat()+uHat())*(87*sqr(tHat())-40*tHat()*uHat()+87*sqr(uHat()))
+ +sqr(sHat())*(397*sqr(tHat())+482*tHat()*uHat()+397*sqr(uHat()))
+ +10*(9*pow<4,1>(tHat())+3*pow<3,1>(tHat())*uHat()
+ +28*sqr(tHat())*sqr(uHat())+3*tHat()*pow<3,1>(uHat())+9*pow<4,1>(uHat())))
+ -2*pow<5,1>(M2)*(72*pow<4,1>(sHat())*(tHat()+uHat())+3*sqr(sHat())*(tHat()+uHat())*(137*sqr(tHat())+62*tHat()*uHat()+137*sqr(uHat()))+pow<3,1>(sHat())*(317*sqr(tHat())+378*tHat()*uHat()+317*sqr(uHat()))+2*(tHat()+uHat())*(40*pow<4,1>(tHat())-21*pow<3,1>(tHat())*uHat()+66*sqr(tHat())*sqr(uHat())-21*tHat()*pow<3,1>(uHat())+40*pow<4,1>(uHat()))+sHat()*(213*pow<4,1>(tHat())+130*pow<3,1>(tHat())*uHat()+178*sqr(tHat())*sqr(uHat())+130*tHat()*pow<3,1>(uHat())+213*pow<4,1>(uHat())))
+ +pow<4,1>(M2)*(3*pow<4,1>(sHat())*(59*sqr(tHat())+54*tHat()*uHat()+59*sqr(uHat()))+4*pow<3,1>(sHat())*(tHat()+uHat())*(180*sqr(tHat())+91*tHat()*uHat()+180*sqr(uHat()))+2*sHat()*(tHat()+uHat())*(268*pow<4,1>(tHat())-47*pow<3,1>(tHat())*uHat()+282*sqr(tHat())*sqr(uHat())-47*tHat()*pow<3,1>(uHat())+268*pow<4,1>(uHat()))+sqr(sHat())*(981*pow<4,1>(tHat())+1496*pow<3,1>(tHat())*uHat()+2054*sqr(tHat())*sqr(uHat())+1496*tHat()*pow<3,1>(uHat())+981*pow<4,1>(uHat()))+2*(80*pow<6,1>(tHat())+111*pow<5,1>(tHat())*uHat()+30*pow<4,1>(tHat())*sqr(uHat())+138*pow<3,1>(tHat())*pow<3,1>(uHat())+30*sqr(tHat())*pow<4,1>(uHat())+111*tHat()*pow<5,1>(uHat())+80*pow<6,1>(uHat())))
+ +2*pow<3,1>(M2)*(-2*pow<4,1>(sHat())*(tHat()+uHat())*(31*sqr(tHat())-4*tHat()*uHat()+31*sqr(uHat()))-2*sqr(sHat())*(tHat()+uHat())*(157*pow<4,1>(tHat())+102*pow<3,1>(tHat())*uHat()+306*sqr(tHat())*sqr(uHat())+102*tHat()*pow<3,1>(uHat())+157*pow<4,1>(uHat()))-pow<3,1>(sHat())*(243*pow<4,1>(tHat())+336*pow<3,1>(tHat())*uHat()+514*sqr(tHat())*sqr(uHat())+336*tHat()*pow<3,1>(uHat())+243*pow<4,1>(uHat()))-3*(tHat()+uHat())*(14*pow<6,1>(tHat())+21*pow<5,1>(tHat())*uHat()+8*pow<4,1>(tHat())*sqr(uHat())+18*pow<3,1>(tHat())*pow<3,1>(uHat())+8*sqr(tHat())*pow<4,1>(uHat())+21*tHat()*pow<5,1>(uHat())+14*pow<6,1>(uHat()))-sHat()*(168*pow<6,1>(tHat())+209*pow<5,1>(tHat())*uHat()+150*pow<4,1>(tHat())*sqr(uHat())+186*pow<3,1>(tHat())*pow<3,1>(uHat())+150*sqr(tHat())*pow<4,1>(uHat())+209*tHat()*pow<5,1>(uHat())+168*pow<6,1>(uHat())))
+ +sqr(M2)*(18*pow<8,1>(tHat())+76*pow<7,1>(tHat())*uHat()+157*pow<6,1>(tHat())*sqr(uHat())+90*pow<5,1>(tHat())*pow<3,1>(uHat())+126*pow<4,1>(tHat())*pow<4,1>(uHat())+90*pow<3,1>(tHat())*pow<5,1>(uHat())+157*sqr(tHat())*pow<6,1>(uHat())+76*tHat()*pow<7,1>(uHat())+18*pow<8,1>(uHat())+18*pow<4,1>(sHat())*(sqr(tHat())+tHat()*uHat()+sqr(uHat()))*(3*sqr(tHat())-2*tHat()*uHat()+3*sqr(uHat()))+2*pow<3,1>(sHat())*(tHat()+uHat())*(91*pow<4,1>(tHat())+23*pow<3,1>(tHat())*uHat()+164*sqr(tHat())*sqr(uHat())+23*tHat()*pow<3,1>(uHat())+91*pow<4,1>(uHat()))+2*sHat()*(tHat()+uHat())*(45*pow<6,1>(tHat())+43*pow<5,1>(tHat())*uHat()+17*pow<4,1>(tHat())*sqr(uHat())+36*pow<3,1>(tHat())*pow<3,1>(uHat())+17*sqr(tHat())*pow<4,1>(uHat())+43*tHat()*pow<5,1>(uHat())+45*pow<6,1>(uHat()))+sqr(sHat())*(201*pow<6,1>(tHat())+350*pow<5,1>(tHat())*uHat()+620*pow<4,1>(tHat())*sqr(uHat())+742*pow<3,1>(tHat())*pow<3,1>(uHat())+620*sqr(tHat())*pow<4,1>(uHat())+350*tHat()*pow<5,1>(uHat())+201*pow<6,1>(uHat())))
+ +2*M2*(-(tHat()*uHat()*pow<3,1>(tHat()+uHat())*(3*tHat()+uHat())*(tHat()+3*uHat())*(sqr(tHat())-tHat()*uHat()+sqr(uHat())))-6*pow<4,1>(sHat())*(pow<5,1>(tHat())+pow<3,1>(tHat())*sqr(uHat())+sqr(tHat())*pow<3,1>(uHat())+pow<5,1>(uHat()))-sqr(sHat())*(tHat()+uHat())*(13*pow<6,1>(tHat())+13*pow<5,1>(tHat())*uHat()+30*pow<4,1>(tHat())*sqr(uHat())+36*pow<3,1>(tHat())*pow<3,1>(uHat())+30*sqr(tHat())*pow<4,1>(uHat())+13*tHat()*pow<5,1>(uHat())+13*pow<6,1>(uHat()))-pow<3,1>(sHat())*(16*pow<6,1>(tHat())+19*pow<5,1>(tHat())*uHat()+31*pow<4,1>(tHat())*sqr(uHat())+32*pow<3,1>(tHat())*pow<3,1>(uHat())+31*sqr(tHat())*pow<4,1>(uHat())+19*tHat()*pow<5,1>(uHat())+16*pow<6,1>(uHat()))-sHat()*(3*pow<8,1>(tHat())+9*pow<7,1>(tHat())*uHat()+19*pow<6,1>(tHat())*sqr(uHat())-5*pow<5,1>(tHat())*pow<3,1>(uHat())+12*pow<4,1>(tHat())*pow<4,1>(uHat())-5*pow<3,1>(tHat())*pow<5,1>(uHat())+19*sqr(tHat())*pow<6,1>(uHat())+9*tHat()*pow<7,1>(uHat())+3*pow<8,1>(uHat()))))/(pow<4,1>(M2-tHat())*pow<4,1>(M2-uHat())*pow<4,1>(tHat()+uHat()));
+ meInfo(save);
+ // matrix element
+ output = 64./9.*O1_*pow<3,1>(Constants::pi*standardModel()->alphaS(scale())/M)/sHat()*
+ (9*pow<4,1>(M2)*sqr(M2-tHat())*sqr(M2-uHat())*sqr(tHat()+uHat())*
+ sqr(sqr(tHat())+tHat()*uHat()+sqr(uHat())-M2*(tHat()+uHat()))
+ +pow<4,1>(sHat())*sqr(tHat()+uHat())*sqr(uHat()*(sHat()+uHat())*(sqr(sHat())+sHat()*uHat()+sqr(uHat()))
+ +sqr(M2)*(3*sqr(sHat())+6*sHat()*uHat()+sqr(uHat()))
+ -M2*(3*sHat()+uHat())*(sqr(sHat())+2*sHat()*uHat()+2*sqr(uHat())))
+ +sqr(M2-tHat())*pow<4,1>(tHat())*sqr(uHat()*(tHat()+uHat())*(sqr(tHat())+tHat()*uHat()+sqr(uHat()))
+ +sqr(M2)*(3*sqr(tHat())+6*tHat()*uHat()+sqr(uHat()))
+ -M2*(3*tHat()+uHat())*(sqr(tHat())+2*tHat()*uHat()+2*sqr(uHat())))
+ +sqr(M2-uHat())*pow<4,1>(uHat())*sqr(tHat()*(tHat()+uHat())*(sqr(tHat())+tHat()*uHat()+sqr(uHat()))
+ -M2*(tHat()+3*uHat())*(2*sqr(tHat())+2*tHat()*uHat()+sqr(uHat()))
+ +sqr(M2)*(sqr(tHat())+6*tHat()*uHat()+3*sqr(uHat()))))
+ /(pow<4,1>(M2-tHat())*tHat()*pow<4,1>(M2-uHat())*uHat()*pow<4,1>(tHat()+uHat()));
+ // test vs NPB 291 731
+ // Energy5 R02 = params_->firstDerivativeRadialWaveFunctionSquared(state_,n_);
+ // Energy6 Q(sHat()*tHat()*uHat());
+ // Energy4 P(sHat()*tHat()+tHat()*uHat()+uHat()*sHat());
+ // double test = 16.*Constants::pi*sqr(sHat())*
+ // 4.*Constants::pi*pow(standardModel()->alphaS(scale()),3)*R02/M/M2/sqr(sHat())/Q/pow<4,1>(Q-M2*P)*
+ // (9.*sqr(M2*sqr(P))*(pow<4,1>(M2)-2.*sqr(M2)*P+sqr(P)) -6*M2*pow<3,1>(P)*Q*(2.*pow<4,1>(M2)-5.*sqr(M2)*P+sqr(P))
+ // -sqr(P*Q)*(pow<4,1>(M2)+2.*sqr(M2)*P-sqr(P))+2.*M2*P*pow<3,1>(Q)*(sqr(M2)-P)+6.*pow<4,1>(M*Q));
+ // cerr << "testing matrix element " << output << " " << test << " "
+ // << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ else if(mePartonData()[1]->id()<0) {
+ // spin sum version
+ double total = -4.*tHat()*(sqr(sHat())+sqr(uHat()))/pow<6,1>(M);
+ // final factors
+ output = 64.*O1_*pow<3,1>(M*Constants::pi*standardModel()->alphaS(scale()))*sqr(tHat()-3.*sqr(M))/(81.*sqr(tHat())*pow<4,1>(tHat()-M2))*total;
+ // analytic test
+ // Energy5 R02 = params_->firstDerivativeRadialWaveFunctionSquared(state_,n_);
+ // double test = -16.*Constants::pi*sqr(sHat())*
+ // 8.*Constants::pi*pow(standardModel()->alphaS(scale()),3)*R02*(sqr(sHat())+sqr(uHat()))
+ // /9./M/M2/sqr(sHat())/tHat()/pow<4,1>(tHat()-M2)*sqr(tHat()-3.*sqr(M));
+ // cerr << "testing matrix element " << output << " " << test << " " << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ // g q -> 3P0 q
+ else if(mePartonData()[1]->id()<6) {
+ // spin sum version
+ double total = -4.*tHat()*(sqr(sHat())+sqr(uHat()))/pow<6,1>(M);
+ // final factors
+ output = 64.*O1_*pow<3,1>(M*Constants::pi*standardModel()->alphaS(scale()))*sqr(tHat()-3.*sqr(M))/(81.*sqr(tHat())*pow<4,1>(tHat()-M2))*total;
+ // analytic test
+ // Energy5 R02 = params_->firstDerivativeRadialWaveFunctionSquared(state_,n_);
+ // double test = -16.*Constants::pi*sqr(sHat())*
+ // 8.*Constants::pi*pow(standardModel()->alphaS(scale()),3)*R02*(sqr(sHat())+sqr(uHat()))
+ // /9./M/M2/sqr(sHat())/tHat()/pow<4,1>(tHat()-M2)*sqr(tHat()-3.*sqr(M));
+ // cerr << "testing matrix element " << output << " " << test << " " << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ else assert(false);
+ }
+ // q qbar -> 3P0 g
+ else if(mePartonData()[0]->id()==-mePartonData()[1]->id()) {
+ // spin sum version
+ double total = 4.*sHat()*(sqr(tHat())+sqr(uHat()))/pow<3,1>(M2);
+ // final factors
+ output = 512.*O1_*pow<3,1>(M*Constants::pi*standardModel()->alphaS(scale()))*sqr(sHat()-3.*M2)/(243.*sqr(sHat())*pow<4,1>(sHat()-M2))*total;
+ // analytic test
+ // Energy5 R02 = params_->firstDerivativeRadialWaveFunctionSquared(state_,n_);
+ // double test = 16.*Constants::pi*8./3.*8.*Constants::pi*pow(standardModel()->alphaS(scale()),3)*R02*(sqr(tHat())+sqr(uHat()))
+ // /9./M/M2/sHat()/pow<4,1>(sHat()-M2)*sqr(sHat()-3.*sqr(M));
+ // cerr << "testing matrix element " << output << " " << test << " " << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ else
+ assert(false);
+ return output;
+}
+
+void MEPPto3P0Jet::constructVertex(tSubProPtr sub) {
+ // extract the particles in the hard process
+ ParticleVector hard;
+ hard.reserve(4);
+ hard.push_back(sub->incoming().first);
+ hard.push_back(sub->incoming().second);
+ hard.push_back(sub->outgoing()[0]);
+ hard.push_back(sub->outgoing()[1]);
+ // get them in the right order
+ bool swapped(false);
+ if(hard[0]->id()==-hard[1]->id()) {
+ if(hard[0]->id()<0) swapped = true;
+ }
+ else if(hard[0]->id()!=ParticleID::g) {
+ swapped=true;
+ }
+ if(swapped) {
+ swap(hard[0],hard[1]);
+ swap(hard[2],hard[3]);
+ }
+ // boost to partonic CMS
+ Lorentz5Momentum pcms = hard[0]->momentum()+hard[1]->momentum();
+ LorentzRotation boost(-pcms.boostVector());
+ for(PPtr part : hard) part->transform(boost);
+ // extract kinematic variables
+ Energy M = hard[2]->mass();
+ Energy2 M2 = sqr(M);
+ double phi = hard[2]->momentum().phi();
+ Energy2 sh = (hard[0]->momentum()+hard[1]->momentum()).m2();
+ Energy2 th = (hard[0]->momentum()-hard[2]->momentum()).m2();
+ Energy2 uh = (hard[0]->momentum()-hard[3]->momentum()).m2();
+ // set basis states and compute the matrix element
+ ProductionMatrixElement me;
+ ScalarWaveFunction( hard[2],outgoing,true);
+ if(hard[0]->id()==ParticleID::g) {
+ // g g -> 3P0 g
+ if(hard[1]->id()==ParticleID::g) {
+ vector<VectorWaveFunction> g1,g2,g4;
+ VectorWaveFunction( g1,hard[0],incoming,false, true,true,vector_phase);
+ VectorWaveFunction( g2,hard[1],incoming,false, true,true,vector_phase);
+ VectorWaveFunction( g4,hard[3],outgoing,true , true,true,vector_phase);
+ ProductionMatrixElement me(PDT::Spin1,PDT::Spin1,PDT::Spin0,PDT::Spin1);
+ Complex phase = exp(Complex(0.,phi));
+ Energy2 um(uh-M2),tm(th-M2),sm(sh-M2);
+ me(0,0,0,0)=(sqrt(2)*phase*sqr(sh)*(uh*(sh+uh)*(sqr(sh)+sh*uh+sqr(uh))+sqr(M2)*(3*sqr(sh)+6*sh*uh+sqr(uh))-M2*(3*sh+uh)*(sqr(sh)+2*sh*uh+2*sqr(uh))))/(sm*sqr(tm)*sqrt(th*uh)*sqr(um));
+ me(0,0,0,2)=(3*sqrt(2)*sqr(M2)*(M2*sm+sqr(th)+th*uh+sqr(uh)))/(phase*sm*tm*sqrt(th*uh)*um);
+ me(0,2,0,0)=-((sqrt(2)*sqr(th)*(-(sm*uh*(sqr(th)+th*uh+sqr(uh)))+sqr(M2)*(3*sqr(th)+6*th*uh+sqr(uh))-M2*(3*th+uh)*(sqr(th)+2*th*uh+2*sqr(uh))))/(phase*sqr(sm)*(-M2+th)*sqrt(th*uh)*sqr(um)));
+ me(0,2,0,2)=(sqrt(2)*sqr(uh)*(-(sm*th*(sqr(th)+th*uh+sqr(uh)))-M2*(th+3*uh)*(2*sqr(th)+2*th*uh+sqr(uh))+sqr(M2)*(sqr(th)+6*th*uh+3*sqr(uh))))/(pow(phase,3)*sqr(sm)*sqr(tm)*sqrt(th*uh)*(-M2+uh));
+ me(2,0,0,0)=-((sqrt(2)*pow(phase,3)*sqr(uh)*(-(sm*th*(sqr(th)+th*uh+sqr(uh)))-M2*(th+3*uh)*(2*sqr(th)+2*th*uh+sqr(uh))+sqr(M2)*(sqr(th)+6*th*uh+3*sqr(uh))))/(sqr(sm)*sqr(tm)*sqrt(th*uh)*(-M2+uh)));
+ me(2,0,0,2)=(sqrt(2)*phase*sqr(th)*(-(sm*uh*(sqr(th)+th*uh+sqr(uh)))+sqr(M2)*(3*sqr(th)+6*th*uh+sqr(uh))-M2*(3*th+uh)*(sqr(th)+2*th*uh+2*sqr(uh))))/(sqr(sm)*(-M2+th)*sqrt(th*uh)*sqr(um));
+ me(2,2,0,0)=(-3*sqrt(2)*sqr(M2)*phase*(M2*sm+sqr(th)+th*uh+sqr(uh)))/(sm*tm*sqrt(th*uh)*um);
+ me(2,2,0,2)=-((sqrt(2)*sqr(sh)*(uh*(sh+uh)*(sqr(sh)+sh*uh+sqr(uh))+sqr(M2)*(3*sqr(sh)+6*sh*uh+sqr(uh))-M2*(3*sh+uh)*(sqr(sh)+2*sh*uh+2*sqr(uh))))/(phase*sm*sqr(tm)*sqrt(th*uh)*sqr(um)));
+ // test the average result
+ // double aver = me.average();
+ // double test = 4.*(9*pow<4,1>(M2)*sqr(M2-th)*sqr(M2-uh)*sqr(th+uh)*
+ // sqr(sqr(th)+th*uh+sqr(uh)-M2*(th+uh))
+ // +pow<4,1>(sh)*sqr(th+uh)*sqr(uh*(sh+uh)*(sqr(sh)+sh*uh+sqr(uh))
+ // +sqr(M2)*(3*sqr(sh)+6*sh*uh+sqr(uh))
+ // -M2*(3*sh+uh)*(sqr(sh)+2*sh*uh+2*sqr(uh)))
+ // +sqr(M2-th)*pow<4,1>(th)*sqr(uh*(th+uh)*(sqr(th)+th*uh+sqr(uh))
+ // +sqr(M2)*(3*sqr(th)+6*th*uh+sqr(uh))
+ // -M2*(3*th+uh)*(sqr(th)+2*th*uh+2*sqr(uh)))
+ // +sqr(M2-uh)*pow<4,1>(uh)*sqr(th*(th+uh)*(sqr(th)+th*uh+sqr(uh))
+ // -M2*(th+3*uh)*(2*sqr(th)+2*th*uh+sqr(uh))
+ // +sqr(M2)*(sqr(th)+6*th*uh+3*sqr(uh))))
+ // /(pow<4,1>(M2-th)*th*pow<4,1>(M2-uh)*uh*pow<4,1>(th+uh));
+ // cerr << "testing spin correlations " << test << " " << me.average() << " "
+ // << abs(test-aver)/(test+aver) << "\n";
+ }
+ // g qbar -> 3P0 qbar
+ else if(hard[1]->id()<0) {
+ vector<VectorWaveFunction> g1;
+ vector<SpinorBarWaveFunction> q2;
+ vector<SpinorWaveFunction> q4;
+ VectorWaveFunction( g1,hard[0],incoming,false,true,true,vector_phase);
+ SpinorBarWaveFunction(q2,hard[1],incoming,false,true);
+ SpinorWaveFunction( q4,hard[3],outgoing,true ,true);
+ g1[1]=g1[2];
+ // matrix element
+ me = ProductionMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin0,PDT::Spin1Half);
+ if(!swapped) {
+ me(0,0,0,0) =-sqrt(2.)*sh*sqrt(-th)/M2/M;
+ me(0,1,0,1) = exp(Complex(0.,-2.*phi))*sqrt(2)*sqrt(-th)*uh/M2/M;
+ me(2,0,0,0) =-exp(Complex(0., 2.*phi))*sqrt(2)*sqrt(-th)*uh/M2/M;
+ me(2,1,0,1) = sqrt(2.)*sh*sqrt(-th)/M2/M;
+ }
+ else {
+ me(0,0,0,0) = -exp(Complex(0., phi))*sqrt(2.)*sh*sqrt(-th)/M2/M;
+ me(0,1,0,1) = exp(Complex(0., phi))*sqrt(2)*sqrt(-th)*uh/M2/M;
+ me(2,0,0,0) = -exp(Complex(0.,-phi))*sqrt(2)*sqrt(-th)*uh/M2/M;
+ me(2,1,0,1) = exp(Complex(0.,-phi))*sqrt(2.)*sh*sqrt(-th)/M2/M;
+ }
+ }
+ // g q -> 3P0 q
+ else if(hard[1]->id()<6) {
+ vector<VectorWaveFunction> g1;
+ vector<SpinorWaveFunction> q2;
+ vector<SpinorBarWaveFunction> q4;
+ VectorWaveFunction( g1,hard[0],incoming,false,true,true,vector_phase);
+ SpinorWaveFunction( q2,hard[1],incoming,false,true);
+ SpinorBarWaveFunction(q4,hard[3],outgoing,true ,true);
+ g1[1]=g1[2];
+ // matrix element
+ me = ProductionMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin0,PDT::Spin1Half);
+ if(!swapped) {
+ me(0,0,0,0) = sqrt(2.)*sh*sqrt(-th)/M2/M;
+ me(0,1,0,1) =-exp(Complex(0.,-2.*phi))*sqrt(2)*sqrt(-th)*uh/M2/M;
+ me(2,0,0,0) = exp(Complex(0., 2.*phi))*sqrt(2)*sqrt(-th)*uh/M2/M;
+ me(2,1,0,1) =-sqrt(2.)*sh*sqrt(-th)/M2/M;
+ }
+ else {
+ me(0,0,0,0) = exp(Complex(0., phi))*sqrt(2.)*sh*sqrt(-th)/M2/M;
+ me(0,1,0,1) = -exp(Complex(0., phi))*sqrt(2)*sqrt(-th)*uh/M2/M;
+ me(2,0,0,0) = exp(Complex(0.,-phi))*sqrt(2)*sqrt(-th)*uh/M2/M;
+ me(2,1,0,1) = -exp(Complex(0.,-phi))*sqrt(2.)*sh*sqrt(-th)/M2/M;
+ }
+ }
+ else
+ assert(false);
+ }
+ else if(hard[0]->id()==-hard[1]->id()) {
+ vector<SpinorWaveFunction> q1;
+ vector<SpinorBarWaveFunction> q2;
+ vector<VectorWaveFunction> g4;
+ SpinorWaveFunction( q1,hard[0],incoming,false,true);
+ SpinorBarWaveFunction(q2,hard[1],incoming,false,true);
+ VectorWaveFunction( g4,hard[3],outgoing,true,true,true,vector_phase);
+ g4[1]=g4[2];
+ // matrix element
+ me = ProductionMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin0,PDT::Spin1);
+ if(!swapped) {
+ me(0,1,0,0) = -sqrt(2.*sh)*th/M2/M;
+ me(0,1,0,2) = -exp(Complex(0.,-2.*phi))*sqrt(2.*sh)*uh/M2/M;
+ me(1,0,0,0) = exp(Complex(0., 2.*phi))*sqrt(2.*sh)*uh/M2/M;
+ me(1,0,0,2) = sqrt(2.*sh)*th/M2/M;
+ }
+ else {
+ me(0,1,0,0) = -double(sqrt(2.*sh)*th/M2/M)*exp(Complex(0., 2.*phi));
+ me(0,1,0,2) = sqrt(2.*sh)*uh/M2/M;
+ me(1,0,0,0) = -sqrt(2.*sh)*uh/M2/M;
+ me(1,0,0,2) = -double(sqrt(2.*sh)*th/M2/M)*exp(Complex(0.,-2.*phi));
+ }
+ }
+ else
+ assert(false);
+ // construct the vertex
+ HardVertexPtr hardvertex = new_ptr(HardVertex());
+ // // set the matrix element for the vertex
+ hardvertex->ME(me);
+ // set the pointers and to and from the vertex
+ for(unsigned int i = 0; i < hard.size(); ++i)
+ hard[i]->spinInfo()->productionVertex(hardvertex);
+ // boost back to lab
+ boost = LorentzRotation(pcms.boostVector());
+ for(PPtr part : hard)
+ part->transform(boost);
+}
diff --git a/MatrixElement/Onium/MEPPto3P0Jet.h b/MatrixElement/Onium/MEPPto3P0Jet.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto3P0Jet.h
@@ -0,0 +1,197 @@
+// -*- C++ -*-
+#ifndef Herwig_MEPPto3P0Jet_H
+#define Herwig_MEPPto3P0Jet_H
+//
+// This is the declaration of the MEPPto3P0Jet class.
+//
+
+#include "Herwig/MatrixElement/HwMEBase.h"
+#include "OniumParameters.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * The MEPPto3P0Jet class implements the colour singlet processes for
+ * \f$gq\to^3\!\!P_0 q\f$, \f$q\bar{q}\to^3\!\!P_0 g\f$ and
+ * \f$gg\to^3\!\!P_0 g\f$.
+ *
+ * @see \ref MEPPto3P0JetInterfaces "The interfaces"
+ * defined for MEPPto3P0Jet.
+ */
+class MEPPto3P0Jet: public HwMEBase {
+
+public:
+
+ /**
+ * The default constructor.
+ */
+ MEPPto3P0Jet() : O1_(ZERO), state_(ccbar), n_(1), process_(0), mOpt_(0)
+ {}
+
+public:
+
+ /** @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 3;
+ }
+
+ /**
+ * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaEW() const {
+ return 0;
+ }
+
+ /**
+ * 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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ MEPPto3P0Jet & operator=(const MEPPto3P0Jet &) = delete;
+
+private:
+
+ /**
+ * Access to the parameters for the quarkonium states
+ */
+ OniumParametersPtr params_;
+
+ /**
+ * The \f$O_1\f$ colour-singlet coefficient
+ */
+ Energy5 O1_;
+
+ /**
+ * Type of state
+ */
+ OniumState state_;
+
+ /**
+ * Principal quantum number
+ */
+ unsigned int n_;
+
+ /**
+ * Which processes to generate
+ */
+ unsigned int process_;
+
+ /**
+ * Option for the onium mass
+ */
+ unsigned int mOpt_;
+};
+
+}
+
+#endif /* Herwig_MEPPto3P0Jet_H */
diff --git a/MatrixElement/Onium/MEPPto3P1Jet.cc b/MatrixElement/Onium/MEPPto3P1Jet.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto3P1Jet.cc
@@ -0,0 +1,748 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the MEPPto3P1Jet class.
+//
+
+#include "MEPPto3P1Jet.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/PDT/EnumParticles.h"
+#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
+#include "ThePEG/Utilities/EnumIO.h"
+#include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
+#include "ThePEG/StandardModel/StandardModelBase.h"
+#include "ThePEG/Helicity/epsilon.h"
+#include "Herwig/MatrixElement/ProductionMatrixElement.h"
+#include "Herwig/MatrixElement/HardVertex.h"
+
+using namespace Herwig;
+
+void MEPPto3P1Jet::doinit() {
+ HwMEBase::doinit();
+ // get the non-perturbative ME
+ O1_ = params_->singletMEProduction<1>(state_,n_,1,1);
+ // set the mass option
+ massOption(vector<unsigned int>({mOpt_+1,0}));
+}
+
+IBPtr MEPPto3P1Jet::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr MEPPto3P1Jet::fullclone() const {
+ return new_ptr(*this);
+}
+
+void MEPPto3P1Jet::persistentOutput(PersistentOStream & os) const {
+ os << params_ << ounit(O1_,GeV*GeV2*GeV2) << oenum(state_) << n_ << process_ << mOpt_;
+}
+
+void MEPPto3P1Jet::persistentInput(PersistentIStream & is, int) {
+ is >> params_ >> iunit(O1_,GeV*GeV2*GeV2) >> ienum(state_) >> n_ >> process_ >> mOpt_;
+}
+
+// The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<MEPPto3P1Jet,HwMEBase>
+describeHerwigMEPPto3P1Jet("Herwig::MEPPto3P1Jet",
+ "HwOniumParameters.so HwMEHadronOnium.so");
+
+void MEPPto3P1Jet::Init() {
+
+ static ClassDocumentation<MEPPto3P1Jet> documentation
+ ("The MEPPto3P1Jet class implements the q qbar -> 3P1 g, g q to 3P1 q"
+ " and g g to 3P1 g processes");
+
+ static Reference<MEPPto3P1Jet,OniumParameters> interfaceParameters
+ ("Parameters",
+ "Quarkonium parameters",
+ &MEPPto3P1Jet::params_, false, false, true, false, false);
+
+ static Switch<MEPPto3P1Jet,OniumState> interfaceState
+ ("State",
+ "The type of onium state",
+ &MEPPto3P1Jet::state_, ccbar, false, false);
+ static SwitchOption interfaceStateccbar
+ (interfaceState,
+ "ccbar",
+ "Charmonium state",
+ ccbar);
+ static SwitchOption interfaceStatebbbar
+ (interfaceState,
+ "bbbar",
+ "Bottomonium state",
+ bbbar);
+
+ static Parameter<MEPPto3P1Jet,unsigned int> interfacePrincipalQuantumNumber
+ ("PrincipalQuantumNumber",
+ "The principle quantum number of the states",
+ &MEPPto3P1Jet::n_, 1, 1, 10,
+ false, false, Interface::limited);
+
+ static Switch<MEPPto3P1Jet,unsigned int> interfaceProcess
+ ("Process",
+ "Which processes to generate",
+ &MEPPto3P1Jet::process_, 0, false, false);
+ static SwitchOption interfaceProcessAll
+ (interfaceProcess,
+ "All",
+ "Generate all the processes",
+ 0);
+ static SwitchOption interfaceProcessGQto3P1Q
+ (interfaceProcess,
+ "GQto3P1Q",
+ "The g q -> 3P1 q process",
+ 1);
+ static SwitchOption interfaceProcessGQbarto3P1Qbar
+ (interfaceProcess,
+ "GQbarto3P1Qbar",
+ "The g qbar -> 3P1 qbar process",
+ 2);
+ static SwitchOption interfaceProcessQQbarto3P1G
+ (interfaceProcess,
+ "QQbarto3P1G",
+ "The q qbar -> 3P1 g process",
+ 3);
+ static SwitchOption interfaceProcessGGto3P1G
+ (interfaceProcess,
+ "GGto3P1G",
+ "The g g -> 3P1 g process",
+ 4);
+
+ static Switch<MEPPto3P1Jet,unsigned int> interfaceMassOption
+ ("MassOption",
+ "Mass of the treatment of the 3P1 mass",
+ &MEPPto3P1Jet::mOpt_, 0, false, false);
+ static SwitchOption interfaceMassOptionOnShell
+ (interfaceMassOption,
+ "OnShell",
+ "Use the on-shell mass",
+ 0);
+ static SwitchOption interfaceMassOptionOffShell
+ (interfaceMassOption,
+ "OffShell",
+ "Use an off-shell mass generated by the MassGenerator object for the 3P1 state.",
+ 1);
+
+}
+
+void MEPPto3P1Jet::getDiagrams() const {
+ // construct the meson PDG code from quark ids
+ unsigned int iq = 4+state_;
+ tcPDPtr ps = getParticleData(long(iq*110 + 20003 + (n_-1)*100000));
+ tcPDPtr g = getParticleData(ParticleID::g);
+ // processes involving quarks
+ for ( int i = 1; i <= 3; ++i ) {
+ tcPDPtr q = getParticleData(i);
+ tcPDPtr qb = q->CC();
+ if(process_ == 0 || process_ == 1)
+ add(new_ptr((Tree2toNDiagram(3), g, g, q , 1, ps, 2, q , -1)));
+ if(process_ == 0 || process_ == 2)
+ add(new_ptr((Tree2toNDiagram(3), g, g, qb, 1, ps, 2, qb, -2)));
+ if(process_ == 0 || process_ == 3)
+ add(new_ptr((Tree2toNDiagram(2), q, qb, 1, g, 3, ps, 3, g, -3)));
+ }
+ // g g -> 3P1 g (s,t,u 4-point)
+ if(process_ == 0 || process_ == 4) {
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, g, 3, ps, 3, g , -4)));
+ add(new_ptr((Tree2toNDiagram(3), g, g, g, 1, ps, 2, g , -5)));
+ add(new_ptr((Tree2toNDiagram(3), g, g, g, 2, ps, 1, g , -6)));
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, ps, 1, g , -7)));
+ }
+}
+
+Selector<MEBase::DiagramIndex>
+MEPPto3P1Jet::diagrams(const DiagramVector & diags) const {
+ Selector<DiagramIndex> sel;
+ for ( DiagramIndex i = 0; i < diags.size(); ++i )
+ if ( diags[i]->id() == -1 ||
+ diags[i]->id() == -2 ||
+ diags[i]->id() == -3 ) sel.insert(1.0, i);
+ else
+ sel.insert(meInfo()[abs(diags[i]->id())-4],i);
+ return sel;
+}
+
+Selector<const ColourLines *>
+MEPPto3P1Jet::colourGeometries(tcDiagPtr diag) const {
+ // g q -> 3P1 q
+ static ColourLines cgq ("1 2 5, -1 -2 3");
+ // g qbar -> 3P1 qbar
+ static ColourLines cgqbar("1 2 -3, -1 -2 -5");
+ // q qbar -> 3P1 g
+ static ColourLines cqqbar("1 3 5, -2 -3 -5");
+ // g g -> 3P1 g
+ static ColourLines cs[2]={ColourLines("1 3 5, -1 2, -2 -3 -5"),
+ ColourLines("1 -2, -1 -3 -5, 2 3 5")};
+ static ColourLines ct[2]={ColourLines("1 2 5, -1 -2 3, -3 -5"),
+ ColourLines("1 2 -3, -1 -2 -5, 3 5")};
+ static ColourLines cu[2]={ColourLines("1 5, -1 -2 3, -3 2 -5"),
+ ColourLines("1 2 -3, -1 -5, 3 -2 5")};
+ // 4 point
+ static ColourLines c4[2]={ColourLines("1 -2, 2 4, -1 -4"),
+ ColourLines("1 4, -4 -2, 2 -1")};
+ // create the selector
+ Selector<const ColourLines *> sel;
+ if (diag->id() == -1) sel.insert(1.0, &cgq );
+ else if (diag->id() == -2) sel.insert(1.0, &cgqbar);
+ else if (diag->id() == -3) sel.insert(1.0, &cqqbar);
+ else if (diag->id() == -4) {
+ sel.insert(0.5, &cs[0]);
+ sel.insert(0.5, &cs[1]);
+ }
+ else if (diag->id() == -5) {
+ sel.insert(0.5, &ct[0]);
+ sel.insert(0.5, &ct[1]);
+ }
+ else if (diag->id() == -6) {
+ sel.insert(0.5, &cu[0]);
+ sel.insert(0.5, &cu[1]);
+ }
+ else if (diag->id() == -7) {
+ sel.insert(0.5, &c4[0]);
+ sel.insert(0.5, &c4[1]);
+ }
+ return sel;
+}
+
+Energy2 MEPPto3P1Jet::scale() const {
+ return sHat();
+}
+
+double MEPPto3P1Jet::me2() const {
+ // return value
+ double output(0.);
+ // mass of the 3P1 state
+ Energy M = meMomenta()[2].mass();
+ Energy2 M2 = sqr(meMomenta()[2].mass());
+ if(mePartonData()[0]->id()==ParticleID::g) {
+ // g qbar -> 3P1 qbar
+ if(mePartonData()[1]->id()==ParticleID::g) {
+ // // weights for the different diagrams
+ // DVector save(4,0.);
+ // save[0] = (8*sqr(sHat()-3*M2)*tHat()*uHat())/pow<4,1>(tHat() + uHat());
+ // save[1] = (4*tHat()*sqr(uHat()-3*M2)*
+ // (pow<4,1>(M2) + pow<4,1>(sHat()) +pow<4,1>(tHat()) -
+ // 2*(pow<3,1>(M2) + pow<3,1>(sHat()) - pow<3,1>(tHat()))*uHat() +
+ // (sqr(M2) + sqr(sHat()) + sqr(tHat()))*sqr(uHat())))/
+ // (pow<4,1>(M2 - uHat())*uHat()*sqr(tHat() + uHat()));
+ // save[2] = (4*sqr(-3*M2 + tHat())*uHat()*
+ // (pow<4,1>(M2) + pow<4,1>(sHat()) - 2*pow<3,1>(M2)*tHat() -
+ // 2*pow<3,1>(sHat())*tHat() + sqr(M2)*sqr(tHat()) +
+ // sqr(sHat())*sqr(tHat()) + sqr(uHat())*sqr(tHat() + uHat())))/
+ // (pow<4,1>(M2 - tHat())*tHat()*sqr(tHat() + uHat()));
+ // save[3]=tHat()*uHat()*(16*pow<10,1>(M2)-32*pow<9,1>(M2)*(tHat()+uHat())
+ // +2*sHat()*sqr(tHat())*sqr(tHat()-uHat())*sqr(uHat())*pow<3,1>(tHat()+uHat())
+ // +sqr(tHat())*sqr(uHat())*pow<4,1>(tHat()+uHat())*(sqr(tHat())+sqr(uHat()))
+ // +2*pow<3,1>(sHat())*(tHat()+uHat())*(sqr(tHat())+sqr(uHat()))*
+ // (sqr(tHat())-tHat()*uHat()+sqr(uHat()))*(sqr(tHat())+tHat()*uHat()+sqr(uHat()))
+ // +4*pow<8,1>(M2)*(4*sqr(sHat())+5*sqr(tHat())+28*tHat()*uHat()+5*sqr(uHat()))
+ // +pow<4,1>(sHat())*sqr(pow<3,1>(tHat())+pow<3,1>(uHat()))
+ // +sqr(sHat())*(pow<8,1>(tHat())+2*pow<7,1>(tHat())*uHat()
+ // +6*pow<6,1>(tHat())*sqr(uHat())+4*pow<5,1>(tHat())*pow<3,1>(uHat())
+ // +14*pow<4,1>(tHat())*pow<4,1>(uHat())+4*pow<3,1>(tHat())*pow<5,1>(uHat())
+ // +6*sqr(tHat())*pow<6,1>(uHat())+2*tHat()*pow<7,1>(uHat())+pow<8,1>(uHat()))
+ // -4*pow<7,1>(M2)*(16*pow<3,1>(sHat())+26*sqr(sHat())*(tHat()+uHat())
+ // +4*sHat()*(2*sqr(tHat())+tHat()*uHat()+2*sqr(uHat()))
+ // +(tHat()+uHat())*(7*sqr(tHat())+22*tHat()*uHat()+7*sqr(uHat())))
+ // +pow<6,1>(M2)*(64*pow<4,1>(sHat())+280*pow<3,1>(sHat())*(tHat()+uHat())
+ // +2*sHat()*(tHat()+uHat())*(87*sqr(tHat())-40*tHat()*uHat()+87*sqr(uHat()))
+ // +sqr(sHat())*(397*sqr(tHat())+482*tHat()*uHat()+397*sqr(uHat()))
+ // +10*(9*pow<4,1>(tHat())+3*pow<3,1>(tHat())*uHat()
+ // +28*sqr(tHat())*sqr(uHat())+3*tHat()*pow<3,1>(uHat())+9*pow<4,1>(uHat())))
+ // -2*pow<5,1>(M2)*(72*pow<4,1>(sHat())*(tHat()+uHat())+3*sqr(sHat())*(tHat()+uHat())*(137*sqr(tHat())+62*tHat()*uHat()+137*sqr(uHat()))+pow<3,1>(sHat())*(317*sqr(tHat())+378*tHat()*uHat()+317*sqr(uHat()))+2*(tHat()+uHat())*(40*pow<4,1>(tHat())-21*pow<3,1>(tHat())*uHat()+66*sqr(tHat())*sqr(uHat())-21*tHat()*pow<3,1>(uHat())+40*pow<4,1>(uHat()))+sHat()*(213*pow<4,1>(tHat())+130*pow<3,1>(tHat())*uHat()+178*sqr(tHat())*sqr(uHat())+130*tHat()*pow<3,1>(uHat())+213*pow<4,1>(uHat())))
+ // +pow<4,1>(M2)*(3*pow<4,1>(sHat())*(59*sqr(tHat())+54*tHat()*uHat()+59*sqr(uHat()))+4*pow<3,1>(sHat())*(tHat()+uHat())*(180*sqr(tHat())+91*tHat()*uHat()+180*sqr(uHat()))+2*sHat()*(tHat()+uHat())*(268*pow<4,1>(tHat())-47*pow<3,1>(tHat())*uHat()+282*sqr(tHat())*sqr(uHat())-47*tHat()*pow<3,1>(uHat())+268*pow<4,1>(uHat()))+sqr(sHat())*(981*pow<4,1>(tHat())+1496*pow<3,1>(tHat())*uHat()+2054*sqr(tHat())*sqr(uHat())+1496*tHat()*pow<3,1>(uHat())+981*pow<4,1>(uHat()))+2*(80*pow<6,1>(tHat())+111*pow<5,1>(tHat())*uHat()+30*pow<4,1>(tHat())*sqr(uHat())+138*pow<3,1>(tHat())*pow<3,1>(uHat())+30*sqr(tHat())*pow<4,1>(uHat())+111*tHat()*pow<5,1>(uHat())+80*pow<6,1>(uHat())))
+ // +2*pow<3,1>(M2)*(-2*pow<4,1>(sHat())*(tHat()+uHat())*(31*sqr(tHat())-4*tHat()*uHat()+31*sqr(uHat()))-2*sqr(sHat())*(tHat()+uHat())*(157*pow<4,1>(tHat())+102*pow<3,1>(tHat())*uHat()+306*sqr(tHat())*sqr(uHat())+102*tHat()*pow<3,1>(uHat())+157*pow<4,1>(uHat()))-pow<3,1>(sHat())*(243*pow<4,1>(tHat())+336*pow<3,1>(tHat())*uHat()+514*sqr(tHat())*sqr(uHat())+336*tHat()*pow<3,1>(uHat())+243*pow<4,1>(uHat()))-3*(tHat()+uHat())*(14*pow<6,1>(tHat())+21*pow<5,1>(tHat())*uHat()+8*pow<4,1>(tHat())*sqr(uHat())+18*pow<3,1>(tHat())*pow<3,1>(uHat())+8*sqr(tHat())*pow<4,1>(uHat())+21*tHat()*pow<5,1>(uHat())+14*pow<6,1>(uHat()))-sHat()*(168*pow<6,1>(tHat())+209*pow<5,1>(tHat())*uHat()+150*pow<4,1>(tHat())*sqr(uHat())+186*pow<3,1>(tHat())*pow<3,1>(uHat())+150*sqr(tHat())*pow<4,1>(uHat())+209*tHat()*pow<5,1>(uHat())+168*pow<6,1>(uHat())))
+ // +sqr(M2)*(18*pow<8,1>(tHat())+76*pow<7,1>(tHat())*uHat()+157*pow<6,1>(tHat())*sqr(uHat())+90*pow<5,1>(tHat())*pow<3,1>(uHat())+126*pow<4,1>(tHat())*pow<4,1>(uHat())+90*pow<3,1>(tHat())*pow<5,1>(uHat())+157*sqr(tHat())*pow<6,1>(uHat())+76*tHat()*pow<7,1>(uHat())+18*pow<8,1>(uHat())+18*pow<4,1>(sHat())*(sqr(tHat())+tHat()*uHat()+sqr(uHat()))*(3*sqr(tHat())-2*tHat()*uHat()+3*sqr(uHat()))+2*pow<3,1>(sHat())*(tHat()+uHat())*(91*pow<4,1>(tHat())+23*pow<3,1>(tHat())*uHat()+164*sqr(tHat())*sqr(uHat())+23*tHat()*pow<3,1>(uHat())+91*pow<4,1>(uHat()))+2*sHat()*(tHat()+uHat())*(45*pow<6,1>(tHat())+43*pow<5,1>(tHat())*uHat()+17*pow<4,1>(tHat())*sqr(uHat())+36*pow<3,1>(tHat())*pow<3,1>(uHat())+17*sqr(tHat())*pow<4,1>(uHat())+43*tHat()*pow<5,1>(uHat())+45*pow<6,1>(uHat()))+sqr(sHat())*(201*pow<6,1>(tHat())+350*pow<5,1>(tHat())*uHat()+620*pow<4,1>(tHat())*sqr(uHat())+742*pow<3,1>(tHat())*pow<3,1>(uHat())+620*sqr(tHat())*pow<4,1>(uHat())+350*tHat()*pow<5,1>(uHat())+201*pow<6,1>(uHat())))
+ // +2*M2*(-(tHat()*uHat()*pow<3,1>(tHat()+uHat())*(3*tHat()+uHat())*(tHat()+3*uHat())*(sqr(tHat())-tHat()*uHat()+sqr(uHat())))-6*pow<4,1>(sHat())*(pow<5,1>(tHat())+pow<3,1>(tHat())*sqr(uHat())+sqr(tHat())*pow<3,1>(uHat())+pow<5,1>(uHat()))-sqr(sHat())*(tHat()+uHat())*(13*pow<6,1>(tHat())+13*pow<5,1>(tHat())*uHat()+30*pow<4,1>(tHat())*sqr(uHat())+36*pow<3,1>(tHat())*pow<3,1>(uHat())+30*sqr(tHat())*pow<4,1>(uHat())+13*tHat()*pow<5,1>(uHat())+13*pow<6,1>(uHat()))-pow<3,1>(sHat())*(16*pow<6,1>(tHat())+19*pow<5,1>(tHat())*uHat()+31*pow<4,1>(tHat())*sqr(uHat())+32*pow<3,1>(tHat())*pow<3,1>(uHat())+31*sqr(tHat())*pow<4,1>(uHat())+19*tHat()*pow<5,1>(uHat())+16*pow<6,1>(uHat()))-sHat()*(3*pow<8,1>(tHat())+9*pow<7,1>(tHat())*uHat()+19*pow<6,1>(tHat())*sqr(uHat())-5*pow<5,1>(tHat())*pow<3,1>(uHat())+12*pow<4,1>(tHat())*pow<4,1>(uHat())-5*pow<3,1>(tHat())*pow<5,1>(uHat())+19*sqr(tHat())*pow<6,1>(uHat())+9*tHat()*pow<7,1>(uHat())+3*pow<8,1>(uHat()))))/(pow<4,1>(M2-tHat())*pow<4,1>(M2-uHat())*pow<4,1>(tHat()+uHat()));
+ // meInfo(save);
+ // // matrix element
+ // output = 64./9.*O1_*pow<3,1>(Constants::pi*standardModel()->alphaS(scale())/M)/sHat()*
+ // (9*pow<4,1>(M2)*sqr(M2-tHat())*sqr(M2-uHat())*sqr(tHat()+uHat())*
+ // sqr(sqr(tHat())+tHat()*uHat()+sqr(uHat())-M2*(tHat()+uHat()))
+ // +pow<4,1>(sHat())*sqr(tHat()+uHat())*sqr(uHat()*(sHat()+uHat())*(sqr(sHat())+sHat()*uHat()+sqr(uHat()))
+ // +sqr(M2)*(3*sqr(sHat())+6*sHat()*uHat()+sqr(uHat()))
+ // -M2*(3*sHat()+uHat())*(sqr(sHat())+2*sHat()*uHat()+2*sqr(uHat())))
+ // +sqr(M2-tHat())*pow<4,1>(tHat())*sqr(uHat()*(tHat()+uHat())*(sqr(tHat())+tHat()*uHat()+sqr(uHat()))
+ // +sqr(M2)*(3*sqr(tHat())+6*tHat()*uHat()+sqr(uHat()))
+ // -M2*(3*tHat()+uHat())*(sqr(tHat())+2*tHat()*uHat()+2*sqr(uHat())))
+ // +sqr(M2-uHat())*pow<4,1>(uHat())*sqr(tHat()*(tHat()+uHat())*(sqr(tHat())+tHat()*uHat()+sqr(uHat()))
+ // -M2*(tHat()+3*uHat())*(2*sqr(tHat())+2*tHat()*uHat()+sqr(uHat()))
+ // +sqr(M2)*(sqr(tHat())+6*tHat()*uHat()+3*sqr(uHat()))))
+ // /(pow<4,1>(M2-tHat())*tHat()*pow<4,1>(M2-uHat())*uHat()*pow<4,1>(tHat()+uHat()));
+ // // test vs NPB 291 731
+ // // Energy5 R02 = params_->firstDerivativeRadialWaveFunctionSquared(state_,n_);
+ // // Energy6 Q(sHat()*tHat()*uHat());
+ // // Energy4 P(sHat()*tHat()+tHat()*uHat()+uHat()*sHat());
+ // // double test = 16.*Constants::pi*sqr(sHat())*
+ // // 4.*Constants::pi*pow(standardModel()->alphaS(scale()),3)*R02/M/M2/sqr(sHat())/Q/pow<4,1>(Q-M2*P)*
+ // // (9.*sqr(M2*sqr(P))*(pow<4,1>(M2)-2.*sqr(M2)*P+sqr(P)) -6*M2*pow<3,1>(P)*Q*(2.*pow<4,1>(M2)-5.*sqr(M2)*P+sqr(P))
+ // // -sqr(P*Q)*(pow<4,1>(M2)+2.*sqr(M2)*P-sqr(P))+2.*M2*P*pow<3,1>(Q)*(sqr(M2)-P)+6.*pow<4,1>(M*Q));
+ // // cerr << "testing matrix element " << output << " " << test << " "
+ // // << (output-test)/(output+test) << " " << output/test << "\n";
+ assert(false);
+ }
+ else if(mePartonData()[1]->id()<0) {
+ // helicity amplitude version of ME
+ // VectorWaveFunction g1w(meMomenta()[0],mePartonData()[0],incoming);
+ // SpinorBarWaveFunction q2w(meMomenta()[1],mePartonData()[1],incoming);
+ // VectorWaveFunction v3w(meMomenta()[2],mePartonData()[2],outgoing);
+ // SpinorWaveFunction q4w(meMomenta()[3],mePartonData()[3],outgoing);
+ // vector<VectorWaveFunction> g1;
+ // vector<SpinorBarWaveFunction> q2;
+ // vector<VectorWaveFunction> v3;
+ // vector<SpinorWaveFunction> q4;
+ // for(unsigned int ix=0;ix<2;++ix) {
+ // g1w.reset(2*ix);
+ // g1.push_back(g1w);
+ // q2w.reset(ix);
+ // q2.push_back(q2w);
+ // q4w.reset(ix);
+ // q4.push_back(q4w);
+ // }
+ // for(unsigned int ix=0;ix<3;++ix) {
+ // v3w.reset(ix,vector_phase);
+ // v3.push_back(v3w);
+ // }
+ // double total(0.);
+ // ProductionMatrixElement me(PDT::Spin1,PDT::Spin1Half,PDT::Spin1,PDT::Spin1Half);
+ // Complex phase = exp(Complex(0.,meMomenta()[2].phi()));
+ // me(0,0,0,0)=(Complex(0,2)*phase*sHat()*sqrt(-(uHat()/sHat())))/M2;
+ // me(0,0,1,0)=(Complex(0,1)*sqrt(2)*sHat()*sqrt(-tHat()))/pow<3,1>(M);
+ // me(0,1,0,1)=(Complex(0,2)*uHat()*sqrt(-(sHat()*uHat())))/(sqr(M2)*phase-M2*phase*sHat());
+ // me(0,1,1,1)=(Complex(0,1)*sqrt(2)*(M2+sHat())*sqrt(-tHat())*uHat())/(pow<3,1>(M)*sqr(phase)*(M2-sHat()));
+ // me(0,1,2,1)=(Complex(0,2)*tHat()*sqrt(-(sHat()*uHat())))/(pow(phase,3)*(sqr(M2)-M2*sHat()));
+ // me(2,0,0,0)=(Complex(0,-2)*pow(phase,3)*tHat()*sqrt(-(sHat()*uHat())))/(sqr(M2)-M2*sHat());
+ // me(2,0,1,0)=(Complex(0,1)*sqrt(2)*sqr(phase)*(M2+sHat())*sqrt(-tHat())*uHat())/(pow<5,1>(M)-pow<3,1>(M)*sHat());
+ // me(2,0,2,0)=(Complex(0,-2)*phase*uHat()*sqrt(-(sHat()*uHat())))/(sqr(M2)-M2*sHat());
+ // me(2,1,1,1)=(Complex(0,1)*sqrt(2)*sHat()*sqrt(-tHat()))/pow<3,1>(M);
+ // me(2,1,2,1)=(Complex(0,-2)*sHat()*sqrt(-(uHat()/sHat())))/(M2*phase);
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // LorentzPolarizationVectorE fCurrent = q4[ih4].dimensionedWave().vectorCurrent(q2[ih2].dimensionedWave());
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // for(unsigned int ih3=0;ih3<3;++ih3) {
+ // auto eps1 = epsilon(meMomenta()[2],v3[ih3].wave(),g1[ih1].wave());
+ // auto eps2 = epsilon(fCurrent,meMomenta()[2],v3[ih3].wave());
+ // Complex amp =-((M2-tHat())*(eps1*fCurrent)
+ // +2.*(meMomenta()[2]*g1[ih1].wave())*(eps2*meMomenta()[0])
+ // -2.*(fCurrent*meMomenta()[2])*(eps1*meMomenta()[0])
+ // )/sqr(M2);
+ // double test = norm(amp/me(2*ih1,ih2,ih3,ih4)-1);
+ // if(norm(me(2*ih1,ih2,ih3,ih4))>1e-10&&test>1e-10) cerr << "testing in hel loop A " << ih1 << " " << ih2 << " " << ih3 << " " << ih4 << " "
+ // << amp << " " << me(2*ih1,ih2,ih3,ih4) << " " << amp/me(2*ih1,ih2,ih3,ih4) << "\n";
+ // total+= norm(amp);
+ // }
+ // }
+ // }
+ // }
+ // spin sum version
+ double total = -((4*sqr(M2-sHat())*sqr(sHat())*tHat()+8*M2*sHat()*(sqr(M2-sHat())+sqr(tHat()))*uHat()+4*sqr(M2+sHat())*tHat()*sqr(uHat())+8*M2*sHat()*pow<3,1>(uHat()))/(pow<3,1>(M2)*sqr(M2-sHat())));
+ // final factors
+ output = 128.*O1_*pow<3,1>(M*Constants::pi*standardModel()->alphaS(scale()))/81./pow<4,1>(tHat()-M2)*total;
+ // analytic test
+ // Energy5 R02 = params_->firstDerivativeRadialWaveFunctionSquared(state_,n_);
+ // double test = -16.*Constants::pi*sqr(sHat())*
+ // 16.*Constants::pi*pow(standardModel()->alphaS(scale()),3)*R02/(3.*M*M2*sqr(sHat())*pow<4,1>(tHat()-M2))*
+ // (tHat()*(sqr(sHat())+sqr(uHat()))+4.*M2*sHat()*uHat());
+ // cerr << "testing matrix element " << output << " " << test << " " << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ // g q -> 3P1 q
+ else if(mePartonData()[1]->id()<6) {
+ // helicity amplitude version of ME
+ // VectorWaveFunction g1w(meMomenta()[0],mePartonData()[0],incoming);
+ // SpinorWaveFunction q2w(meMomenta()[1],mePartonData()[1],incoming);
+ // VectorWaveFunction v3w(meMomenta()[2],mePartonData()[2],outgoing);
+ // SpinorBarWaveFunction q4w(meMomenta()[3],mePartonData()[3],outgoing);
+ // vector<VectorWaveFunction> g1;
+ // vector<SpinorWaveFunction> q2;
+ // vector<VectorWaveFunction> v3;
+ // vector<SpinorBarWaveFunction> q4;
+ // for(unsigned int ix=0;ix<2;++ix) {
+ // g1w.reset(2*ix);
+ // g1.push_back(g1w);
+ // q2w.reset(ix);
+ // q2.push_back(q2w);
+ // q4w.reset(ix);
+ // q4.push_back(q4w);
+ // }
+ // for(unsigned int ix=0;ix<3;++ix) {
+ // v3w.reset(ix,vector_phase);
+ // v3.push_back(v3w);
+ // }
+ // double total(0.);
+ // ProductionMatrixElement me(PDT::Spin1,PDT::Spin1Half,PDT::Spin1,PDT::Spin1Half);
+ // Complex phase = exp(Complex(0.,meMomenta()[2].phi()));
+ // me(0,0,0,0)=(Complex(0,-2)*phase*sHat()*sqrt(-(uHat()/sHat())))/M2;
+ // me(0,0,1,0)=(Complex(0,-1)*sqrt(2)*sHat()*sqrt(-tHat()))/pow<3,1>(M);
+ // me(0,1,0,1)=(Complex(0,-2)*uHat()*sqrt(-(sHat()*uHat())))/M2/phase/(M2-sHat());
+ // me(0,1,1,1)=(Complex(0,-1)*sqrt(2)*(M2+sHat())*sqrt(-tHat())*uHat())/(pow<3,1>(M)*sqr(phase)*(M2-sHat()));
+ // me(0,1,2,1)=(Complex(0,-2)*tHat()*sqrt(-(sHat()*uHat())))/(pow(phase,3)*(sqr(M2)-M2*sHat()));
+ // me(2,0,0,0)=(Complex(0,2)*pow(phase,3)*tHat()*sqrt(-(sHat()*uHat())))/(sqr(M2)-M2*sHat());
+ // me(2,0,1,0)=(Complex(0,-1)*sqrt(2)*sqr(phase)*(M2+sHat())*sqrt(-tHat())*uHat())/(pow<5,1>(M)-pow<3,1>(M)*sHat());
+ // me(2,0,2,0)=(Complex(0,2)*phase*uHat()*sqrt(-(sHat()*uHat())))/(sqr(M2)-M2*sHat());
+ // me(2,1,1,1)=(Complex(0,-1)*sqrt(2)*sHat()*sqrt(-tHat()))/pow<3,1>(M);
+ // me(2,1,2,1)=(Complex(0,2)*sHat()*sqrt(-(uHat()/sHat())))/(M2*phase);
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // LorentzPolarizationVectorE fCurrent = q2[ih2].dimensionedWave().vectorCurrent(q4[ih4].dimensionedWave());
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // for(unsigned int ih3=0;ih3<3;++ih3) {
+ // auto eps1 = epsilon(meMomenta()[2],v3[ih3].wave(),g1[ih1].wave());
+ // auto eps2 = epsilon(fCurrent,meMomenta()[2],v3[ih3].wave());
+ // Complex amp = ((M2-tHat())*(eps1*fCurrent)
+ // +2.*(meMomenta()[2]*g1[ih1].wave())*(eps2*meMomenta()[0])
+ // -2.*(fCurrent*meMomenta()[2])*(eps1*meMomenta()[0])
+ // )/sqr(M2);
+ // double test = norm(amp/me(2*ih1,ih2,ih3,ih4)-1);
+ // if(norm(me(2*ih1,ih2,ih3,ih4))>1e-10&&test>1e-10) cerr << "testing in hel loop A " << ih1 << " " << ih2 << " " << ih3 << " " << ih4 << " "
+ // << amp << " " << me(2*ih1,ih2,ih3,ih4) << " " << amp/me(2*ih1,ih2,ih3,ih4) << "\n";
+ // total+= norm(amp);
+ // }
+ // }
+ // }
+ // }
+ // spin sum version
+ double total = -((4*sqr(M2-sHat())*sqr(sHat())*tHat()+8*M2*sHat()*(sqr(M2-sHat())+sqr(tHat()))*uHat()+4*sqr(M2+sHat())*tHat()*sqr(uHat())+8*M2*sHat()*pow<3,1>(uHat()))/(pow<3,1>(M2)*sqr(M2-sHat())));
+ // final factors
+ output = 128.*O1_*pow<3,1>(M*Constants::pi*standardModel()->alphaS(scale()))/81./pow<4,1>(tHat()-M2)*total;
+ // analytic test
+ // Energy5 R02 = params_->firstDerivativeRadialWaveFunctionSquared(state_,n_);
+ // double test = -16.*Constants::pi*sqr(sHat())*
+ // 16.*Constants::pi*pow(standardModel()->alphaS(scale()),3)*R02/(3.*M*M2*sqr(sHat())*pow<4,1>(tHat()-M2))*
+ // (tHat()*(sqr(sHat())+sqr(uHat()))+4.*M2*sHat()*uHat());
+ // cerr << "testing matrix element " << output << " " << test << " " << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ else assert(false);
+ }
+ // q qbar -> 3P1 g
+ else if(mePartonData()[0]->id()==-mePartonData()[1]->id()) {
+ // helicity amplitude version of ME
+ // SpinorWaveFunction q1w(meMomenta()[0],mePartonData()[1],incoming);
+ // SpinorBarWaveFunction q2w(meMomenta()[1],mePartonData()[0],incoming);
+ // VectorWaveFunction v3w(meMomenta()[2],mePartonData()[2],outgoing);
+ // VectorWaveFunction g4w(meMomenta()[3],mePartonData()[3],outgoing);
+ // vector<SpinorWaveFunction> q1;
+ // vector<SpinorBarWaveFunction> q2;
+ // vector<VectorWaveFunction> v3;
+ // vector<VectorWaveFunction> g4;
+ // for(unsigned int ix=0;ix<2;++ix) {
+ // g4w.reset(2*ix,vector_phase);
+ // g4.push_back(g4w);
+ // q1w.reset(ix);
+ // q1.push_back(q1w);
+ // q2w.reset(ix);
+ // q2.push_back(q2w);
+ // }
+ // for(unsigned int ix=0;ix<3;++ix) {
+ // v3w.reset(ix,vector_phase);
+ // v3.push_back(v3w);
+ // }
+ // double total(0.);
+ // ProductionMatrixElement me(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1,PDT::Spin1);
+ // Complex phase = exp(Complex(0.,meMomenta()[2].phi()));
+ // me(0,1,0,0)=(Complex(0,2)*phase*sqrt(tHat()*uHat()))/M2;
+ // me(0,1,1,0)=(Complex(0,-1)*sqrt(2)*sqrt(sHat())*tHat())/pow<3,1>(M);
+ // me(0,1,1,2)=(Complex(0,1)*sqrt(2)*sqrt(sHat())*uHat())/(pow<3,1>(M)*sqr(phase));
+ // me(0,1,2,2)=(Complex(0,-2)*sqrt(tHat()*uHat()))/(M2*pow(phase,3));
+ // me(1,0,0,0)=(Complex(0,2)*pow(phase,3)*sqrt(tHat()*uHat()))/M2;
+ // me(1,0,1,0)=(Complex(0,1)*sqrt(2)*sqr(phase)*sqrt(sHat())*uHat())/pow<3,1>(M);
+ // me(1,0,1,2)=(Complex(0,-1)*sqrt(2)*sqrt(sHat())*tHat())/pow<3,1>(M);
+ // me(1,0,2,2)=(Complex(0,-2)*sqrt(tHat()*uHat()))/(M2*phase);
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // LorentzPolarizationVectorE fCurrent = q1[ih1].dimensionedWave().vectorCurrent(q2[ih2].dimensionedWave());
+ // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // for(unsigned int ih3=0;ih3<3;++ih3) {
+ // auto eps1 = epsilon(meMomenta()[2],v3[ih3].wave(),g4[ih4].wave());
+ // auto eps2 = epsilon(fCurrent,meMomenta()[2],v3[ih3].wave());
+ // Complex amp = ((M2-sHat())*(eps1*fCurrent) + 2.*(fCurrent*meMomenta()[2])*(eps1*meMomenta()[3])
+ // -2.*(meMomenta()[2]*g4[ih4].wave())*(eps2*meMomenta()[3]))/sqr(M2);
+ // double test = norm(amp/me(ih1,ih2,ih3,2*ih4)-1);
+ // if(norm(me(ih1,ih2,ih3,2*ih4))>1e-10&&test>1e-10)
+ // cerr << "testing in hel loop A " << ih1 << " " << ih2 << " " << ih3 << " " << ih4 << " "
+ // << amp << " " << me(ih1,ih2,ih3,2*ih4) << " " << amp/me(ih1,ih2,ih3,2*ih4) << "\n";
+ // total+= norm(amp);
+ // }
+ // }
+ // }
+ // }
+ // spin sum version
+ double total = 4.*(4.*M2*tHat()*uHat()+sHat()*(sqr(tHat())+sqr(uHat())))/pow<3,1>(M2);
+ // final factors
+ output = 1024.*O1_*pow<3,1>(M*Constants::pi*standardModel()->alphaS(scale()))/(243.*pow<4,1>(sHat()-M2))*total;
+ // analytic test
+ // Energy5 R02 = params_->firstDerivativeRadialWaveFunctionSquared(state_,n_);
+ // double test = 16.*Constants::pi*sqr(sHat())*8./3.*sqr(tHat()/sHat())*
+ // 16.*Constants::pi*pow(standardModel()->alphaS(scale()),3)*R02*
+ // (sHat()*(sqr(tHat())+sqr(uHat()))+4.*M2*tHat()*uHat())/3./M/M2/sqr(tHat())/pow<4,1>(sHat()-M2);
+ // cerr << "testing matrix element " << output << " " << test << " " << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ else
+ assert(false);
+ return output;
+}
+
+void MEPPto3P1Jet::constructVertex(tSubProPtr sub) {
+ // extract the particles in the hard process
+ ParticleVector hard;
+ hard.reserve(4);
+ hard.push_back(sub->incoming().first);
+ hard.push_back(sub->incoming().second);
+ hard.push_back(sub->outgoing()[0]);
+ hard.push_back(sub->outgoing()[1]);
+ // get them in the right order
+ bool swapped(false);
+ if(hard[0]->id()==-hard[1]->id()) {
+ if(hard[0]->id()<0) swapped = true;
+ }
+ else if(hard[0]->id()!=ParticleID::g) {
+ swapped=true;
+ }
+ if(swapped) {
+ swap(hard[0],hard[1]);
+ swap(hard[2],hard[3]);
+ }
+ // boost to partonic CMS
+ Lorentz5Momentum pcms = hard[0]->momentum()+hard[1]->momentum();
+ LorentzRotation boost(-pcms.boostVector());
+ for(PPtr part : hard) part->transform(boost);
+ // extract kinematic variables
+ Energy M = hard[2]->mass();
+ Energy2 M2 = sqr(M);
+ double phi = hard[2]->momentum().phi();
+ Complex phase = exp(Complex(0.,phi));
+ Energy2 sh = (hard[0]->momentum()+hard[1]->momentum()).m2();
+ Energy2 th = (hard[0]->momentum()-hard[2]->momentum()).m2();
+ Energy2 uh = (hard[0]->momentum()-hard[3]->momentum()).m2();
+ // set basis states and compute the matrix element
+ ProductionMatrixElement me;
+ vector<VectorWaveFunction> v3;
+ VectorWaveFunction(v3,hard[2],outgoing,true ,false,true,vector_phase);
+ if(hard[0]->id()==ParticleID::g) {
+ // g g -> 3P1 g
+ if(hard[1]->id()==ParticleID::g) {
+ vector<VectorWaveFunction> g1,g2,g4;
+ VectorWaveFunction( g1,hard[0],incoming,false, true,true,vector_phase);
+ VectorWaveFunction( g2,hard[1],incoming,false, true,true,vector_phase);
+ VectorWaveFunction( g4,hard[3],outgoing,true , true,true,vector_phase);
+ ProductionMatrixElement me(PDT::Spin1,PDT::Spin1,PDT::Spin1,PDT::Spin1);
+ // Complex phase = exp(Complex(0.,phi));
+ // Energy2 um(uh-M2),tm(th-M2),sm(sh-M2);
+ // me(0,0,0,0)=(sqrt(2)*phase*sqr(sh)*(uh*(sh+uh)*(sqr(sh)+sh*uh+sqr(uh))+sqr(M2)*(3*sqr(sh)+6*sh*uh+sqr(uh))-M2*(3*sh+uh)*(sqr(sh)+2*sh*uh+2*sqr(uh))))/(sm*sqr(tm)*sqrt(th*uh)*sqr(um));
+ // me(0,0,0,2)=(3*sqrt(2)*sqr(M2)*(M2*sm+sqr(th)+th*uh+sqr(uh)))/(phase*sm*tm*sqrt(th*uh)*um);
+ // me(0,2,0,0)=-((sqrt(2)*sqr(th)*(-(sm*uh*(sqr(th)+th*uh+sqr(uh)))+sqr(M2)*(3*sqr(th)+6*th*uh+sqr(uh))-M2*(3*th+uh)*(sqr(th)+2*th*uh+2*sqr(uh))))/(phase*sqr(sm)*(-M2+th)*sqrt(th*uh)*sqr(um)));
+ // me(0,2,0,2)=(sqrt(2)*sqr(uh)*(-(sm*th*(sqr(th)+th*uh+sqr(uh)))-M2*(th+3*uh)*(2*sqr(th)+2*th*uh+sqr(uh))+sqr(M2)*(sqr(th)+6*th*uh+3*sqr(uh))))/(pow(phase,3)*sqr(sm)*sqr(tm)*sqrt(th*uh)*(-M2+uh));
+ // me(2,0,0,0)=-((sqrt(2)*pow(phase,3)*sqr(uh)*(-(sm*th*(sqr(th)+th*uh+sqr(uh)))-M2*(th+3*uh)*(2*sqr(th)+2*th*uh+sqr(uh))+sqr(M2)*(sqr(th)+6*th*uh+3*sqr(uh))))/(sqr(sm)*sqr(tm)*sqrt(th*uh)*(-M2+uh)));
+ // me(2,0,0,2)=(sqrt(2)*phase*sqr(th)*(-(sm*uh*(sqr(th)+th*uh+sqr(uh)))+sqr(M2)*(3*sqr(th)+6*th*uh+sqr(uh))-M2*(3*th+uh)*(sqr(th)+2*th*uh+2*sqr(uh))))/(sqr(sm)*(-M2+th)*sqrt(th*uh)*sqr(um));
+ // me(2,2,0,0)=(-3*sqrt(2)*sqr(M2)*phase*(M2*sm+sqr(th)+th*uh+sqr(uh)))/(sm*tm*sqrt(th*uh)*um);
+ // me(2,2,0,2)=-((sqrt(2)*sqr(sh)*(uh*(sh+uh)*(sqr(sh)+sh*uh+sqr(uh))+sqr(M2)*(3*sqr(sh)+6*sh*uh+sqr(uh))-M2*(3*sh+uh)*(sqr(sh)+2*sh*uh+2*sqr(uh))))/(phase*sm*sqr(tm)*sqrt(th*uh)*sqr(um)));
+ // // test the average result
+ // // double aver = me.average();
+ // // double test = 4.*(9*pow<4,1>(M2)*sqr(M2-th)*sqr(M2-uh)*sqr(th+uh)*
+ // // sqr(sqr(th)+th*uh+sqr(uh)-M2*(th+uh))
+ // // +pow<4,1>(sh)*sqr(th+uh)*sqr(uh*(sh+uh)*(sqr(sh)+sh*uh+sqr(uh))
+ // // +sqr(M2)*(3*sqr(sh)+6*sh*uh+sqr(uh))
+ // // -M2*(3*sh+uh)*(sqr(sh)+2*sh*uh+2*sqr(uh)))
+ // // +sqr(M2-th)*pow<4,1>(th)*sqr(uh*(th+uh)*(sqr(th)+th*uh+sqr(uh))
+ // // +sqr(M2)*(3*sqr(th)+6*th*uh+sqr(uh))
+ // // -M2*(3*th+uh)*(sqr(th)+2*th*uh+2*sqr(uh)))
+ // // +sqr(M2-uh)*pow<4,1>(uh)*sqr(th*(th+uh)*(sqr(th)+th*uh+sqr(uh))
+ // // -M2*(th+3*uh)*(2*sqr(th)+2*th*uh+sqr(uh))
+ // // +sqr(M2)*(sqr(th)+6*th*uh+3*sqr(uh))))
+ // // /(pow<4,1>(M2-th)*th*pow<4,1>(M2-uh)*uh*pow<4,1>(th+uh));
+ // // cerr << "testing spin correlations " << test << " " << me.average() << " "
+ // // << abs(test-aver)/(test+aver) << "\n";
+ }
+ // g qbar -> 3P1 qbar
+ else if(hard[1]->id()<0) {
+ vector<VectorWaveFunction> g1;
+ vector<SpinorBarWaveFunction> q2;
+ vector<SpinorWaveFunction> q4;
+ VectorWaveFunction( g1,hard[0],incoming,false,true,true,vector_phase);
+ SpinorBarWaveFunction(q2,hard[1],incoming,false,true);
+ SpinorWaveFunction( q4,hard[3],outgoing,true ,true);
+ g1[1]=g1[2];
+ // matrix element
+ me = ProductionMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1,PDT::Spin1Half);
+ if(!swapped) {
+ me(0,0,0,0)=(Complex(0,2)*phase*sh*sqrt(-(uh/sh)))/M2;
+ me(0,0,1,0)=(Complex(0,1)*sqrt(2)*sh*sqrt(-th))/pow<3,1>(M);
+ me(0,1,0,1)=(Complex(0,2)*uh*sqrt(-(sh*uh)))/(sqr(M2)*phase-M2*phase*sh);
+ me(0,1,1,1)=(Complex(0,1)*sqrt(2)*(M2+sh)*sqrt(-th)*uh)/(pow<3,1>(M)*sqr(phase)*(M2-sh));
+ me(0,1,2,1)=(Complex(0,2)*th*sqrt(-(sh*uh)))/(pow(phase,3)*(sqr(M2)-M2*sh));
+ me(2,0,0,0)=(Complex(0,-2)*pow(phase,3)*th*sqrt(-(sh*uh)))/(sqr(M2)-M2*sh);
+ me(2,0,1,0)=(Complex(0,1)*sqrt(2)*sqr(phase)*(M2+sh)*sqrt(-th)*uh)/(pow<5,1>(M)-pow<3,1>(M)*sh);
+ me(2,0,2,0)=(Complex(0,-2)*phase*uh*sqrt(-(sh*uh)))/(sqr(M2)-M2*sh);
+ me(2,1,1,1)=(Complex(0,1)*sqrt(2)*sh*sqrt(-th))/pow<3,1>(M);
+ me(2,1,2,1)=(Complex(0,-2)*sh*sqrt(-(uh/sh)))/(M2*phase);
+ }
+ else {
+ phase *= -1.;
+ me(0,0,0,0)=(Complex(0,2)*sqr(phase)*sqrt(-(sh*uh))*(th+uh))/(M2*(-M2+sh));
+ me(0,0,1,0)=(Complex(0,-1)*sqrt(2)*phase*sh*sqrt(-th))/pow<3,1>(M);
+ me(0,1,0,1)=(Complex(0,-2)*sqr(phase)*uh*sqrt(-(sh*uh)))/(sqr(M2)-M2*sh);
+ me(0,1,1,1)=(Complex(0,-1)*sqrt(2)*phase*(M2+sh)*sqrt(-th)*uh)/(pow<5,1>(M)-pow<3,1>(M)*sh);
+ me(0,1,2,1)=(Complex(0,2)*th*sqrt(-(sh/uh))*uh)/(sqr(M2)-M2*sh);
+ me(2,0,0,0)=(Complex(0,-2)*th*sqrt(-(sh/uh))*uh)/(sqr(M2)-M2*sh);
+ me(2,0,1,0)=(Complex(0,1)*sqrt(2)*(M2+sh)*sqrt(-(th/sqr(M2-sh)))*uh)/(pow<3,1>(M)*phase);
+ me(2,0,2,0)=(Complex(0,2)*uh*sqrt(-(sh*uh)))/(sqr(phase)*(sqr(M2)-M2*sh));
+ me(2,1,1,1)=(Complex(0,-1)*sqrt(2)*sh*sqrt(-th))/(pow<3,1>(M)*phase);
+ me(2,1,2,1)=(Complex(0,2)*sqrt(-(sh*uh))*(th+uh))/(M2*sqr(phase)*(M2-sh));
+ }
+ // Helicity code version
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // LorentzPolarizationVectorE fCurrent = q4[ih4].dimensionedWave().vectorCurrent(q2[ih2].dimensionedWave());
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // for(unsigned int ih3=0;ih3<3;++ih3) {
+ // auto eps1 = epsilon(hard[2]->momentum(),v3[ih3].wave(),g1[ih1].wave());
+ // auto eps2 = epsilon(fCurrent,hard[2]->momentum(),v3[ih3].wave());
+ // Complex amp =-((M2-th)*(eps1*fCurrent)
+ // +2.*(hard[2]->momentum()*g1[ih1].wave())*(eps2*hard[0]->momentum())
+ // -2.*(fCurrent*hard[2]->momentum())*(eps1*hard[0]->momentum())
+ // )/sqr(M2);
+ // double test = norm(amp/me(2*ih1,ih2,ih3,ih4)-1);
+ // if(norm(me(2*ih1,ih2,ih3,ih4))>1e-10&&test>1e-10)
+ // cerr << "testing in hel loop B " << ih1 << " " << ih2 << " " << ih3 << " " << ih4 << " "
+ // << amp << " " << me(2*ih1,ih2,ih3,ih4) << " " << amp/me(2*ih1,ih2,ih3,ih4) << "\n";
+ // }
+ // }
+ // }
+ // }
+ }
+ // g q -> 3P1 q
+ else if(hard[1]->id()<6) {
+ vector<VectorWaveFunction> g1;
+ vector<SpinorWaveFunction> q2;
+ vector<SpinorBarWaveFunction> q4;
+ VectorWaveFunction( g1,hard[0],incoming,false,true,true,vector_phase);
+ SpinorWaveFunction( q2,hard[1],incoming,false,true);
+ SpinorBarWaveFunction(q4,hard[3],outgoing,true ,true);
+ g1[1]=g1[2];
+ // matrix element
+ me = ProductionMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1,PDT::Spin1Half);
+ if(!swapped) {
+ me(0,0,0,0)=(Complex(0,-2)*phase*sh*sqrt(-(uh/sh)))/M2;
+ me(0,0,1,0)=(Complex(0,-1)*sqrt(2)*sh*sqrt(-th))/pow<3,1>(M);
+ me(0,1,0,1)=(Complex(0,-2)*uh*sqrt(-(sh*uh)))/M2/phase/(M2-sh);
+ me(0,1,1,1)=(Complex(0,-1)*sqrt(2)*(M2+sh)*sqrt(-th)*uh)/(pow<3,1>(M)*sqr(phase)*(M2-sh));
+ me(0,1,2,1)=(Complex(0,-2)*th*sqrt(-(sh*uh)))/(pow(phase,3)*(sqr(M2)-M2*sh));
+ me(2,0,0,0)=(Complex(0,2)*pow(phase,3)*th*sqrt(-(sh*uh)))/(sqr(M2)-M2*sh);
+ me(2,0,1,0)=(Complex(0,-1)*sqrt(2)*sqr(phase)*(M2+sh)*sqrt(-th)*uh)/(pow<5,1>(M)-pow<3,1>(M)*sh);
+ me(2,0,2,0)=(Complex(0,2)*phase*uh*sqrt(-(sh*uh)))/(sqr(M2)-M2*sh);
+ me(2,1,1,1)=(Complex(0,-1)*sqrt(2)*sh*sqrt(-th))/pow<3,1>(M);
+ me(2,1,2,1)=(Complex(0,2)*sh*sqrt(-(uh/sh)))/(M2*phase);
+ }
+ else {
+ phase *=-1.;
+ me(0,0,0,0)=(Complex(0,2)*sqr(phase)*sqrt(-(sh*uh))*(th+uh))/(sqr(M2)-M2*sh);
+ me(0,0,1,0)=(Complex(0,1)*sqrt(2)*phase*sh*sqrt(-th))/pow<3,1>(M);
+ me(0,1,0,1)=(Complex(0,2)*sqr(phase)*uh*sqrt(-(sh*uh)))/(sqr(M2)-M2*sh);
+ me(0,1,1,1)=(Complex(0,-1)*sqrt(2)*phase*(M2+sh)*sqrt(-(th/sqr(M2-sh)))*uh)/pow<3,1>(M);
+ me(0,1,2,1)=(Complex(0,-2)*th*sqrt(-(sh/uh))*uh)/(sqr(M2)-M2*sh);
+ me(2,0,0,0)=(Complex(0,2)*th*sqrt(-(sh/uh))*uh)/(sqr(M2)-M2*sh);
+ me(2,0,1,0)=(Complex(0,1)*sqrt(2)*(M2+sh)*sqrt(-th)*uh)/(pow<3,1>(M)*phase*(M2-sh));
+ me(2,0,2,0)=(Complex(0,2)*uh*sqrt(-(sh*uh)))/(M2*sqr(phase)*(-M2+sh));
+ me(2,1,1,1)=(Complex(0,1)*sqrt(2)*sh*sqrt(-th))/(pow<3,1>(M)*phase);
+ me(2,1,2,1)=(Complex(0,2)*sqrt(-(sh*uh))*(th+uh))/(M2*sqr(phase)*(-M2+sh));
+ }
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // LorentzPolarizationVectorE fCurrent = q2[ih2].dimensionedWave().vectorCurrent(q4[ih4].dimensionedWave());
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // for(unsigned int ih3=0;ih3<3;++ih3) {
+ // auto eps1 = epsilon(hard[2]->momentum(),v3[ih3].wave(),g1[ih1].wave());
+ // auto eps2 = epsilon(fCurrent,hard[2]->momentum(),v3[ih3].wave());
+ // Complex amp = ((M2-th)*(eps1*fCurrent)
+ // +2.*(hard[2]->momentum()*g1[ih1].wave())*(eps2*hard[0]->momentum())
+ // -2.*(fCurrent*hard[2]->momentum())*(eps1*hard[0]->momentum())
+ // )/sqr(M2);
+ // double test = norm(amp/me(2*ih1,ih2,ih3,ih4)-1);
+ // if(norm(me(2*ih1,ih2,ih3,ih4))>1e-10&&test>1e-10)
+ // cerr << "testing in hel loop B " << ih1 << " " << ih2 << " " << ih3 << " " << ih4 << " "
+ // << amp << " " << me(2*ih1,ih2,ih3,ih4) << " " << amp/me(2*ih1,ih2,ih3,ih4) << "\n";
+ // }
+ // }
+ // }
+ // }
+ }
+ else
+ assert(false);
+ }
+ else if(hard[0]->id()==-hard[1]->id()) {
+ vector<SpinorWaveFunction> q1;
+ vector<SpinorBarWaveFunction> q2;
+ vector<VectorWaveFunction> g4;
+ SpinorWaveFunction( q1,hard[0],incoming,false,true);
+ SpinorBarWaveFunction(q2,hard[1],incoming,false,true);
+ VectorWaveFunction( g4,hard[3],outgoing,true,true,true,vector_phase);
+ g4[1]=g4[2];
+ // matrix element
+ me = ProductionMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1,PDT::Spin1);
+ if(!swapped) {
+ me(0,1,0,0)=(Complex(0,2)*phase*sqrt(th*uh))/M2;
+ me(0,1,1,0)=(Complex(0,-1)*sqrt(2)*sqrt(sh)*th)/pow<3,1>(M);
+ me(0,1,1,2)=(Complex(0,1)*sqrt(2)*sqrt(sh)*uh)/(pow<3,1>(M)*sqr(phase));
+ me(0,1,2,2)=(Complex(0,-2)*sqrt(th*uh))/(M2*pow(phase,3));
+ me(1,0,0,0)=(Complex(0,2)*pow(phase,3)*sqrt(th*uh))/M2;
+ me(1,0,1,0)=(Complex(0,1)*sqrt(2)*sqr(phase)*sqrt(sh)*uh)/pow<3,1>(M);
+ me(1,0,1,2)=(Complex(0,-1)*sqrt(2)*sqrt(sh)*th)/pow<3,1>(M);
+ me(1,0,2,2)=(Complex(0,-2)*sqrt(th*uh))/(M2*phase);
+ }
+ else {
+ phase *=-1.;
+ me(0,1,0,0)=(Complex(0,-2)*pow(phase,3)*sqrt(th*uh))/M2;
+ me(0,1,1,0)=(Complex(0,1)*sqrt(2)*sqr(phase)*sqrt(sh)*th)/pow<3,1>(M);
+ me(0,1,1,2)=(Complex(0,-1)*sqrt(2)*sqrt(sh)*uh)/pow<3,1>(M);
+ me(0,1,2,2)=(Complex(0,2)*sqrt(th*uh))/(M2*phase);
+ me(1,0,0,0)=(Complex(0,-2)*phase*sqrt(th*uh))/M2;
+ me(1,0,1,0)=(Complex(0,-1)*sqrt(2)*sqrt(sh)*uh)/pow<3,1>(M);
+ me(1,0,1,2)=(Complex(0,1)*sqrt(2)*sqrt(sh)*th)/(pow<3,1>(M)*sqr(phase));
+ me(1,0,2,2)=(Complex(0,2)*sqrt(th*uh))/(M2*pow(phase,3));
+ }
+ // Helicity code version
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // LorentzPolarizationVectorE fCurrent = q1[ih1].dimensionedWave().vectorCurrent(q2[ih2].dimensionedWave());
+ // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // for(unsigned int ih3=0;ih3<3;++ih3) {
+ // auto eps1 = epsilon(hard[2]->momentum(),v3[ih3].wave(),g4[ih4].wave());
+ // auto eps2 = epsilon(fCurrent,hard[2]->momentum(),v3[ih3].wave());
+ // Complex amp = ((M2-sh)*(eps1*fCurrent) + 2.*(fCurrent*hard[2]->momentum())*(eps1*hard[3]->momentum())
+ // -2.*(hard[2]->momentum()*g4[ih4].wave())*(eps2*hard[3]->momentum()))/sqr(M2);
+ // double test=norm(amp/me(ih1,ih2,ih3,2*ih4)-1.);
+ // if(norm(me(ih1,ih2,ih3,2*ih4))>1e-10&&test>1e-10 )
+ // cerr << "testing in hel loop B " << ih1 << " " << ih2 << " " << ih3 << " " << ih4 << " "
+ // << amp << " " << me(ih1,ih2,ih3,2*ih4) << " " << amp/me(ih1,ih2,ih3,2*ih4) << "\n";
+ // }
+ // }
+ // }
+ // }
+ }
+ else
+ assert(false);
+ // construct the vertex
+ HardVertexPtr hardvertex = new_ptr(HardVertex());
+ // // set the matrix element for the vertex
+ hardvertex->ME(me);
+ // set the pointers and to and from the vertex
+ for(unsigned int i = 0; i < hard.size(); ++i)
+ hard[i]->spinInfo()->productionVertex(hardvertex);
+ // boost back to lab
+ boost = LorentzRotation(pcms.boostVector());
+ for(PPtr part : hard)
+ part->transform(boost);
+}
diff --git a/MatrixElement/Onium/MEPPto3P1Jet.h b/MatrixElement/Onium/MEPPto3P1Jet.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto3P1Jet.h
@@ -0,0 +1,197 @@
+// -*- C++ -*-
+#ifndef Herwig_MEPPto3P1Jet_H
+#define Herwig_MEPPto3P1Jet_H
+//
+// This is the declaration of the MEPPto3P1Jet class.
+//
+
+#include "Herwig/MatrixElement/HwMEBase.h"
+#include "OniumParameters.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * The MEPPto3P1Jet class implements the colour singlet processes for
+ * \f$gq\to^3\!\!P_1 q\f$, \f$q\bar{q}\to^3\!\!P_1 g\f$ and
+ * \f$gg\to^3\!\!P_1 g\f$.
+ *
+ * @see \ref MEPPto3P1JetInterfaces "The interfaces"
+ * defined for MEPPto3P1Jet.
+ */
+class MEPPto3P1Jet: public HwMEBase {
+
+public:
+
+ /**
+ * The default constructor.
+ */
+ MEPPto3P1Jet() : O1_(ZERO), state_(ccbar), n_(1), process_(0), mOpt_(0)
+ {}
+
+public:
+
+ /** @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 3;
+ }
+
+ /**
+ * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaEW() const {
+ return 0;
+ }
+
+ /**
+ * 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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ MEPPto3P1Jet & operator=(const MEPPto3P1Jet &) = delete;
+
+private:
+
+ /**
+ * Access to the parameters for the quarkonium states
+ */
+ OniumParametersPtr params_;
+
+ /**
+ * The \f$O_1\f$ colour-singlet coefficient
+ */
+ Energy5 O1_;
+
+ /**
+ * Type of state
+ */
+ OniumState state_;
+
+ /**
+ * Principal quantum number
+ */
+ unsigned int n_;
+
+ /**
+ * Which processes to generate
+ */
+ unsigned int process_;
+
+ /**
+ * Option for the onium mass
+ */
+ unsigned int mOpt_;
+};
+
+}
+
+#endif /* Herwig_MEPPto3P1Jet_H */
diff --git a/MatrixElement/Onium/MEPPto3P2Jet.cc b/MatrixElement/Onium/MEPPto3P2Jet.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto3P2Jet.cc
@@ -0,0 +1,805 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the MEPPto3P2Jet class.
+//
+
+#include "MEPPto3P2Jet.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/PDT/EnumParticles.h"
+#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
+#include "ThePEG/Utilities/EnumIO.h"
+#include "ThePEG/Helicity/WaveFunction/TensorWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
+#include "ThePEG/StandardModel/StandardModelBase.h"
+#include "Herwig/MatrixElement/ProductionMatrixElement.h"
+#include "Herwig/MatrixElement/HardVertex.h"
+
+using namespace Herwig;
+
+void MEPPto3P2Jet::doinit() {
+ HwMEBase::doinit();
+ // get the non-perturbative ME
+ O1_ = params_->singletMEProduction<1>(state_,n_,1,2);
+ // set the mass option
+ massOption(vector<unsigned int>({mOpt_+1,0}));
+}
+
+IBPtr MEPPto3P2Jet::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr MEPPto3P2Jet::fullclone() const {
+ return new_ptr(*this);
+}
+
+void MEPPto3P2Jet::persistentOutput(PersistentOStream & os) const {
+ os << params_ << ounit(O1_,GeV*GeV2*GeV2) << oenum(state_) << n_ << process_ << mOpt_;
+}
+
+void MEPPto3P2Jet::persistentInput(PersistentIStream & is, int) {
+ is >> params_ >> iunit(O1_,GeV*GeV2*GeV2) >> ienum(state_) >> n_ >> process_ >> mOpt_;
+}
+
+// The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<MEPPto3P2Jet,HwMEBase>
+describeHerwigMEPPto3P2Jet("Herwig::MEPPto3P2Jet",
+ "HwOniumParameters.so HwMEHadronOnium.so");
+
+void MEPPto3P2Jet::Init() {
+
+ static ClassDocumentation<MEPPto3P2Jet> documentation
+ ("The MEPPto3P2Jet class implements the q qbar -> 3P2 g, g q to 3P2 q"
+ " and g g to 3P2 g processes");
+
+ static Reference<MEPPto3P2Jet,OniumParameters> interfaceParameters
+ ("Parameters",
+ "Quarkonium parameters",
+ &MEPPto3P2Jet::params_, false, false, true, false, false);
+
+ static Switch<MEPPto3P2Jet,OniumState> interfaceState
+ ("State",
+ "The type of onium state",
+ &MEPPto3P2Jet::state_, ccbar, false, false);
+ static SwitchOption interfaceStateccbar
+ (interfaceState,
+ "ccbar",
+ "Charmonium state",
+ ccbar);
+ static SwitchOption interfaceStatebbbar
+ (interfaceState,
+ "bbbar",
+ "Bottomonium state",
+ bbbar);
+
+ static Parameter<MEPPto3P2Jet,unsigned int> interfacePrincipalQuantumNumber
+ ("PrincipalQuantumNumber",
+ "The principle quantum number of the states",
+ &MEPPto3P2Jet::n_, 1, 1, 10,
+ false, false, Interface::limited);
+
+ static Switch<MEPPto3P2Jet,unsigned int> interfaceProcess
+ ("Process",
+ "Which processes to generate",
+ &MEPPto3P2Jet::process_, 0, false, false);
+ static SwitchOption interfaceProcessAll
+ (interfaceProcess,
+ "All",
+ "Generate all the processes",
+ 0);
+ static SwitchOption interfaceProcessGQto3P2Q
+ (interfaceProcess,
+ "GQto3P2Q",
+ "The g q -> 3P2 q process",
+ 1);
+ static SwitchOption interfaceProcessGQbarto3P2Qbar
+ (interfaceProcess,
+ "GQbarto3P2Qbar",
+ "The g qbar -> 3P2 qbar process",
+ 2);
+ static SwitchOption interfaceProcessQQbarto3P2G
+ (interfaceProcess,
+ "QQbarto3P2G",
+ "The q qbar -> 3P2 g process",
+ 3);
+ static SwitchOption interfaceProcessGGto3P2G
+ (interfaceProcess,
+ "GGto3P2G",
+ "The g g -> 3P2 g process",
+ 4);
+
+ static Switch<MEPPto3P2Jet,unsigned int> interfaceMassOption
+ ("MassOption",
+ "Mass of the treatment of the 3P2 mass",
+ &MEPPto3P2Jet::mOpt_, 0, false, false);
+ static SwitchOption interfaceMassOptionOnShell
+ (interfaceMassOption,
+ "OnShell",
+ "Use the on-shell mass",
+ 0);
+ static SwitchOption interfaceMassOptionOffShell
+ (interfaceMassOption,
+ "OffShell",
+ "Use an off-shell mass generated by the MassGenerator object for the 3P2 state.",
+ 1);
+
+}
+
+void MEPPto3P2Jet::getDiagrams() const {
+ // construct the meson PDG code from quark ids
+ unsigned int iq = 4+state_;
+ tcPDPtr ps = getParticleData(long(iq*110 + 5 + (n_-1)*100000));
+ tcPDPtr g = getParticleData(ParticleID::g);
+ // processes involving quarks
+ for ( int i = 1; i <= 3; ++i ) {
+ tcPDPtr q = getParticleData(i);
+ tcPDPtr qb = q->CC();
+ if(process_ == 0 || process_ == 1)
+ add(new_ptr((Tree2toNDiagram(3), g, g, q , 1, ps, 2, q , -1)));
+ if(process_ == 0 || process_ == 2)
+ add(new_ptr((Tree2toNDiagram(3), g, g, qb, 1, ps, 2, qb, -2)));
+ if(process_ == 0 || process_ == 3)
+ add(new_ptr((Tree2toNDiagram(2), q, qb, 1, g, 3, ps, 3, g, -3)));
+ }
+ // g g -> 3P2 g (s,t,u 4-point)
+ if(process_ == 0 || process_ == 4) {
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, g, 3, ps, 3, g , -4)));
+ add(new_ptr((Tree2toNDiagram(3), g, g, g, 1, ps, 2, g , -5)));
+ add(new_ptr((Tree2toNDiagram(3), g, g, g, 2, ps, 1, g , -6)));
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, ps, 1, g , -7)));
+ }
+}
+
+Selector<MEBase::DiagramIndex>
+MEPPto3P2Jet::diagrams(const DiagramVector & diags) const {
+ Energy M=meMomenta()[3].mass();
+ Energy2 M2(sqr(M));
+ Selector<DiagramIndex> sel;
+ DVector save(4);
+ if(mePartonData()[1]->id()==ParticleID::g &&
+ mePartonData()[1]->id()==ParticleID::g ) {
+ save[0]=16*M2*(3*M2*sHat()*sqr(tHat()-uHat())+12*sqr(M2)*tHat()*uHat()+2*sqr(sHat())*tHat()*uHat())/(3.*pow<4,1>(M2-sHat())*sHat());
+ save[1]=16*M2*(2*sqr(sHat())*tHat()*sqr(sHat()+tHat())*(2*sqr(sHat())+2*sHat()*tHat()+sqr(tHat()))
+ +pow<4,1>(M2)*(3*pow<3,1>(sHat())+20*sqr(sHat())*tHat()+29*sHat()*sqr(tHat())+14*pow<3,1>(tHat()))
+ -pow<3,1>(M2)*(9*pow<4,1>(sHat())+59*pow<3,1>(sHat())*tHat()+97*sqr(sHat())*sqr(tHat())+55*sHat()*pow<3,1>(tHat())+4*pow<4,1>(tHat()))
+ -M2*sHat()*(sHat()+tHat())*(3*pow<4,1>(sHat())+24*pow<3,1>(sHat())*tHat()+59*sqr(sHat())*sqr(tHat())+38*sHat()*pow<3,1>(tHat())+8*pow<4,1>(tHat()))
+ +sqr(M2)*(9*pow<5,1>(sHat())+74*pow<4,1>(sHat())*tHat()+163*pow<3,1>(sHat())*sqr(tHat())
+ +132*sqr(sHat())*pow<3,1>(tHat())+34*sHat()*pow<4,1>(tHat())+2*pow<5,1>(tHat())))
+ /(3.*sqr(M2-sHat())*sHat()*pow<4,1>(M2-uHat())*uHat());
+ save[2]=16*M2*(2*sqr(sHat())*uHat()*sqr(sHat()+uHat())*(2*sqr(sHat())+2*sHat()*uHat()+sqr(uHat()))
+ +pow<4,1>(M2)*(3*pow<3,1>(sHat())+20*sqr(sHat())*uHat()+29*sHat()*sqr(uHat())+14*pow<3,1>(uHat()))
+ -pow<3,1>(M2)*(9*pow<4,1>(sHat())+59*pow<3,1>(sHat())*uHat()+97*sqr(sHat())*sqr(uHat())+55*sHat()*pow<3,1>(uHat())+4*pow<4,1>(uHat()))
+ -M2*sHat()*(sHat()+uHat())*(3*pow<4,1>(sHat())+24*pow<3,1>(sHat())*uHat()+59*sqr(sHat())*sqr(uHat())+38*sHat()*pow<3,1>(uHat())+8*pow<4,1>(uHat()))
+ +sqr(M2)*(9*pow<5,1>(sHat())+74*pow<4,1>(sHat())*uHat()+163*pow<3,1>(sHat())*sqr(uHat())
+ +132*sqr(sHat())*pow<3,1>(uHat())+34*sHat()*pow<4,1>(uHat())+2*pow<5,1>(uHat())))
+ /(3.*sqr(M2-sHat())*sHat()*pow<4,1>(M2-tHat())*tHat());
+ save[3]=16*M2*(4*sqr(sHat())*pow<5,1>(tHat())*pow<5,1>(uHat())+6*pow<9,1>(M2)*sHat()*(4*sqr(tHat())+9*tHat()*uHat()+4*sqr(uHat()))
+ -pow<10,1>(M2)*(21*sqr(tHat())+46*tHat()*uHat()+21*sqr(uHat()))
+ -pow<8,1>(M2)*(72*pow<4,1>(tHat())+311*pow<3,1>(tHat())*uHat()
+ +440*sqr(tHat())*sqr(uHat())+311*tHat()*pow<3,1>(uHat())+72*pow<4,1>(uHat()))
+ +pow<7,1>(M2)*sHat()*(153*pow<4,1>(tHat())+649*pow<3,1>(tHat())*uHat()
+ +962*sqr(tHat())*sqr(uHat())+649*tHat()*pow<3,1>(uHat())+153*pow<4,1>(uHat()))
+ +2*M2*sHat()*sqr(tHat())*sqr(uHat())*(3*pow<6,1>(tHat())+6*pow<5,1>(tHat())*uHat()+16*pow<4,1>(tHat())*sqr(uHat())
+ +14*pow<3,1>(tHat())*pow<3,1>(uHat())+16*sqr(tHat())*pow<4,1>(uHat())
+ +6*tHat()*pow<5,1>(uHat())+3*pow<6,1>(uHat()))
+ +pow<6,1>(M2)*(45*pow<6,1>(tHat())+308*pow<5,1>(tHat())*uHat()+808*pow<4,1>(tHat())*sqr(uHat())
+ +1174*pow<3,1>(tHat())*pow<3,1>(uHat())+808*sqr(tHat())*pow<4,1>(uHat())
+ +308*tHat()*pow<5,1>(uHat())+45*pow<6,1>(uHat()))
+ +pow<5,1>(M2)*sHat()*(135*pow<6,1>(tHat())+819*pow<5,1>(tHat())*uHat()+1941*pow<4,1>(tHat())*sqr(uHat())
+ +2444*pow<3,1>(tHat())*pow<3,1>(uHat())+1941*sqr(tHat())*pow<4,1>(uHat())+819*tHat()*pow<5,1>(uHat())+135*pow<6,1>(uHat()))
+ +pow<3,1>(M2)*sHat()*(12*pow<8,1>(tHat())+120*pow<7,1>(tHat())*uHat()+419*pow<6,1>(tHat())*sqr(uHat())
+ +805*pow<5,1>(tHat())*pow<3,1>(uHat())+938*pow<4,1>(tHat())*pow<4,1>(uHat())
+ +805*pow<3,1>(tHat())*pow<5,1>(uHat())+419*sqr(tHat())*pow<6,1>(uHat())
+ +120*tHat()*pow<7,1>(uHat())+12*pow<8,1>(uHat()))
+ +sqr(M2)*tHat()*uHat()*(18*pow<8,1>(tHat())+84*pow<7,1>(tHat())*uHat()+229*pow<6,1>(tHat())*sqr(uHat())
+ +396*pow<5,1>(tHat())*pow<3,1>(uHat())+490*pow<4,1>(tHat())*pow<4,1>(uHat())
+ +396*pow<3,1>(tHat())*pow<5,1>(uHat())+229*sqr(tHat())*pow<6,1>(uHat())
+ +84*tHat()*pow<7,1>(uHat())+18*pow<8,1>(uHat()))
+ +pow<4,1>(M2)*(48*pow<8,1>(tHat())+355*pow<7,1>(tHat())*uHat()+1211*pow<6,1>(tHat())*sqr(uHat())
+ +2262*pow<5,1>(tHat())*pow<3,1>(uHat())+2778*pow<4,1>(tHat())*pow<4,1>(uHat())
+ +2262*pow<3,1>(tHat())*pow<5,1>(uHat())+1211*sqr(tHat())*pow<6,1>(uHat())
+ +355*tHat()*pow<7,1>(uHat())+48*pow<8,1>(uHat())))
+ /(3.*pow<4,1>(M2-sHat())*sHat()*pow<4,1>(M2-tHat())*pow<4,1>(M2-uHat()));
+ }
+ for ( DiagramIndex i = 0; i < diags.size(); ++i )
+ if ( diags[i]->id() == -1 ||
+ diags[i]->id() == -2 ||
+ diags[i]->id() == -3 ) sel.insert(1.0, i);
+ else
+ sel.insert(save[abs(diags[i]->id())-4],i);
+ return sel;
+}
+
+Selector<const ColourLines *>
+MEPPto3P2Jet::colourGeometries(tcDiagPtr diag) const {
+ // g q -> 3P2 q
+ static ColourLines cgq ("1 2 5, -1 -2 3");
+ // g qbar -> 3P2 qbar
+ static ColourLines cgqbar("1 2 -3, -1 -2 -5");
+ // q qbar -> 3P2 g
+ static ColourLines cqqbar("1 3 5, -2 -3 -5");
+ // g g -> 3P2 g
+ static ColourLines cs[2]={ColourLines("1 3 5, -1 2, -2 -3 -5"),
+ ColourLines("1 -2, -1 -3 -5, 2 3 5")};
+ static ColourLines ct[2]={ColourLines("1 2 5, -1 -2 3, -3 -5"),
+ ColourLines("1 2 -3, -1 -2 -5, 3 5")};
+ static ColourLines cu[2]={ColourLines("1 5, -1 -2 3, -3 2 -5"),
+ ColourLines("1 2 -3, -1 -5, 3 -2 5")};
+ // 4 point
+ static ColourLines c4[2]={ColourLines("1 -2, 2 4, -1 -4"),
+ ColourLines("1 4, -4 -2, 2 -1")};
+ // create the selector
+ Selector<const ColourLines *> sel;
+ if (diag->id() == -1) sel.insert(1.0, &cgq );
+ else if (diag->id() == -2) sel.insert(1.0, &cgqbar);
+ else if (diag->id() == -3) sel.insert(1.0, &cqqbar);
+ else if (diag->id() == -4) {
+ sel.insert(0.5, &cs[0]);
+ sel.insert(0.5, &cs[1]);
+ }
+ else if (diag->id() == -5) {
+ sel.insert(0.5, &ct[0]);
+ sel.insert(0.5, &ct[1]);
+ }
+ else if (diag->id() == -6) {
+ sel.insert(0.5, &cu[0]);
+ sel.insert(0.5, &cu[1]);
+ }
+ else if (diag->id() == -7) {
+ sel.insert(0.5, &c4[0]);
+ sel.insert(0.5, &c4[1]);
+ }
+ return sel;
+}
+
+Energy2 MEPPto3P2Jet::scale() const {
+ return sHat();
+}
+
+double MEPPto3P2Jet::me2() const {
+ // return value
+ double output(0.);
+ // mass of the 3P2 state
+ Energy M = meMomenta()[2].mass();
+ Energy2 M2 = sqr(meMomenta()[2].mass());
+ if(mePartonData()[0]->id()==ParticleID::g) {
+ // g qbar -> 3P2 qbar
+ if(mePartonData()[1]->id()==ParticleID::g) {
+ // matrix element
+ output = 8.*O1_*pow(Constants::pi*standardModel()->alphaS(scale()),3)/(15.*sqr(M2)*M)*
+ (16*M2*(12*pow<10,1>(M2)*pow<4,1>(tHat()+uHat())+2*sqr(tHat())*sqr(uHat())*sqr(tHat()+uHat())*pow<4,1>(sqr(tHat())+tHat()*uHat()+sqr(uHat()))-24*pow<9,1>(M2)*pow<3,1>(tHat()+uHat())*(3*sqr(tHat())+5*tHat()*uHat()+3*sqr(uHat()))+pow<8,1>(M2)*sqr(tHat()+uHat())*(204*pow<4,1>(tHat())+651*pow<3,1>(tHat())*uHat()+880*sqr(tHat())*sqr(uHat())+651*tHat()*pow<3,1>(uHat())+204*pow<4,1>(uHat()))-M2*tHat()*uHat()*(tHat()+uHat())*sqr(sqr(tHat())+tHat()*uHat()+sqr(uHat()))*(12*pow<6,1>(tHat())+48*pow<5,1>(tHat())*uHat()+43*pow<4,1>(tHat())*sqr(uHat())+6*pow<3,1>(tHat())*pow<3,1>(uHat())+43*sqr(tHat())*pow<4,1>(uHat())+48*tHat()*pow<5,1>(uHat())+12*pow<6,1>(uHat()))-pow<7,1>(M2)*(tHat()+uHat())*(360*pow<6,1>(tHat())+1635*pow<5,1>(tHat())*uHat()+3314*pow<4,1>(tHat())*sqr(uHat())+4114*pow<3,1>(tHat())*pow<3,1>(uHat())+3314*sqr(tHat())*pow<4,1>(uHat())+1635*tHat()*pow<5,1>(uHat())+360*pow<6,1>(uHat()))-pow<5,1>(M2)*(tHat()+uHat())*(360*pow<8,1>(tHat())+1914*pow<7,1>(tHat())*uHat()+4376*pow<6,1>(tHat())*sqr(uHat())+6271*pow<5,1>(tHat())*pow<3,1>(uHat())+6914*pow<4,1>(tHat())*pow<4,1>(uHat())+6271*pow<3,1>(tHat())*pow<5,1>(uHat())+4376*sqr(tHat())*pow<6,1>(uHat())+1914*tHat()*pow<7,1>(uHat())+360*pow<8,1>(uHat()))+pow<6,1>(M2)*(432*pow<8,1>(tHat())+2526*pow<7,1>(tHat())*uHat()+6652*pow<6,1>(tHat())*sqr(uHat())+10877*pow<5,1>(tHat())*pow<3,1>(uHat())+12640*pow<4,1>(tHat())*pow<4,1>(uHat())+10877*pow<3,1>(tHat())*pow<5,1>(uHat())+6652*sqr(tHat())*pow<6,1>(uHat())+2526*tHat()*pow<7,1>(uHat())+432*pow<8,1>(uHat()))-pow<3,1>(M2)*(tHat()+uHat())*(72*pow<10,1>(tHat())+543*pow<9,1>(tHat())*uHat()+1542*pow<8,1>(tHat())*sqr(uHat())+2336*pow<7,1>(tHat())*pow<3,1>(uHat())+2412*pow<6,1>(tHat())*pow<4,1>(uHat())+2266*pow<5,1>(tHat())*pow<5,1>(uHat())+2412*pow<4,1>(tHat())*pow<6,1>(uHat())+2336*pow<3,1>(tHat())*pow<7,1>(uHat())+1542*sqr(tHat())*pow<8,1>(uHat())+543*tHat()*pow<9,1>(uHat())+72*pow<10,1>(uHat()))+pow<4,1>(M2)*(204*pow<10,1>(tHat())+1455*pow<9,1>(tHat())*uHat()+4328*pow<8,1>(tHat())*sqr(uHat())+7504*pow<7,1>(tHat())*pow<3,1>(uHat())+9232*pow<6,1>(tHat())*pow<4,1>(uHat())+9614*pow<5,1>(tHat())*pow<5,1>(uHat())+9232*pow<4,1>(tHat())*pow<6,1>(uHat())+7504*pow<3,1>(tHat())*pow<7,1>(uHat())+4328*sqr(tHat())*pow<8,1>(uHat())+1455*tHat()*pow<9,1>(uHat())+204*pow<10,1>(uHat()))+sqr(M2)*(12*pow<12,1>(tHat())+144*pow<11,1>(tHat())*uHat()+616*pow<10,1>(tHat())*sqr(uHat())+1345*pow<9,1>(tHat())*pow<3,1>(uHat())+1824*pow<8,1>(tHat())*pow<4,1>(uHat())+1806*pow<7,1>(tHat())*pow<5,1>(uHat())+1688*pow<6,1>(tHat())*pow<6,1>(uHat())+1806*pow<5,1>(tHat())*pow<7,1>(uHat())+1824*pow<4,1>(tHat())*pow<8,1>(uHat())+1345*pow<3,1>(tHat())*pow<9,1>(uHat())+616*sqr(tHat())*pow<10,1>(uHat())+144*tHat()*pow<11,1>(uHat())+12*pow<12,1>(uHat()))))/(3.*sHat()*pow<4,1>(M2-tHat())*tHat()*pow<4,1>(M2-uHat())*uHat()*pow<4,1>(tHat()+uHat()));
+ // test vs NPB 291 731
+ // Energy5 R02 = params_->firstDerivativeRadialWaveFunctionSquared(state_,n_);
+ // Energy6 Q(sHat()*tHat()*uHat());
+ // Energy4 P(sHat()*tHat()+tHat()*uHat()+uHat()*sHat());
+ // Energy8 M8(pow<4,1>(M2));
+ // double test = 16.*Constants::pi*sqr(sHat())*
+ // 4.*Constants::pi*R02*pow(standardModel()->alphaS(scale()),3)/(M*M2*sqr(sHat())*Q*pow<4,1>(Q-M2*P))*
+ // (12.*sqr(M2)*pow<4,1>(P)*(M8 - 2*sqr(M2)*P + sqr(P))
+ // -3.*M2*P*sqr(P)*(8*M8 - sqr(M2)*P + 4*sqr(P))*Q
+ // - 2*sqr(P*Q)*(7*M8 - 43*sqr(M2)*P - sqr(P))
+ // + M2*P*Q*sqr(Q)*(16*sqr(M2) - 61*P) + 12*sqr(M2*sqr(Q)));
+ // cerr << "testing matrix element " << output << " " << test << " "
+ // << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ // g qbar -> 3P2 qbar
+ else if(mePartonData()[1]->id()<0) {
+ // // helicity amplitude version of ME
+ // VectorWaveFunction g1w(meMomenta()[0],mePartonData()[0],incoming);
+ // SpinorBarWaveFunction q2w(meMomenta()[1],mePartonData()[1],incoming);
+ // TensorWaveFunction t3w(meMomenta()[2],mePartonData()[2],outgoing);
+ // SpinorWaveFunction q4w(meMomenta()[3],mePartonData()[3],outgoing);
+ // vector<VectorWaveFunction> g1;
+ // vector<SpinorBarWaveFunction> q2;
+ // vector<TensorWaveFunction> t3;
+ // vector<SpinorWaveFunction> q4;
+ // for(unsigned int ix=0;ix<2;++ix) {
+ // g1w.reset(2*ix);
+ // g1.push_back(g1w);
+ // q2w.reset(ix);
+ // q2.push_back(q2w);
+ // q4w.reset(ix);
+ // q4.push_back(q4w);
+ // }
+ // for(unsigned int ix=0;ix<5;++ix) {
+ // t3w.reset(ix,tensor_phase);
+ // t3.push_back(t3w);
+ // }
+ // double total(0.);
+ // ProductionMatrixElement me(PDT::Spin1,PDT::Spin1Half,PDT::Spin2,PDT::Spin1Half);
+ // Complex phase = exp(Complex(0.,meMomenta()[2].phi()));
+ // me(0,0,0,0)=(2.*sqrt(2)*sqr(phase)*sqrt(-tHat())*uHat())/pow<3,1>(M);
+ // me(0,0,1,0)=(2.*sqrt(2)*phase*sHat()*tHat()*sqrt(-(uHat()/sHat())))/sqr(M2);
+ // me(0,0,2,0)=(2.*sHat()*sqrt(-tHat())*tHat())/(sqrt(3)*pow<5,1>(M));
+ // me(0,1,0,1)=(-2.*sqrt(2)*sHat()*sqrt(-tHat())*sqr(uHat()))/(pow<3,1>(M)*sqr(tHat()+uHat()));
+ // me(0,1,1,1)=(-2.*sqrt(2)*(M2+sHat())*tHat()*uHat()*sqrt(-(sHat()*uHat())))/(sqr(M2)*phase*sqr(tHat()+uHat()));
+ // me(0,1,2,1)=(2.*(sqr(M2)+4*M2*sHat()+sqr(sHat()))*(-tHat())*sqrt(-tHat())*uHat())/(sqrt(3)*pow<5,1>(M)*sqr(phase)*sqr(tHat()+uHat()));
+ // me(0,1,3,1)=(-2.*sqrt(2)*(M2+sHat())*sqr(tHat())*sqrt(-(sHat()*uHat())))/(sqr(M2)*pow(phase,3)*sqr(tHat()+uHat()));
+ // me(0,1,4,1)=(-2.*sqrt(2)*sHat()*sqr(tHat())*sqrt(-tHat()))/(pow<3,1>(M)*pow(phase,4)*sqr(tHat()+uHat()));
+ // me(2,0,0,0)=(2.*sqrt(2)*pow(phase,4)*sHat()*sqr(tHat())*sqrt(-tHat()))/(pow<3,1>(M)*sqr(tHat()+uHat()));
+ // me(2,0,1,0)=(-2.*sqrt(2)*pow(phase,3)*(M2+sHat())*sqr(tHat())*sqrt(-(sHat()*uHat())))/(sqr(M2)*sqr(tHat()+uHat()));
+ // me(2,0,2,0)=(2.*sqr(phase)*(sqr(M2)+4*M2*sHat()+sqr(sHat()))*sqrt(-tHat())*tHat()*uHat())/(sqrt(3)*pow<5,1>(M)*sqr(tHat()+uHat()));
+ // me(2,0,3,0)=(-2.*sqrt(2)*phase*(M2+sHat())*tHat()*uHat()*sqrt(-(sHat()*uHat())))/(sqr(M2)*sqr(tHat()+uHat()));
+ // me(2,0,4,0)=(2.*sqrt(2)*sHat()*sqrt(-tHat())*sqr(uHat()))/(pow<3,1>(M)*sqr(tHat()+uHat()));
+ // me(2,1,2,1)=(2.*sHat()*(-tHat())*sqrt(-tHat()))/(sqrt(3)*pow<5,1>(M));
+ // me(2,1,3,1)=(2.*sqrt(2)*sHat()*tHat()*sqrt(-(uHat()/sHat())))/(sqr(M2)*phase);
+ // me(2,1,4,1)=(-2.*sqrt(2)*sqrt(-tHat())*uHat())/(pow<3,1>(M)*sqr(phase));
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // LorentzPolarizationVectorE fCurrent = q4[ih4].dimensionedWave().vectorCurrent(q2[ih2].dimensionedWave());
+ // for(unsigned int ih3=0;ih3<5;++ih3) {
+ // auto vfPre = t3[ih3].wave().preDot(fCurrent);
+ // auto vfPost = t3[ih3].wave().postDot(fCurrent);
+ // auto vp1Pre = t3[ih3].wave().preDot(meMomenta()[0]);
+ // auto vp1Post = t3[ih3].wave().postDot(meMomenta()[0]);
+ // complex<Energy2> d11 = vp1Pre*meMomenta()[0];
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // complex<Energy> d3=meMomenta()[2]*g1[ih1].wave();
+ // Complex amp =-1./sqr(M2)/M*(-2.*M2*(vfPre*meMomenta()[0]*d3 + tHat()*vfPre*g1[ih1].wave()
+ // +2.*d11*(fCurrent*g1[ih1].wave()))
+ // +(fCurrent*meMomenta()[2])*(2.*(M2+tHat())*(vp1Pre*g1[ih1].wave())
+ // -2.*(tHat()-M2)*(vp1Post*g1[ih1].wave()))
+ // -(tHat()+M2)*((tHat()-M2)*(vfPost*g1[ih1].wave())+2.*vfPost*meMomenta()[0]*d3)
+ // +sqr(M2)*(vfPre*g1[ih1].wave())+tHat()*(2.*(vfPre*meMomenta()[0])*d3+tHat()*vfPre*g1[ih1].wave())
+ // );
+ // double test = norm(amp/me(2*ih1,ih2,ih3,ih4)-1.);
+ // if(norm(me(2*ih1,ih2,ih3,ih4))>1e-10 && test>1e-10)
+ // cerr << "testing in hel loop A " << ih1 << " " << ih2 << " " << ih3 << " " << ih4 << " "
+ // << amp << " " << me(2*ih1,ih2,ih3,ih4) << " " << test << "\n";
+ // total+= norm(amp);
+ // }
+ // }
+ // }
+ // }
+ // spin sum version
+ double total = -8*tHat()*(pow<4,1>(M2)*sqr(tHat())*sqr(uHat())
+ +2*pow<3,1>(M2)*sHat()*tHat()*uHat()*(3*sqr(tHat())+4*tHat()*uHat()+3*sqr(uHat()))
+ +sqr(sHat())*sqr(tHat())*(pow<4,1>(tHat())+4*pow<3,1>(tHat())*uHat()
+ +(sqr(sHat())+6*sqr(tHat()))*sqr(uHat())
+ +4*tHat()*pow<3,1>(uHat())+pow<4,1>(uHat()))
+ +6*sqr(M2)*(sqr(uHat())*pow<4,1>(tHat()+uHat())+sqr(sHat())*sqr(sqr(tHat())+tHat()*uHat()+sqr(uHat())))
+ +2*M2*sHat()*tHat()*uHat()*(3*pow<4,1>(tHat()+uHat())+sqr(sHat())*(3*sqr(tHat())+4*tHat()*uHat()+3*sqr(uHat()))))
+ /(3.*pow<5,1>(M2)*pow<4,1>(tHat()+uHat()));
+ // final factors
+ output = 64.*O1_*pow<3,1>(M*Constants::pi*standardModel()->alphaS(scale()))*sqr(M2)/(135.*sqr(tHat())*pow<4,1>(tHat()-M2))*total;
+ // analytic test
+ // Energy5 R02 = params_->firstDerivativeRadialWaveFunctionSquared(state_,n_);
+ // double test = -16.*Constants::pi*sqr(sHat())*
+ // 16.*Constants::pi*pow(standardModel()->alphaS(scale()),3)*R02/(9.*M*M2*sqr(sHat())*tHat()*pow<4,1>(tHat()-M2))*
+ // (sqr(tHat()-M2)*(sqr(tHat())+6.*sqr(M2)) -2.*sHat()*uHat()*(sqr(tHat())-6.*M2*(tHat()-M2)));
+ // cerr << "testing matrix element " << output << " " << test << " " << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ // g q -> 3P2 q
+ else if(mePartonData()[1]->id()<6) {
+ // helicity amplitude version of ME
+ // VectorWaveFunction g1w(meMomenta()[0],mePartonData()[0],incoming);
+ // SpinorWaveFunction q2w(meMomenta()[1],mePartonData()[1],incoming);
+ // TensorWaveFunction t3w(meMomenta()[2],mePartonData()[2],outgoing);
+ // SpinorBarWaveFunction q4w(meMomenta()[3],mePartonData()[3],outgoing);
+ // vector<VectorWaveFunction> g1;
+ // vector<SpinorWaveFunction> q2;
+ // vector<TensorWaveFunction> t3;
+ // vector<SpinorBarWaveFunction> q4;
+ // for(unsigned int ix=0;ix<2;++ix) {
+ // g1w.reset(2*ix);
+ // g1.push_back(g1w);
+ // q2w.reset(ix);
+ // q2.push_back(q2w);
+ // q4w.reset(ix);
+ // q4.push_back(q4w);
+ // }
+ // for(unsigned int ix=0;ix<5;++ix) {
+ // t3w.reset(ix,tensor_phase);
+ // t3.push_back(t3w);
+ // }
+ // double total(0.);
+ // ProductionMatrixElement me(PDT::Spin1,PDT::Spin1Half,PDT::Spin2,PDT::Spin1Half);
+ // Complex phase = exp(Complex(0.,meMomenta()[2].phi()));
+ // me(0,0,0,0)=(-2.*sqrt(2)*sqr(phase)*sqrt(-tHat())*uHat())/pow<3,1>(M);
+ // me(0,0,1,0)=(-2.*sqrt(2)*phase*sHat()*tHat()*sqrt(-(uHat()/sHat())))/sqr(M2);
+ // me(0,0,2,0)=(2.*sHat()*(-tHat())*sqrt(-tHat()))/(sqrt(3)*pow<5,1>(M));
+ // me(0,1,0,1)=(2.*sqrt(2)*sHat()*sqrt(-tHat())*sqr(uHat()))/(pow<3,1>(M)*sqr(tHat()+uHat()));
+ // me(0,1,1,1)=(2.*sqrt(2)*(M2+sHat())*tHat()*uHat()*sqrt(-(sHat()*uHat())))/(sqr(M2)*phase*sqr(tHat()+uHat()));
+ // me(0,1,2,1)=(2.*(sqr(M2)+4*M2*sHat()+sqr(sHat()))*sqrt(-tHat())*tHat()*uHat())/(sqrt(3)*pow<5,1>(M)*sqr(phase)*sqr(tHat()+uHat()));
+ // me(0,1,3,1)=(2.*sqrt(2)*(M2+sHat())*sqr(tHat())*sqrt(-(sHat()*uHat())))/(sqr(M2)*pow(phase,3)*sqr(tHat()+uHat()));
+ // me(0,1,4,1)=(2.*sqrt(2)*sHat()*sqr(tHat())*sqrt(-tHat()))/(pow<3,1>(M)*pow(phase,4)*sqr(tHat()+uHat()));
+ // me(2,0,0,0)=(-2.*sqrt(2)*pow(phase,4)*sHat()*sqr(tHat())*sqrt(-tHat()))/(pow<3,1>(M)*sqr(tHat()+uHat()));
+ // me(2,0,1,0)=(2.*sqrt(2)*pow(phase,3)*(M2+sHat())*sqr(tHat())*sqrt(-(sHat()*uHat())))/(sqr(M2)*sqr(tHat()+uHat()));
+ // me(2,0,2,0)=(2.*sqr(phase)*(sqr(M2)+4*M2*sHat()+sqr(sHat()))*(-tHat())*sqrt(-tHat())*uHat())/(sqrt(3)*pow<5,1>(M)*sqr(tHat()+uHat()));
+ // me(2,0,3,0)=(2.*sqrt(2)*phase*(M2+sHat())*tHat()*uHat()*sqrt(-(sHat()*uHat())))/(sqr(M2)*sqr(tHat()+uHat()));
+ // me(2,0,4,0)=(-2.*sqrt(2)*sHat()*sqrt(-tHat())*sqr(uHat()))/(pow<3,1>(M)*sqr(tHat()+uHat()));
+ // me(2,1,2,1)=(2.*sHat()*sqrt(-tHat())*tHat())/(sqrt(3)*pow<5,1>(M));
+ // me(2,1,3,1)=(-2.*sqrt(2)*sHat()*tHat()*sqrt(-(uHat()/sHat())))/(sqr(M2)*phase);
+ // me(2,1,4,1)=(2.*sqrt(2)*sqrt(-tHat())*uHat())/(pow<3,1>(M)*sqr(phase));
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // LorentzPolarizationVectorE fCurrent = q2[ih2].dimensionedWave().vectorCurrent(q4[ih4].dimensionedWave());
+ // for(unsigned int ih3=0;ih3<5;++ih3) {
+ // auto vfPre = t3[ih3].wave().preDot(fCurrent);
+ // auto vfPost = t3[ih3].wave().postDot(fCurrent);
+ // auto vp1Pre = t3[ih3].wave().preDot(meMomenta()[0]);
+ // auto vp1Post = t3[ih3].wave().postDot(meMomenta()[0]);
+ // complex<Energy2> d11 = vp1Pre*meMomenta()[0];
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // complex<Energy> d3=meMomenta()[2]*g1[ih1].wave();
+ // Complex amp = 1./sqr(M2)/M*(-2.*M2*(vfPre*meMomenta()[0]*d3 + tHat()*vfPre*g1[ih1].wave()
+ // +2.*d11*(fCurrent*g1[ih1].wave()))
+ // +(fCurrent*meMomenta()[2])*(2.*(M2+tHat())*(vp1Pre*g1[ih1].wave())
+ // -2.*(tHat()-M2)*(vp1Post*g1[ih1].wave()))
+ // -(tHat()+M2)*((tHat()-M2)*(vfPost*g1[ih1].wave())+2.*vfPost*meMomenta()[0]*d3)
+ // +sqr(M2)*(vfPre*g1[ih1].wave())+tHat()*(2.*(vfPre*meMomenta()[0])*d3+tHat()*vfPre*g1[ih1].wave())
+ // );
+ // double test = norm(amp/me(2*ih1,ih2,ih3,ih4)-1.);
+ // if(norm(me(2*ih1,ih2,ih3,ih4))>1e-10 && test>1e-10)
+ // cerr << "testing in hel loop A " << ih1 << " " << ih2 << " " << ih3 << " " << ih4 << " "
+ // << amp << " " << me(2*ih1,ih2,ih3,ih4) << " " << test << "\n";
+ // total+= norm(amp);
+ // }
+ // }
+ // }
+ // }
+ // spin sum version
+ double total = -8*tHat()*(pow<4,1>(M2)*sqr(tHat())*sqr(uHat())
+ +2*pow<3,1>(M2)*sHat()*tHat()*uHat()*(3*sqr(tHat())+4*tHat()*uHat()+3*sqr(uHat()))
+ +sqr(sHat())*sqr(tHat())*(pow<4,1>(tHat())+4*pow<3,1>(tHat())*uHat()
+ +(sqr(sHat())+6*sqr(tHat()))*sqr(uHat())
+ +4*tHat()*pow<3,1>(uHat())+pow<4,1>(uHat()))
+ +6*sqr(M2)*(sqr(uHat())*pow<4,1>(tHat()+uHat())+sqr(sHat())*sqr(sqr(tHat())+tHat()*uHat()+sqr(uHat())))
+ +2*M2*sHat()*tHat()*uHat()*(3*pow<4,1>(tHat()+uHat())+sqr(sHat())*(3*sqr(tHat())+4*tHat()*uHat()+3*sqr(uHat()))))
+ /(3.*pow<5,1>(M2)*pow<4,1>(tHat()+uHat()));
+ // final factors
+ output = 64.*O1_*pow<3,1>(M*Constants::pi*standardModel()->alphaS(scale()))*sqr(M2)/(135.*sqr(tHat())*pow<4,1>(tHat()-M2))*total;
+ // analytic test
+ // Energy5 R02 = params_->firstDerivativeRadialWaveFunctionSquared(state_,n_);
+ // double test = -16.*Constants::pi*sqr(sHat())*
+ // 16.*Constants::pi*pow(standardModel()->alphaS(scale()),3)*R02/(9.*M*M2*sqr(sHat())*tHat()*pow<4,1>(tHat()-M2))*
+ // (sqr(tHat()-M2)*(sqr(tHat())+6.*sqr(M2)) -2.*sHat()*uHat()*(sqr(tHat())-6.*M2*(tHat()-M2)));
+ // cerr << "testing matrix element " << output << " " << test << " " << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ else assert(false);
+ }
+ // q qbar -> 3P2 g
+ else if(mePartonData()[0]->id()==-mePartonData()[1]->id()) {
+ // // helicity amplitude version of ME
+ // // SpinorWaveFunction q1w(meMomenta()[0],mePartonData()[1],incoming);
+ // // SpinorBarWaveFunction q2w(meMomenta()[1],mePartonData()[0],incoming);
+ // // VectorWaveFunction g4w(meMomenta()[3],mePartonData()[3],outgoing);
+ // // vector<SpinorWaveFunction> q1;
+ // // vector<SpinorBarWaveFunction> q2;
+ // // vector<VectorWaveFunction> g4;
+ // // for(unsigned int ix=0;ix<2;++ix) {
+ // // g4w.reset(2*ix,vector_phase);
+ // // g4.push_back(g4w);
+ // // q1w.reset(ix);
+ // // q1.push_back(q1w);
+ // // q2w.reset(ix);
+ // // q2.push_back(q2w);
+ // // }
+ // // double total(0.);
+ // // ProductionMatrixElement me(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin2,PDT::Spin1);
+ // // double phi = meMomenta()[2].phi();
+ // // me(0,1,0,0) = -sqrt(2.*sHat())*tHat()/M2/M;
+ // // me(0,1,0,2) = -exp(Complex(0.,-2.*phi))*sqrt(2.*sHat())*uHat()/M2/M;
+ // // me(1,0,0,0) = exp(Complex(0., 2.*phi))*sqrt(2.*sHat())*uHat()/M2/M;
+ // // me(1,0,0,2) = sqrt(2.*sHat())*tHat()/M2/M;
+ // // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // // LorentzPolarizationVectorE fCurrent = q1[ih1].dimensionedWave().vectorCurrent(q2[ih2].dimensionedWave());
+ // // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // // Complex amp = ((sHat()-M2)*(fCurrent*g4[ih4].wave())-2.*(meMomenta()[2]*g4[ih4].wave())*(fCurrent*meMomenta()[3]))/M2/M;
+ // // if(norm(me(ih1,ih2,0,2*ih4))>1e-10)
+ // // cerr << "testing in hel loop A " << ih1 << " " << ih2 << " " << ih4 << " "
+ // // << amp << " " << me(ih1,ih2,0,2*ih4) << " " << amp/me(ih1,ih2,0,2*ih4) << " " << norm(amp/me(ih1,ih2,0,2*ih4)) << "\n";
+ // // total+= norm(amp);
+ // // }
+ // // }
+ // // }
+ // // spin sum version
+ // double total = 4.*sHat()*(sqr(tHat())+sqr(uHat()))/pow<3,1>(M2);
+ // // final factors
+ // output = 512.*O1_*pow<3,1>(M*Constants::pi*standardModel()->alphaS(scale()))*sqr(sHat()-3.*M2)/(243.*sqr(sHat())*pow<4,1>(sHat()-M2))*total;
+ // // analytic test
+ // // Energy5 R02 = params_->firstDerivativeRadialWaveFunctionSquared(state_,n_);
+ // // double test = 16.*Constants::pi*8./3.*8.*Constants::pi*pow(standardModel()->alphaS(scale()),3)*R02*(sqr(tHat())+sqr(uHat()))
+ // // /9./M/M2/sHat()/pow<4,1>(sHat()-M2)*sqr(sHat()-3.*sqr(M));
+ // // cerr << "testing matrix element " << output << " " << test << " " << (output-test)/(output+test) << " " << output/test << "\n";
+ }
+ else
+ assert(false);
+ return output;
+}
+
+void MEPPto3P2Jet::constructVertex(tSubProPtr sub) {
+ // extract the particles in the hard process
+ ParticleVector hard;
+ hard.reserve(4);
+ hard.push_back(sub->incoming().first);
+ hard.push_back(sub->incoming().second);
+ hard.push_back(sub->outgoing()[0]);
+ hard.push_back(sub->outgoing()[1]);
+ // get them in the right order
+ bool swapped(false);
+ if(hard[0]->id()==-hard[1]->id()) {
+ if(hard[0]->id()<0) swapped = true;
+ }
+ else if(hard[0]->id()!=ParticleID::g) {
+ swapped=true;
+ }
+ if(swapped) {
+ swap(hard[0],hard[1]);
+ swap(hard[2],hard[3]);
+ }
+ // boost to partonic CMS
+ Lorentz5Momentum pcms = hard[0]->momentum()+hard[1]->momentum();
+ LorentzRotation boost(-pcms.boostVector());
+ for(PPtr part : hard) part->transform(boost);
+ // extract kinematic variables
+ Energy M = hard[2]->mass();
+ Energy2 M2 = sqr(M);
+ double phi = hard[2]->momentum().phi();
+ Energy2 sh = (hard[0]->momentum()+hard[1]->momentum()).m2();
+ Energy2 th = (hard[0]->momentum()-hard[2]->momentum()).m2();
+ Energy2 uh = (hard[0]->momentum()-hard[3]->momentum()).m2();
+ Complex phase = exp(Complex(0.,phi));
+ // set basis states and compute the matrix element
+ ProductionMatrixElement me;
+ vector<TensorWaveFunction> t3;
+ TensorWaveFunction(t3,hard[2],outgoing,true,false,true,tensor_phase);
+ if(hard[0]->id()==ParticleID::g) {
+ // g g -> 3P2 g
+ if(hard[1]->id()==ParticleID::g) {
+ vector<VectorWaveFunction> g1,g2,g4;
+ VectorWaveFunction( g1,hard[0],incoming,false, true,true,vector_phase);
+ VectorWaveFunction( g2,hard[1],incoming,false, true,true,vector_phase);
+ VectorWaveFunction( g4,hard[3],outgoing,true , true,true,vector_phase);
+ ProductionMatrixElement me(PDT::Spin1,PDT::Spin1,PDT::Spin2,PDT::Spin1);
+ Complex phase = exp(Complex(0.,phi));
+ Energy2 um(uh-M2),tm(th-M2),sm(sh-M2);
+ me(0,0,0,0)=(-4*pow<3,1>(M)*pow(phase,3)*(sqr(M2)*sm*sqr(th-uh)-pow<3,1>(M2)*th*uh+sm*(pow<4,1>(th)+pow<4,1>(uh))+M2*(2*pow<4,1>(th)+pow<3,1>(th)*uh-sqr(th)*sqr(uh)+th*pow<3,1>(uh)+2*pow<4,1>(uh))))/(sqrt(sh)*sm*sqr(tm)*sqrt(th*uh)*sqr(um));
+ me(0,0,1,0)=(2*M2*sqr(phase)*sh*(th-uh)*(-2*sqr(sh)-sh*uh-sqr(uh)+M2*(sh+uh)))/(sm*sqr(tm)*sqr(um));
+ me(0,0,2,0)=(-2*sqrt(2./3.)*M*phase*sh*sqrt(sh)*sqrt(th*uh)*(sqr(sh)+sh*uh+uh*(-M2+uh)))/(sm*sqr(tm)*sqr(um));
+ me(0,2,0,0)=(-4*pow<3,1>(M)*phase*(pow<3,1>(M2)*sqr(sh+th)-sh*sqr(th)*(sqr(sh)+sh*th+sqr(th))-sqr(M2)*(sh+th)*(sqr(sh)+2*sh*th+2*sqr(th))+M2*th*(pow<3,1>(sh)+2*sqr(sh)*th+3*sh*sqr(th)+pow<3,1>(th)))*sqr(uh))/(sqrt(sh)*pow<3,1>(sm)*sqr(tm)*sqrt(th*uh)*sqr(um));
+ me(0,2,0,2)=(-4*pow<3,1>(M)*sqr(sh)*sqrt(sh)*sqr(uh)*(M2*sm+sqr(th)+sqr(uh)))/(phase*pow<3,1>(sm)*sqr(tm)*sqrt(th*uh)*sqr(um));
+ me(0,2,1,0)=(2*M2*(pow<3,1>(M2)*(sh+th)*(4*sh+3*th)-2*sh*sqr(th)*(sqr(sh)+sh*th+sqr(th))+M2*th*(2*pow<3,1>(sh)+3*sqr(sh)*th+7*sh*sqr(th)+2*pow<3,1>(th))-sqr(M2)*(4*pow<3,1>(sh)+9*sqr(sh)*th+12*sh*sqr(th)+5*pow<3,1>(th)))*uh)/(pow<3,1>(sm)*sqr(tm)*sqr(um));
+ me(0,2,1,2)=(-2*M2*sh*uh*(sh*sqr(uh)*(-sh+uh)+sqr(M2)*(4*sqr(sh)+7*sh*uh+sqr(uh))-M2*(4*pow<3,1>(sh)+7*sqr(sh)*uh+8*sh*sqr(uh)+pow<3,1>(uh))))/(sqr(phase)*pow<3,1>(sm)*sqr(tm)*sqr(um));
+ me(0,2,2,0)=(-2*sqrt(2./3.)*M*sqrt(sh)*(-(sh*sqr(th)*(sqr(sh)+sh*th+sqr(th)))+pow<3,1>(M2)*(6*sqr(sh)+10*sh*th+3*sqr(th))+M2*th*(pow<3,1>(sh)+5*sh*sqr(th)+pow<3,1>(th))-sqr(M2)*(6*pow<3,1>(sh)+11*sqr(sh)*th+14*sh*sqr(th)+4*pow<3,1>(th)))*sqrt(th*uh))/(phase*pow<3,1>(sm)*sqr(tm)*sqr(um));
+ me(0,2,2,2)=(2*sqrt(2./3.)*M*sqrt(sh)*sqrt(th*uh)*(-(sh*sqr(uh)*(sqr(sh)+sh*uh+sqr(uh)))+pow<3,1>(M2)*(6*sqr(sh)+10*sh*uh+3*sqr(uh))+M2*uh*(pow<3,1>(sh)+5*sh*sqr(uh)+pow<3,1>(uh))-sqr(M2)*(6*pow<3,1>(sh)+11*sqr(sh)*uh+14*sh*sqr(uh)+4*pow<3,1>(uh))))/(pow(phase,3)*pow<3,1>(sm)*sqr(tm)*sqr(um));
+ me(0,2,3,0)=(2*M2*sh*th*(sh*sqr(th)*(-sh+th)+sqr(M2)*(4*sqr(sh)+7*sh*th+sqr(th))-M2*(4*pow<3,1>(sh)+7*sqr(sh)*th+8*sh*sqr(th)+pow<3,1>(th))))/(sqr(phase)*pow<3,1>(sm)*sqr(tm)*sqr(um));
+ me(0,2,3,2)=(-2*M2*th*(pow<3,1>(M2)*(sh+uh)*(4*sh+3*uh)-2*sh*sqr(uh)*(sqr(sh)+sh*uh+sqr(uh))+M2*uh*(2*pow<3,1>(sh)+3*sqr(sh)*uh+7*sh*sqr(uh)+2*pow<3,1>(uh))-sqr(M2)*(4*pow<3,1>(sh)+9*sqr(sh)*uh+12*sh*sqr(uh)+5*pow<3,1>(uh))))/(pow(phase,4)*pow<3,1>(sm)*sqr(tm)*sqr(um));
+ me(0,2,4,0)=(4*pow<3,1>(M)*sqr(sh)*sqrt(sh)*sqr(th)*(M2*sm+sqr(th)+sqr(uh)))/(pow(phase,3)*pow<3,1>(sm)*sqr(tm)*sqrt(th*uh)*sqr(um));
+ me(0,2,4,2)=(4*pow<3,1>(M)*sqr(th)*(pow<3,1>(M2)*sqr(sh+uh)-sh*sqr(uh)*(sqr(sh)+sh*uh+sqr(uh))-sqr(M2)*(sh+uh)*(sqr(sh)+2*sh*uh+2*sqr(uh))+M2*uh*(pow<3,1>(sh)+2*sqr(sh)*uh+3*sh*sqr(uh)+pow<3,1>(uh))))/(pow(phase,5)*sqrt(sh)*pow<3,1>(sm)*sqr(tm)*sqrt(th*uh)*sqr(um));
+ me(2,0,0,0)=(-4*pow<3,1>(M)*pow(phase,5)*sqr(th)*(pow<3,1>(M2)*sqr(sh+uh)-sh*sqr(uh)*(sqr(sh)+sh*uh+sqr(uh))-sqr(M2)*(sh+uh)*(sqr(sh)+2*sh*uh+2*sqr(uh))+M2*uh*(pow<3,1>(sh)+2*sqr(sh)*uh+3*sh*sqr(uh)+pow<3,1>(uh))))/(sqrt(sh)*pow<3,1>(sm)*sqr(tm)*sqrt(th*uh)*sqr(um));
+ me(2,0,0,2)=(-4*pow<3,1>(M)*pow(phase,3)*sqr(sh)*sqrt(sh)*sqr(th)*(M2*sm+sqr(th)+sqr(uh)))/(pow<3,1>(sm)*sqr(tm)*sqrt(th*uh)*sqr(um));
+ me(2,0,1,0)=(-2*M2*pow(phase,4)*th*(pow<3,1>(M2)*(sh+uh)*(4*sh+3*uh)-2*sh*sqr(uh)*(sqr(sh)+sh*uh+sqr(uh))+M2*uh*(2*pow<3,1>(sh)+3*sqr(sh)*uh+7*sh*sqr(uh)+2*pow<3,1>(uh))-sqr(M2)*(4*pow<3,1>(sh)+9*sqr(sh)*uh+12*sh*sqr(uh)+5*pow<3,1>(uh))))/(pow<3,1>(sm)*sqr(tm)*sqr(um));
+ me(2,0,1,2)=(2*M2*sqr(phase)*sh*th*(sh*sqr(th)*(-sh+th)+sqr(M2)*(4*sqr(sh)+7*sh*th+sqr(th))-M2*(4*pow<3,1>(sh)+7*sqr(sh)*th+8*sh*sqr(th)+pow<3,1>(th))))/(pow<3,1>(sm)*sqr(tm)*sqr(um));
+ me(2,0,2,0)=(-2*sqrt(2./3.)*M*pow(phase,3)*sqrt(sh)*sqrt(th*uh)*(-(sh*sqr(uh)*(sqr(sh)+sh*uh+sqr(uh)))+pow<3,1>(M2)*(6*sqr(sh)+10*sh*uh+3*sqr(uh))+M2*uh*(pow<3,1>(sh)+5*sh*sqr(uh)+pow<3,1>(uh))-sqr(M2)*(6*pow<3,1>(sh)+11*sqr(sh)*uh+14*sh*sqr(uh)+4*pow<3,1>(uh))))/(pow<3,1>(sm)*sqr(tm)*sqr(um));
+ me(2,0,2,2)=(2*sqrt(2./3.)*M*phase*sqrt(sh)*(-(sh*sqr(th)*(sqr(sh)+sh*th+sqr(th)))+pow<3,1>(M2)*(6*sqr(sh)+10*sh*th+3*sqr(th))+M2*th*(pow<3,1>(sh)+5*sh*sqr(th)+pow<3,1>(th))-sqr(M2)*(6*pow<3,1>(sh)+11*sqr(sh)*th+14*sh*sqr(th)+4*pow<3,1>(th)))*sqrt(th*uh))/(pow<3,1>(sm)*sqr(tm)*sqr(um));
+ me(2,0,3,0)=(-2*M2*sqr(phase)*sh*uh*(sh*sqr(uh)*(-sh+uh)+sqr(M2)*(4*sqr(sh)+7*sh*uh+sqr(uh))-M2*(4*pow<3,1>(sh)+7*sqr(sh)*uh+8*sh*sqr(uh)+pow<3,1>(uh))))/(pow<3,1>(sm)*sqr(tm)*sqr(um));
+ me(2,0,3,2)=(2*M2*(pow<3,1>(M2)*(sh+th)*(4*sh+3*th)-2*sh*sqr(th)*(sqr(sh)+sh*th+sqr(th))+M2*th*(2*pow<3,1>(sh)+3*sqr(sh)*th+7*sh*sqr(th)+2*pow<3,1>(th))-sqr(M2)*(4*pow<3,1>(sh)+9*sqr(sh)*th+12*sh*sqr(th)+5*pow<3,1>(th)))*uh)/(pow<3,1>(sm)*sqr(tm)*sqr(um));
+ me(2,0,4,0)=(4*pow<3,1>(M)*phase*sqr(sh)*sqrt(sh)*sqr(uh)*(M2*sm+sqr(th)+sqr(uh)))/(pow<3,1>(sm)*sqr(tm)*sqrt(th*uh)*sqr(um));
+ me(2,0,4,2)=(4*pow<3,1>(M)*(pow<3,1>(M2)*sqr(sh+th)-sh*sqr(th)*(sqr(sh)+sh*th+sqr(th))-sqr(M2)*(sh+th)*(sqr(sh)+2*sh*th+2*sqr(th))+M2*th*(pow<3,1>(sh)+2*sqr(sh)*th+3*sh*sqr(th)+pow<3,1>(th)))*sqr(uh))/(phase*sqrt(sh)*pow<3,1>(sm)*sqr(tm)*sqrt(th*uh)*sqr(um));
+ me(2,2,2,2)=(2*sqrt(2./3.)*M*sh*sqrt(sh)*sqrt(th*uh)*(sqr(sh)+sh*uh+uh*(-M2+uh)))/(phase*sm*sqr(tm)*sqr(um));
+ me(2,2,3,2)=(2*M2*sh*(th-uh)*(-2*sqr(sh)-sh*uh-sqr(uh)+M2*(sh+uh)))/(sqr(phase)*sm*sqr(tm)*sqr(um));
+ me(2,2,4,2)=(4*pow<3,1>(M)*(sqr(M2)*sm*sqr(th-uh)-pow<3,1>(M2)*th*uh+sm*(pow<4,1>(th)+pow<4,1>(uh))+M2*(2*pow<4,1>(th)+pow<3,1>(th)*uh-sqr(th)*sqr(uh)+th*pow<3,1>(uh)+2*pow<4,1>(uh))))/(pow(phase,3)*sqrt(sh)*sm*sqr(tm)*sqrt(th*uh)*sqr(um));
+ // test the average result
+ // double aver = me.average();
+ // double test = (16*M2*(12*pow<10,1>(M2)*pow<4,1>(tHat()+uHat())+2*sqr(tHat())*sqr(uHat())*sqr(tHat()+uHat())*pow<4,1>(sqr(tHat())+tHat()*uHat()+sqr(uHat()))-24*pow<9,1>(M2)*pow<3,1>(tHat()+uHat())*(3*sqr(tHat())+5*tHat()*uHat()+3*sqr(uHat()))+pow<8,1>(M2)*sqr(tHat()+uHat())*(204*pow<4,1>(tHat())+651*pow<3,1>(tHat())*uHat()+880*sqr(tHat())*sqr(uHat())+651*tHat()*pow<3,1>(uHat())+204*pow<4,1>(uHat()))-M2*tHat()*uHat()*(tHat()+uHat())*sqr(sqr(tHat())+tHat()*uHat()+sqr(uHat()))*(12*pow<6,1>(tHat())+48*pow<5,1>(tHat())*uHat()+43*pow<4,1>(tHat())*sqr(uHat())+6*pow<3,1>(tHat())*pow<3,1>(uHat())+43*sqr(tHat())*pow<4,1>(uHat())+48*tHat()*pow<5,1>(uHat())+12*pow<6,1>(uHat()))-pow<7,1>(M2)*(tHat()+uHat())*(360*pow<6,1>(tHat())+1635*pow<5,1>(tHat())*uHat()+3314*pow<4,1>(tHat())*sqr(uHat())+4114*pow<3,1>(tHat())*pow<3,1>(uHat())+3314*sqr(tHat())*pow<4,1>(uHat())+1635*tHat()*pow<5,1>(uHat())+360*pow<6,1>(uHat()))-pow<5,1>(M2)*(tHat()+uHat())*(360*pow<8,1>(tHat())+1914*pow<7,1>(tHat())*uHat()+4376*pow<6,1>(tHat())*sqr(uHat())+6271*pow<5,1>(tHat())*pow<3,1>(uHat())+6914*pow<4,1>(tHat())*pow<4,1>(uHat())+6271*pow<3,1>(tHat())*pow<5,1>(uHat())+4376*sqr(tHat())*pow<6,1>(uHat())+1914*tHat()*pow<7,1>(uHat())+360*pow<8,1>(uHat()))+pow<6,1>(M2)*(432*pow<8,1>(tHat())+2526*pow<7,1>(tHat())*uHat()+6652*pow<6,1>(tHat())*sqr(uHat())+10877*pow<5,1>(tHat())*pow<3,1>(uHat())+12640*pow<4,1>(tHat())*pow<4,1>(uHat())+10877*pow<3,1>(tHat())*pow<5,1>(uHat())+6652*sqr(tHat())*pow<6,1>(uHat())+2526*tHat()*pow<7,1>(uHat())+432*pow<8,1>(uHat()))-pow<3,1>(M2)*(tHat()+uHat())*(72*pow<10,1>(tHat())+543*pow<9,1>(tHat())*uHat()+1542*pow<8,1>(tHat())*sqr(uHat())+2336*pow<7,1>(tHat())*pow<3,1>(uHat())+2412*pow<6,1>(tHat())*pow<4,1>(uHat())+2266*pow<5,1>(tHat())*pow<5,1>(uHat())+2412*pow<4,1>(tHat())*pow<6,1>(uHat())+2336*pow<3,1>(tHat())*pow<7,1>(uHat())+1542*sqr(tHat())*pow<8,1>(uHat())+543*tHat()*pow<9,1>(uHat())+72*pow<10,1>(uHat()))+pow<4,1>(M2)*(204*pow<10,1>(tHat())+1455*pow<9,1>(tHat())*uHat()+4328*pow<8,1>(tHat())*sqr(uHat())+7504*pow<7,1>(tHat())*pow<3,1>(uHat())+9232*pow<6,1>(tHat())*pow<4,1>(uHat())+9614*pow<5,1>(tHat())*pow<5,1>(uHat())+9232*pow<4,1>(tHat())*pow<6,1>(uHat())+7504*pow<3,1>(tHat())*pow<7,1>(uHat())+4328*sqr(tHat())*pow<8,1>(uHat())+1455*tHat()*pow<9,1>(uHat())+204*pow<10,1>(uHat()))+sqr(M2)*(12*pow<12,1>(tHat())+144*pow<11,1>(tHat())*uHat()+616*pow<10,1>(tHat())*sqr(uHat())+1345*pow<9,1>(tHat())*pow<3,1>(uHat())+1824*pow<8,1>(tHat())*pow<4,1>(uHat())+1806*pow<7,1>(tHat())*pow<5,1>(uHat())+1688*pow<6,1>(tHat())*pow<6,1>(uHat())+1806*pow<5,1>(tHat())*pow<7,1>(uHat())+1824*pow<4,1>(tHat())*pow<8,1>(uHat())+1345*pow<3,1>(tHat())*pow<9,1>(uHat())+616*sqr(tHat())*pow<10,1>(uHat())+144*tHat()*pow<11,1>(uHat())+12*pow<12,1>(uHat()))))/(3.*sHat()*pow<4,1>(M2-tHat())*tHat()*pow<4,1>(M2-uHat())*uHat()*pow<4,1>(tHat()+uHat()));
+ // cerr << "testing spin correlations " << test << " " << me.average() << " "
+ // << abs(test-aver)/(test+aver) << "\n";
+ }
+ // g qbar -> 3P2 qbar
+ else if(hard[1]->id()<0) {
+ vector<VectorWaveFunction> g1;
+ vector<SpinorBarWaveFunction> q2;
+ vector<SpinorWaveFunction> q4;
+ VectorWaveFunction( g1,hard[0],incoming,false,true,true,vector_phase);
+ SpinorBarWaveFunction(q2,hard[1],incoming,false,true);
+ SpinorWaveFunction( q4,hard[3],outgoing,true ,true);
+ g1[1]=g1[2];
+ // matrix element
+ me = ProductionMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin2,PDT::Spin1Half);
+ if(!swapped) {
+ me(0,0,0,0)=(2.*sqrt(2)*sqr(phase)*sqrt(-th)*uh)/pow<3,1>(M);
+ me(0,0,1,0)=(2.*sqrt(2)*phase*sh*th*sqrt(-(uh/sh)))/sqr(M2);
+ me(0,0,2,0)=(2.*sh*sqrt(-th)*th)/(sqrt(3)*pow<5,1>(M));
+ me(0,1,0,1)=(-2.*sqrt(2)*sh*sqrt(-th)*sqr(uh))/(pow<3,1>(M)*sqr(th+uh));
+ me(0,1,1,1)=(-2.*sqrt(2)*(M2+sh)*th*uh*sqrt(-(sh*uh)))/(sqr(M2)*phase*sqr(th+uh));
+ me(0,1,2,1)=(2.*(sqr(M2)+4*M2*sh+sqr(sh))*(-th)*sqrt(-th)*uh)/(sqrt(3)*pow<5,1>(M)*sqr(phase)*sqr(th+uh));
+ me(0,1,3,1)=(-2.*sqrt(2)*(M2+sh)*sqr(th)*sqrt(-(sh*uh)))/(sqr(M2)*pow(phase,3)*sqr(th+uh));
+ me(0,1,4,1)=(-2.*sqrt(2)*sh*sqr(th)*sqrt(-th))/(pow<3,1>(M)*pow(phase,4)*sqr(th+uh));
+ me(2,0,0,0)=(2.*sqrt(2)*pow(phase,4)*sh*sqr(th)*sqrt(-th))/(pow<3,1>(M)*sqr(th+uh));
+ me(2,0,1,0)=(-2.*sqrt(2)*pow(phase,3)*(M2+sh)*sqr(th)*sqrt(-(sh*uh)))/(sqr(M2)*sqr(th+uh));
+ me(2,0,2,0)=(2.*sqr(phase)*(sqr(M2)+4*M2*sh+sqr(sh))*sqrt(-th)*th*uh)/(sqrt(3)*pow<5,1>(M)*sqr(th+uh));
+ me(2,0,3,0)=(-2.*sqrt(2)*phase*(M2+sh)*th*uh*sqrt(-(sh*uh)))/(sqr(M2)*sqr(th+uh));
+ me(2,0,4,0)=(2.*sqrt(2)*sh*sqrt(-th)*sqr(uh))/(pow<3,1>(M)*sqr(th+uh));
+ me(2,1,2,1)=(2.*sh*(-th)*sqrt(-th))/(sqrt(3)*pow<5,1>(M));
+ me(2,1,3,1)=(2.*sqrt(2)*sh*th*sqrt(-(uh/sh)))/(sqr(M2)*phase);
+ me(2,1,4,1)=(-2.*sqrt(2)*sqrt(-th)*uh)/(pow<3,1>(M)*sqr(phase));
+ }
+ else {
+ me(0,0,0,0)=(-2.*sqrt(2)*pow(phase,3)*sqrt(-tHat())*uHat())/pow<3,1>(M);
+ me(0,0,1,0)=(-2.*sqrt(2)*sqr(phase)*sqr(M2-sHat())*tHat()*sqrt(-(sHat()*uHat())))/(sqr(M2)*sqr(tHat()+uHat()));
+ me(0,0,2,0)=(2.*phase*sqr(M2-sHat())*sHat()*(-tHat())*sqrt(-tHat()))/(sqrt(3)*pow<5,1>(M)*sqr(tHat()+uHat()));
+ me(0,1,0,1)=(-2.*sqrt(2)*pow(phase,3)*sqrt(-tHat())*sqr(uHat())*(-M2+tHat()+uHat()))/(pow<3,1>(M)*sqr(tHat()+uHat()));
+ me(0,1,1,1)=(2.*sqrt(2)*sqr(phase)*(M2+sHat())*tHat()*uHat()*sqrt(-(sHat()*uHat())))/(sqr(M2)*sqr(tHat()+uHat()));
+ me(0,1,2,1)=(2.*phase*(sqr(M2)+4*M2*sHat()+sqr(sHat()))*sqrt(-tHat())*tHat()*uHat())/(sqrt(3)*pow<5,1>(M)*sqr(tHat()+uHat()));
+ me(0,1,3,1)=(-2.*sqrt(2)*sqr(tHat())*sqrt(-(uHat()/((M2-sHat())*sHat()*(tHat()+uHat()))))*(sqr(M2)+sqr(sHat())-M2*(tHat()+uHat())))/(sqr(M2)*(tHat()+uHat()));
+ me(0,1,4,1)=(-2.*sqrt(2)*sqr(tHat())*sqrt(-tHat())*(-M2+tHat()+uHat()))/(pow<3,1>(M)*phase*sqr(tHat()+uHat()));
+ me(2,0,0,0)=(2.*sqrt(2)*phase*sqr(tHat())*sqrt(-tHat())*(-M2+tHat()+uHat()))/(pow<3,1>(M)*sqr(tHat()+uHat()));
+ me(2,0,1,0)=(-2.*sqrt(2)*sqr(tHat())*sqrt(-(uHat()/((M2-sHat())*sHat()*(tHat()+uHat()))))*(sqr(M2)+sqr(sHat())-M2*(tHat()+uHat())))/(sqr(M2)*(tHat()+uHat()));
+ me(2,0,2,0)=(2.*(sqr(M2)+4*M2*sHat()+sqr(sHat()))*(-tHat())*sqrt(-tHat())*uHat())/(sqrt(3)*pow<5,1>(M)*phase*sqr(tHat()+uHat()));
+ me(2,0,3,0)=(2.*sqrt(2)*(M2+sHat())*tHat()*uHat()*sqrt(-(sHat()*uHat())))/(sqr(M2)*sqr(phase)*sqr(tHat()+uHat()));
+ me(2,0,4,0)=(2.*sqrt(2)*sqrt(-tHat())*sqr(uHat())*(-M2+tHat()+uHat()))/(pow<3,1>(M)*pow(phase,3)*sqr(tHat()+uHat()));
+ me(2,1,2,1)=(2.*sqr(M2-sHat())*sHat()*sqrt(-tHat())*tHat())/(sqrt(3)*pow<5,1>(M)*phase*sqr(tHat()+uHat()));
+ me(2,1,3,1)=(-2.*sqrt(2)*sqr(M2-sHat())*tHat()*sqrt(-(sHat()*uHat())))/(sqr(M2)*sqr(phase)*sqr(tHat()+uHat()));
+ me(2,1,4,1)=(2.*sqrt(2)*sqrt(-tHat())*uHat())/(pow<3,1>(M)*pow(phase,3));
+ }
+ // Helicity code version
+ for(unsigned int ih2=0;ih2<2;++ih2) {
+ for(unsigned int ih4=0;ih4<2;++ih4) {
+ LorentzPolarizationVectorE fCurrent = q4[ih4].dimensionedWave().vectorCurrent(q2[ih2].dimensionedWave());
+ for(unsigned int ih3=0;ih3<5;++ih3) {
+ auto vfPre = t3[ih3].wave().preDot(fCurrent);
+ auto vfPost = t3[ih3].wave().postDot(fCurrent);
+ auto vp1Pre = t3[ih3].wave().preDot(hard[0]->momentum());
+ auto vp1Post = t3[ih3].wave().postDot(hard[0]->momentum());
+ complex<Energy2> d11 = vp1Pre*hard[0]->momentum();
+ for(unsigned int ih1=0;ih1<2;++ih1) {
+ complex<Energy> d3=hard[2]->momentum()*g1[ih1].wave();
+ Complex amp =-1./sqr(M2)/M*(-2.*M2*(vfPre*hard[0]->momentum()*d3 + th*vfPre*g1[ih1].wave()
+ +2.*d11*(fCurrent*g1[ih1].wave()))
+ +(fCurrent*hard[2]->momentum())*(2.*(M2+th)*(vp1Pre*g1[ih1].wave())
+ -2.*(th-M2)*(vp1Post*g1[ih1].wave()))
+ -(th+M2)*((th-M2)*(vfPost*g1[ih1].wave())+2.*vfPost*hard[0]->momentum()*d3)
+ +sqr(M2)*(vfPre*g1[ih1].wave())+th*(2.*(vfPre*hard[0]->momentum())*d3+th*vfPre*g1[ih1].wave())
+ );
+ double test = norm(amp/me(2*ih1,ih2,ih3,ih4)-1.);
+ if(norm(me(2*ih1,ih2,ih3,ih4))>1e-10 && test>1e-10)
+ cerr << "testing in hel loop B " << ih1 << " " << ih2 << " " << ih3 << " " << ih4 << " "
+ << amp << " " << me(2*ih1,ih2,ih3,ih4) << " " << test << " " << amp/me(2*ih1,ih2,ih3,ih4) << "\n";
+ }
+ }
+ }
+ }
+ }
+ // g q -> 3P2 q
+ else if(hard[1]->id()<6) {
+ vector<VectorWaveFunction> g1;
+ vector<SpinorWaveFunction> q2;
+ vector<SpinorBarWaveFunction> q4;
+ VectorWaveFunction( g1,hard[0],incoming,false,true,true,vector_phase);
+ SpinorWaveFunction( q2,hard[1],incoming,false,true);
+ SpinorBarWaveFunction(q4,hard[3],outgoing,true ,true);
+ g1[1]=g1[2];
+ // matrix element
+ me = ProductionMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin2,PDT::Spin1Half);
+ if(!swapped) {
+ me(0,0,0,0)=(-2.*sqrt(2)*sqr(phase)*sqrt(-th)*uh)/pow<3,1>(M);
+ me(0,0,1,0)=(-2.*sqrt(2)*phase*sh*th*sqrt(-(uh/sh)))/sqr(M2);
+ me(0,0,2,0)=(2.*sh*(-th)*sqrt(-th))/(sqrt(3)*pow<5,1>(M));
+ me(0,1,0,1)=(2.*sqrt(2)*sh*sqrt(-th)*sqr(uh))/(pow<3,1>(M)*sqr(th+uh));
+ me(0,1,1,1)=(2.*sqrt(2)*(M2+sh)*th*uh*sqrt(-(sh*uh)))/(sqr(M2)*phase*sqr(th+uh));
+ me(0,1,2,1)=(2.*(sqr(M2)+4*M2*sh+sqr(sh))*sqrt(-th)*th*uh)/(sqrt(3)*pow<5,1>(M)*sqr(phase)*sqr(th+uh));
+ me(0,1,3,1)=(2.*sqrt(2)*(M2+sh)*sqr(th)*sqrt(-(sh*uh)))/(sqr(M2)*pow(phase,3)*sqr(th+uh));
+ me(0,1,4,1)=(2.*sqrt(2)*sh*sqr(th)*sqrt(-th))/(pow<3,1>(M)*pow(phase,4)*sqr(th+uh));
+ me(2,0,0,0)=(-2.*sqrt(2)*pow(phase,4)*sh*sqr(th)*sqrt(-th))/(pow<3,1>(M)*sqr(th+uh));
+ me(2,0,1,0)=(2.*sqrt(2)*pow(phase,3)*(M2+sh)*sqr(th)*sqrt(-(sh*uh)))/(sqr(M2)*sqr(th+uh));
+ me(2,0,2,0)=(2.*sqr(phase)*(sqr(M2)+4*M2*sh+sqr(sh))*(-th)*sqrt(-th)*uh)/(sqrt(3)*pow<5,1>(M)*sqr(th+uh));
+ me(2,0,3,0)=(2.*sqrt(2)*phase*(M2+sh)*th*uh*sqrt(-(sh*uh)))/(sqr(M2)*sqr(th+uh));
+ me(2,0,4,0)=(-2.*sqrt(2)*sh*sqrt(-th)*sqr(uh))/(pow<3,1>(M)*sqr(th+uh));
+ me(2,1,2,1)=(2.*sh*sqrt(-th)*th)/(sqrt(3)*pow<5,1>(M));
+ me(2,1,3,1)=(-2.*sqrt(2)*sh*th*sqrt(-(uh/sh)))/(sqr(M2)*phase);
+ me(2,1,4,1)=(2.*sqrt(2)*sqrt(-th)*uh)/(pow<3,1>(M)*sqr(phase));
+ }
+ else {
+ phase*=-1;
+ me(0,0,0,0)=(2.*sqrt(2)*pow(phase,3)*sqrt(-th)*uh)/pow<3,1>(M);
+ me(0,0,1,0)=(2.*sqrt(2)*sqr(phase)*sqr(M2-sh)*th*sqrt(-(sh*uh)))/(sqr(M2)*sqr(th+uh));
+ me(0,0,2,0)=(2.*phase*sqr(M2-sh)*sh*sqrt(-th)*th)/(sqrt(3)*pow<5,1>(M)*sqr(th+uh));
+ me(0,1,0,1)=(2.*sqrt(2)*pow(phase,3)*sqrt(-th)*sqr(uh)*(-M2+th+uh))/(pow<3,1>(M)*sqr(th+uh));
+ me(0,1,1,1)=(-2.*sqrt(2)*sqr(phase)*(M2+sh)*th*uh*sqrt(-(sh*uh)))/(sqr(M2)*sqr(th+uh));
+ me(0,1,2,1)=(2.*phase*(sqr(M2)+4*M2*sh+sqr(sh))*(-th)*sqrt(-th)*uh)/(sqrt(3)*pow<5,1>(M)*sqr(th+uh));
+ me(0,1,3,1)=(2.*sqrt(2)*sqr(th)*sqrt(-(uh/((M2-sh)*sh*(th+uh))))*(sqr(M2)+sqr(sh)-M2*(th+uh)))/(sqr(M2)*(th+uh));
+ me(0,1,4,1)=(2.*sqrt(2)*sqr(th)*sqrt(-th)*(-M2+th+uh))/(pow<3,1>(M)*phase*sqr(th+uh));
+ me(2,0,0,0)=(-2.*sqrt(2)*phase*sqr(th)*sqrt(-th)*(-M2+th+uh))/(pow<3,1>(M)*sqr(th+uh));
+ me(2,0,1,0)=(2.*sqrt(2)*sqr(th)*sqrt(-(uh/((M2-sh)*sh*(th+uh))))*(sqr(M2)+sqr(sh)-M2*(th+uh)))/(sqr(M2)*(th+uh));
+ me(2,0,2,0)=(2.*(sqr(M2)+4*M2*sh+sqr(sh))*sqrt(-th)*th*uh)/(sqrt(3)*pow<5,1>(M)*phase*sqr(th+uh));
+ me(2,0,3,0)=(-2.*sqrt(2)*(M2+sh)*th*uh*sqrt(-(sh*uh)))/(sqr(M2)*sqr(phase)*sqr(th+uh));
+ me(2,0,4,0)=(-2.*sqrt(2)*sqrt(-th)*sqr(uh)*(-M2+th+uh))/(pow<3,1>(M)*pow(phase,3)*sqr(th+uh));
+ me(2,1,2,1)=(2.*sqr(M2-sh)*sh*(-th)*sqrt(-th))/(sqrt(3)*pow<5,1>(M)*phase*sqr(th+uh));
+ me(2,1,3,1)=(2.*sqrt(2)*sqr(M2-sh)*th*sqrt(-(sh*uh)))/(sqr(M2)*sqr(phase)*sqr(th+uh));
+ me(2,1,4,1)=(-2.*sqrt(2)*sqrt(-th)*uh)/(pow<3,1>(M)*pow(phase,3));
+ }
+ // Helicity code version
+ // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // LorentzPolarizationVectorE fCurrent = q2[ih2].dimensionedWave().vectorCurrent(q4[ih4].dimensionedWave());
+ // for(unsigned int ih3=0;ih3<5;++ih3) {
+ // auto vfPre = t3[ih3].wave().preDot(fCurrent);
+ // auto vfPost = t3[ih3].wave().postDot(fCurrent);
+ // auto vp1Pre = t3[ih3].wave().preDot(hard[0]->momentum());
+ // auto vp1Post = t3[ih3].wave().postDot(hard[0]->momentum());
+ // complex<Energy2> d11 = vp1Pre*hard[0]->momentum();
+ // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // complex<Energy> d3=hard[2]->momentum()*g1[ih1].wave();
+ // Complex amp = 1./sqr(M2)/M*(-2.*M2*(vfPre*hard[0]->momentum()*d3 + th*vfPre*g1[ih1].wave()
+ // +2.*d11*(fCurrent*g1[ih1].wave()))
+ // +(fCurrent*hard[2]->momentum())*(2.*(M2+th)*(vp1Pre*g1[ih1].wave())
+ // -2.*(th-M2)*(vp1Post*g1[ih1].wave()))
+ // -(th+M2)*((th-M2)*(vfPost*g1[ih1].wave())+2.*vfPost*hard[0]->momentum()*d3)
+ // +sqr(M2)*(vfPre*g1[ih1].wave())+th*(2.*(vfPre*hard[0]->momentum())*d3+th*vfPre*g1[ih1].wave())
+ // );
+ // double test = norm(amp/me(2*ih1,ih2,ih3,ih4)-1.);
+ // if(norm(me(2*ih1,ih2,ih3,ih4))>1e-10 && test>1e-10)
+ // cerr << "testing in hel loop B " << ih1 << " " << ih2 << " " << ih3 << " " << ih4 << " "
+ // << amp << " " << me(2*ih1,ih2,ih3,ih4) << " " << test << " " << amp/me(2*ih1,ih2,ih3,ih4) << "\n";
+ // }
+ // }
+ // }
+ // }
+ }
+ else
+ assert(false);
+ }
+ else if(hard[0]->id()==-hard[1]->id()) {
+ vector<SpinorWaveFunction> q1;
+ vector<SpinorBarWaveFunction> q2;
+ vector<VectorWaveFunction> g4;
+ SpinorWaveFunction( q1,hard[0],incoming,false,true);
+ SpinorBarWaveFunction(q2,hard[1],incoming,false,true);
+ VectorWaveFunction( g4,hard[3],outgoing,true,true,true,vector_phase);
+ g4[1]=g4[2];
+ // matrix element
+ me = ProductionMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin2,PDT::Spin1);
+ // if(!swapped) {
+ // me(0,1,0,0) = -sqrt(2.*sh)*th/M2/M;
+ // me(0,1,0,2) = -exp(Complex(0.,-2.*phi))*sqrt(2.*sh)*uh/M2/M;
+ // me(1,0,0,0) = exp(Complex(0., 2.*phi))*sqrt(2.*sh)*uh/M2/M;
+ // me(1,0,0,2) = sqrt(2.*sh)*th/M2/M;
+ // }
+ // else {
+ // me(0,1,0,0) = -double(sqrt(2.*sh)*th/M2/M)*exp(Complex(0., 2.*phi));
+ // me(0,1,0,2) = sqrt(2.*sh)*uh/M2/M;
+ // me(1,0,0,0) = -sqrt(2.*sh)*uh/M2/M;
+ // me(1,0,0,2) = -double(sqrt(2.*sh)*th/M2/M)*exp(Complex(0.,-2.*phi));
+ // }
+ // // Helicity code version
+ // // for(unsigned int ih1=0;ih1<2;++ih1) {
+ // // for(unsigned int ih2=0;ih2<2;++ih2) {
+ // // LorentzPolarizationVectorE fCurrent = q1[ih1].dimensionedWave().vectorCurrent(q2[ih2].dimensionedWave());
+ // // for(unsigned int ih4=0;ih4<2;++ih4) {
+ // // Complex amp = ((sh-M2)*(fCurrent*g4[ih4].wave())-2.*(hard[2]->momentum()*g4[ih4].wave())*(fCurrent*hard[3]->momentum()))/M2/M;
+ // // if(norm(me(ih1,ih2,0,2*ih4))>1e-10)
+ // // cerr << "testing in hel loop B " << ih1 << " " << ih2 << " " << ih4 << " "
+ // // << amp << " " << me(ih1,ih2,0,2*ih4) << " " << amp/me(ih1,ih2,0,2*ih4)
+ // // << " " << norm(amp/me(ih1,ih2,0,2*ih4)) << "\n";
+ // // }
+ // // }
+ // // }
+ }
+ else
+ assert(false);
+ // construct the vertex
+ HardVertexPtr hardvertex = new_ptr(HardVertex());
+ // // set the matrix element for the vertex
+ hardvertex->ME(me);
+ // set the pointers and to and from the vertex
+ for(unsigned int i = 0; i < hard.size(); ++i)
+ hard[i]->spinInfo()->productionVertex(hardvertex);
+ // boost back to lab
+ boost = LorentzRotation(pcms.boostVector());
+ for(PPtr part : hard)
+ part->transform(boost);
+}
diff --git a/MatrixElement/Onium/MEPPto3P2Jet.h b/MatrixElement/Onium/MEPPto3P2Jet.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto3P2Jet.h
@@ -0,0 +1,197 @@
+// -*- C++ -*-
+#ifndef Herwig_MEPPto3P2Jet_H
+#define Herwig_MEPPto3P2Jet_H
+//
+// This is the declaration of the MEPPto3P2Jet class.
+//
+
+#include "Herwig/MatrixElement/HwMEBase.h"
+#include "OniumParameters.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * The MEPPto3P2Jet class implements the colour singlet processes for
+ * \f$gq\to^3\!\!P_2 q\f$, \f$q\bar{q}\to^3\!\!P_2 g\f$ and
+ * \f$gg\to^3\!\!P_2 g\f$.
+ *
+ * @see \ref MEPPto3P2JetInterfaces "The interfaces"
+ * defined for MEPPto3P2Jet.
+ */
+class MEPPto3P2Jet: public HwMEBase {
+
+public:
+
+ /**
+ * The default constructor.
+ */
+ MEPPto3P2Jet() : O1_(ZERO), state_(ccbar), n_(1), process_(0), mOpt_(0)
+ {}
+
+public:
+
+ /** @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 3;
+ }
+
+ /**
+ * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaEW() const {
+ return 0;
+ }
+
+ /**
+ * 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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ MEPPto3P2Jet & operator=(const MEPPto3P2Jet &) = delete;
+
+private:
+
+ /**
+ * Access to the parameters for the quarkonium states
+ */
+ OniumParametersPtr params_;
+
+ /**
+ * The \f$O_1\f$ colour-singlet coefficient
+ */
+ Energy5 O1_;
+
+ /**
+ * Type of state
+ */
+ OniumState state_;
+
+ /**
+ * Principal quantum number
+ */
+ unsigned int n_;
+
+ /**
+ * Which processes to generate
+ */
+ unsigned int process_;
+
+ /**
+ * Option for the onium mass
+ */
+ unsigned int mOpt_;
+};
+
+}
+
+#endif /* Herwig_MEPPto3P2Jet_H */
diff --git a/MatrixElement/Onium/MEPPto3S1Jet.cc b/MatrixElement/Onium/MEPPto3S1Jet.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto3S1Jet.cc
@@ -0,0 +1,224 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the MEPPto3S1Jet class.
+//
+
+#include "MEPPto3S1Jet.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/PDT/EnumParticles.h"
+#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
+#include "ThePEG/Utilities/EnumIO.h"
+#include "ThePEG/StandardModel/StandardModelBase.h"
+#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
+#include "Herwig/MatrixElement/ProductionMatrixElement.h"
+#include "Herwig/MatrixElement/HardVertex.h"
+
+using namespace Herwig;
+
+void MEPPto3S1Jet::doinit() {
+ HwMEBase::doinit();
+ // get the non-perturbative ME
+ O1_ = params_->singletMEProduction<0>(state_,n_,1,1);
+ // set the mass option
+ massOption(vector<unsigned int>({mOpt_+1,0}));
+}
+
+IBPtr MEPPto3S1Jet::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr MEPPto3S1Jet::fullclone() const {
+ return new_ptr(*this);
+}
+
+void MEPPto3S1Jet::persistentOutput(PersistentOStream & os) const {
+ os << params_ << ounit(O1_,GeV*GeV2) << oenum(state_) << n_ << mOpt_;
+}
+
+void MEPPto3S1Jet::persistentInput(PersistentIStream & is, int) {
+ is >> params_ >> iunit(O1_,GeV*GeV2) >> ienum(state_) >> n_ >> mOpt_;
+}
+
+//The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<MEPPto3S1Jet,HwMEBase>
+describeHerwigMEPPto3S1Jet("Herwig::MEPPto3S1Jet",
+ "HwOniumParameters.so HwMEHadronOnium.so");
+
+void MEPPto3S1Jet::Init() {
+
+ static ClassDocumentation<MEPPto3S1Jet> documentation
+ ("The MEPPto3S1Jet class implements the g g to 3S1 g processes");
+
+ static Reference<MEPPto3S1Jet,OniumParameters> interfaceParameters
+ ("Parameters",
+ "Quarkonium parameters",
+ &MEPPto3S1Jet::params_, false, false, true, false, false);
+
+ static Switch<MEPPto3S1Jet,OniumState> interfaceState
+ ("State",
+ "The type of onium state",
+ &MEPPto3S1Jet::state_, ccbar, false, false);
+ static SwitchOption interfaceStateccbar
+ (interfaceState,
+ "ccbar",
+ "Charmonium state",
+ ccbar);
+ static SwitchOption interfaceStatebbbar
+ (interfaceState,
+ "bbbar",
+ "Bottomonium state",
+ bbbar);
+
+ static Parameter<MEPPto3S1Jet,unsigned int> interfacePrincipalQuantumNumber
+ ("PrincipalQuantumNumber",
+ "The principle quantum number of the states",
+ &MEPPto3S1Jet::n_, 1, 1, 10,
+ false, false, Interface::limited);
+
+ static Switch<MEPPto3S1Jet,unsigned int> interfaceMassOption
+ ("MassOption",
+ "Mass of the treatment of the 3S1 mass",
+ &MEPPto3S1Jet::mOpt_, 0, false, false);
+ static SwitchOption interfaceMassOptionOnShell
+ (interfaceMassOption,
+ "OnShell",
+ "Use the on-shell mass",
+ 0);
+ static SwitchOption interfaceMassOptionOffShell
+ (interfaceMassOption,
+ "OffShell",
+ "Use an off-shell mass generated by the MassGenerator object for the 3S1 state.",
+ 1);
+}
+
+void MEPPto3S1Jet::getDiagrams() const {
+ // construct the meson PDG code from quark ids
+ unsigned int iq = 4+state_;
+ tcPDPtr ps = getParticleData(long(iq*110+3 + (n_-1)*100000));
+ tcPDPtr g = getParticleData(ParticleID::g);
+ add(new_ptr((Tree2toNDiagram(2), g, g, 1, ps, 1, g , -1)));
+}
+
+Selector<MEBase::DiagramIndex>
+MEPPto3S1Jet::diagrams(const DiagramVector & diags) const {
+ Selector<DiagramIndex> sel;
+ for ( DiagramIndex i = 0; i < diags.size(); ++i )
+ if ( diags[i]->id() == -1 ) sel.insert(1.0, i);
+ return sel;
+}
+
+Selector<const ColourLines *>
+MEPPto3S1Jet::colourGeometries(tcDiagPtr ) const {
+ static ColourLines c1("1 -2, 2 4, -1 -4");
+ static ColourLines c2("1 4, -4 -2, 2 -1");
+ Selector<const ColourLines *> sel;
+ sel.insert(0.5, &c1);
+ sel.insert(0.5, &c2);
+ return sel;
+}
+
+Energy2 MEPPto3S1Jet::scale() const {
+ return sHat();
+}
+
+double MEPPto3S1Jet::me2() const {
+ Energy M = meMomenta()[2].mass();
+ Energy2 M2=sqr(M);
+ Energy4 um(sqr(uHat()-M2)),tm(sqr(tHat()-M2)),sm(sqr(sHat()-M2));
+ double output = 160./81.*pow(Constants::pi*standardModel()->alphaS(scale()),3)*M*O1_*
+ (sqr(sHat())*sm+sqr(tHat())*tm+sqr(uHat())*um)/(sm*tm*um);
+ // test vs NPB 291 731
+ // Energy3 R02 = params_->radialWaveFunctionSquared(state_,n_);
+ // double test = 16.*Constants::pi*sqr(sHat())*
+ // 5*Constants::pi*pow(standardModel()->alphaS(scale()),3)*R02*M/9./sqr(sHat())*
+ // (sqr(sHat()/(tHat()-M2)/(uHat()-M2))+sqr(tHat()/(sHat()-M2)/(uHat()-M2))+sqr(uHat()/(sHat()-M2)/(tHat()-M2)));
+ // cerr << "testing matrix element " << output << " " << test << " "
+ // << (output-test)/(output+test) << " " << output/test << "\n";
+ return output;
+}
+
+
+void MEPPto3S1Jet::constructVertex(tSubProPtr sub) {
+ using namespace ThePEG::Helicity;
+ // extract the particles in the hard process
+ // only one order
+ ParticleVector hard;
+ hard.reserve(4);
+ hard.push_back(sub->incoming().first);
+ hard.push_back(sub->incoming().second);
+ hard.push_back(sub->outgoing()[0]);
+ hard.push_back(sub->outgoing()[1]);
+ // boost to partonic CMS
+ Lorentz5Momentum pcms = hard[0]->momentum()+hard[1]->momentum();
+ LorentzRotation boost(-pcms.boostVector());
+ for(PPtr part : hard) part->transform(boost);
+ // set the wavefunctions
+ vector<VectorWaveFunction> g1,g2,psi,g4;
+ VectorWaveFunction( g1,hard[0],incoming,false, true,true,vector_phase);
+ VectorWaveFunction( g2,hard[1],incoming,false, true,true,vector_phase);
+ VectorWaveFunction(psi,hard[2],outgoing,true ,false,true,vector_phase);
+ VectorWaveFunction( g4,hard[3],outgoing,true , true,true,vector_phase);
+ // extract kinematic variables
+ Energy M = hard[2]->mass();
+ Energy2 M2 = sqr(hard[2]->mass());
+ double phi = hard[2]->momentum().phi();
+ Energy2 sh = (hard[0]->momentum()+hard[1]->momentum()).m2();
+ Energy2 th = (hard[0]->momentum()-hard[2]->momentum()).m2();
+ Energy2 uh = (hard[0]->momentum()-hard[3]->momentum()).m2();
+ Energy2 um(uh-M2),tm(th-M2),sm(sh-M2);
+ Complex phase = exp(Complex(0.,phi));
+ Energy rstu = sqrt(th*uh/sh);
+ // calculate the matrix element
+ ProductionMatrixElement me(PDT::Spin1,PDT::Spin1,PDT::Spin1,PDT::Spin1);
+ me(0,0,0,0)=(2.*sqr(phase)*sqr(sh))/(tm*um);
+ me(0,0,0,2)=0;
+ me(0,0,1,0)=0;
+ me(0,0,1,2)=0;
+ me(0,0,2,0)=0;
+ me(0,0,2,2)=0;
+ me(0,2,0,0)=2.*M2*sh*th*uh/(sqr(sm)*tm*um);
+ me(0,2,0,2)=(2.*sqr(sh)*sqr(uh))/(sqr(phase)*sqr(sm)*tm*um);
+ me(0,2,1,0)=(-2.*sqrt(2)*M*rstu*sqr(sh)*th)/(phase*sqr(sm)*tm*um);
+ me(0,2,1,2)=(-2.*sqrt(2)*M*rstu*sqr(sh)*uh)/(pow(phase,3)*sqr(sm)*tm*um);
+ me(0,2,2,0)=(2.*sqr(sh)*sqr(th))/(sqr(phase)*sqr(sm)*tm*um);
+ me(0,2,2,2)=(2.*M2*sh*th*uh)/(pow(phase,4)*sqr(sm)*tm*um);
+ me(2,0,0,0)=(2.*M2*pow(phase,4)*sh*th*uh)/(sqr(sm)*tm*um);
+ me(2,0,0,2)=(2.*sqr(phase)*sqr(sh)*sqr(th))/(sqr(sm)*tm*um);
+ me(2,0,1,0)=(2.*sqrt(2)*M*pow(phase,3)*rstu*sqr(sh)*uh)/(sqr(sm)*tm*um);
+ me(2,0,1,2)=(2.*sqrt(2)*M*phase*rstu*sqr(sh)*th)/(sqr(sm)*tm*um);
+ me(2,0,2,0)=(2.*sqr(phase)*sqr(sh)*sqr(uh))/(sqr(sm)*tm*um);
+ me(2,0,2,2)=(2.*M2*sh*th*uh)/(sqr(sm)*tm*um);
+ me(2,2,0,0)=0;
+ me(2,2,0,2)=0;
+ me(2,2,1,0)=0;
+ me(2,2,1,2)=0;
+ me(2,2,2,0)=0;
+ me(2,2,2,2)=(2.*sqr(sh))/(sqr(phase)*tm*um);
+ // test the spin averaged result
+ // double test = 8.*sqr(sh)*(sqr(sh*sm)+sqr(th*tm)+sqr(uh*um))/sqr(sm*tm*um);
+ // double aver = me.average();
+ // cerr << "testing spin correlations " << test << " " << me.average() << " "
+ // << abs(test-aver)/(test+aver) << "\n";
+ // construct the vertex
+ HardVertexPtr hardvertex = new_ptr(HardVertex());
+ // // set the matrix element for the vertex
+ hardvertex->ME(me);
+ // set the pointers and to and from the vertex
+ for(unsigned int i = 0; i < hard.size(); ++i)
+ hard[i]->spinInfo()->productionVertex(hardvertex);
+ // boost back to lab
+ boost = LorentzRotation(pcms.boostVector());
+ for(PPtr part : hard)
+ part->transform(boost);
+}
diff --git a/MatrixElement/Onium/MEPPto3S1Jet.h b/MatrixElement/Onium/MEPPto3S1Jet.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/MEPPto3S1Jet.h
@@ -0,0 +1,191 @@
+// -*- C++ -*-
+#ifndef Herwig_MEPPto3S1Jet_H
+#define Herwig_MEPPto3S1Jet_H
+//
+// This is the declaration of the MEPPto3S1Jet class.
+//
+
+#include "Herwig/MatrixElement/HwMEBase.h"
+#include "OniumParameters.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * The MEPPto3S1Jet class implements the colour singlet processes for
+ * \f$gg\to^3\!\!S_1 g\f$.
+ *
+ * @see \ref MEPPto3S1JetInterfaces "The interfaces"
+ * defined for MEPPto3S1Jet.
+ */
+class MEPPto3S1Jet: public HwMEBase {
+
+public:
+
+ /**
+ * The default constructor.
+ */
+ MEPPto3S1Jet(): O1_(ZERO), state_(ccbar), n_(1), mOpt_(0)
+ {}
+
+public:
+
+ /** @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 3;
+ }
+
+ /**
+ * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+ * element is given.
+ */
+ virtual unsigned int orderInAlphaEW() const {
+ return 0;
+ }
+
+ /**
+ * 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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ MEPPto3S1Jet & operator=(const MEPPto3S1Jet &) = delete;
+
+private:
+
+ /**
+ * Access to the parameters for the quarkonium states
+ */
+ OniumParametersPtr params_;
+
+ /**
+ * The \f$O_1\f$ colour-singlet coefficient
+ */
+ Energy3 O1_;
+
+ /**
+ * Type of state
+ */
+ OniumState state_;
+
+ /**
+ * Principal quantum number
+ */
+ unsigned int n_;
+
+ /**
+ * Option for the onium mass
+ */
+ unsigned int mOpt_;
+};
+
+}
+
+#endif /* Herwig_MEPPto3S1Jet_H */
diff --git a/MatrixElement/Onium/Makefile.am b/MatrixElement/Onium/Makefile.am
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/Makefile.am
@@ -0,0 +1,26 @@
+pkglib_LTLIBRARIES = HwMEHadronOnium.la HwMEGammaGammaOnium.la HwOniumParameters.la
+
+HwMEHadronOnium_la_SOURCES = \
+MEGGto1S0.h MEGGto1S0.cc MEPPto1S0Jet.h MEPPto1S0Jet.cc \
+MEPPto3S1Jet.h MEPPto3S1Jet.cc \
+MEPPto1P1Jet.h MEPPto1P1Jet.cc \
+MEGGto3P0.h MEGGto3P0.cc MEPPto3P0Jet.h MEPPto3P0Jet.cc \
+MEPPto3P1Jet.h MEPPto3P1Jet.cc \
+MEGGto3P2.h MEGGto3P2.cc MEPPto3P2Jet.h MEPPto3P2Jet.cc \
+MEGGto1D2.h MEGGto1D2.cc MEPPto1D2Jet.h MEPPto1D2Jet.cc \
+MEPPto3D1Jet.h MEPPto3D1Jet.cc \
+MEPPto3D2Jet.h MEPPto3D2Jet.cc \
+MEPPto3D3Jet.h MEPPto3D3Jet.cc
+HwMEHadronOnium_la_LDFLAGS = $(AM_LDFLAGS) -module -version-info 1:0:0
+
+HwMEGammaGammaOnium_la_SOURCES = \
+GammaGamma2Onium1S0Amplitude.h GammaGamma2Onium1S0Amplitude.cc\
+GammaGamma2Onium3P0Amplitude.h GammaGamma2Onium3P0Amplitude.cc\
+GammaGamma2Onium3P2Amplitude.h GammaGamma2Onium3P2Amplitude.cc\
+GammaGamma2Onium1D2Amplitude.h GammaGamma2Onium1D2Amplitude.cc
+HwMEGammaGammaOnium_la_LDFLAGS = $(AM_LDFLAGS) -module -version-info 1:0:0
+
+
+HwOniumParameters_la_SOURCES = \
+OniumParameters.h OniumParameters.fh OniumParameters.cc
+HwOniumParameters_la_LDFLAGS = $(AM_LDFLAGS) -module -version-info 1:0:0
diff --git a/MatrixElement/Onium/OniumParameters.cc b/MatrixElement/Onium/OniumParameters.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/OniumParameters.cc
@@ -0,0 +1,247 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the OniumParameters class.
+//
+
+#include "OniumParameters.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Command.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/Utilities/StringUtils.h"
+
+using namespace Herwig;
+
+IBPtr OniumParameters::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr OniumParameters::fullclone() const {
+ return new_ptr(*this);
+}
+
+void OniumParameters::persistentOutput(PersistentOStream & os) const {
+ os << singletFromWaveFunction_ << ounit(R02_,GeV2*GeV)
+ << ounit(Rp02_,GeV2*GeV2*GeV) << ounit(Rpp02_,GeV2*GeV2*GeV2*GeV)
+ << ounit(O1_S_prod_,GeV2*GeV)
+ << ounit(O1_P_prod_,GeV2*GeV2*GeV) << ounit(O1_D_prod_,GeV2*GeV2*GeV2*GeV)
+ << ounit(O1_S_dec_,GeV2*GeV)
+ << ounit(O1_P_dec_,GeV2*GeV2*GeV) << ounit(O1_D_dec_,GeV2*GeV2*GeV2*GeV)
+ << ounit(O8_S_prod_,GeV2*GeV)
+ << singletTripletMixing_;
+}
+
+void OniumParameters::persistentInput(PersistentIStream & is, int) {
+ is >> singletFromWaveFunction_ >> iunit(R02_,GeV2*GeV)
+ >> iunit(Rp02_,GeV2*GeV2*GeV) >> iunit(Rpp02_,GeV2*GeV2*GeV2*GeV)
+ >> iunit(O1_S_prod_,GeV2*GeV)
+ >> iunit(O1_P_prod_,GeV2*GeV2*GeV) >> iunit(O1_D_prod_,GeV2*GeV2*GeV2*GeV)
+ >> iunit(O1_S_dec_,GeV2*GeV)
+ >> iunit(O1_P_dec_,GeV2*GeV2*GeV) >> iunit(O1_D_dec_,GeV2*GeV2*GeV2*GeV)
+ >> iunit(O8_S_prod_,GeV2*GeV)
+ >> singletTripletMixing_;
+}
+
+// The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<OniumParameters,Interfaced>
+describeHerwigOniumParameters("Herwig::OniumParameters", "HwOniumParameters.so");
+
+void OniumParameters::Init() {
+
+ static ClassDocumentation<OniumParameters> documentation
+ ("The OniumParameters class stores the parameters for quarkonium production");
+
+ static Command<OniumParameters> interfaceSetWaveFunction
+ ("SetWaveFunction",
+ "Set the value of the wavefunction, or its deriviatives at the origin",
+ &OniumParameters::setWaveFunction, false);
+
+ static Command<OniumParameters> interfaceSetSingletTripletMixing
+ ("SetSingletTripletMixing",
+ "Set the value of the singlet/triplet mixing for B_c states",
+ &OniumParameters::setSingletTripletMixing, false);
+
+ static Command<OniumParameters> interfaceSetOctetProductionMatrixElement
+ ("SetOctetProductionMatrixElement",
+ "Set the matrix element for the production of an octet state",
+ &OniumParameters::setOctetProductionMatrixElement, false);
+
+}
+
+string OniumParameters::setWaveFunction(string arg) {
+ // parse first bit of the string
+ string stype = StringUtils::car(arg);
+ arg = StringUtils::cdr(arg);
+ // get the type of the wavefunction
+ OniumState type;
+ if(stype=="ccbar")
+ type=ccbar;
+ else if(stype=="bbbar")
+ type=bbbar;
+ else if(stype=="bcbar")
+ type=bcbar;
+ else if(stype=="cc")
+ type=cc;
+ else if(stype=="bb")
+ type=bb;
+ else if(stype=="bc")
+ type=bc;
+ else
+ return "Error: Invalid string for wave function type " + stype;
+ // get the principal quantum number and orbital AM quantum numbers
+ stype = StringUtils::car(arg);
+ arg = StringUtils::cdr(arg);
+ if(stype.size()!=2)
+ return "Error: Invalid string for wave function level " + stype;
+ unsigned int n = stoi(stype);
+ // get the value
+ double value = stof(arg);
+ // now get the l value and set the wavefunction
+ if(stype[1]=='S') {
+ if(n>R02_[type].size()) R02_[type].resize(n,ZERO);
+ R02_[type][n-1] = value*GeV2*GeV;
+ }
+ else if(stype[1]=='P') {
+ if(n>Rp02_[type].size()) Rp02_[type].resize(n,ZERO);
+ Rp02_[type][n-1] = value*GeV2*GeV2*GeV;
+ }
+ else if(stype[1]=='D') {
+ if(n>Rpp02_[type].size()) Rpp02_[type].resize(n,ZERO);
+ Rpp02_[type][n-1] = value*GeV2*GeV2*GeV2*GeV;
+ }
+ else
+ return "Error: Invalid string for wave function l value " + stype;
+ // success
+ return "";
+}
+
+
+string OniumParameters::setSingletTripletMixing(string arg) {
+ // get the principal quantum number and orbital AM quantum numbers
+ string stype = StringUtils::car(arg);
+ arg = StringUtils::cdr(arg);
+ if(stype.size()!=2)
+ return "Error: Invalid string for mixing level " + stype;
+ unsigned int n = stoi(stype);
+ if(n>singletTripletMixing_.size()) {
+ singletTripletMixing_.resize(n,vector<double>({0.,0.}));
+ }
+ // get the value
+ double value = stof(arg);
+ // now get the l value and set the wavefunction
+ if(stype[1]=='S')
+ return "No mixing for s-wave states";
+ else if(stype[1]=='P')
+ singletTripletMixing_[n-1][0] = value/180.*Constants::pi;
+ else if(stype[1]=='D')
+ singletTripletMixing_[n-1][1] = value/180.*Constants::pi;
+ else
+ return "Error: Invalid string for mixing l value " + stype;
+ // success
+ return "";
+}
+
+void OniumParameters::doinit() {
+ Interfaced::doinit();
+ if ( ! singletFromWaveFunction_ )
+ throw Exception() << "Only calculate of singlet elements ffrom wavefunction currently supported\n";
+ // s wave
+ for(unsigned int type=0;type<R02_.size();++type) {
+ if(O1_S_prod_[type].size()<R02_[type].size()) O1_S_prod_[type].resize(R02_[type].size(),{ZERO,ZERO});
+ if(O1_S_dec_ [type].size()<R02_[type].size()) O1_S_dec_ [type].resize(R02_[type].size(),{ZERO,ZERO});
+ for(unsigned int n=0;n<R02_[type].size();++n) {
+ Energy3 Odec = 1.5/Constants::pi*R02_[type][n];
+ O1_S_prod_[type][n][0] = Odec;
+ O1_S_prod_[type][n][1] = 3.*Odec;
+ O1_S_dec_ [type][n][0] = Odec;
+ O1_S_dec_ [type][n][1] = Odec;
+ }
+ }
+ // p wave
+ for(unsigned int type=0;type<Rp02_.size();++type) {
+ if(O1_P_prod_[type].size()<Rp02_[type].size()) O1_P_prod_[type].resize(Rp02_[type].size(),{ZERO,ZERO,ZERO,ZERO});
+ if(O1_P_dec_ [type].size()<Rp02_[type].size()) O1_P_dec_ [type].resize(Rp02_[type].size(),{ZERO,ZERO,ZERO,ZERO});
+ for(unsigned int n=0;n<Rp02_[type].size();++n) {
+ Energy5 Odec = 4.5/Constants::pi*Rp02_[type][n];
+ O1_P_prod_[type][n][0] = 3.*Odec;
+ O1_P_prod_[type][n][1] = Odec;
+ O1_P_prod_[type][n][2] = 3.*Odec;
+ O1_P_prod_[type][n][3] = 5.*Odec;
+ O1_P_dec_ [type][n][0] = Odec;
+ O1_P_dec_ [type][n][1] = Odec;
+ O1_P_dec_ [type][n][2] = Odec;
+ O1_P_dec_ [type][n][3] = Odec;
+ }
+ }
+ // d wave
+ for(unsigned int type=0;type<Rpp02_.size();++type) {
+ if(O1_D_prod_[type].size()<Rpp02_[type].size()) O1_D_prod_[type].resize(Rpp02_[type].size(),{ZERO,ZERO,ZERO,ZERO});
+ if(O1_D_dec_ [type].size()<Rpp02_[type].size()) O1_D_dec_ [type].resize(Rpp02_[type].size(),{ZERO,ZERO,ZERO,ZERO});
+ for(unsigned int n=0;n<Rpp02_[type].size();++n) {
+ Energy7 Odec = 3.75*3./Constants::pi*Rpp02_[type][n];
+ O1_D_prod_[type][n][0] = 5.*Odec;
+ O1_D_prod_[type][n][1] = 3.*Odec;
+ O1_D_prod_[type][n][2] = 5.*Odec;
+ O1_D_prod_[type][n][3] = 7.*Odec;
+ O1_D_dec_ [type][n][0] = Odec;
+ O1_D_dec_ [type][n][1] = Odec;
+ O1_D_dec_ [type][n][2] = Odec;
+ O1_D_dec_ [type][n][3] = Odec;
+ }
+ }
+}
+
+string OniumParameters::setOctetProductionMatrixElement(string arg) {
+ // parse first bit of the string
+ string stype = StringUtils::car(arg);
+ arg = StringUtils::cdr(arg);
+ // get the type of the wavefunction
+ OniumState type;
+ if(stype=="ccbar")
+ type=ccbar;
+ else if(stype=="bbbar")
+ type=bbbar;
+ else
+ return "Error: Invalid string for wave function type " + stype;
+ // get the orbital AM and spin quantum numbers
+ stype = StringUtils::car(arg);
+ arg = StringUtils::cdr(arg);
+ if(stype.size()!=3)
+ return "Error: Invalid string for spin and L quantum numbers " + stype;
+ unsigned int s = (stoi(stype)-1)/2;
+ unsigned int L=0;
+ if (stype[1]=='S') L=0;
+ else if(stype[1]=='P') L=1;
+ else if(stype[1]=='D') L=2;
+ else
+ return "Error: Invalid string for spin and L quantum numbers " + stype;
+ // get the pdg code and value
+ stype = StringUtils::car(arg);
+ arg = StringUtils::cdr(arg);
+ // get the pdg code
+ long pid = stoi(stype);
+ // get the value
+ double value = stof(arg);
+ // set the value
+ if(L==0) {
+ O8_S_prod_[type][s][pid] = value*GeV*GeV2;
+ }
+ else
+ return "Error: Invalid string for wave function l value " + stype;
+ // else if(stype[1]=='P') {
+ // if(n>Rp02_[type].size()) Rp02_[type].resize(n,ZERO);
+ // Rp02_[type][n-1] = value*GeV2*GeV2*GeV;
+ // }
+ // else if(stype[1]=='D') {
+ // if(n>Rpp02_[type].size()) Rpp02_[type].resize(n,ZERO);
+ // Rpp02_[type][n-1] = value*GeV2*GeV2*GeV2*GeV;
+ // }
+ // success
+ return "";
+}
diff --git a/MatrixElement/Onium/OniumParameters.fh b/MatrixElement/Onium/OniumParameters.fh
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/OniumParameters.fh
@@ -0,0 +1,18 @@
+// -*- C++ -*-
+//
+// This is the forward declaration of the OniumParameters class.
+//
+#ifndef Herwig_OniumParameters_FH
+#define Herwig_OniumParameters_FH
+
+#include "ThePEG/Config/ThePEG.h"
+
+namespace Herwig {
+
+class OniumParameters;
+
+ThePEG_DECLARE_POINTERS(Herwig::OniumParameters,OniumParametersPtr);
+
+}
+
+#endif
diff --git a/MatrixElement/Onium/OniumParameters.h b/MatrixElement/Onium/OniumParameters.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Onium/OniumParameters.h
@@ -0,0 +1,351 @@
+// -*- C++ -*-
+#ifndef Herwig_OniumParameters_H
+#define Herwig_OniumParameters_H
+//
+// This is the declaration of the OniumParameters class.
+//
+
+#include "OniumParameters.fh"
+#include "ThePEG/Interface/Interfaced.h"
+#include <cassert>
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * Enum to define the type of onium state
+ */
+enum OniumState {ccbar=0,bbbar=1,bcbar=2,cc=3,bb=4,bc=5};
+
+/**
+ * The OniumParameters class stores the parameters for quarkonium production
+ *
+ * @see \ref OniumParametersInterfaces "The interfaces"
+ * defined for OniumParameters.
+ */
+class OniumParameters: public Interfaced {
+
+public:
+
+ /**
+ * The default constructor.
+ */
+ OniumParameters() : singletFromWaveFunction_(true),
+ R02_ (vector<vector<Energy3> >(6,vector<Energy3>())),
+ Rp02_ (vector<vector<Energy5> >(6,vector<Energy5>())),
+ Rpp02_(vector<vector<Energy7> >(6,vector<Energy7>())),
+ O1_S_prod_(vector<vector<vector<Energy3> > >(6,vector<vector<Energy3> >())),
+ O1_P_prod_(vector<vector<vector<Energy5> > >(6,vector<vector<Energy5> >())),
+ O1_D_prod_(vector<vector<vector<Energy7> > >(6,vector<vector<Energy7> >())),
+ O1_S_dec_ (vector<vector<vector<Energy3> > >(6,vector<vector<Energy3> >())),
+ O1_P_dec_ (vector<vector<vector<Energy5> > >(6,vector<vector<Energy5> >())),
+ O1_D_dec_ (vector<vector<vector<Energy7> > >(6,vector<vector<Energy7> >())),
+ O8_S_prod_(vector<vector<map<long,Energy3> > >(2,vector<map<long,Energy3> >(2)))
+ {}
+
+public:
+
+ // Get the singlet matrix element for onium decay
+ template <unsigned int L>
+ ThePEG::Qty<std::ratio<0,1>, std::ratio<3+2*L,1>, std::ratio<0,1>> inline
+ singletMEDecay(OniumState type,unsigned int n, unsigned int S, unsigned int J) const;
+
+ // Get the singlet matrix element for onium production
+ template <unsigned int L>
+ ThePEG::Qty<std::ratio<0,1>, std::ratio<3+2*L,1>, std::ratio<0,1>> inline
+ singletMEProduction(OniumState type,unsigned int n, unsigned int S, unsigned int J) const;
+
+ // Get the octet matrix element for onium production
+ template <unsigned int L>
+ ThePEG::Qty<std::ratio<0,1>, std::ratio<3+2*L,1>, std::ratio<0,1>> inline
+ octetMEProduction(OniumState type, unsigned int S, unsigned int J, long pid) const;
+
+ // Get \f$|R(0)|^2\f$ for s-wave states
+ Energy3 radialWaveFunctionSquared(OniumState type,unsigned int n) {
+ assert(R02_[type].size()>=n);
+ return R02_[type][n-1];
+ }
+
+ // Get \f$|R'(0)|^2\f$ for s-wave states
+ Energy5 firstDerivativeRadialWaveFunctionSquared(OniumState type,unsigned int n) const{
+ assert(Rp02_[type].size()>=n);
+ return Rp02_[type][n-1];
+ }
+
+ // Get \f$|R''(0)|^2\f$ for s-wave states
+ Energy7 secondDerivativeRadialWaveFunctionSquared(OniumState type,unsigned int n) const {
+ assert(Rpp02_[type].size()>=n);
+ return Rpp02_[type][n-1];
+ }
+
+ // Get the singlet-triplet mxing for \f$B_c\f$ states
+ double singletTripletMixing(unsigned int n, unsigned int l) const {
+ if(n>singletTripletMixing_.size()) return 0.;
+ else if(l>singletTripletMixing_[n-1].size()) return 0.;
+ else
+ return singletTripletMixing_[n-1][l-1];
+ }
+
+public:
+
+ /**
+ * Set the values of the wavefunction at the origin
+ */
+ string setWaveFunction(string arg);
+
+ /**
+ * Set the values of the octet production matrix elements
+ */
+ string setOctetProductionMatrixElement(string arg);
+
+ /**
+ * Set the values of the wavefunction at the origin
+ */
+ string setSingletTripletMixing(string arg);
+
+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;
+
+ /** 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;
+ //@}
+
+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();
+ //@}
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ OniumParameters & operator=(const OniumParameters &) = delete;
+
+private :
+
+ /**
+ * Calculate the singlet matrix elements from the wavefunctions
+ */
+ bool singletFromWaveFunction_;
+
+ /**
+ * Wavefunctions
+ */
+ //@{
+ /**
+ * \f$|R(0)|^2\f$ for the \f$s\f$-wave states
+ */
+ vector<vector<Energy3> > R02_;
+
+ /**
+ * \f$|R'(0)|^2\f$ for the \f$p\f$-wave states
+ */
+ vector<vector<Energy5> > Rp02_;
+
+ /**
+ * \f$|R''(0)|^2\f$ for the \f$d\f$-wave states
+ */
+ vector<vector<Energy7> > Rpp02_;
+ //@}
+
+ /**
+ * Singlet matrix elements production
+ */
+ //@{
+ /**
+ * \f$|R(0)|^2\f$ for the \f$s\f$-wave states
+ */
+ vector<vector<vector<Energy3> > > O1_S_prod_;
+
+ /**
+ * \f$|R'(0)|^2\f$ for the \f$p\f$-wave states
+ */
+ vector<vector<vector<Energy5 > > > O1_P_prod_;
+
+ /**
+ * \f$|R''(0)|^2\f$ for the \f$d\f$-wave states
+ */
+ vector<vector<vector<Energy7> > > O1_D_prod_;
+ //@}
+
+ /**
+ * Singlet matrix elements decay
+ */
+ //@{
+ /**
+ * \f$|R(0)|^2\f$ for the \f$s\f$-wave states
+ */
+ vector<vector<vector<Energy3> > > O1_S_dec_;
+
+ /**
+ * \f$|R'(0)|^2\f$ for the \f$p\f$-wave states
+ */
+ vector<vector<vector<Energy5 > > > O1_P_dec_;
+
+ /**
+ * \f$|R''(0)|^2\f$ for the \f$d\f$-wave states
+ */
+ vector<vector<vector<Energy7> > > O1_D_dec_;
+ //@}
+
+ /**
+ * Mixing for \f$B_c\f$ states
+ */
+ vector<vector<double> > singletTripletMixing_;
+
+ /**
+ * Octet matrix elements production
+ */
+ //@{
+ /**
+ * \f$O_8()\f$ for the \f$s\f$-wave states
+ */
+ vector<vector<map<long,Energy3> > > O8_S_prod_;
+
+ // /**
+ // * \f$|R'(0)|^2\f$ for the \f$p\f$-wave states
+ // */
+ // vector<vector<vector<Energy5 > > > O8_P_prod_;
+
+ // /**
+ // * \f$|R''(0)|^2\f$ for the \f$d\f$-wave states
+ // */
+ // vector<vector<vector<Energy7> > > O8_D_prod_;
+ //@}
+};
+
+// Get the singlet matrix element production
+// s-wave
+template <>
+ThePEG::Qty<std::ratio<0,1>, std::ratio<3,1>, std::ratio<0,1>>
+inline OniumParameters::singletMEProduction<0>(OniumState type, unsigned int n, unsigned int S, unsigned int J) const {
+ assert(O1_S_prod_[type].size()>=n);
+ assert(S==J && S<=1);
+ return O1_S_prod_[type][n-1][J];
+}
+// p-wave
+template <>
+ThePEG::Qty<std::ratio<0,1>, std::ratio<5,1>, std::ratio<0,1>>
+inline OniumParameters::singletMEProduction<1>(OniumState type, unsigned int n, unsigned int S, unsigned int J) const {
+ assert(O1_P_prod_[type].size()>=n);
+ assert(S<=1&&J<=2);
+ if(S==0) {
+ assert(J==1);
+ return O1_P_prod_[type][n-1][0];
+ }
+ else {
+ return O1_P_prod_[type][n-1][J+1];
+ }
+}
+// d-wave
+template <>
+ThePEG::Qty<std::ratio<0,1>, std::ratio<7,1>, std::ratio<0,1>>
+inline OniumParameters::singletMEProduction<2>(OniumState type, unsigned int n, unsigned int S, unsigned int J) const {
+ assert(O1_D_prod_[type].size()>=n);
+ assert(S<=1&&J>0&&J<=3);
+ if(S==0) {
+ assert(J==2);
+ return O1_D_prod_[type][n-1][0];
+ }
+ else {
+ return O1_D_prod_[type][n-1][J];
+ }
+}
+
+// Get the singlet matrix element decay
+// s-wave
+template <>
+ThePEG::Qty<std::ratio<0,1>, std::ratio<3,1>, std::ratio<0,1>>
+inline OniumParameters::singletMEDecay<0>(OniumState type, unsigned int n, unsigned int S, unsigned int J) const {
+ assert(O1_S_dec_[type].size()>=n);
+ assert(S==J && S<=1);
+ return O1_S_dec_[type][n-1][J];
+}
+// p-wave
+template <>
+ThePEG::Qty<std::ratio<0,1>, std::ratio<5,1>, std::ratio<0,1>>
+inline OniumParameters::singletMEDecay<1>(OniumState type, unsigned int n, unsigned int S, unsigned int J) const {
+ assert(O1_P_dec_[type].size()>=n);
+ assert(S<=1&&J<=2);
+ if(S==0) {
+ assert(J==1);
+ return O1_P_dec_[type][n-1][0];
+ }
+ else {
+ return O1_P_dec_[type][n-1][J+1];
+ }
+}
+// d-wave
+template <>
+ThePEG::Qty<std::ratio<0,1>, std::ratio<7,1>, std::ratio<0,1>>
+inline OniumParameters::singletMEDecay<2>(OniumState type, unsigned int n, unsigned int S, unsigned int J) const {
+ assert(O1_D_dec_[type].size()>=n);
+ assert(S<=1&&J>0&&J<=3);
+ if(S==0) {
+ assert(J==2);
+ return O1_D_dec_[type][n-1][0];
+ }
+ else {
+ return O1_D_dec_[type][n-1][J];
+ }
+}
+
+// Octet production matrix elements
+// s-wave
+template <>
+ThePEG::Qty<std::ratio<0,1>, std::ratio<3,1>, std::ratio<0,1>>
+inline OniumParameters::octetMEProduction<0>(OniumState type, unsigned int S, unsigned int J, long pid) const {
+ assert(S==J && S<=1);
+ map<long,Energy3>::const_iterator it = O8_S_prod_[type][S].find(pid);
+ assert(it!=O8_S_prod_[type][S].end());
+ return it->second;
+}
+}
+
+#endif /* Herwig_OniumParameters_H */
diff --git a/Tests/Makefile.am b/Tests/Makefile.am
--- a/Tests/Makefile.am
+++ b/Tests/Makefile.am
@@ -1,408 +1,412 @@
AM_LDFLAGS += -module -avoid-version -rpath /dummy/path/not/used
EXTRA_DIST = Inputs python Rivet
EXTRA_LTLIBRARIES = LeptonTest.la GammaTest.la HadronTest.la DISTest.la
if WANT_LIBFASTJET
EXTRA_LTLIBRARIES += HadronJetTest.la LeptonJetTest.la
HadronJetTest_la_SOURCES = \
Hadron/VHTest.h Hadron/VHTest.cc\
Hadron/VTest.h Hadron/VTest.cc\
Hadron/HTest.h Hadron/HTest.cc
HadronJetTest_la_CPPFLAGS = $(AM_CPPFLAGS) $(FASTJETINCLUDE) \
-I$(FASTJETPATH)
HadronJetTest_la_LIBADD = $(FASTJETLIBS)
LeptonJetTest_la_SOURCES = \
Lepton/TopDecay.h Lepton/TopDecay.cc
LeptonJetTest_la_CPPFLAGS = $(AM_CPPFLAGS) $(FASTJETINCLUDE) \
-I$(FASTJETPATH)
LeptonJetTest_la_LIBADD = $(FASTJETLIBS)
endif
LeptonTest_la_SOURCES = \
Lepton/VVTest.h Lepton/VVTest.cc \
Lepton/VBFTest.h Lepton/VBFTest.cc \
Lepton/VHTest.h Lepton/VHTest.cc \
Lepton/FermionTest.h Lepton/FermionTest.cc
GammaTest_la_SOURCES = \
Gamma/GammaMETest.h Gamma/GammaMETest.cc \
Gamma/GammaPMETest.h Gamma/GammaPMETest.cc
DISTest_la_SOURCES = \
DIS/DISTest.h DIS/DISTest.cc
HadronTest_la_SOURCES = \
Hadron/HadronVVTest.h Hadron/HadronVVTest.cc\
Hadron/HadronVBFTest.h Hadron/HadronVBFTest.cc\
Hadron/WHTest.h Hadron/WHTest.cc\
Hadron/ZHTest.h Hadron/ZHTest.cc\
Hadron/VGammaTest.h Hadron/VGammaTest.cc\
Hadron/ZJetTest.h Hadron/ZJetTest.cc\
Hadron/WJetTest.h Hadron/WJetTest.cc\
Hadron/QQHTest.h Hadron/QQHTest.cc
REPO = $(top_builddir)/src/HerwigDefaults.rpo
HERWIG = $(top_builddir)/src/Herwig
HWREAD = $(HERWIG) read --repo $(REPO) -L $(builddir)/.libs -i $(top_builddir)/src
HWBUILD = $(HERWIG) build --repo $(REPO) -L $(builddir)/.libs -i $(top_builddir)/src
HWINTEGRATE = $(HERWIG) integrate
HWRUN = $(HERWIG) run -N $${NUMEVENTS:-10000}
tests : tests-LEP tests-DIS tests-LHC tests-Gamma
LEPDEPS = \
test-LEP-VV \
test-LEP-VH \
test-LEP-VBF \
test-LEP-BB \
test-LEP-Quarks \
test-LEP-Leptons
if WANT_LIBFASTJET
LEPDEPS += test-LEP-TopDecay
endif
tests-LEP : $(LEPDEPS)
tests-DIS : test-DIS-Charged test-DIS-Neutral
LHCDEPS = \
test-LHC-WW test-LHC-WZ test-LHC-ZZ \
test-LHC-ZGamma test-LHC-WGamma \
test-LHC-ZH test-LHC-WH \
test-LHC-ZJet test-LHC-WJet \
test-LHC-Z test-LHC-W \
test-LHC-ZZVBF test-LHC-VBF \
test-LHC-WWVBF \
test-LHC-bbH test-LHC-ttH \
test-LHC-GammaGamma test-LHC-GammaJet \
test-LHC-Higgs test-LHC-HiggsJet \
test-LHC-QCDFast test-LHC-QCD \
test-LHC-Top
if WANT_LIBFASTJET
LHCDEPS += \
test-LHC-Bottom \
test-LHC-WHJet test-LHC-ZHJet test-LHC-HJet \
test-LHC-ZShower test-LHC-WShower \
test-LHC-WHJet-Powheg test-LHC-ZHJet-Powheg test-LHC-HJet-Powheg \
test-LHC-ZShower-Powheg test-LHC-WShower-Powheg
endif
tests-LHC : $(LHCDEPS)
tests-Gamma : test-Gamma-FF test-Gamma-WW test-Gamma-P
LEPLIBS = LeptonTest.la
HADLIBS = HadronTest.la
if WANT_LIBFASTJET
LEPLIBS += LeptonJetTest.la
HADLIBS += HadronJetTest.la
endif
test-LEP-% : Inputs/LEP-%.in $(LEPLIBS)
$(HWREAD) $<
$(HWRUN) $(notdir $(subst .in,.run,$<))
test-Gamma-% : Inputs/Gamma-%.in GammaTest.la
$(HWREAD) $<
$(HWRUN) $(notdir $(subst .in,.run,$<))
test-DIS-% : Inputs/DIS-%.in DISTest.la
$(HWREAD) $<
$(HWRUN) $(notdir $(subst .in,.run,$<))
test-LHC-% : Inputs/LHC-%.in GammaTest.la $(HADLIBS)
$(HWREAD) $<
$(HWRUN) $(notdir $(subst .in,.run,$<))
tests-Rivet : Rivet-EE Rivet-DIS Rivet-Fixed \
Rivet-TVT-WZ Rivet-TVT-Photon Rivet-TVT-Jets \
Rivet-LHC-Jets Rivet-LHC-EW Rivet-LHC-Photon Rivet-LHC-Higgs
Rivet-%-UE-Cent.yoda : Rivet-%-UE-Cent.run Rivet-%-Cent.run
rm -rf $(subst .yoda,,$@)
mkdir $(subst .yoda,,$@)
mv $(subst .yoda,.run,$@) $(subst UE-,,$(subst .yoda,.run,$@)) $(subst .yoda,,$@)
cd $(subst .yoda,,$@); ../$(HWRUN) $(subst UE-,,$(subst .yoda,.run,$@)); mv $(subst UE-,,$@) ALICE_2015_PPCentrality.yoda
cd $(subst .yoda,,$@); export RIVET_ANALYSIS_PATH=`pwd`; ../$(HWRUN) $(subst .yoda,.run,$@)
mv $(subst .yoda,,$@)/$@ .
rm -rf $(subst .yoda,,$@)
Rivet-%.run : Rivet/%.in
export RIVET_ANALYSIS_PATH=`pwd`/Analyses; $(HWBUILD) -c .cache/$(subst .run,,$@) $<
Rivet-Matchbox-%.yoda : Rivet-Matchbox-%.run
export RIVET_ANALYSIS_PATH=`pwd`/Analyses; $(HWINTEGRATE) -c .cache/$(subst .run,,$<) $<
export RIVET_ANALYSIS_PATH=`pwd`/Analyses; $(HWRUN) -c .cache/$(subst .run,,$<) $<
Rivet-%.yoda : Rivet-%.run
export RIVET_ANALYSIS_PATH=`pwd`/Analyses; $(HWRUN) $<
Rivet/%.in :
python/make_input_files.py $(notdir $(subst .in,,$@))
Rivet-inputfiles: $(shell echo Rivet/EE{,-Powheg,-Matchbox,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox-Powheg,-Merging}-{7.7,9.4,12,13,17,27.6,27.7,29,30.2,30.3,30.5,30.7,30.8,30,31.2,31.3,31.6,34,34.8,41,41.5,42.1,42.6,43.5,43.6,45,50,52,53.3,55,55.3,56,57,58,59.5,60.8,60,61.4,65.4,66,75.7,76,82,85,10,12.8,21.5,22,22.5,25,26.8,34.5,35,36.2,44,48.0,91,93.0,130,130.1,133,136,161,161.3,172,172.3,177,182.8,183,188.6,189,192,194.4,196,197,200,200.2,202,205,206,206.2,207,91-nopi}.in) \
$(shell echo Rivet/EE-{183,189}-WW.in) \
$(shell echo Rivet/EE{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Powheg,-Matchbox-Powheg}-{14,14.8}.in) \
$(shell echo Rivet/EE{,-Dipole}-{10.5,11.96,12.8,13.96,16.86,21.84,26.8,28.48,35.44,48.0,97.0}-gg.in) \
$(shell echo Rivet/EE{,-Powheg,-Matchbox,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox-Powheg}-{2.2,2.6,3.0,3.2,4.17,4.3,4.41,5.0,5.2,4.6,4.8,5.8,6.2,6.5,6.6,7.0,7.4,3.63,4.03,4.5,8.8,9.27,9.46,9.51,10.52,10.52-sym,10.54,10.58,10.45,10.47,10.6}.in) \
$(shell echo Rivet/EE-{Upsilon,Upsilon2,Upsilon3,Upsilon4,Upsilon5,Upsilon4-asym,JPsi,Psi2S,Psi2S-All,Psi3770,Tau,Phi,Lambdac,Omega-Meson,Omega-Baryon,Eta,Xi0,Xic0,Xicp,Omegac0,Ds,Bc,Etac,Xim}.in) \
$(shell echo Rivet/DIS{,-NoME,-Powheg,-Matchbox,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox-Powheg,-Merging}-{225,251,300,318,318-CMS}-e+-{VeryLow,Low,Med,High}Q2.in) \
$(shell echo Rivet/DIS{,-NoME,-Powheg,-Matchbox,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox-Powheg,-Merging}-318-{e+,e-}-CC-{VeryLow,Low,Med,High}Q2.in) \
$(shell echo Rivet/DIS{,-NoME,-Powheg,-Matchbox,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox-Powheg,-Merging}-{296,300,318}-e--{VeryLow,Low,Med,High}Q2.in) \
$(shell echo Rivet/TVT{,-Powheg,-Matchbox,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox-Powheg,-Merging}-{Run-I-Z,Run-I-W,Run-I-WZ,Run-II-Z-e,Run-II-Z-{,LowMass-,HighMass-}mu,Run-II-W}.in) \
$(shell echo Rivet/TVT{,-Dipole}-Run-II-{DiPhoton-GammaGamma,DiPhoton-GammaJet,PromptPhoton}.in) \
$(shell echo Rivet/TVT-Powheg-Run-II-{DiPhoton-GammaGamma,DiPhoton-GammaJet}.in) \
$(shell echo Rivet/TVT{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-Run-{I,II}-{Jets-{1..6},DiJets-{1..4}}.in ) \
$(shell echo Rivet/TVT{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-{630-Jets-{1..3},300-Jets-1,900-Jets-1}.in ) \
$(shell echo Rivet/TVT{,-Dipole}-{Run-I,Run-II,300,630,900}-UE.in) \
$(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-7-DiJets-{1..7}-{A,B,C}.in ) \
$(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-13-DiJets-{{1..11}-A,{6..11}-B}.in ) \
$(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-{7,8,13}-Jets-{0..10}.in ) \
$(shell echo Rivet/LHC{,-Dipole}-{900,2360,2760,7,8,13}-UE.in ) \
$(shell echo Rivet/LHC{,-Dipole}-2760-Jets-{1..3}.in ) \
$(shell echo Rivet/LHC{,-Dipole}-{900,7,13}-UE-Long.in ) \
$(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-7-Charm-{0..5}.in) \
$(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-{5,13}-Charm-0.in) \
$(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-7-Bottom-{0..9}.in) \
$(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-13-Bottom-{0..6}.in) \
$(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-7-Top-{L,SL}.in) \
$(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-{8,13}-Top-{All,L,SL}.in) \
$(shell echo Rivet/Star{,-Dipole}-{UE,Jets-{1..4}}.in ) \
$(shell echo Rivet/SppS{,-Dipole}-{53,63,200,500,546,900}-UE.in ) \
$(shell echo Rivet/LHC{,-Matchbox,-Matchbox-Powheg,-Powheg,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-{{,8-}W-{e,mu},13-W-mu,{,8-,13-}Z-{e,mu}-Mass{1..5},13-Z-nu,Z-mu-SOPHTY,WZ,WW-{emu,ll},13-WW-ll,13-ZZ-ll,ZZ-{ll,lv},{8,13}-WZ,8-ZZ-lv,8-WW-ll,Z-mu-Short}.in) \
$(shell echo Rivet/LHC{,-Dipole}-7-{W,Z}Gamma-{e,mu}.in) \
$(shell echo Rivet/LHC{,-Dipole}-8-ZGamma-{e,mu}.in) \
$(shell echo Rivet/LHC{,-Matchbox,-Matchbox-Powheg,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-{7-W-Jet-{1..3}-e,7-Z-Jet-{0..3}-e,7-Z-Jet-0-mu}.in) \
$(shell echo Rivet/LHC{-Matchbox,-Matchbox-Powheg,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-{Z-b,Z-bb,8-Z-b,8-Z-bb,13-Z-b,13-Z-bb,W-b,8-Z-jj}.in) \
$(shell echo Rivet/LHC{,-Dipole}-{7,8,13}-PromptPhoton-{1..5}.in) Rivet/LHC-GammaGamma-7.in \
$(shell echo Rivet/LHC{,-Powheg,-Dipole}-{7,8,13}-{DiPhoton-GammaGamma,DiPhoton-GammaJet}.in) \
$(shell echo Rivet/LHC{,-Powheg,-Matchbox,-Matchbox-Powheg,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-{ggH,VBF,WH,ZH}.in) \
$(shell echo Rivet/LHC{,-Powheg,-Matchbox,-Matchbox-Powheg,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-8-{{ggH,VBF,WH,ZH}{,-GammaGamma},ggH-WW}.in) \
$(shell echo Rivet/LHC{,-Matchbox,-Matchbox-Powheg,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-ggHJet.in) \
$(shell echo Rivet/ISR{,-Dipole}-{{30,44,53,62}-UE,{44,62}-Z-mu}.in Rivet/EHS{,-Dipole}-UE.in) \
$(shell echo Rivet/SPS{,-Dipole}-{17.4-UE,200-Z-mu}.in ) \
$(shell echo Rivet/Fermilab{,-Dipole}-{27.4,38.8}-Z-mu.in ) \
$(shell echo Rivet/EE-Gamma-Direct-mumu-{161,172,183,189,196,206}.in ) \
$(shell echo Rivet/EE-Gamma-Direct-tautau-{189,196,206}.in ) \
$(shell echo Rivet/EE-Gamma-{pi0,Eta,EtaPrime}-10.58.in ) \
$(shell echo Rivet/EE-Gamma-{Eta-{1,29},EtaPrime-{34.3,91.2}}.in ) \
$(shell echo Rivet/EE-Gamma-{Direct,Single-Resolved,Double-Resolved}-Jets-{198,206}.in )
#$(shell echo Rivet/LHC{,-Dipole}-{7,13}{,-UE}-Cent.in )
Analyses/RivetHerwig.so: Analyses/*.cc
rivet-build Analyses/RivetHerwig.so Analyses/*.cc
Rivet-GammaGamma: Rivet-GammaGamma/done
touch $@
Rivet-GammaGamma/done: $(shell echo Rivet-GammaGamma-mumu-{3.5,4.5,5.5,6.5,7.5,9.0,12.5,17.5,30.0}.yoda )
rm -rf Rivet-GammaGamma
python/merge-GammaGamma GammaGamma
rivet-mkhtml -o Rivet-GammaGamma GammaGamma.yoda:Hw
touch $@
Rivet-EE-Gamma: Rivet-EE-Gamma/done
touch $@
Rivet-EE-Gamma/done: $(shell echo Rivet-EE-Gamma-Direct-mumu-{161,172,183,189,196,206}.yoda ) \
$(shell echo Rivet-EE-Gamma-Direct-tautau-{189,196,206}.yoda ) \
$(shell echo Rivet-EE-Gamma-{pi0,Eta,EtaPrime}-10.58.yoda ) \
$(shell echo Rivet-EE-Gamma-{Eta-{1,29},EtaPrime-{34.3,91.2}}.yoda ) \
$(shell echo Rivet-EE-Gamma-{Direct,Single-Resolved,Double-Resolved}-Jets-{198,206}.yoda )
rm -rf Rivet-EE-Gamma
python/merge-EE-Gamma EE-Gamma
export RIVET_ANALYSIS_PATH=`pwd`/Analyses; rivet-mkhtml -o Rivet-EE-Gamma EE-Gamma.yoda:Hw
touch $@
Rivet-EE : Rivet-EE/done
touch $@
Rivet-EE/done : $(shell echo Rivet{,-Powheg}-EE-{7.7,9.4,12,13,14,14.8,17,27.6,27.7,29,30.2,30.3,30.5,30.7,30.8,30,31.2,31.3,31.6,34,34.8,43.5,43.6,45,50,52,53.3,55,55.3,56,57,58,59.5,60.8,60,61.4,65.4,66,75.7,76,10,12.8,21.5,22,22.5,25,26.8,34.5,35,36.2,41,41.5,42.1,42.6,44,48.0,82,85,91,93.0,130,130.1,133,136,136.1,161,161.3,172,172.3,177,182.8,183,188.6,189,192,194.4,196,197,200,200.2,202,205,206,206.2,207,91-nopi}.yoda) \
$(shell echo Rivet-EE-{183,189}-WW.yoda) \
$(shell echo Rivet-EE-{10.5,11.96,12.8,13.96,16.86,21.84,26.8,28.48,35.44,48.0,97.0}-gg.yoda) \
$(shell echo Rivet-EE-{10.52,10.52-sym,10.6,2.2,2.6,3.0,3.2,4.6,4.8,5.8,6.2,6.5,6.6,7.0,7.4,3.63,4.03,4.17,4.3,4.41,5.0,5.2,4.5,8.8,9.27,9.46,9.51,10.54,10.58,10.45,10.47,Upsilon,Upsilon2,Upsilon3,Upsilon4,Upsilon5,Upsilon4-asym,Tau,Phi,Lambdac,Omega-Meson,Omega-Baryon,Eta,Xi0,Xic0,Xicp,Omegac0,Ds,Bc,Etac,Xim,JPsi,Psi2S,Psi2S-All,Psi3770}.yoda)
rm -rf Rivet-EE
python/merge-EE --with-gg --with-decay --with-WW EE
python/merge-EE Powheg-EE
rivet-mkhtml -o Rivet-EE EE.yoda:Hw Powheg-EE.yoda:Hw-Powheg
python/plot-EE Rivet-EE
touch $@
+Onium-Sigma: Analyses/RivetHerwig.so
+ OUTPUT=`python/OniumSigma.py --generate-input-files | grep -v CT14 | grep -v LHAPDF | grep -v Eur.Phys`; $(MAKE) $$OUTPUT NUMEVENTS=$${NUMEVENTS:-10000};
+ export RIVET_ANALYSIS_PATH=`pwd`/Analyses; python/OniumSigma.py --fast --analyse
+
Rivet-LowEnergy-%.yoda:
export RIVET_ANALYSIS_PATH=`pwd`/Analyses; $(HWBUILD) -c .cache/$(subst .yoda,,$@) Rivet/$(subst .yoda,.in,$@)
export RIVET_ANALYSIS_PATH=`pwd`/Analyses; $(HWRUN) $(subst .yoda,.run,$@)
Rivet-LowEnergy-EE-%:
args="--process "$(word 1,$(subst -, ,$(subst Rivet-LowEnergy-EE-,,$@))); if [ -n "$(strip $(word 2,$(subst -, ,$(subst Rivet-LowEnergy-EE-,,$@))))" ]; then args+=" --flavour "$(word 2,$(subst -, ,$(subst Rivet-LowEnergy-EE-,,$@))); fi; OUTPUT=`python/LowEnergy-EE.py $$args --non-perturbative --perturbative`; $(MAKE) $$OUTPUT NUMEVENTS=$${NUMEVENTS:-10000};
args="--process "$(word 1,$(subst -, ,$(subst Rivet-LowEnergy-EE-,,$@))); plots=`python/LowEnergy-EE.py $$args --plots`; python/mergeLowEnergy.py $(subst Rivet-LowEnergy-,,$@) $$plots; if [ -e LowEnergy-NonPerturbative-EE-$(subst Rivet-LowEnergy-EE-,,$@).yoda ] && [ -e LowEnergy-Perturbative-EE-$(subst Rivet-LowEnergy-EE-,,$@).yoda ]; then rivet-mkhtml -o Rivet-LowEnergy-EE-$(subst Rivet-LowEnergy-EE-,,$@) LowEnergy-NonPerturbative-EE-$(subst Rivet-LowEnergy-EE-,,$@).yoda:"Non-Pert" LowEnergy-Perturbative-EE-$(subst Rivet-LowEnergy-EE-,,$@).yoda:"Pert" $$plots; elif [ -e LowEnergy-NonPerturbative-EE-$(subst Rivet-LowEnergy-EE-,,$@).yoda ]; then rivet-mkhtml -o Rivet-LowEnergy-EE-$(subst Rivet-LowEnergy-EE-,,$@) LowEnergy-NonPerturbative-EE-$(subst Rivet-LowEnergy-EE-,,$@).yoda:"Non-Pert" $$plots; elif [ -e LowEnergy-Perturbative-EE-$(subst Rivet-LowEnergy-EE-,,$@).yoda ]; then rivet-mkhtml -o Rivet-LowEnergy-EE-$(subst Rivet-LowEnergy-EE-,,$@) LowEnergy-Perturbative-EE-$(subst Rivet-LowEnergy-EE-,,$@).yoda:"Pert" $$plots; fi
Rivet-LowEnergy-Photon-%:
args="--process "$(word 1,$(subst -, ,$(subst Rivet-LowEnergy-Photon-,,$@))); if [ -n "$(strip $(word 2,$(subst -, ,$(subst Rivet-LowEnergy-Photon-,,$@))))" ]; then args+=" --flavour "$(word 2,$(subst -, ,$(subst Rivet-LowEnergy-Photon-,,$@))); fi; OUTPUT=`python/LowEnergy-Photon.py $$args --non-perturbative --perturbative --resonance`; $(MAKE) $$OUTPUT NUMEVENTS=$${NUMEVENTS:-10000};
args="--process "$(word 1,$(subst -, ,$(subst Rivet-LowEnergy-Photon-,,$@))); plots=`python/LowEnergy-Photon.py $$args --plots`; yodaArgs=`python/mergeLowEnergy.py $(subst Rivet-LowEnergy-Photon-,GammaGamma-,$@) $$plots`; rivet-mkhtml -o Rivet-LowEnergy-Photon-$(subst Rivet-LowEnergy-Photon-,,$@) $$yodaArgs $$plots;
Rivet-R:
OUTPUT=`python/R.py --perturbative --non-perturbative`; $(MAKE) $$OUTPUT NUMEVENTS=$${NUMEVENTS:-10000};
plots=`python/R.py --perturbative --non-perturbative --plots`; python/mergeLowEnergy.py R $$plots; rivet-mkhtml -o Rivet-R LowEnergy-Perturbative-R.yoda:"Pert" LowEnergy-NonPerturbative-R.yoda:"Non-Pert" $$plots
Rivet-DIS : Rivet-DIS/done
touch $@
Rivet-DIS/done: $(shell echo Rivet{-DIS,-NoME-DIS,-Powheg-DIS}-{225,251,300,318,318-CMS}-e+-{VeryLow,Low,Med,High}Q2.yoda) \
$(shell echo Rivet{-DIS,-NoME-DIS,-Powheg-DIS}-{296,300,318}-e--{VeryLow,Low,Med,High}Q2.yoda) \
$(shell echo Rivet{-DIS,-NoME-DIS,-Powheg-DIS}-318-{e+,e-}-CC-{VeryLow,Low,Med,High}Q2.yoda)
rm -rf Rivet-DIS
python/merge-DIS DIS
python/merge-DIS Powheg-DIS
python/merge-DIS NoME-DIS
rivet-mkhtml -o Rivet-DIS DIS.yoda:Hw Powheg-DIS.yoda:Hw-Powheg NoME-DIS.yoda:Hw-NoME
touch $@
Rivet-TVT-EW : Rivet-TVT-EW/done
touch $@
Rivet-TVT-EW/done: $(shell echo Rivet{,-Powheg}-TVT-{Run-I-Z,Run-I-W,Run-I-WZ,Run-II-Z-{e,{,LowMass-,HighMass-}mu},Run-II-W}.yoda)
rm -rf Rivet-TVT-EW
python/merge-TVT-EW TVT
python/merge-TVT-EW Powheg-TVT
rivet-mkhtml -o Rivet-TVT-EW TVT-EW.yoda:Hw Powheg-TVT-EW.yoda:Hw-Powheg
touch $@
Rivet-TVT-Photon : Rivet-TVT-Photon/done
touch $@
Rivet-TVT-Photon/done: $(shell echo Rivet{,-Powheg}-TVT-Run-II-{DiPhoton-GammaGamma,DiPhoton-GammaJet}.yoda Rivet-TVT-Run-II-PromptPhoton.yoda)
rm -rf Rivet-TVT-Photon
python/merge-TVT-Photon TVT
python/merge-TVT-Photon Powheg-TVT
rivet-mkhtml -o Rivet-TVT-Photon TVT-Photon.yoda:Hw Powheg-TVT-Photon.yoda:Hw-Powheg
touch $@
Rivet-TVT-Jets : Rivet-TVT-Jets/done
touch $@
Rivet-TVT-Jets/done: $(shell echo Rivet-TVT-Run-{I,II}-{Jets-{1..6},DiJets-{1..4}}.yoda ) \
$(shell echo Rivet-TVT-{630-Jets-{1..3},300-Jets-1,900-Jets-1}.yoda ) \
$(shell echo Rivet-TVT-{Run-I,Run-II,300,630,900}-UE.yoda)
rm -rf Rivet-TVT-Jets
python/merge-TVT-Jets TVT
rivet-mkhtml -o Rivet-TVT-Jets TVT-Jets.yoda:Hw
touch $@
Rivet-Fixed : Rivet-Fixed/done
touch $@
Rivet-Fixed/done : $(shell echo Rivet-SppS-{53,63,200,500,546,900}-UE.yoda ) \
$(shell echo Rivet-ISR-{{30,44,53,62}-UE,{44,62}-Z-mu}.yoda ) Rivet-EHS-UE.yoda \
$(shell echo Rivet-Star-{UE,Jets-{1..4}}.yoda ) \
$(shell echo Rivet-SPS-{17.4-UE,200-Z-mu}.yoda ) \
$(shell echo Rivet-Fermilab-{27.4,38.8}-Z-mu.yoda )
rm -rf Rivet-Fixed
python/merge-Fixed Fixed
rivet-mkhtml -o Rivet-Fixed Fixed.yoda:Hw
touch $@
Rivet-LHC-Jets : Rivet-LHC-Jets/done
touch $@
Rivet-LHC-Jets/done : \
$(shell echo Rivet-LHC-7-DiJets-{1..7}-{A,B,C}.yoda ) \
$(shell echo Rivet-LHC-13-DiJets-{{1..11}-A,{6..11}-B}.yoda ) \
$(shell echo Rivet-LHC-{7,8,13}-Jets-{0..10}.yoda ) \
$(shell echo Rivet-LHC-2760-Jets-{1..3}.yoda ) \
$(shell echo Rivet-LHC-{900,2360,2760,7,8,13}-UE.yoda ) \
$(shell echo Rivet-LHC-{900,7,13}-UE-Long.yoda ) \
$(shell echo Rivet-LHC-7-Charm-{0..5}.yoda ) \
$(shell echo Rivet-LHC-{5,13}-Charm-0.yoda ) \
$(shell echo Rivet-LHC-7-Bottom-{0..9}.yoda ) \
$(shell echo Rivet-LHC-13-Bottom-{0..6}.yoda ) \
$(shell echo Rivet-LHC-{7,8,13}-Top-{L,SL}.yoda ) \
$(shell echo Rivet-LHC-{8,13}-Top-All.yoda )
# $(shell echo Rivet-LHC-{7,13}-UE-Cent.yoda )
rm -rf Rivet-LHC-Jets
python/merge-LHC-Jets LHC
rivet-mkhtml -o Rivet-LHC-Jets LHC-Jets.yoda:Hw
touch $@
Rivet-LHC-EW : Rivet-LHC-EW/done
touch $@
Rivet-LHC-EW/done: \
$(shell echo Rivet{,-Powheg}-LHC-{{,8-}W-{e,mu},13-W-mu,{,8-,13-}Z-{e,mu}-Mass{1..5},13-Z-nu,Z-mu-SOPHTY,WZ,WW-{emu,ll},13-WW-ll,ZZ-{ll,lv},{8,13}-WZ,13-ZZ-ll,8-ZZ-lv,8-WW-ll,Z-mu-Short}.yoda) \
$(shell echo Rivet-LHC-{7-W-Jet-{1..3}-e,7-Z-Jet-{0..3}-e,7-Z-Jet-0-mu}.yoda) \
$(shell echo Rivet-LHC-7-{W,Z}Gamma-{e,mu}.yoda) \
$(shell echo Rivet-LHC-8-ZGamma-{e,mu}.yoda)
rm -rf Rivet-LHC-EW;
python/merge-LHC-EW LHC
python/merge-LHC-EW Powheg-LHC
rivet-mkhtml -o Rivet-LHC-EW LHC-EW.yoda:Hw Powheg-LHC-EW.yoda:Hw-Powheg \
Rivet-LHC-Z-mu-SOPHTY.yoda:Hw Rivet-Powheg-LHC-Z-mu-SOPHTY.yoda:Hw-Powheg
touch $@
Rivet-LHC-Photon : Rivet-LHC-Photon/done
touch $@
Rivet-LHC-Photon/done: \
$(shell echo Rivet-LHC-{7,8,13}-PromptPhoton-{1..5}.yoda) \
Rivet-LHC-GammaGamma-7.yoda \
$(shell echo Rivet{,-Powheg}-LHC-{7,8,13}-{DiPhoton-GammaGamma,DiPhoton-GammaJet}.yoda)
rm -rf Rivet-LHC-Photon
python/merge-LHC-Photon LHC
python/merge-LHC-Photon Powheg-LHC
rivet-mkhtml -o Rivet-LHC-Photon LHC-Photon.yoda:Hw Powheg-LHC-Photon.yoda:Hw-Powheg
touch $@
Rivet-LHC-Higgs : Rivet-LHC-Higgs/done
touch $@
Rivet-LHC-Higgs/done: \
$(shell echo Rivet{,-Powheg}-LHC-{ggH,VBF,WH,ZH}.yoda) \
$(shell echo Rivet{,-Powheg}-LHC-8-{{ggH,VBF,WH,ZH}{,-GammaGamma},ggH-WW}.yoda) \
Rivet-LHC-ggHJet.yoda
rivet-merge Rivet-Powheg-LHC-8-{ggH{-GammaGamma,-WW,},{VBF,ZH,WH}{,-GammaGamma}}.yoda -o Powheg-LHC-Higgs.yoda
rivet-merge Rivet-LHC-8-{ggH{-GammaGamma,-WW,},{VBF,ZH,WH}{,-GammaGamma}}.yoda -o LHC-Higgs.yoda
rm -rf Rivet-LHC-Higgs
rivet-mkhtml -o Rivet-LHC-Higgs Powheg-LHC-Higgs.yoda:Hw-Powheg LHC-Higgs.yoda:Hw\
Rivet-Powheg-LHC-ggH.yoda:gg-Powheg Rivet-LHC-ggH.yoda:gg Rivet-LHC-ggHJet.yoda:HJet \
Rivet-Powheg-LHC-VBF.yoda:VBF-Powheg Rivet-LHC-VBF.yoda:VBF Rivet-LHC-WH.yoda:WH Rivet-LHC-ZH.yoda:ZH \
Rivet-Powheg-LHC-WH.yoda:WH-Powheg Rivet-Powheg-LHC-ZH.yoda:ZH-Powheg
touch $@
clean-local:
rm -f *.out *.log *.tex *.top *.run *.dump *.mult *.Bmult *.yoda Rivet/*.in anatohepmc.txt hepmctoana.txt
rm -rf Rivet-*
rm -rf Onium-Splitting
rm -rf Analyses/*.so
distclean-local:
rm -rf .cache
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -1,271 +1,272 @@
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ([2.63])
AC_INIT([Herwig],[devel],[herwig@projects.hepforge.org],[Herwig])
AC_CONFIG_SRCDIR([Utilities/HerwigStrategy.cc])
AC_CONFIG_AUX_DIR([Config])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([Config/config.h])
dnl AC_PRESERVE_HELP_ORDER
AC_CANONICAL_HOST
dnl === disable debug symbols by default =====
if test "x$CXXFLAGS" = "x"; then
CXXFLAGS="-O2 -DBOOST_UBLAS_NDEBUG -Wno-deprecated-declarations -Wno-deprecated-copy"
fi
if test "x$CFLAGS" = "x"; then
CFLAGS=-O2
fi
AC_LANG([C++])
AM_INIT_AUTOMAKE([1.11 subdir-objects gnu dist-bzip2 no-dist-gzip -Wall -Wno-portability])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
dnl Checks for C++ compiler. Handle C++11 flags.
AC_PROG_CXX
AX_CXX_COMPILE_STDCXX([11],[noext],[mandatory])
dnl check for POSIX
AC_CHECK_HEADER([unistd.h],[],
[AC_MSG_ERROR([Herwig needs "unistd.h". Non-POSIX systems are not supported.])])
AC_CHECK_HEADER([sys/stat.h],[],
[AC_MSG_ERROR([Herwig needs "sys/stat.h". Non-POSIX systems are not supported.])])
dnl Checks for programs.
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_PROG_LN_S
dnl modified search order
AC_PROG_FC([gfortran g95 g77])
dnl xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn xlf90 f90 pgf90 pghpf epcf90 xlf f77 frt pgf77 cf77 fort77 fl32 af77])
AC_LANG_PUSH([Fortran])
AC_MSG_CHECKING([if the Fortran compiler ($FC) works])
AC_COMPILE_IFELSE(
AC_LANG_PROGRAM([],[ print *[,]"Hello"]),
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
AC_MSG_ERROR([A Fortran compiler is required to build Herwig.])
]
)
AC_LANG_POP([Fortran])
AC_FC_WRAPPERS
LT_PREREQ([2.2.6])
LT_INIT([disable-static dlopen pic-only])
dnl ####################################
dnl ####################################
dnl for Doc/fixinterfaces.pl
AC_PATH_PROG(PERL, perl)
dnl for Models/Feynrules
AM_PATH_PYTHON([2.6],, [:])
AM_CONDITIONAL([HAVE_PYTHON], [test "x$PYTHON" != "x:"])
HERWIG_CHECK_GSL
HERWIG_CHECK_THEPEG
BOOST_REQUIRE([1.41])
BOOST_FIND_HEADER([boost/numeric/ublas/io.hpp])
dnl Boost 1.64 is missing a required header to make these work
dnl we just assume they're there if io.hpp has been found OK above
dnl BOOST_FIND_HEADER([boost/numeric/ublas/matrix.hpp])
dnl BOOST_FIND_HEADER([boost/numeric/ublas/matrix_proxy.hpp])
dnl BOOST_FIND_HEADER([boost/numeric/ublas/matrix_sparse.hpp])
dnl BOOST_FIND_HEADER([boost/numeric/ublas/symmetric.hpp])
dnl BOOST_FIND_HEADER([boost/numeric/ublas/vector.hpp])
BOOST_FIND_HEADER([boost/operators.hpp])
BOOST_TEST()
HERWIG_CHECK_VBFNLO
HERWIG_CHECK_NJET
HERWIG_CHECK_GOSAM
HERWIG_CHECK_GOSAM_CONTRIB
HERWIG_CHECK_OPENLOOPS
HERWIG_CHECK_MADGRAPH
HERWIG_CHECK_EVTGEN
HERWIG_CHECK_PYTHIA
HERWIG_COMPILERFLAGS
HERWIG_LOOPTOOLS
FASTJET_CHECK_FASTJET
HERWIG_ENABLE_MODELS
SHARED_FLAG=-shared
AM_CONDITIONAL(NEED_APPLE_FIXES,
[test "xx${host/darwin/foundit}xx" != "xx${host}xx"])
if test "xx${host/darwin/foundit}xx" != "xx${host}xx"; then
APPLE_DSO_FLAGS=-Wl,-undefined,dynamic_lookup
SHARED_FLAG=-bundle
fi
AC_SUBST([APPLE_DSO_FLAGS])
AC_SUBST([SHARED_FLAG])
AC_SUBST([PYTHON])
AC_CONFIG_FILES([UnderlyingEvent/Makefile
Models/Makefile
Models/StandardModel/Makefile
Models/RSModel/Makefile
Models/General/Makefile
Models/Susy/Makefile
Models/Susy/NMSSM/Makefile
Models/Susy/RPV/Makefile
Models/UED/Makefile
Models/LH/Makefile
Models/DarkMatter/Makefile
Models/LHTP/Makefile
Models/Transplanckian/Makefile
Models/Leptoquarks/Makefile
Models/Zprime/Makefile
Models/TTbAsymm/Makefile
Models/Feynrules/Makefile
Models/Feynrules/python/Makefile-FR
Models/ADD/Makefile
Models/Sextet/Makefile
Decay/Makefile
Decay/FormFactors/Makefile
Decay/Tau/Makefile
Decay/Baryon/Makefile
Decay/VectorMeson/Makefile
Decay/Perturbative/Makefile
Decay/HeavyMeson/Makefile
Decay/ScalarMeson/Makefile
Decay/Dalitz/Makefile
Decay/TensorMeson/Makefile
Decay/WeakCurrents/Makefile
Decay/Partonic/Makefile
Decay/General/Makefile
Decay/Radiation/Makefile
Decay/EvtGen/Makefile
Doc/refman.conf
Doc/refman.h
PDT/Makefile
PDF/Makefile
MatrixElement/Makefile
MatrixElement/General/Makefile
MatrixElement/Lepton/Makefile
MatrixElement/Hadron/Makefile
MatrixElement/DIS/Makefile
MatrixElement/Powheg/Makefile
MatrixElement/Gamma/Makefile
MatrixElement/Reweighters/Makefile
+ MatrixElement/Onium/Makefile
MatrixElement/Matchbox/Makefile
MatrixElement/Matchbox/Base/Makefile
MatrixElement/Matchbox/Utility/Makefile
MatrixElement/Matchbox/Phasespace/Makefile
MatrixElement/Matchbox/Dipoles/Makefile
MatrixElement/Matchbox/InsertionOperators/Makefile
MatrixElement/Matchbox/Matching/Makefile
MatrixElement/Matchbox/Cuts/Makefile
MatrixElement/Matchbox/Scales/Makefile
MatrixElement/Matchbox/ColorFull/Makefile
MatrixElement/Matchbox/CVolver/Makefile
MatrixElement/Matchbox/Builtin/Makefile
MatrixElement/Matchbox/Builtin/Amplitudes/Makefile
MatrixElement/Matchbox/Tests/Makefile
MatrixElement/Matchbox/External/Makefile
MatrixElement/Matchbox/External/BLHAGeneric/Makefile
MatrixElement/Matchbox/External/VBFNLO/Makefile
MatrixElement/Matchbox/External/NJet/Makefile
MatrixElement/Matchbox/External/GoSam/Makefile
MatrixElement/Matchbox/External/OpenLoops/Makefile
MatrixElement/Matchbox/External/MadGraph/Makefile
MatrixElement/Matchbox/External/MadGraph/mg2herwig
MatrixElement/Matchbox/External/GoSam/gosam2herwig
MatrixElement/FxFx/Makefile
Sampling/Makefile
Sampling/CellGrids/Makefile
Shower/Makefile
Shower/QTilde/Makefile
Shower/QTilde/Matching/Makefile
Shower/Dipole/Makefile
Shower/Dipole/Base/Makefile
Shower/Dipole/Kernels/Makefile
Shower/Dipole/Kinematics/Makefile
Shower/Dipole/Utility/Makefile
Shower/Dipole/AlphaS/Makefile
Shower/Dipole/SpinCorrelations/Makefile
Utilities/Makefile
Utilities/XML/Makefile
Utilities/Statistics/Makefile
Hadronization/Makefile
lib/Makefile
include/Makefile
src/Makefile
src/defaults/Makefile
src/snippets/Makefile
src/Matchbox/Makefile
src/herwig-config
Doc/Makefile
Doc/HerwigDefaults.in
Looptools/Makefile
Analysis/Makefile
API/Makefile
src/Makefile-UserModules
src/defaults/Analysis.in
src/defaults/MatchboxDefaults.in
src/defaults/Decays.in
src/defaults/decayers.in
src/defaults/setup.gosam.in
src/Matchbox/LO-DefaultShower.in
src/Matchbox/LO-DipoleShower.in
src/Matchbox/MCatLO-DefaultShower.in
src/Matchbox/MCatLO-DipoleShower.in
src/Matchbox/LO-NoShower.in
src/Matchbox/MCatNLO-DefaultShower.in
src/Matchbox/MCatNLO-DipoleShower.in
src/Matchbox/NLO-NoShower.in
src/Matchbox/Powheg-DefaultShower.in
src/Matchbox/Powheg-DipoleShower.in
src/Merging/Makefile
Shower/Dipole/Merging/Makefile
src/defaults/MatchboxMergingDefaults.in
Contrib/Makefile
Contrib/make_makefiles.sh
Tests/Makefile
Makefile])
AC_CONFIG_FILES([Tests/python/rivet_check ],[chmod +x Tests/python/rivet_check ])
AC_CONFIG_FILES([Tests/python/LowEnergy-EE.py ],[chmod +x Tests/python/LowEnergy-EE.py ])
AC_CONFIG_FILES([Tests/python/LowEnergy-Photon.py],[chmod +x Tests/python/LowEnergy-Photon.py])
AC_CONFIG_FILES([Tests/python/make_input_files.py],[chmod +x Tests/python/make_input_files.py])
AC_CONFIG_FILES([Tests/python/merge-DIS ],[chmod +x Tests/python/merge-DIS ])
AC_CONFIG_FILES([Tests/python/merge-EE ],[chmod +x Tests/python/merge-EE ])
AC_CONFIG_FILES([Tests/python/merge-EE-Gamma ],[chmod +x Tests/python/merge-EE-Gamma ])
AC_CONFIG_FILES([Tests/python/merge-Fixed ],[chmod +x Tests/python/merge-Fixed ])
AC_CONFIG_FILES([Tests/python/merge-GammaGamma ],[chmod +x Tests/python/merge-GammaGamma ])
AC_CONFIG_FILES([Tests/python/merge-LHC-EW ],[chmod +x Tests/python/merge-LHC-EW ])
AC_CONFIG_FILES([Tests/python/merge-LHC-Jets ],[chmod +x Tests/python/merge-LHC-Jets ])
AC_CONFIG_FILES([Tests/python/merge-LHC-Photon ],[chmod +x Tests/python/merge-LHC-Photon ])
AC_CONFIG_FILES([Tests/python/mergeLowEnergy.py ],[chmod +x Tests/python/mergeLowEnergy.py ])
AC_CONFIG_FILES([Tests/python/merge-Star ],[chmod +x Tests/python/merge-Star ])
AC_CONFIG_FILES([Tests/python/merge-SppS ],[chmod +x Tests/python/merge-SppS ])
AC_CONFIG_FILES([Tests/python/merge-TVT-EW ],[chmod +x Tests/python/merge-TVT-EW ])
AC_CONFIG_FILES([Tests/python/merge-TVT-Jets ],[chmod +x Tests/python/merge-TVT-Jets ])
AC_CONFIG_FILES([Tests/python/merge-TVT-Photon ],[chmod +x Tests/python/merge-TVT-Photon ])
AC_CONFIG_FILES([Tests/python/plot-EE ],[chmod +x Tests/python/plot-EE ])
AC_CONFIG_FILES([Tests/python/R.py ],[chmod +x Tests/python/R.py ])
AC_CONFIG_FILES([Sampling/herwig-mergegrids ],[chmod +x Sampling/herwig-mergegrids ])
AC_CONFIG_LINKS([Doc/BSMlibs.in:Doc/BSMlibs.in])
AC_CONFIG_FILES([Doc/fixinterfaces.pl],[chmod +x Doc/fixinterfaces.pl])
AC_CONFIG_HEADERS([PDF/SaSPhotonPDF.cc])
HERWIG_OVERVIEW
AC_CONFIG_COMMANDS([summary],[cat config.herwig])
AC_OUTPUT
diff --git a/src/defaults/HerwigDefaults.in b/src/defaults/HerwigDefaults.in
--- a/src/defaults/HerwigDefaults.in
+++ b/src/defaults/HerwigDefaults.in
@@ -1,175 +1,176 @@
# -*- ThePEG-repository -*-
###################################################################
#
# This is the main repository setup file for Herwig.
#
# It is read using the 'Herwig init' command which prepares the
# default repository file 'HerwigDefaults.rpo'.
#
# The 'Herwig read' step allows additional configuration
# instructions to be read from a run-specific file, to modify the
# default values. (We provide LEP.in, ILC.in, LHC.in and TVT.in as
# examples)
#
# You will not need to change any settings here.
# Any modifications can be made in your own input files.
#
###################################################################
globallibrary Herwig.so
###################################################################
# The repository contains its own internal directory structure to
# keep track of created objects. (This is entirely independent of
# the file system)
###################################################################
globallibrary Herwig.so
# Make the root directory in the Repository
rrmdir /Herwig
mkdir /Herwig
#####################################################################
# The 'create' command creates an object in the repository from
# a C++ class. The arguments are (1) the C++ class name, (2) your
# chosen repository name, and optionally, (3) the library name where
# the class can be found.
#
# Created objects are _not_ automatically associated to a run. They
# need to be assigned to it using a chain of 'set' or 'insert'
# commands (see below).
#####################################################################
# the default random number generator
create ThePEG::StandardRandom /Herwig/Random
# the default phase space sampler
create ThePEG::ACDCSampler /Herwig/ACDCSampler ACDCSampler.so
#####################################################################
# Objects in the repository are influenced through 'interfaces'.
# The most important ones can be found in these files, and the
# doxygen documentation provides complete lists.
#
# To set an interface to a new value, use the 'set' command:
# set object:interface value
#
# Note that only repository names can be used here. You must 'create'
# objects before you can use them in a 'set' command
#####################################################################
newdef /Herwig/ACDCSampler:Margin 1.1
###################################################################
# The 'read' command includes external files in place, to reduce
# clutter. You can also use it for blocks of settings you're likely
# to use again and again.
###################################################################
read Particles.in
read QEDRadiation.in
read Model.in
read Partons.in
+read Onium.in
read UnderlyingEvent.in
read Shower.in
read MatrixElements.in
read Hadronization.in
read Decays.in
read BSM.in
#######################################################################
# The EventHandler is the most important object in a run. It
# (directly or indirectly) owns most of the objects that have been
# created up to now.
#
# Below we create one handler for LEP and one for LHC.
#
# Try to understand the following few lines (also look at the external
# .in files if you can't find the 'create' line for an object).
#
# If you need to make modifications, it's best to make them in your
# own input file (for the 'Herwig read' step) and not here.
#######################################################################
mkdir /Herwig/EventHandlers
cd /Herwig/EventHandlers
# Create the EventHandler
create ThePEG::StandardEventHandler EventHandler
newdef EventHandler:CascadeHandler /Herwig/Shower/ShowerHandler
newdef EventHandler:HadronizationHandler /Herwig/Hadronization/ClusterHadHandler
newdef EventHandler:DecayHandler /Herwig/Decays/DecayHandler
newdef EventHandler:Sampler /Herwig/ACDCSampler
insert EventHandler:SubProcessHandlers[0] /Herwig/MatrixElements/SubProcess
insert EventHandler:PostHadronizationHandlers 0 /Herwig/Hadronization/SpinHadronizer
mkdir /Herwig/Generators
cd /Herwig/Generators
#################################################################
# Finally, the EventGenerator objects are responsible
# for the run. They tie together an EventHandler on the one side
# with a physics model (Feynman rules, etc) and random number
# generator on the other.
#
# In your own input files, it will be this EventGenerator object
# that will be called with the 'run' command to start the event
# generation (see LEP.in, LHC.in, TVT.in or LHC.in for examples)
#################################################################
# The Strategy objects can be used for default settings
# (see the Doxygen documentation)
# Currently it only provides the LaTeX reference to Herwig
create Herwig::HerwigStrategy DefaultStrategy
# set DefaultStrategy:LocalParticlesDir /Herwig/Particles
insert DefaultStrategy:DefaultParticlesDirs[0] /Herwig/Particles
# The EventGenerator
create ThePEG::EventGenerator EventGenerator
newdef EventGenerator:RandomNumberGenerator /Herwig/Random
newdef EventGenerator:StandardModelParameters /Herwig/Model
newdef EventGenerator:EventHandler /Herwig/EventHandlers/EventHandler
newdef EventGenerator:Strategy DefaultStrategy
newdef EventGenerator:DumpPeriod -1
newdef EventGenerator:RandomNumberGenerator:Seed 31122001
newdef EventGenerator:DebugLevel 1
newdef EventGenerator:PrintEvent 10
newdef EventGenerator:MaxErrors 10000
newdef EventGenerator:NumberOfEvents 100000000
############################################
# The default cuts
############################################
read Cuts.in
cd /Herwig/Generators
##########################################
# include some default analysis handlers
##########################################
read Analysis.in
##########################################
# setup additional samplers
##########################################
read Samplers.in
##########################################
# setup the matchbox framework
##########################################
read MatchboxDefaults.in
##########################################
# setup the merging framework
##########################################
read MatchboxMergingDefaults.in
##########################################
# setup the dipole shower
##########################################
read DipoleShowerDefaults.in
cd /
diff --git a/src/defaults/Makefile.am b/src/defaults/Makefile.am
--- a/src/defaults/Makefile.am
+++ b/src/defaults/Makefile.am
@@ -1,47 +1,47 @@
BUILT_SOURCES = done-all-links
defaultsdir = ${pkgdatadir}/defaults
INPUTFILES = Analysis.in \
baryon_decays.in baryons.in boson_decays.in \
bosons.in Cuts.in decayers.in \
Decays.in DiffractiveParticles.in diquarks.in \
Hadronization.in HerwigDefaults.in \
lepton_decays.in leptons.in \
masses.in MatrixElements.in meson_decays.in mesons.in Model.in BSM.in \
-Particles.in QEDRadiation.in quark_decays.in quarks.in \
+Particles.in Onium.in QEDRadiation.in quark_decays.in quarks.in \
setup.gosam.in Shower.in StandardModelVertices.in UnderlyingEvent.in widths.in Partons.in \
MatchboxDefaults.in DipoleShowerDefaults.in MatchboxLoopInduced.in Samplers.in \
EvtGenDecayer.in EvtGenBDecays.in HerwigBDecays.in MatchboxMergingDefaults.in
dist_defaults_DATA = $(INPUTFILES)
EXTRA_DIST = PDF.in.in
defaults_DATA = PDF.in
CLEANFILES = PDF.in done-all-links
## For an explanation of this magic, see autoconf book 4.7.2
edit = sed -e "s,@HERWIG_PDF_POMERON\@,`cd $(top_srcdir) && pwd`/PDF/diffraction/,"
## may still be broken and need $(DESTDIR)
installnamePOMERON = $(pkgdatadir)/PDF/diffraction/
install-data-hook:
rm -f $(DESTDIR)$(defaultsdir)/PDF.in
sed -e 's,@HERWIG_PDF_POMERON\@,$(installnamePOMERON),' \
$(srcdir)/PDF.in.in > $(DESTDIR)$(defaultsdir)/PDF.in
PDF.in: Makefile $(srcdir)/PDF.in.in
@echo "Updating PDF.in"
@rm -f PDF.in PDF.in.tmp
@$(edit) $(srcdir)/PDF.in.in > PDF.in.tmp
@mv PDF.in.tmp PDF.in
done-all-links: $(INPUTFILES)
@echo "Linking input files"
@for i in $(INPUTFILES); do \
if test -f $(srcdir)/$$i -a ! -e $$i; then \
$(LN_S) -f $(srcdir)/$$i; fi; done
@touch done-all-links
diff --git a/src/defaults/MatrixElements.in b/src/defaults/MatrixElements.in
--- a/src/defaults/MatrixElements.in
+++ b/src/defaults/MatrixElements.in
@@ -1,354 +1,608 @@
# -*- ThePEG-repository -*-
##############################################################################
# Setup of default matrix elements.
#
# Only one ME is activated by default, but this file lists
# some alternatives. All available MEs can be found in the
# 'include/Herwig/MatrixElements' subdirectory of your Herwig
# installation.
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Instead of editing this file directly, you should reset
# the matrix elements in your own input files:
#
# - create your custom SubProcessHandler
# - insert the MEs you need
# - set your SubProcessHandler instead of the default (see HerwigDefaults.in)
##############################################################################
mkdir /Herwig/MatrixElements
cd /Herwig/MatrixElements
library HwMELepton.so
library HwMEHadron.so
library HwMEDIS.so
############################################################
# e+e- matrix elements
############################################################
# e+e- > q qbar
create Herwig::MEee2gZ2qq MEee2gZ2qq
newdef MEee2gZ2qq:MinimumFlavour 1
newdef MEee2gZ2qq:MaximumFlavour 5
newdef MEee2gZ2qq:AlphaQCD /Herwig/Shower/AlphaQCDFSR
newdef MEee2gZ2qq:AlphaQED /Herwig/Shower/AlphaQED
# e+e- -> l+l-
create Herwig::MEee2gZ2ll MEee2gZ2ll
newdef MEee2gZ2ll:Allowed Charged
set MEee2gZ2ll:AlphaQED /Herwig/Shower/AlphaQED
# e+e- -> l+l-
create Herwig::MEee2ff MEee2ff
set MEee2ff:AlphaQED /Herwig/Shower/AlphaQED
# e+e- -> W+W- ZZ
create Herwig::MEee2VV MEee2VV
# e+e- -> ZH
create Herwig::MEee2ZH MEee2ZH
newdef MEee2ZH:Coupling /Herwig/Shower/AlphaQCDFSR
# e+e- -> e+e-H/nu_enu_ebarH
create Herwig::MEee2HiggsVBF MEee2HiggsVBF
############################################################
# Low energy matrix elements
############################################################
# e+ e- -> pi+pi-
create Herwig::MEee2Mesons MEee2Pions HwMELeptonLowEnergy.so
create Herwig::TwoPionCzyzCurrent /Herwig/Decays/TwoPionCzyzCurrent HwWeakCurrents.so
set MEee2Pions:WeakCurrent /Herwig/Decays/TwoPionCzyzCurrent
# e+ e- -> K+K-/ K0K0
create Herwig::MEee2Mesons MEee2Kaons HwMELeptonLowEnergy.so
create Herwig::TwoKaonCzyzCurrent /Herwig/Decays/TwoKaonCzyzCurrent
set MEee2Kaons:WeakCurrent /Herwig/Decays/TwoKaonCzyzCurrent
# e+ e- -> pi+ pi- pi0
create Herwig::MEee2Mesons MEee3Pions HwMELeptonLowEnergy.so
create Herwig::ThreePionCzyzCurrent /Herwig/Decays/ThreePionCzyzCurrent
set MEee3Pions:WeakCurrent /Herwig/Decays/ThreePionCzyzCurrent
# e+ e- -> 2pi+ 2pi-, 2pi0, pi+ pi-
create Herwig::MEee2Mesons MEee4Pions HwMELeptonLowEnergy.so
create Herwig::FourPionCzyzCurrent /Herwig/Decays/FourPionCzyzCurrent
set MEee4Pions:WeakCurrent /Herwig/Decays/FourPionCzyzCurrent
# e+ e- -> eta pi+ pi-
create Herwig::MEee2Mesons MEee2EtaPiPi HwMELeptonLowEnergy.so
create Herwig::EtaPiPiCurrent /Herwig/Decays/EtaPiPiCurrent
set MEee2EtaPiPi:WeakCurrent /Herwig/Decays/EtaPiPiCurrent
# e+ e- -> eta' pi+ pi-
create Herwig::MEee2Mesons MEee2EtaPrimePiPi HwMELeptonLowEnergy.so
create Herwig::EtaPrimePiPiCurrent /Herwig/Decays/EtaPrimePiPiCurrent
set MEee2EtaPrimePiPi:WeakCurrent /Herwig/Decays/EtaPrimePiPiCurrent
# e+ e- -> omega pi (omega -> pi0 gamma)
create Herwig::MEee2Mesons MEee2OmegaPi HwMELeptonLowEnergy.so
create Herwig::TwoPionPhotonSNDCurrent /Herwig/Decays/OmegaPiCurrent
set MEee2OmegaPi:WeakCurrent /Herwig/Decays/OmegaPiCurrent
# e+ e- > pi0 gamma
create Herwig::MEee2Mesons MEee2PiGamma HwMELeptonLowEnergy.so
create Herwig::PionPhotonCurrent /Herwig/Decays/PiGammaCurrent
set MEee2PiGamma:WeakCurrent /Herwig/Decays/PiGammaCurrent
# e+e- -> eta gamma
create Herwig::MEee2Mesons MEee2EtaGamma HwMELeptonLowEnergy.so
create Herwig::EtaPhotonCurrent /Herwig/Decays/EtaGammaCurrent
set MEee2EtaGamma:WeakCurrent /Herwig/Decays/EtaGammaCurrent
# e+e- -> eta phi
create Herwig::MEee2Mesons MEee2EtaPhi HwMELeptonLowEnergy.so
create Herwig::EtaPhiCurrent /Herwig/Decays/EtaPhiCurrent
set MEee2EtaPhi:WeakCurrent /Herwig/Decays/EtaPhiCurrent
# e+e- -> eta omega
create Herwig::MEee2Mesons MEee2EtaOmega HwMELeptonLowEnergy.so
create Herwig::EtaOmegaCurrent /Herwig/Decays/EtaOmegaCurrent
set MEee2EtaOmega:WeakCurrent /Herwig/Decays/EtaOmegaCurrent
# e+e- > p pbar
create Herwig::MEee2Mesons MEee2PPbar HwMELeptonLowEnergy.so
create Herwig::WeakBaryonCurrent /Herwig/Decays/CzyzCurrent
create Herwig::CzyzNucleonFormFactor /Herwig/Decays/CzyzFormFactor HwFormFactors.so
set /Herwig/Decays/CzyzCurrent:FormFactor /Herwig/Decays/CzyzFormFactor
set MEee2PPbar:WeakCurrent /Herwig/Decays/CzyzCurrent
# e+e- > hyperons
create Herwig::MEee2Mesons MEee2LL HwMELeptonLowEnergy.so
create Herwig::WeakBaryonCurrent /Herwig/Decays/KornerKurodaCurrent
create Herwig::KornerKurodaFormFactor /Herwig/Decays/KornerKurodaFormFactor
set /Herwig/Decays/KornerKurodaFormFactor:IncludeNucleon No
set /Herwig/Decays/KornerKurodaCurrent:FormFactor /Herwig/Decays/KornerKurodaFormFactor
set MEee2LL:WeakCurrent /Herwig/Decays/KornerKurodaCurrent
# e+e- -> KKpi
create Herwig::MEee2Mesons MEee2KKPi HwMELeptonLowEnergy.so
create Herwig::KKPiCurrent /Herwig/Decays/KKPiCurrent
set MEee2KKPi:WeakCurrent /Herwig/Decays/KKPiCurrent
# e+e- -> phi pi
create Herwig::MEee2Mesons MEee2PhiPi HwMELeptonLowEnergy.so
create Herwig::PhiPiCurrent /Herwig/Decays/PhiPiCurrent
set MEee2PhiPi:WeakCurrent /Herwig/Decays/PhiPiCurrent
# e+ e- -> omega pi pi
create Herwig::MEee2Mesons MEee2OmegaPiPi HwMELeptonLowEnergy.so
create Herwig::OmegaPiPiCurrent /Herwig/Decays/OmegaPiPiCurrent
set MEee2OmegaPiPi:WeakCurrent /Herwig/Decays/OmegaPiPiCurrent
############################################################
# NLO (POWHEG e+e- matrix elements
############################################################
library HwPowhegMELepton.so
create Herwig::MEee2gZ2qqPowheg PowhegMEee2gZ2qq
newdef PowhegMEee2gZ2qq:MinimumFlavour 1
newdef PowhegMEee2gZ2qq:MaximumFlavour 5
newdef PowhegMEee2gZ2qq:AlphaQCD /Herwig/Shower/AlphaQCDFSR
newdef PowhegMEee2gZ2qq:AlphaQED /Herwig/Shower/AlphaQED
create Herwig::MEee2gZ2llPowheg PowhegMEee2gZ2ll
newdef PowhegMEee2gZ2ll:Allowed Charged
set PowhegMEee2gZ2ll:AlphaQED /Herwig/Shower/AlphaQED
############################################################
# hadron-hadron matrix elements
############################################################
###################################
# Electroweak processes
###################################
# q qbar -> gamma/Z -> l+l-
create Herwig::MEqq2gZ2ff MEqq2gZ2ff
newdef MEqq2gZ2ff:Process 3
newdef MEqq2gZ2ff:Coupling /Herwig/Shower/AlphaQCDISR
# q qbar to W -> l nu
create Herwig::MEqq2W2ff MEqq2W2ff
newdef MEqq2W2ff:Process 2
newdef MEqq2W2ff:Coupling /Herwig/Shower/AlphaQCDISR
# W+jet
create Herwig::MEPP2WJet MEWJet
newdef MEWJet:WDecay Leptons
# Z+jet
create Herwig::MEPP2ZJet MEZJet
newdef MEZJet:ZDecay ChargedLeptons
# PP->WW/WZ/ZZ
create Herwig::MEPP2VV MEPP2VV
# PP->WZ gamma
create Herwig::MEPP2VGamma MEPP2VGamma
###################################
# Photon and jet processes
###################################
# qqbar/gg -> gamma gamma
create Herwig::MEPP2GammaGamma MEGammaGamma
# hadron-hadron to gamma+jet
create Herwig::MEPP2GammaJet MEGammaJet
# QCD 2-to-2
create Herwig::MEQCD2to2 MEQCD2to2
# MinBias
create Herwig::MEMinBias MEMinBias
newdef MEMinBias:csNorm 0.01
newdef MEMinBias:Scale 2.0
###################################
# Heavy Quark
###################################
# qqbar/gg -> t tbar
create Herwig::MEPP2QQ MEHeavyQuark
create Herwig::MEPP2SingleTop MESingleTopTChannel
set MESingleTopTChannel:Process tChannel
create Herwig::MEPP2SingleTop MESingleTopSChannel
set MESingleTopSChannel:Process sChannel
create Herwig::MEPP2SingleTop MESingleTopTW
set MESingleTopTW:Process tW
###################################
# Higgs processes
###################################
# hadron-hadron to higgs
create Herwig::MEPP2Higgs MEHiggs
newdef MEHiggs:ShapeScheme MassGenerator
newdef MEHiggs:Process gg
newdef MEHiggs:Coupling /Herwig/Shower/AlphaQCDISR
# hadron-hadron to higgs+jet
create Herwig::MEPP2HiggsJet MEHiggsJet
# PP->ZH
create Herwig::MEPP2ZH MEPP2ZH
newdef MEPP2ZH:Coupling /Herwig/Shower/AlphaQCDISR
# PP->WH
create Herwig::MEPP2WH MEPP2WH
newdef MEPP2WH:Coupling /Herwig/Shower/AlphaQCDISR
# PP -> Higgs via VBF
create Herwig::MEPP2HiggsVBF MEPP2HiggsVBF
newdef MEPP2HiggsVBF:ShowerAlphaQCD /Herwig/Shower/AlphaQCDISR
# PP -> t tbar Higgs
create Herwig::MEPP2QQHiggs MEPP2ttbarH
newdef MEPP2ttbarH:QuarkType Top
# PP -> b bbar Higgs
create Herwig::MEPP2QQHiggs MEPP2bbbarH
newdef MEPP2bbbarH:QuarkType Bottom
##########################################################
# Hadron-Hadron NLO matrix elements in the Powheg scheme
##########################################################
library HwPowhegMEHadron.so
# q qbar -> gamma/Z -> l+l-
create Herwig::MEqq2gZ2ffPowheg PowhegMEqq2gZ2ff
newdef PowhegMEqq2gZ2ff:Process 3
newdef PowhegMEqq2gZ2ff:Coupling /Herwig/Shower/AlphaQCDISR
# q qbar to W -> l nu
create Herwig::MEqq2W2ffPowheg PowhegMEqq2W2ff
newdef PowhegMEqq2W2ff:Process 2
newdef PowhegMEqq2W2ff:Coupling /Herwig/Shower/AlphaQCDISR
# PP->ZH
create Herwig::MEPP2ZHPowheg PowhegMEPP2ZH
newdef PowhegMEPP2ZH:Coupling /Herwig/Shower/AlphaQCDISR
# PP->WH
create Herwig::MEPP2WHPowheg PowhegMEPP2WH
newdef PowhegMEPP2WH:Coupling /Herwig/Shower/AlphaQCDISR
# hadron-hadron to higgs
create Herwig::MEPP2HiggsPowheg PowhegMEHiggs
newdef PowhegMEHiggs:ShapeScheme MassGenerator
newdef PowhegMEHiggs:Process gg
newdef PowhegMEHiggs:Coupling /Herwig/Shower/AlphaQCDISR
# PP->VV
create Herwig::MEPP2VVPowheg PowhegMEPP2VV
newdef PowhegMEPP2VV:Coupling /Herwig/Shower/AlphaQCDISR
# PP -> Higgs via VBF
create Herwig::MEPP2HiggsVBFPowheg PowhegMEPP2HiggsVBF
newdef PowhegMEPP2HiggsVBF:ShowerAlphaQCD /Herwig/Shower/AlphaQCDISR
# PP -> diphoton NLO
create Herwig::MEPP2GammaGammaPowheg MEGammaGammaPowheg
set MEGammaGammaPowheg:Process 0
set MEGammaGammaPowheg:Contribution 1
set MEGammaGammaPowheg:ShowerAlphaQCD /Herwig/Shower/AlphaQCDISR
set MEGammaGammaPowheg:ShowerAlphaQED /Herwig/Shower/AlphaQED
##########################################################
+# Hadron Hadron onium matrix elements
+##########################################################
+
+# g g -> eta_c(1S)
+create Herwig::MEGGto1S0 MEgg2EtaC1S HwMEHadronOnium.so
+set MEgg2EtaC1S:Parameters /Herwig/OniumParameters
+set MEgg2EtaC1S:State ccbar
+set MEgg2EtaC1S:PrincipalQuantumNumber 1
+
+# g g -> eta_c(2S)
+create Herwig::MEGGto1S0 MEgg2EtaC2S HwMEHadronOnium.so
+set MEgg2EtaC2S:Parameters /Herwig/OniumParameters
+set MEgg2EtaC2S:State ccbar
+set MEgg2EtaC2S:PrincipalQuantumNumber 2
+
+# g g -> chi_c0(1P)
+create Herwig::MEGGto3P0 MEgg2ChiC01P HwMEHadronOnium.so
+set MEgg2ChiC01P:Parameters /Herwig/OniumParameters
+set MEgg2ChiC01P:State ccbar
+set MEgg2ChiC01P:PrincipalQuantumNumber 1
+
+# g g -> chi_c2(1P)
+create Herwig::MEGGto3P2 MEgg2ChiC21P HwMEHadronOnium.so
+set MEgg2ChiC21P:Parameters /Herwig/OniumParameters
+set MEgg2ChiC21P:State ccbar
+set MEgg2ChiC21P:PrincipalQuantumNumber 1
+
+# g g -> chi_c0(2P)
+create Herwig::MEGGto3P0 MEgg2ChiC02P HwMEHadronOnium.so
+set MEgg2ChiC02P:Parameters /Herwig/OniumParameters
+set MEgg2ChiC02P:State ccbar
+set MEgg2ChiC02P:PrincipalQuantumNumber 2
+
+# g g -> chi_c2(2P)
+create Herwig::MEGGto3P2 MEgg2ChiC22P HwMEHadronOnium.so
+set MEgg2ChiC22P:Parameters /Herwig/OniumParameters
+set MEgg2ChiC22P:State ccbar
+set MEgg2ChiC22P:PrincipalQuantumNumber 2
+
+# g g -> eta_b(1S)
+create Herwig::MEGGto1S0 MEgg2EtaB1S HwMEHadronOnium.so
+set MEgg2EtaB1S:Parameters /Herwig/OniumParameters
+set MEgg2EtaB1S:State bbbar
+set MEgg2EtaB1S:PrincipalQuantumNumber 1
+
+# g g -> eta_b(2S)
+create Herwig::MEGGto1S0 MEgg2EtaB2S HwMEHadronOnium.so
+set MEgg2EtaB2S:Parameters /Herwig/OniumParameters
+set MEgg2EtaB2S:State bbbar
+set MEgg2EtaB2S:PrincipalQuantumNumber 2
+
+# g g -> eta_b(3S)
+create Herwig::MEGGto1S0 MEgg2EtaB3S HwMEHadronOnium.so
+set MEgg2EtaB3S:Parameters /Herwig/OniumParameters
+set MEgg2EtaB3S:State bbbar
+set MEgg2EtaB3S:PrincipalQuantumNumber 3
+
+# g g -> chi_b0(1P)
+create Herwig::MEGGto3P0 MEgg2ChiB01P HwMEHadronOnium.so
+set MEgg2ChiB01P:Parameters /Herwig/OniumParameters
+set MEgg2ChiB01P:State bbbar
+set MEgg2ChiB01P:PrincipalQuantumNumber 1
+
+# g g -> chi_b0(2P)
+create Herwig::MEGGto3P0 MEgg2ChiB02P HwMEHadronOnium.so
+set MEgg2ChiB02P:Parameters /Herwig/OniumParameters
+set MEgg2ChiB02P:State bbbar
+set MEgg2ChiB02P:PrincipalQuantumNumber 2
+
+# g g -> chi_b0(3P)
+create Herwig::MEGGto3P0 MEgg2ChiB03P HwMEHadronOnium.so
+set MEgg2ChiB03P:Parameters /Herwig/OniumParameters
+set MEgg2ChiB03P:State bbbar
+set MEgg2ChiB03P:PrincipalQuantumNumber 3
+
+# g g -> chi_b2(1P)
+create Herwig::MEGGto3P2 MEgg2ChiB21P HwMEHadronOnium.so
+set MEgg2ChiB21P:Parameters /Herwig/OniumParameters
+set MEgg2ChiB21P:State bbbar
+set MEgg2ChiB21P:PrincipalQuantumNumber 1
+
+# g g -> chi_b2(2P)
+create Herwig::MEGGto3P2 MEgg2ChiB22P HwMEHadronOnium.so
+set MEgg2ChiB22P:Parameters /Herwig/OniumParameters
+set MEgg2ChiB22P:State bbbar
+set MEgg2ChiB22P:PrincipalQuantumNumber 2
+
+# g g -> chi_b2(3P)
+create Herwig::MEGGto3P2 MEgg2ChiB23P HwMEHadronOnium.so
+set MEgg2ChiB23P:Parameters /Herwig/OniumParameters
+set MEgg2ChiB23P:State bbbar
+set MEgg2ChiB23P:PrincipalQuantumNumber 3
+
+# g g -> eta_b2(1D)
+create Herwig::MEGGto1D2 MEgg2EtaB21D HwMEHadronOnium.so
+set MEgg2EtaB21D:Parameters /Herwig/OniumParameters
+set MEgg2EtaB21D:State bbbar
+set MEgg2EtaB21D:PrincipalQuantumNumber 1
+
+##########################################################
# DIS matrix elements
##########################################################
# neutral current
create Herwig::MENeutralCurrentDIS MEDISNC
newdef MEDISNC:Coupling /Herwig/Shower/AlphaQCDISR
newdef MEDISNC:Contribution 0
# charged current
create Herwig::MEChargedCurrentDIS MEDISCC
newdef MEDISCC:Coupling /Herwig/Shower/AlphaQCDISR
newdef MEDISCC:Contribution 0
# neutral current (POWHEG)
create Herwig::MENeutralCurrentDIS PowhegMEDISNC
newdef PowhegMEDISNC:Coupling /Herwig/Shower/AlphaQCDISR
newdef PowhegMEDISNC:Contribution 1
# charged current (POWHEG)
create Herwig::MEChargedCurrentDIS PowhegMEDISCC
newdef PowhegMEDISCC:Coupling /Herwig/Shower/AlphaQCDISR
newdef PowhegMEDISCC:Contribution 1
##########################################################
# Gamma-Gamma matrix elements
##########################################################
# fermion-antiferimon
create Herwig::MEGammaGamma2X MEgg2ff HwMEGammaGamma.so
create Herwig::GammaGamma2ffAmplitude gg2ffAmp
newdef MEgg2ff:Amplitude gg2ffAmp
# W+ W-
create Herwig::MEGammaGamma2WW MEgg2WW HwMEGammaGamma.so
# f f -> f f pi0,eta,eta' via 2 photon process
# pi0
create Herwig::MEff2ffX MEff2ffpi0
create Herwig::GammaGamma2PseudoScalarAmplitude AmpGG2pi0
newdef MEff2ffpi0:Amplitude AmpGG2pi0
set AmpGG2pi0:FTT 0.274
set AmpGG2pi0:LambdaP2 0.6
set AmpGG2pi0:Particle /Herwig/Particles/pi0
# eta
create Herwig::MEff2ffX MEff2ffeta
create Herwig::GammaGamma2PseudoScalarAmplitude AmpGG2eta
newdef MEff2ffeta:Amplitude AmpGG2eta
set AmpGG2eta:FTT 0.274
set AmpGG2eta:LambdaP2 0.6
set AmpGG2eta:Particle /Herwig/Particles/eta
# eta'
create Herwig::MEff2ffX MEff2ffetaPrime
create Herwig::GammaGamma2PseudoScalarAmplitude AmpGG2etaPrime
set AmpGG2etaPrime:Particle /Herwig/Particles/eta'
set AmpGG2etaPrime:FTT 0.344
set AmpGG2etaPrime:LambdaP2 0.6
set AmpGG2etaPrime:MassOption OffShell
newdef MEff2ffetaPrime:Amplitude AmpGG2etaPrime
+# f f -> f f eta_c via 2 photon process
+create Herwig::MEff2ffX MEff2ffEtaC1S
+create Herwig::GammaGamma2Onium1S0Amplitude AmpGG2EtaC1S HwMEGammaGammaOnium.so
+set AmpGG2EtaC1S:Parameters /Herwig/OniumParameters
+set AmpGG2EtaC1S:State ccbar
+set AmpGG2EtaC1S:MassOption OffShell
+set AmpGG2EtaC1S:PrincipalQuantumNumber 1
+set MEff2ffEtaC1S:Amplitude AmpGG2EtaC1S
+
+# f f -> f f eta_c(2S) via 2 photon process
+create Herwig::MEff2ffX MEff2ffEtaC2S
+create Herwig::GammaGamma2Onium1S0Amplitude AmpGG2EtaC2S HwMEGammaGammaOnium.so
+set AmpGG2EtaC2S:Parameters /Herwig/OniumParameters
+set AmpGG2EtaC2S:State ccbar
+set AmpGG2EtaC2S:MassOption OffShell
+set AmpGG2EtaC2S:PrincipalQuantumNumber 2
+set MEff2ffEtaC2S:Amplitude AmpGG2EtaC2S
+
+# f f -> f f chi_c0(1P) via 2 photon process
+create Herwig::MEff2ffX MEff2ffChiC01P
+create Herwig::GammaGamma2Onium3P0Amplitude AmpGG2ChiC01P HwMEGammaGammaOnium.so
+set AmpGG2ChiC01P:Parameters /Herwig/OniumParameters
+set AmpGG2ChiC01P:State ccbar
+set AmpGG2ChiC01P:MassOption OffShell
+set AmpGG2ChiC01P:PrincipalQuantumNumber 1
+set MEff2ffChiC01P:Amplitude AmpGG2ChiC01P
+
+# f f -> f f chi_c2(1P) via 2 photon process
+create Herwig::MEff2ffX MEff2ffChiC21P
+create Herwig::GammaGamma2Onium3P2Amplitude AmpGG2ChiC21P HwMEGammaGammaOnium.so
+set AmpGG2ChiC21P:Parameters /Herwig/OniumParameters
+set AmpGG2ChiC21P:State ccbar
+set AmpGG2ChiC21P:MassOption OffShell
+set AmpGG2ChiC21P:PrincipalQuantumNumber 1
+set MEff2ffChiC21P:Amplitude AmpGG2ChiC21P
+
+# f f -> f f chi_c0(2P) via 2 photon process
+create Herwig::MEff2ffX MEff2ffChiC02P
+create Herwig::GammaGamma2Onium3P0Amplitude AmpGG2ChiC02P HwMEGammaGammaOnium.so
+set AmpGG2ChiC02P:Parameters /Herwig/OniumParameters
+set AmpGG2ChiC02P:State ccbar
+set AmpGG2ChiC02P:MassOption OffShell
+set AmpGG2ChiC02P:PrincipalQuantumNumber 2
+set MEff2ffChiC02P:Amplitude AmpGG2ChiC02P
+
+# f f -> f f chi_c2(2P) via 2 photon process
+create Herwig::MEff2ffX MEff2ffChiC22P
+create Herwig::GammaGamma2Onium3P2Amplitude AmpGG2ChiC22P HwMEGammaGammaOnium.so
+set AmpGG2ChiC22P:Parameters /Herwig/OniumParameters
+set AmpGG2ChiC22P:State ccbar
+set AmpGG2ChiC22P:MassOption OffShell
+set AmpGG2ChiC22P:PrincipalQuantumNumber 2
+set MEff2ffChiC22P:Amplitude AmpGG2ChiC22P
+
+# f f -> f f eta_b via 2 photon process
+create Herwig::MEff2ffX MEff2ffEtaB1S
+create Herwig::GammaGamma2Onium1S0Amplitude AmpGG2EtaB1S HwMEGammaGammaOnium.so
+set AmpGG2EtaB1S:Parameters /Herwig/OniumParameters
+set AmpGG2EtaB1S:State bbbar
+set AmpGG2EtaB1S:MassOption OffShell
+set AmpGG2EtaB1S:PrincipalQuantumNumber 1
+set AmpGG2EtaB1S:Lambda2 89.4916
+set MEff2ffEtaB1S:Amplitude AmpGG2EtaB1S
+
+# f f -> f f eta_b(2S) via 2 photon process
+create Herwig::MEff2ffX MEff2ffEtaB2S
+create Herwig::GammaGamma2Onium1S0Amplitude AmpGG2EtaB2S HwMEGammaGammaOnium.so
+set AmpGG2EtaB2S:Parameters /Herwig/OniumParameters
+set AmpGG2EtaB2S:State bbbar
+set AmpGG2EtaB2S:MassOption OffShell
+set AmpGG2EtaB2S:PrincipalQuantumNumber 2
+set AmpGG2EtaB2S:Lambda2 89.4916
+set MEff2ffEtaB2S:Amplitude AmpGG2EtaB2S
+
+# f f -> f f eta_b(3S) via 2 photon process
+create Herwig::MEff2ffX MEff2ffEtaB3S
+create Herwig::GammaGamma2Onium1S0Amplitude AmpGG2EtaB3S HwMEGammaGammaOnium.so
+set AmpGG2EtaB3S:Parameters /Herwig/OniumParameters
+set AmpGG2EtaB3S:State bbbar
+set AmpGG2EtaB3S:MassOption OffShell
+set AmpGG2EtaB3S:PrincipalQuantumNumber 3
+set AmpGG2EtaB3S:Lambda2 89.4916
+set MEff2ffEtaB3S:Amplitude AmpGG2EtaB3S
+
+# f f -> f f chi_b0(1P) via 2 photon process
+create Herwig::MEff2ffX MEff2ffChiB01P
+create Herwig::GammaGamma2Onium3P0Amplitude AmpGG2ChiB01P HwMEGammaGammaOnium.so
+set AmpGG2ChiB01P:Parameters /Herwig/OniumParameters
+set AmpGG2ChiB01P:State bbbar
+set AmpGG2ChiB01P:MassOption OffShell
+set AmpGG2ChiB01P:PrincipalQuantumNumber 1
+set AmpGG2ChiB01P:Lambda2 89.4916
+set MEff2ffChiB01P:Amplitude AmpGG2ChiB01P
+
+# f f -> f f chi_b2(1P) via 2 photon process
+create Herwig::MEff2ffX MEff2ffChiB21P
+create Herwig::GammaGamma2Onium3P2Amplitude AmpGG2ChiB21P HwMEGammaGammaOnium.so
+set AmpGG2ChiB21P:Parameters /Herwig/OniumParameters
+set AmpGG2ChiB21P:State bbbar
+set AmpGG2ChiB21P:MassOption OffShell
+set AmpGG2ChiB21P:PrincipalQuantumNumber 1
+set AmpGG2ChiB21P:Lambda2 89.4916
+set MEff2ffChiB21P:Amplitude AmpGG2ChiB21P
+
+# f f -> f f chi_b0(2P) via 2 photon process
+create Herwig::MEff2ffX MEff2ffChiB02P
+create Herwig::GammaGamma2Onium3P0Amplitude AmpGG2ChiB02P HwMEGammaGammaOnium.so
+set AmpGG2ChiB02P:Parameters /Herwig/OniumParameters
+set AmpGG2ChiB02P:State bbbar
+set AmpGG2ChiB02P:MassOption OffShell
+set AmpGG2ChiB02P:PrincipalQuantumNumber 2
+set AmpGG2ChiB02P:Lambda2 89.4916
+set MEff2ffChiB02P:Amplitude AmpGG2ChiB02P
+
+# f f -> f f chi_b2(2P) via 2 photon process
+create Herwig::MEff2ffX MEff2ffChiB22P
+create Herwig::GammaGamma2Onium3P2Amplitude AmpGG2ChiB22P HwMEGammaGammaOnium.so
+set AmpGG2ChiB22P:Parameters /Herwig/OniumParameters
+set AmpGG2ChiB22P:State bbbar
+set AmpGG2ChiB22P:MassOption OffShell
+set AmpGG2ChiB22P:PrincipalQuantumNumber 2
+set AmpGG2ChiB22P:Lambda2 89.4916
+set MEff2ffChiB22P:Amplitude AmpGG2ChiB22P
+
+# f f -> f f chi_b0(3P) via 2 photon process
+create Herwig::MEff2ffX MEff2ffChiB03P
+create Herwig::GammaGamma2Onium3P0Amplitude AmpGG2ChiB03P HwMEGammaGammaOnium.so
+set AmpGG2ChiB03P:Parameters /Herwig/OniumParameters
+set AmpGG2ChiB03P:State bbbar
+set AmpGG2ChiB03P:MassOption OffShell
+set AmpGG2ChiB03P:PrincipalQuantumNumber 3
+set AmpGG2ChiB03P:Lambda2 89.4916
+set MEff2ffChiB03P:Amplitude AmpGG2ChiB03P
+
+# f f -> f f chi_b2(3P) via 2 photon process
+create Herwig::MEff2ffX MEff2ffChiB23P
+create Herwig::GammaGamma2Onium3P2Amplitude AmpGG2ChiB23P HwMEGammaGammaOnium.so
+set AmpGG2ChiB23P:Parameters /Herwig/OniumParameters
+set AmpGG2ChiB23P:State bbbar
+set AmpGG2ChiB23P:MassOption OffShell
+set AmpGG2ChiB23P:PrincipalQuantumNumber 3
+set AmpGG2ChiB23P:Lambda2 89.4916
+set MEff2ffChiB23P:Amplitude AmpGG2ChiB23P
+
+# f f -> f f eta_b2(1D) via 2 photon process
+create Herwig::MEff2ffX MEff2ffEtaB21D
+create Herwig::GammaGamma2Onium1D2Amplitude AmpGG2EtaB21D HwMEGammaGammaOnium.so
+set AmpGG2EtaB21D:Parameters /Herwig/OniumParameters
+set AmpGG2EtaB21D:State bbbar
+set AmpGG2EtaB21D:MassOption OffShell
+set AmpGG2EtaB21D:PrincipalQuantumNumber 1
+set AmpGG2EtaB21D:Lambda2 89.4916
+set MEff2ffEtaB21D:Amplitude AmpGG2EtaB21D
+
##########################################################
# Gamma-Hadron matrix elements
##########################################################
# gamma parton -> 2 jets
create Herwig::MEGammaP2Jets MEGammaP2Jets HwMEGammaHadron.so
##########################################################
# Set up the Subprocesses
#
# Generic for all colliders
##########################################################
create ThePEG::SubProcessHandler SubProcess
newdef SubProcess:PartonExtractor /Herwig/Partons/PPExtractor
diff --git a/src/defaults/Onium.in b/src/defaults/Onium.in
new file mode 100644
--- /dev/null
+++ b/src/defaults/Onium.in
@@ -0,0 +1,87 @@
+# -*- ThePEG-repository -*-
+#
+# Set up the global parameters for quarkonium production
+#
+cd /Herwig
+create Herwig::OniumParameters OniumParameters HwOniumParameters.so
+#
+# all from 1904.11542 apart from s-wave ccbar and bbar calculated from e+e- partial width using PDG)
+#
+# ccbar
+do OniumParameters:SetWaveFunction ccbar 1S 0.560236
+do OniumParameters:SetWaveFunction ccbar 1P 0.1296
+do OniumParameters:SetWaveFunction ccbar 1D 0.0329
+do OniumParameters:SetWaveFunction ccbar 2S 0.334412
+do OniumParameters:SetWaveFunction ccbar 2P 0.1767
+do OniumParameters:SetWaveFunction ccbar 2D 0.06923
+do OniumParameters:SetWaveFunction ccbar 3S 0.5951
+do OniumParameters:SetWaveFunction ccbar 3P 0.2106
+do OniumParameters:SetWaveFunction ccbar 3D 0.1074
+do OniumParameters:SetWaveFunction ccbar 4S 0.5461
+do OniumParameters:SetWaveFunction ccbar 4P 0.2389
+do OniumParameters:SetWaveFunction ccbar 5S 0.5160
+# bbar
+do OniumParameters:SetWaveFunction bbbar 1S 5.06718
+do OniumParameters:SetWaveFunction bbbar 1P 1.6057
+do OniumParameters:SetWaveFunction bbbar 1D 0.8394
+do OniumParameters:SetWaveFunction bbbar 2S 2.59789
+do OniumParameters:SetWaveFunction bbbar 2P 1.8240
+do OniumParameters:SetWaveFunction bbbar 2D 1.5572
+do OniumParameters:SetWaveFunction bbbar 3S 2.00712
+do OniumParameters:SetWaveFunction bbbar 3P 1.9804
+do OniumParameters:SetWaveFunction bbbar 3D 2.2324
+do OniumParameters:SetWaveFunction bbbar 4S 1.2863
+do OniumParameters:SetWaveFunction bbbar 4P 2.1175
+do OniumParameters:SetWaveFunction bbbar 4D 2.8903
+do OniumParameters:SetWaveFunction bbbar 5S 1.7990
+do OniumParameters:SetWaveFunction bbbar 5P 2.2430
+do OniumParameters:SetWaveFunction bbbar 5D 3.5411
+do OniumParameters:SetWaveFunction bbbar 6S 1.6885
+do OniumParameters:SetWaveFunction bbbar 6P 2.3600
+do OniumParameters:SetWaveFunction bbbar 7S 1.6080
+# B_c
+do OniumParameters:SetWaveFunction bcbar 1S 1.9943
+do OniumParameters:SetWaveFunction bcbar 1P 0.3083
+do OniumParameters:SetWaveFunction bcbar 1D 0.0986
+do OniumParameters:SetWaveFunction bcbar 2S 1.1443
+do OniumParameters:SetWaveFunction bcbar 2P 0.3939
+do OniumParameters:SetWaveFunction bcbar 2D 0.1989
+do OniumParameters:SetWaveFunction bcbar 3S 0.9440
+do OniumParameters:SetWaveFunction bcbar 3P 0.4540
+do OniumParameters:SetWaveFunction bcbar 4S 0.8504
+# and the mixing
+do OniumParameters:SetSingletTripletMixing 1P 25.0
+do OniumParameters:SetSingletTripletMixing 1D 34.4
+# diquarks (naive scale 1/8 of onium value hep-ph/9305315 page 3 below eqn 2)
+# cc
+do OniumParameters:SetWaveFunction cc 1S 0.07
+# bb
+do OniumParameters:SetWaveFunction bb 1S 0.633
+# bc
+do OniumParameters:SetWaveFunction bc 1S 0.250
+
+#
+# Octet matrix elements
+#
+do /Herwig/OniumParameters:SetOctetProductionMatrixElement ccbar 3S1 443 1.2e-2
+do /Herwig/OniumParameters:SetOctetProductionMatrixElement ccbar 3S1 100443 4.3e-3
+
+do /Herwig/OniumParameters:SetOctetProductionMatrixElement ccbar 3S1 10441 0.31e-2
+do /Herwig/OniumParameters:SetOctetProductionMatrixElement ccbar 3S1 20443 0.93e-2
+do /Herwig/OniumParameters:SetOctetProductionMatrixElement ccbar 3S1 445 1.55e-2
+
+do /Herwig/OniumParameters:SetOctetProductionMatrixElement bbbar 3S1 553 4.3e-3
+do /Herwig/OniumParameters:SetOctetProductionMatrixElement bbbar 3S1 100553 4.3e-3
+do /Herwig/OniumParameters:SetOctetProductionMatrixElement bbbar 3S1 200553 4.3e-3
+
+do /Herwig/OniumParameters:SetOctetProductionMatrixElement bbbar 3S1 10551 0.31e-2
+do /Herwig/OniumParameters:SetOctetProductionMatrixElement bbbar 3S1 20553 0.93e-2
+do /Herwig/OniumParameters:SetOctetProductionMatrixElement bbbar 3S1 555 1.55e-2
+
+do /Herwig/OniumParameters:SetOctetProductionMatrixElement bbbar 3S1 110551 0.31e-2
+do /Herwig/OniumParameters:SetOctetProductionMatrixElement bbbar 3S1 120553 0.93e-2
+do /Herwig/OniumParameters:SetOctetProductionMatrixElement bbbar 3S1 100555 1.55e-2
+
+do /Herwig/OniumParameters:SetOctetProductionMatrixElement bbbar 3S1 210551 0.31e-2
+do /Herwig/OniumParameters:SetOctetProductionMatrixElement bbbar 3S1 220553 0.93e-2
+do /Herwig/OniumParameters:SetOctetProductionMatrixElement bbbar 3S1 200555 1.55e-2

File Metadata

Mime Type
text/x-diff
Expires
Tue, Nov 19, 7:25 PM (1 d, 10 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3805816
Default Alt Text
(519 KB)

Event Timeline