Page MenuHomeHEPForge

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/Decay/Baryon/Baryon1MesonDecayerBase.cc b/Decay/Baryon/Baryon1MesonDecayerBase.cc
--- a/Decay/Baryon/Baryon1MesonDecayerBase.cc
+++ b/Decay/Baryon/Baryon1MesonDecayerBase.cc
@@ -1,978 +1,978 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the Baryon1MesonDecayerBase class.
//
#include "Baryon1MesonDecayerBase.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/PDT/DecayMode.h"
#include "Herwig/Utilities/Kinematics.h"
#include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
#include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
#include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
#include "ThePEG/Helicity/WaveFunction/RSSpinorWaveFunction.h"
#include "ThePEG/Helicity/WaveFunction/RSSpinorBarWaveFunction.h"
#include "ThePEG/Helicity/LorentzPolarizationVector.h"
#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
#include "Herwig/Decay/TwoBodyDecayMatrixElement.h"
using namespace Herwig;
using namespace ThePEG::Helicity;
// The following static variable is needed for the type
// description system in ThePEG.
DescribeAbstractNoPIOClass<Baryon1MesonDecayerBase,DecayIntegrator>
describeHerwigBaryon1MesonDecayerBase("Herwig::Baryon1MesonDecayerBase", "HwBaryonDecay.so");
void Baryon1MesonDecayerBase::Init() {
static ClassDocumentation<Baryon1MesonDecayerBase> documentation
("The Baryon1MesonDecayerBase class is the base class for"
" the decays of the baryons to a baryon and a pseudoscalar or vector meson.");
}
// return the matrix element squared for a given mode and phase-space channel
// (inherited from DecayIntegrator and implemented here)
double Baryon1MesonDecayerBase::me2(const int ichan,
const Particle & inpart,
const ParticleVector & decay,
MEOption meopt) const {
double me(0.);
// decide which matrix element we are doing
// incoming spin-1/2 particle
if(inpart.dataPtr()->iSpin()==2) {
// decay to spin-1/2 particle
if(decay[0]->dataPtr()->iSpin()==2) {
// scalar meson
if(decay[1]->dataPtr()->iSpin()==1)
me=halfHalfScalar(ichan,inpart,decay,meopt);
// vector meson
else if(decay[1]->dataPtr()->iSpin()==3)
me=halfHalfVector(ichan,inpart,decay,meopt);
else
throw DecayIntegratorError() << "Unknown outgoing meson spin in "
<< "Baryon1MesonDecayerBase::me2()"
<< Exception::abortnow;
}
// decay to spin-3/2 particle
else if(decay[0]->dataPtr()->iSpin()==4) {
// scalar meson
if(decay[1]->dataPtr()->iSpin()==1)
me=halfThreeHalfScalar(ichan,inpart,decay,meopt);
// vector meson
else if(decay[1]->dataPtr()->iSpin()==3)
me=halfThreeHalfVector(ichan,inpart,decay,meopt);
else
throw DecayIntegratorError() << "Unknown outgoing meson spin in "
<< "Baryon1MesonDecayerBase::me2()"
<< Exception::abortnow;
}
// unknown
else
throw DecayIntegratorError() << "Unknown outgoing baryon spin in "
<< "Baryon1MesonDecayerBase::me2()"
<< Exception::abortnow;
}
// incoming spin-3/2 particle
else if(inpart.dataPtr()->iSpin()==4) {
// decay to spin-1/2 particle
if(decay[0]->dataPtr()->iSpin()==2) {
// scalar meson
if(decay[1]->dataPtr()->iSpin()==1)
me=threeHalfHalfScalar(ichan,inpart,decay,meopt);
// vector meson
else if(decay[1]->dataPtr()->iSpin()==3)
me=threeHalfHalfVector(ichan,inpart,decay,meopt);
else
throw DecayIntegratorError() << "Unknown outgoing meson spin in "
<< "Baryon1MesonDecayerBase::me2()"
<< Exception::abortnow;
}
// decay to spin-3/2 particle
else if(decay[0]->dataPtr()->iSpin()==4) {
// scalar meson
if(decay[1]->dataPtr()->iSpin()==1)
me=threeHalfThreeHalfScalar(ichan,inpart,decay,meopt);
else
throw DecayIntegratorError() << "Unknown outgoing meson spin in "
<< "Baryon1MesonDecayerBase::me2()"
<< Exception::abortnow;
}
// unknown
else
throw DecayIntegratorError() << "Unknown outgoing baryon spin in "
<< "Baryon1MesonDecayerBase::me2()"
<< Exception::abortnow;
}
// unknown
else
throw DecayIntegratorError() << "Unknown incoming spin in "
<< "Baryon1MesonDecayerBase::me2()"
<< Exception::abortnow;
return me;
}
// matrix element for the decay of a spin-1/2 fermion to a spin-1/2 fermion and
// a pseudoscalar meson
double Baryon1MesonDecayerBase::
halfHalfScalar(const int,const Particle & inpart,
const ParticleVector & decay,MEOption meopt) const {
if(!ME())
ME(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin0)));
// spinors etc for the decaying particle
if(meopt==Initialize) {
// spinors and rho
if(inpart.id()>0)
SpinorWaveFunction ::calculateWaveFunctions(_inHalf,_rho,
const_ptr_cast<tPPtr>(&inpart),
incoming);
else
SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,_rho,
const_ptr_cast<tPPtr>(&inpart),
incoming);
// matrix element
}
// setup spin info when needed
if(meopt==Terminate) {
// for the decaying particle
if(inpart.id()>0) {
SpinorWaveFunction::
constructSpinInfo(_inHalf,const_ptr_cast<tPPtr>(&inpart),incoming,true);
SpinorBarWaveFunction::constructSpinInfo(_inHalfBar,decay[0],outgoing,true);
}
else {
SpinorBarWaveFunction::
constructSpinInfo(_inHalfBar,const_ptr_cast<tPPtr>(&inpart),incoming,true);
SpinorWaveFunction::constructSpinInfo(_inHalf,decay[0],outgoing,true);
}
ScalarWaveFunction::constructSpinInfo(decay[1],outgoing,true);
return 0.;
}
// spinors for the decay product
if(inpart.id()>0) {
SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,decay[0],outgoing);
}
else {
SpinorWaveFunction ::calculateWaveFunctions(_inHalf,decay[0],outgoing);
}
// get the couplings
Complex A,B;
halfHalfScalarCoupling(imode(),inpart.mass(),decay[0]->mass(),decay[1]->mass(),A,B);
- Complex left,right,meout;
+ Complex left,right;
// coupling for an incoming particle
if(inpart.id()>0) {
left = (A-B);
right = (A+B);
}
// coupling for an incoming antiparticle
else {
left = conj(A+B);
right = conj(A-B);
}
// calculate the matrix element
vector<unsigned int> ispin(3,0);
unsigned int ix,iy;
// Complex output(0.);
for(ix=0;ix<2;++ix) {
for(iy=0;iy<2;++iy) {
if(decay[0]->id()>0){ispin[0]=iy;ispin[1]=ix;}
else{ispin[0]=ix;ispin[1]=iy;}
(*ME())(ispin)=Complex(_inHalf[iy].generalScalar(_inHalfBar[ix],left,right)/inpart.mass());
// output += norm(ME()(ispin));
}
}
// test of the matrix elemen// t
// Energy m1(inpart.mass()),m2(decay[0]->mass()),m3(decay[1]->mass());
// Energy Qp(sqrt(sqr(m1+m2)-sqr(m3))),Qm(sqrt(sqr(m1-m2)-sqr(m3)));
// Complex h1(2.*Qp*A/inpart.mass()),h2(-2.*Qm*B/inpart.mass());
// generator()->log() << "testing 1/2->1/2 0 "
// << 0.5*output << " "
// << 0.25*(h1*conj(h1)+h2*conj(h2)) << " "
// << 0.5*(h1*conj(h1)+h2*conj(h2))/output << endl;
// generator()->log() << "testing alpha " <<
// (norm(0.5*(h1+h2))-norm(0.5*(h1-h2)))/
// (norm(0.5*(h1+h2))+norm(0.5*(h1-h2))) << "\n";
// Energy pcm(Kinematics::pstarTwoBodyDecay(m1,m2,m3));
// generator()->log() << "testing masses " << m1/GeV << " " << m2/GeV << " " << m3/GeV
// << "\n";
// generator()->log() << "testing partial " << pcm*0.5*output/8./Constants::pi/MeV
// << "\n";
// store the matrix element
return (ME()->contract(_rho)).real();
}
// matrix element for the decay of a spin-1/2 fermion to a spin-1/2 fermion and
// a vector meson
double Baryon1MesonDecayerBase::
halfHalfVector(const int,const Particle & inpart,
const ParticleVector & decay,MEOption meopt) const {
if(!ME())
ME(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1)));
// check if the outgoing meson is really a photon
bool photon=decay[1]->id()==ParticleID::gamma;
// spinors etc for the decaying particle
if(meopt==Initialize) {
// spinors and rho
if(inpart.id()>0)
SpinorWaveFunction ::calculateWaveFunctions(_inHalf,_rho,
const_ptr_cast<tPPtr>(&inpart),
incoming);
else
SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,_rho,
const_ptr_cast<tPPtr>(&inpart),
incoming);
// matrix element
}
// setup spin info when needed
if(meopt==Terminate) {
// for the decaying particle
if(inpart.id()>0) {
SpinorWaveFunction::
constructSpinInfo(_inHalf,const_ptr_cast<tPPtr>(&inpart),incoming,true);
SpinorBarWaveFunction::constructSpinInfo(_inHalfBar,decay[0],outgoing,true);
}
else {
SpinorBarWaveFunction::
constructSpinInfo(_inHalfBar,const_ptr_cast<tPPtr>(&inpart),incoming,true);
SpinorWaveFunction::constructSpinInfo(_inHalf,decay[0],outgoing,true);
}
VectorWaveFunction::constructSpinInfo(_inVec,decay[1],outgoing,true,photon);
return 0.;
}
// spinors for the decay product
if(inpart.id()>0) {
SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,decay[0],outgoing);
}
else {
SpinorWaveFunction ::calculateWaveFunctions(_inHalf,decay[0],outgoing);
}
VectorWaveFunction::calculateWaveFunctions(_inVec,decay[1],outgoing,photon);
// get the couplings
Complex A1,A2,B1,B2;
halfHalfVectorCoupling(imode(),inpart.mass(),decay[0]->mass(),decay[1]->mass(),
A1,A2,B1,B2);
Complex lS,rS,lV,rV;
complex<Energy> scalar;
// couplings for an incoming particle
if(inpart.id()>0) {
lS = (A2-B2);
rS = (A2+B2);
lV = (A1-B1);
rV = (A1+B1);
}
else {
lS = -conj(A2+B2);
rS = -conj(A2-B2);
lV = conj(A1-B1);
rV = conj(A1+B1);
}
// calculate the matrix element
// decide which type of mode to do
Energy msum(inpart.mass()+decay[0]->mass());
vector<unsigned int> ispin(3);
LorentzVector<complex<Energy> > svec;
Complex prod;
// Complex output(0.);
unsigned int ix,iy;
for(ix=0;ix<2;++ix) {
for(iy=0;iy<2;++iy) {
// scalar like piece
scalar = _inHalf[iy].generalScalar(_inHalfBar[ix],lS,rS);
// vector like piece
svec = _inHalf[iy].generalCurrent(_inHalfBar[ix],lV,rV);
if(decay[0]->id()>0) {
ispin[0] = iy;
ispin[1] = ix;
}
else {
ispin[0] = ix;
ispin[1] = iy;
}
for(ispin[2]=0;ispin[2]<3;++ispin[2]) {
ispin[2]=ispin[2];
prod=_inVec[ispin[2]].dot(inpart.momentum())/msum;
(*ME())(ispin)=(svec.dot(_inVec[ispin[2]])+prod*scalar)/inpart.mass();
// output += norm(ME()(ispin));
}
}
}
// test of the matrix element
// Energy m1(inpart.mass()),m2(decay[0]->mass()),m3(decay[1]->mass());
// Energy Qp(sqrt(sqr(m1+m2)-sqr(m3))),Qm(sqrt(sqr(m1-m2)-sqr(m3)));
// double r2(sqrt(2.));
// Energy pcm(Kinematics::pstarTwoBodyDecay(m1,m2,m3));
// Complex h1(2.*r2*Qp*B1/inpart.mass()),h2(-2.*r2*Qm*A1/inpart.mass()),
// h3(2./m3*(Qp*(m1-m2)*B1-Qm*m1*B2*pcm/(m1+m2))/inpart.mass()),
// h4(2./m3*(Qm*(m1+m2)*A1+Qp*m1*A2*pcm/(m1+m2))/inpart.mass());
// generator()->log() << "testing 1/2->1/2 1 "
// << 0.5*output << " "
// << 0.25*(h1*conj(h1)+h2*conj(h2)+h3*conj(h3)+h4*conj(h4)) << " "
// << 0.50*(h1*conj(h1)+h2*conj(h2)+h3*conj(h3)+h4*conj(h4))/output
// << "\n";
// generator()->log() << "alpha = " << 2.*(norm(h3)+norm(h4))/(norm(h1)+norm(h2))-1.
// << "\n";
// return the answer
return (ME()->contract(_rho)).real();
}
// matrix element for the decay of a spin-1/2 fermion to a spin-3/2 fermion and
// a scalar meson
double Baryon1MesonDecayerBase::halfThreeHalfScalar(const int,
const Particle & inpart,
const ParticleVector & decay,
MEOption meopt) const {
if(!ME())
ME(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin3Half,PDT::Spin0)));
// spinors etc for the decaying particle
if(meopt==Initialize) {
// spinors and rho
if(inpart.id()>0)
SpinorWaveFunction ::calculateWaveFunctions(_inHalf,_rho,
const_ptr_cast<tPPtr>(&inpart),
incoming);
else
SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,_rho,
const_ptr_cast<tPPtr>(&inpart),
incoming);
// matrix element
}
// setup spin info when needed
if(meopt==Terminate) {
// for the decaying particle
if(inpart.id()>0) {
SpinorWaveFunction::
constructSpinInfo(_inHalf,const_ptr_cast<tPPtr>(&inpart),incoming,true);
RSSpinorBarWaveFunction::constructSpinInfo(_inThreeHalfBar,
decay[0],outgoing,true);
}
else {
SpinorBarWaveFunction::
constructSpinInfo(_inHalfBar,const_ptr_cast<tPPtr>(&inpart),incoming,true);
RSSpinorWaveFunction::constructSpinInfo(_inThreeHalf,
decay[0],outgoing,true);
}
ScalarWaveFunction::constructSpinInfo(decay[1],outgoing,true);
return 0.;
}
// spinors for the decay product
LorentzPolarizationVector in=UnitRemoval::InvE*inpart.momentum();
if(inpart.id()>0) {
RSSpinorBarWaveFunction::
calculateWaveFunctions(_inThreeHalfBar,decay[0],outgoing);
_inHalfBar.resize(_inThreeHalfBar.size());
for(unsigned int ix=0;ix<_inThreeHalfBar.size();++ix)
_inHalfBar[ix] = _inThreeHalfBar[ix].dot(in);
}
else {
RSSpinorWaveFunction::
calculateWaveFunctions(_inThreeHalf,decay[0],outgoing);
_inHalf.resize(_inThreeHalf.size());
for(unsigned int ix=0;ix<_inThreeHalf.size();++ix)
_inHalf[ix] = _inThreeHalf[ix].dot(in);
}
// get the couplings
Complex A,B,left,right;
Energy msum(inpart.mass()+decay[0]->mass());
halfThreeHalfScalarCoupling(imode(),inpart.mass(),decay[0]->mass(),decay[1]->mass(),
A,B);
// incoming particle
if(inpart.id()>0) {
left=(A-B);
right=(A+B);
}
// incoming anti-particle
else {
left=conj(A+B);
right=conj(A-B);
}
vector<unsigned int> ispin(3,0);
//Complex output(0.);
for(unsigned ixa=0;ixa<2;++ixa) {
for(unsigned int iya=0;iya<4;++iya) {
unsigned int ix(iya),iy(ixa);
if(decay[0]->id()<0) swap(ix,iy);
ispin[0]=ixa;
ispin[1]=iya;
complex<double> value = _inHalf[iy].generalScalar(_inHalfBar[ix],left,right)
*UnitRemoval::E/inpart.mass()/msum;
(*ME())(ispin) = value;
//output+= norm(ME()(ispin));
}
}
double output = (ME()->contract(_rho)).real();
// test of the matrix element
// Energy m1(inpart.mass()),m2(decay[0]->mass()),m3(decay[1]->mass());
// Energy Qp(sqrt(sqr(m1+m2)-sqr(m3))),Qm(sqrt(sqr(m1-m2)-sqr(m3)));
// double r23(sqrt(2./3.));
// Energy pcm(Kinematics::pstarTwoBodyDecay(m1,m2,m3));
// complex<Energy> h1(-2.*r23*pcm*m1/m2*Qm*B/(m1+m2)),h2( 2.*r23*pcm*m1/m2*Qp*A/(m1+m2));
// cout << "testing 1/2->3/2 0 " << inpart.id() << " "
// << output << " "
// << 0.25*(h1*conj(h1)+h2*conj(h2))/sqr(inpart.mass()) << " "
// << 0.25*(h1*conj(h1)+h2*conj(h2))/sqr(inpart.mass())/output << endl;
// return the answer
return output;
}
// matrix element for the decay of a spin-1/2 fermion to a spin-3/2 fermion and
// a vector meson
double Baryon1MesonDecayerBase::
halfThreeHalfVector(const int,const Particle & inpart,
const ParticleVector & decay, MEOption meopt) const {
if(!ME())
ME(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin3Half,PDT::Spin1)));
// check if the outgoing meson is really a photon
bool photon=decay[1]->id()==ParticleID::gamma;
// spinors etc for the decaying particle
if(meopt==Initialize) {
// spinors and rho
if(inpart.id()>0)
SpinorWaveFunction ::calculateWaveFunctions(_inHalf,_rho,
const_ptr_cast<tPPtr>(&inpart),
incoming);
else
SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,_rho,
const_ptr_cast<tPPtr>(&inpart),
incoming);
// matrix element
}
// setup spin info when needed
if(meopt==Terminate) {
// for the decaying particle
if(inpart.id()>0) {
SpinorWaveFunction::
constructSpinInfo(_inHalf,const_ptr_cast<tPPtr>(&inpart),incoming,true);
RSSpinorBarWaveFunction::constructSpinInfo(_inThreeHalfBar,
decay[0],outgoing,true);
}
else {
SpinorBarWaveFunction::
constructSpinInfo(_inHalfBar,const_ptr_cast<tPPtr>(&inpart),incoming,true);
RSSpinorWaveFunction::constructSpinInfo(_inThreeHalf,
decay[0],outgoing,true);
}
VectorWaveFunction::constructSpinInfo(_inVec,decay[1],outgoing,true,photon);
return 0.;
}
LorentzPolarizationVector in=UnitRemoval::InvE*inpart.momentum();
if(inpart.id()>0) {
RSSpinorBarWaveFunction::
calculateWaveFunctions(_inThreeHalfBar,decay[0],outgoing);
_inHalfBar.resize(_inThreeHalfBar.size());
for(unsigned int ix=0;ix<_inThreeHalfBar.size();++ix)
_inHalfBar[ix] = _inThreeHalfBar[ix].dot(in);
}
else {
RSSpinorWaveFunction::
calculateWaveFunctions(_inThreeHalf,decay[0],outgoing);
_inHalf.resize(_inThreeHalf.size());
for(unsigned int ix=0;ix<_inThreeHalf.size();++ix)
_inHalf[ix] = _inThreeHalf[ix].dot(in);
}
ME()->zero();
VectorWaveFunction::calculateWaveFunctions(_inVec,decay[1],outgoing,photon);
// get the couplings
Complex A1,A2,A3,B1,B2,B3;
halfThreeHalfVectorCoupling(imode(),inpart.mass(),decay[0]->mass(),decay[1]->mass(),
A1,A2,A3,B1,B2,B3);
Energy msum(inpart.mass()+decay[0]->mass());
Complex lS,rS,lV,rV,left,right;
// incoming particle
if(inpart.id()>0) {
lS=(A3-B3);rS=(A3+B3);
lV=(A2-B2);rV=(A2+B2);
left=(A1-B1);right=(A1+B1);
}
// incoming anti-particle
else {
lS=conj(A3+B3);rS=conj(A3-B3);
lV=-conj(A2-B2);rV=-conj(A2+B2);
left=conj(A1+B1);right=conj(A1-B1);
}
// compute the matrix element
vector<unsigned int> ispin(3);
LorentzVector<complex<Energy> > svec;
Complex prod;
complex<Energy> scalar;
LorentzSpinor<SqrtEnergy> stemp;
LorentzSpinorBar<SqrtEnergy> sbtemp;
for(unsigned iya=0;iya<4;++iya) {
ispin[1]=iya;
// piece where the vector-spinor is dotted with the momentum of the
// incoming fermion
for(unsigned ixa=0;ixa<2;++ixa) {
unsigned int ix(iya),iy(ixa);
if(decay[0]->id()<0) swap(ix,iy);
scalar = _inHalf[iy].generalScalar (_inHalfBar[ix],lS,rS);
svec = _inHalf[iy].generalCurrent(_inHalfBar[ix],lV,rV);
ispin[0]=ixa;
for(unsigned int iz=0;iz<3;++iz) {
ispin[2]=iz;
prod=_inVec[iz].dot(inpart.momentum())/msum;
(*ME())(ispin) += (svec.dot(_inVec[iz])+prod*scalar)*
UnitRemoval::E/msum/inpart.mass();
}
}
// the piece where the vector spinor is dotted with the polarization vector
for(unsigned int iz=0;iz<3;++iz) {
ispin[2]=iz;
if(decay[0]->id()>0) sbtemp = _inThreeHalfBar[iya].dot(_inVec[iz]);
else stemp = _inThreeHalf[iya].dot(_inVec[iz]);
for(unsigned int ixa=0;ixa<2;++ixa) {
ispin[0]=ixa;
if(decay[0]->id()>0) stemp = _inHalf[ixa];
else sbtemp = _inHalfBar[ixa];
(*ME())(ispin) += Complex(stemp.generalScalar(sbtemp,left,right)/inpart.mass());
}
}
}
double output = (ME()->contract(_rho)).real();
// test of the matrix element
// Energy m1(inpart.mass()),m2(decay[0]->mass()),m3(decay[1]->mass());
// Energy2 m12(m1*m1),m22(m2*m2),m32(m3*m3);
// Energy Qp(sqrt(sqr(m1+m2)-sqr(m3))),Qm(sqrt(sqr(m1-m2)-sqr(m3)));
// double r2(sqrt(2.)),r3(sqrt(3.));
// Energy pcm(Kinematics::pstarTwoBodyDecay(m1,m2,m3));
// complex<Energy> h1(-2.*Qp*A1),h2(2.*Qm*B1);
// complex<Energy> h3(-2./r3*Qp*(A1-Qm*Qm/m2*A2/msum));
// complex<Energy> h4( 2./r3*Qm*(B1-Qp*Qp/m2*B2/msum));
// complex<Energy> h5(-2.*r2/r3/m2/m3*Qp*(0.5*(m12-m22-m32)*A1+0.5*Qm*Qm*(m1+m2)*A2/msum
// +m12*pcm*pcm*A3/msum/msum));
// complex<Energy> h6( 2.*r2/r3/m2/m3*Qm*(0.5*(m12-m22-m32)*B1-0.5*Qp*Qp*(m1-m2)*B2/msum
// +m12*pcm*pcm*B3/msum/msum));
// cout << "testing 1/2->3/2 1 " << inpart.id() << " "
// << output << " "
// << 0.25*(h1*conj(h1)+h2*conj(h2)+h3*conj(h3)+
// h4*conj(h4)+h5*conj(h5)+h6*conj(h6))/sqr(inpart.mass()) << " "
// << 0.25*(h1*conj(h1)+h2*conj(h2)+h3*conj(h3)+
// h4*conj(h4)+h5*conj(h5)+h6*conj(h6))/sqr(inpart.mass())/output << endl;
// return the answer
return output;
}
// matrix element for the decay of a spin-3/2 fermion to a spin-1/2 fermion and
// a scalar meson
double Baryon1MesonDecayerBase::
threeHalfHalfScalar(const int,const Particle & inpart,
const ParticleVector & decay, MEOption meopt) const {
if(!ME())
ME(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin3Half,PDT::Spin1Half,PDT::Spin0)));
// spinors etc for the decaying particle
if(meopt==Initialize) {
// spinors and rho
if(inpart.id()>0) {
RSSpinorWaveFunction ::calculateWaveFunctions(_inThreeHalf,_rho,
const_ptr_cast<tPPtr>(&inpart),
incoming);
}
else {
RSSpinorBarWaveFunction::calculateWaveFunctions(_inThreeHalfBar,_rho,
const_ptr_cast<tPPtr>(&inpart),
incoming);
}
// matrix element
}
// setup spin info when needed
if(meopt==Terminate) {
// for the decaying particle
if(inpart.id()>0) {
RSSpinorWaveFunction::
constructSpinInfo(_inThreeHalf,const_ptr_cast<tPPtr>(&inpart),incoming,true);
SpinorBarWaveFunction::constructSpinInfo(_inHalfBar,decay[0],outgoing,true);
}
else {
RSSpinorBarWaveFunction::
constructSpinInfo(_inThreeHalfBar,const_ptr_cast<tPPtr>(&inpart),incoming,true);
SpinorWaveFunction::constructSpinInfo(_inHalf,decay[0],outgoing,true);
}
ScalarWaveFunction::constructSpinInfo(decay[1],outgoing,true);
return 0.;
}
// spinors for the decay product
if(inpart.id()>0) {
SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,decay[0],outgoing);
}
else {
SpinorWaveFunction ::calculateWaveFunctions(_inHalf,decay[0],outgoing);
}
LorentzPolarizationVector out=UnitRemoval::InvE*decay[0]->momentum();
if(inpart.id()>0) {
_inHalf.resize(_inThreeHalf.size());
for(unsigned int ix=0;ix<_inThreeHalf.size();++ix)
_inHalf[ix] = _inThreeHalf[ix].dot(out);
}
else {
_inHalfBar.resize(_inThreeHalfBar.size());
for(unsigned int ix=0;ix<_inThreeHalfBar.size();++ix)
_inHalfBar[ix] = _inThreeHalfBar[ix].dot(out);
}
// get the couplings
Complex A,B;
Energy msum=inpart.mass()+decay[0]->mass();
threeHalfHalfScalarCoupling(imode(),inpart.mass(),decay[0]->mass(),decay[1]->mass(),
A,B);
Complex left,right;
// incoming particle
if(inpart.id()>0) {
left=(A-B);
right=(A+B);
}
// incoming anti-particle
else {
left=conj(A+B);
right=conj(A-B);
}
// compute the matrix element
vector<unsigned int> ispin(3,0);
for(unsigned ixa=0;ixa<2;++ixa) {
for(unsigned iya=0;iya<4;++iya) {
unsigned int iy=iya,ix=ixa;
if(decay[0]->id()<0) swap(ix,iy);
ispin[0]=iya;
ispin[1]=ixa;
(*ME())(ispin) = Complex(_inHalf[iy].generalScalar(_inHalfBar[ix],left,right)*
UnitRemoval::E/msum/inpart.mass());
}
}
double output = (ME()->contract(_rho)).real();
// test of the matrix element
// Energy m1(inpart.mass()),m2(decay[0]->mass()),m3(decay[1]->mass());
// Energy Qp(sqrt(sqr(m1+m2)-sqr(m3))),Qm(sqrt(sqr(m1-m2)-sqr(m3)));
// double r23(sqrt(2./3.));
// Energy pcm(Kinematics::pstarTwoBodyDecay(m1,m2,m3));
// complex<Energy> h1(-2.*r23*pcm*Qm*B/(m1+m2)),h2( 2.*r23*pcm*Qp*A/(m1+m2));
// cout << "testing 3/2->1/2 0 " << inpart.id() << " "
// << output << " "
// << 0.125*(h1*conj(h1)+h2*conj(h2))/sqr(inpart.mass()) << " "
// << 0.125*(h1*conj(h1)+h2*conj(h2))/sqr(inpart.mass())/output << endl;
// return the answer
return output;
}
// matrix element for the decay of a spin-3/2 fermion to a spin-3/2 fermion and
// a scalar meson
double Baryon1MesonDecayerBase::threeHalfThreeHalfScalar(const int,
const Particle & inpart,
const ParticleVector & decay,
MEOption meopt) const {
if(!ME())
ME(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin3Half,PDT::Spin3Half,PDT::Spin0)));
// spinors etc for the decaying particle
if(meopt==Initialize) {
// spinors and rho
if(inpart.id()>0) {
RSSpinorWaveFunction ::calculateWaveFunctions(_inThreeHalf,_rho,
const_ptr_cast<tPPtr>(&inpart),
incoming);
}
else {
RSSpinorBarWaveFunction::calculateWaveFunctions(_inThreeHalfBar,_rho,
const_ptr_cast<tPPtr>(&inpart),
incoming);
}
// matrix element
}
// setup spin info when needed
if(meopt==Terminate) {
// for the decaying particle
if(inpart.id()>0) {
RSSpinorWaveFunction::
constructSpinInfo(_inThreeHalf,const_ptr_cast<tPPtr>(&inpart),incoming,true);
RSSpinorBarWaveFunction::constructSpinInfo(_inThreeHalfBar,
decay[0],outgoing,true);
}
else {
RSSpinorBarWaveFunction::
constructSpinInfo(_inThreeHalfBar,const_ptr_cast<tPPtr>(&inpart),incoming,true);
RSSpinorWaveFunction::constructSpinInfo(_inThreeHalf,
decay[0],outgoing,true);
}
ScalarWaveFunction::constructSpinInfo(decay[1],outgoing,true);
return 0.;
}
// spinors for the decay product
LorentzPolarizationVector in=UnitRemoval::InvE*inpart.momentum();
if(inpart.id()>0) {
RSSpinorBarWaveFunction::
calculateWaveFunctions(_inThreeHalfBar,decay[0],outgoing);
}
else {
RSSpinorWaveFunction::
calculateWaveFunctions(_inThreeHalf,decay[0],outgoing);
}
_inHalf.resize(_inThreeHalf.size());
_inHalfBar.resize(_inThreeHalfBar.size());
for(unsigned int ix=0;ix<_inThreeHalf.size();++ix) {
_inHalf[ix] = _inThreeHalf[ix].dot(in);
_inHalfBar[ix] = _inThreeHalfBar[ix].dot(in);
}
// get the couplings
Complex A1,B1,A2,B2;
Energy msum(inpart.mass()+decay[0]->mass());
threeHalfThreeHalfScalarCoupling(imode(),inpart.mass(),decay[0]->mass(),
decay[1]->mass(),A1,A2,B1,B2);
Complex left1,right1,left2,right2;
// incoming particle
if(inpart.id()>0) {
left1=(A1-B1); right1=(A1+B1);
left2=(A2-B2); right2=(A2+B2);
}
// incoming anti-particle
else {
left1=(A1+B1); right1=(A1-B1);
left2=(A2+B2); right2=(A2-B2);
}
// compute the matrix element
vector<unsigned int> ispin(3,0);
for(unsigned ixa=0;ixa<4;++ixa) {
for(unsigned iya=0;iya<4;++iya) {
unsigned int iy=iya,ix=ixa;
if(decay[0]->id()<0) swap(ix,iy);
ispin[0]=iya;
ispin[1]=ixa;
(*ME())(ispin)=Complex((_inThreeHalf[iy].generalScalar(_inThreeHalfBar[ix],left1,right1)
+_inHalf[iy].generalScalar( _inHalfBar[ix],left2,right2)
*UnitRemoval::E2/sqr(msum))/inpart.mass());
}
}
// return the answer
return (ME()->contract(_rho)).real();
}
// matrix element for the decay of a spin-3/2 fermion to a spin-1/2 fermion and
// a vector meson
double Baryon1MesonDecayerBase::
threeHalfHalfVector(const int,const Particle & inpart,
const ParticleVector & decay,MEOption meopt) const {
if(!ME())
ME(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin3Half,PDT::Spin1Half,PDT::Spin1)));
// check if the outgoing meson is really a photon
bool photon=decay[1]->id()==ParticleID::gamma;
// spinors etc for the decaying particle
if(meopt==Initialize) {
// spinors and rho
if(inpart.id()>0) {
RSSpinorWaveFunction ::calculateWaveFunctions(_inThreeHalf,_rho,
const_ptr_cast<tPPtr>(&inpart),
incoming);
}
else {
RSSpinorBarWaveFunction::calculateWaveFunctions(_inThreeHalfBar,_rho,
const_ptr_cast<tPPtr>(&inpart),
incoming);
}
// matrix element
}
// setup spin info when needed
if(meopt==Terminate) {
// for the decaying particle
if(inpart.id()>0) {
RSSpinorWaveFunction::
constructSpinInfo(_inThreeHalf,const_ptr_cast<tPPtr>(&inpart),incoming,true);
SpinorBarWaveFunction::constructSpinInfo(_inHalfBar,decay[0],outgoing,true);
}
else {
RSSpinorBarWaveFunction::
constructSpinInfo(_inThreeHalfBar,const_ptr_cast<tPPtr>(&inpart),incoming,true);
SpinorWaveFunction::constructSpinInfo(_inHalf,decay[0],outgoing,true);
}
VectorWaveFunction::constructSpinInfo(_inVec,decay[1],outgoing,true,photon);
return 0.;
}
// spinors for the decay product
if(inpart.id()>0) {
SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,decay[0],outgoing);
}
else {
SpinorWaveFunction ::calculateWaveFunctions(_inHalf,decay[0],outgoing);
}
LorentzPolarizationVector out=UnitRemoval::InvE*decay[0]->momentum();
if(inpart.id()>0) {
_inHalf.resize(_inThreeHalf.size());
for(unsigned int ix=0;ix<_inThreeHalf.size();++ix)
_inHalf[ix] = _inThreeHalf[ix].dot(out);
}
else {
_inHalfBar.resize(_inThreeHalfBar.size());
for(unsigned int ix=0;ix<_inThreeHalfBar.size();++ix)
_inHalfBar[ix] = _inThreeHalfBar[ix].dot(out);
}
ME()->zero();
VectorWaveFunction::calculateWaveFunctions(_inVec,decay[1],outgoing,photon);
// get the couplings
- Complex A1,A2,A3,B1,B2,B3,prod,meout;
+ Complex A1,A2,A3,B1,B2,B3,prod;
threeHalfHalfVectorCoupling(imode(),inpart.mass(),decay[0]->mass(),decay[1]->mass(),
A1,A2,A3,B1,B2,B3);
Energy msum(inpart.mass()+decay[0]->mass());
Complex lS,rS,lV,rV,left,right;
// incoming particle
if(inpart.id()>0) {
lS=(A3-B3);rS=(A3+B3);
lV=(A2-B2);rV=(A2+B2);
left=(A1-B1);right=(A1+B1);
}
// incoming anti-particle
else {
lS=conj(A3+B3);rS=conj(A3-B3);
lV=-conj(A2-B2);rV=-conj(A2+B2);
left=conj(A1+B1);right=conj(A1-B1);
}
// compute the matrix element
vector<unsigned int> ispin(3);
LorentzVector<complex<Energy> > svec;
LorentzSpinor<SqrtEnergy> stemp;
LorentzSpinorBar<SqrtEnergy> sbtemp;
complex<Energy> scalar;
for(unsigned iya=0;iya<4;++iya) {
ispin[0]=iya;
for(unsigned ixa=0;ixa<2;++ixa) {
unsigned int iy=iya,ix=ixa;
if(decay[0]->id()<0) swap(ix,iy);
scalar = _inHalf[iy].generalScalar( _inHalfBar[ix],lS,rS);
svec = _inHalf[iy].generalCurrent(_inHalfBar[ix],lV,rV);
ispin[1]=ixa;
for(unsigned int iz=0;iz<3;++iz) {
ispin[2]=iz;
prod=_inVec[iz].dot(decay[0]->momentum())/msum;
(*ME())(ispin) += (svec.dot(_inVec[iz])+prod*scalar)*
UnitRemoval::E/msum/inpart.mass();
}
}
// the piece where the vector spinor is dotted with the polarization vector
for(unsigned iz=0;iz<3;++iz) {
ispin[2]=iz;
if(decay[0]->id()>0) stemp = _inThreeHalf[iya].dot(_inVec[iz]);
else sbtemp = _inThreeHalfBar[iya].dot(_inVec[iz]);
for(unsigned int ixa=0;ixa<2;++ixa) {
ispin[1]=ixa;
if(decay[0]->id()>0) sbtemp = _inHalfBar[ixa];
else stemp = _inHalf[ixa];
(*ME())(ispin) += Complex(stemp.generalScalar(sbtemp,left,right)/inpart.mass());
}
}
}
double output = (ME()->contract(_rho)).real();
// testing code
// Energy m1(inpart.mass()),m2(decay[0]->mass()),m3(decay[1]->mass());
// Energy2 m12(m1*m1),m22(m2*m2),m32(m3*m3);
// Energy Qp(sqrt(sqr(m1+m2)-sqr(m3))),Qm(sqrt(sqr(m1-m2)-sqr(m3)));
// double r2(sqrt(2.)),r3(sqrt(3.));
// Energy pcm(Kinematics::pstarTwoBodyDecay(m1,m2,m3));
// complex<Energy> h1(-2.*Qp*A1),h2(2.*Qm*B1);
// complex<Energy> h3(-2./r3*Qp*(A1-Qm*Qm/m1*A2/msum));
// complex<Energy> h4( 2./r3*Qm*(B1-Qp*Qp/m1*B2/msum));
// complex<Energy> h5(-2.*r2/r3/m1/m3*Qp*(0.5*(m22-m12-m32)*A1+0.5*Qm*Qm*(m1+m2)*A2/msum
// +m12*pcm*pcm*A3/msum/msum));
// complex<Energy> h6( 2.*r2/r3/m1/m3*Qm*(0.5*(m22-m12-m32)*B1-0.5*Qp*Qp*(m2-m1)*B2/msum
// +m22*pcm*pcm*B3/msum/msum));
// cout << "testing 3/2->1/2 1 " << inpart.id() << " "
// << output << " "
// << 0.25*(h1*conj(h1)+h2*conj(h2)+h3*conj(h3)+
// h4*conj(h4)+h5*conj(h5)+h6*conj(h6))/sqr(inpart.mass()) << " "
// << 0.25*(h1*conj(h1)+h2*conj(h2)+h3*conj(h3)+
// h4*conj(h4)+h5*conj(h5)+h6*conj(h6))/sqr(inpart.mass())/output << endl;
// return the answer
return output;
}
void Baryon1MesonDecayerBase::halfHalfScalarCoupling(int,Energy,Energy,Energy,
Complex&,Complex&) const {
throw DecayIntegratorError() << "Baryon1MesonDecayerBase::halfHalfScalarCoupling()"
<< " called from base class this must be implemented"
<< " in the inheriting class" << Exception::abortnow;
}
void Baryon1MesonDecayerBase::halfHalfVectorCoupling(int,Energy,Energy,Energy,
Complex&,Complex&,
Complex&,Complex&) const {
throw DecayIntegratorError() << "Baryon1MesonDecayerBase::halfHalfVectorCoupling()"
<< " called from base class this must be implemented "
<< "in the inheriting class" << Exception::abortnow;
}
void Baryon1MesonDecayerBase::halfThreeHalfScalarCoupling(int,Energy,Energy,Energy,
Complex&,Complex&) const {
throw DecayIntegratorError() << "Baryon1MesonDecayerBase::halfThreeHalfScalarCoupling"
<< "() called from base class this must be implemented"
<< " in the inheriting class" << Exception::abortnow;
}
void Baryon1MesonDecayerBase::halfThreeHalfVectorCoupling(int,Energy,Energy,Energy,
Complex&,Complex&,
Complex&,Complex&,
Complex&,Complex&) const {
throw DecayIntegratorError() << "Baryon1MesonDecayerBase::halfThreeHalfVectorCoupling"
<< "() called from base class this must be implemented "
<< "in the inheriting class" << Exception::abortnow;
}
void Baryon1MesonDecayerBase::threeHalfHalfScalarCoupling(int,Energy,Energy,Energy,
Complex&,Complex&) const {
throw DecayIntegratorError() << "Baryon1MesonDecayerBase::threeHalfHalfScalarCoupling"
<< "() called from base class this must be implemented"
<< " in the inheriting class" << Exception::abortnow;
}
void Baryon1MesonDecayerBase::threeHalfHalfVectorCoupling(int,Energy,Energy,Energy,
Complex&,Complex&,
Complex&,Complex&,
Complex&,Complex&) const {
throw DecayIntegratorError() << "Baryon1MesonDecayerBase::threeHalfHalfVectorCoupling"
<< "() called from base class this must be implemented "
<< "in the inheriting class" << Exception::abortnow;
}
void Baryon1MesonDecayerBase::threeHalfThreeHalfScalarCoupling(int,Energy,Energy,
Energy,Complex&,
Complex&,Complex&,
Complex&) const {
throw DecayIntegratorError() << "Baryon1MesonDecayerBase::threeHalfThreeHalfScalar"
<< "Coupling() called from base class this must be "
<< "implemented in the inheriting class"
<< Exception::abortnow;
}
bool Baryon1MesonDecayerBase::twoBodyMEcode(const DecayMode & dm,int & mecode,
double & coupling) const {
coupling=1.;
unsigned int inspin(dm.parent()->iSpin()),outspin,outmes;
ParticleMSet::const_iterator pit(dm.products().begin());
bool order;
if((**pit).iSpin()%2==0) {
order=true;
outspin=(**pit).iSpin();
++pit;outmes=(**pit).iSpin();
}
else {
order=false;
outmes=(**pit).iSpin();++pit;
outspin=(**pit).iSpin();
}
mecode=-1;
if(inspin==2) {
if(outspin==2){if(outmes==1){mecode=101;}else{mecode=102;}}
else if(outspin==4){if(outmes==1){mecode=103;}else{mecode=104;}}
}
else if(inspin==4) {
if(outspin==2){if(outmes==1){mecode=105;}else{mecode=106;}}
else if(outspin==4){if(outmes==1){mecode=107;}else{mecode=108;}}
}
return order;
}
void Baryon1MesonDecayerBase::dataBaseOutput(ofstream & os,bool header) const {
DecayIntegrator::dataBaseOutput(os,header);
}
diff --git a/Decay/FormFactors/ChengHeavyBaryonFormFactor.cc b/Decay/FormFactors/ChengHeavyBaryonFormFactor.cc
--- a/Decay/FormFactors/ChengHeavyBaryonFormFactor.cc
+++ b/Decay/FormFactors/ChengHeavyBaryonFormFactor.cc
@@ -1,440 +1,440 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the ChengHeavyBaryonFormFactor class.
//
#include "ChengHeavyBaryonFormFactor.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/ParVector.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
using namespace ThePEG;
ChengHeavyBaryonFormFactor::ChengHeavyBaryonFormFactor() {
// consituent quark masses
_mu = 338*MeV;
_md = 322*MeV;
_ms = 510*MeV;
_mc = 1.6*GeV;
_mb = 5.0*GeV;
// masses for the q^2 dependence
_mVbc = 6.34*GeV;
_mVbs = 5.42*GeV;
_mVcs = 2.11*GeV;
_mVbd = 5.32*GeV;
_mVcu = 2.01*GeV;
_mAbc = 6.73*GeV;
_mAbs = 5.86*GeV;
_mAcs = 2.54*GeV;
_mAbd = 5.71*GeV;
_mAcu = 2.42*GeV;
double one3(1./sqrt(3.)),one2(1./sqrt(2.));
// lambda_b to lambda_c
addFormFactor(5122,4122,2,2,1,2,5,4);_Nfi.push_back(1. );_eta.push_back(1.);
// lambda_b to lambda
addFormFactor(5122,3122,2,2,1,2,5,3);_Nfi.push_back(one3 );_eta.push_back(1.);
// lambda_b to n
addFormFactor(5122,2112,2,2,1,2,5,1);_Nfi.push_back(one2 );_eta.push_back(1.);
// xi_b to xi_c
addFormFactor(5232,4232,2,2,2,3,5,4);_Nfi.push_back(1. );_eta.push_back(1.);
addFormFactor(5132,4132,2,2,1,3,5,4);_Nfi.push_back(1. );_eta.push_back(1.);
// xi_b to xi
addFormFactor(5232,3322,2,2,2,3,5,3);_Nfi.push_back(one2 );_eta.push_back(1.);
addFormFactor(5132,3312,2,2,1,3,5,3);_Nfi.push_back(one2 );_eta.push_back(1.);
// xi_b to sigma
addFormFactor(5232,3212,2,2,2,3,5,1);_Nfi.push_back(0.5 );_eta.push_back(1.);
addFormFactor(5132,3112,2,2,1,3,5,1);_Nfi.push_back(0.5 );_eta.push_back(1.);
// xi_b to lambda
addFormFactor(5232,3122,2,2,2,3,5,1);_Nfi.push_back(one3/2.);_eta.push_back(1.);
// omega_b to omega_c
addFormFactor(5332,4332,2,2,3,3,5,4);_Nfi.push_back(1. );_eta.push_back(-1./3.);
// omega_b to xi
addFormFactor(5332,3312,2,2,3,3,5,1);_Nfi.push_back(one3 );_eta.push_back(-1./3.);
// omega_b to omega_c*
addFormFactor(5332,4334,2,4,3,3,5,4);_Nfi.push_back(1. );_eta.push_back(0.);
// omega_b to omega
addFormFactor(5332,3334,2,4,3,3,5,3);_Nfi.push_back(1. );_eta.push_back(0.);
// omega_b to xi*
addFormFactor(5332,3314,2,4,3,3,5,1);_Nfi.push_back(one3 );_eta.push_back(0.);
// omega_c to omega
addFormFactor(4332,3334,2,4,3,3,4,3);_Nfi.push_back(1. );_eta.push_back(0.);
// omega_c to xi*
addFormFactor(4332,3324,2,4,3,3,4,2);_Nfi.push_back(one3 );_eta.push_back(0.);
// lambda_c to lambda_0
addFormFactor(4122,3122,2,2,1,2,4,3);_Nfi.push_back(1./sqrt(3.));_eta.push_back(1.);
// xi_c to xi
addFormFactor(4232,3322,2,2,2,3,4,3);_Nfi.push_back(1./sqrt(3.));_eta.push_back(1.);
addFormFactor(4132,3312,2,2,1,3,4,3);_Nfi.push_back(1./sqrt(3.));_eta.push_back(1.);
// initial number of form factors
initialModes(numberOfFactors());
}
void ChengHeavyBaryonFormFactor::doinit() {
BaryonFormFactor::doinit();
// check the parameters are consistent
unsigned int isize(numberOfFactors());
if(isize!=_eta.size()||isize!=_Nfi.size())
{throw InitException() << "Inconsistent paramters in ChengHeavyBaryon"
<< "FormFactor::doinit() " << Exception::abortnow;}
Energy mi,mf,mq,mQ,lambda,delta,msum;
int id0,id1,inspin,outspin,isp1,isp2,inq,outq;
for(unsigned int ix=0;ix<numberOfFactors();++ix)
{
// ids of the external particles
particleID(ix,id0,id1);
formFactorInfo(ix,inspin,outspin,isp1,isp2,inq,outq);
id0=abs(id0);id1=abs(id1);
mi=getParticleData(id0)->mass();
mf=getParticleData(id1)->mass();
msum=mi+mf;
// masses of the incoming and outgoing quarks
if((id0==4122&&id1==3122)||(id0==4232&&id1==3322)||(id0==4132&&id1==3312)||
(id0==4332&&id1==3334))
{mq=_ms;mQ=_mc;}
else if((id0==4332&&id1==3322)||(id0==4332&&id1==3324))
{mq=_mu;mQ=_mc;}
else if((id0==5122&&id1==4122)||(id0==5232&&id1==4232)||(id0==5132&&id1==4132)||
(id0==5332&&id1==4332)||(id0==5332&&id1==4334))
{mq=_mc;mQ=_mb;}
else if((id0==5122&&id1==3122)||(id0==5132&&id1==3312)||(id0==5232&&id1==3322)||
(id0==5332&&id1==3334))
{mq=_ms;mQ=_mb;}
else if((id0==5122&&id1==2112)||(id0==5132&&id1==3112)||(id0==5232&&id1==3212)||
(id0==5332&&id1==3312)||(id0==5232&&id1==3122)||(id0==5332&&id1==3314))
{mq=_md;mQ=_mb;}
else
{throw InitException() << "Unknown decay in ChengHeavyBaryon"
<< "FormFactor::doinit() " << Exception::abortnow;}
// parameters
lambda = mf-mq;
delta = mi-mf;
// compute the form-factors
if(inspin==2&&outspin==2)
{
_f1.push_back(_Nfi[ix]*(1.-0.5*delta/mi
+0.25*delta/mi/mq*(1.-0.5*lambda/mf)*
(mi+mf-_eta[ix]*delta)
-0.125*delta/mi/mf/mQ*lambda*(mi+mf+_eta[ix]*delta)));
_f2.push_back(_Nfi[ix]*msum*(0.5/mi+0.25/mi/mq*(1.-0.5*lambda/mf)*
(delta-(mi+mf)*_eta[ix])
-0.125*lambda/mi/mf/mQ*(delta+(mi+mf)*_eta[ix])));
_f3.push_back(_Nfi[ix]*msum*(0.5/mi-0.25/mi/mq*(1.-0.5*lambda/mf)*
(mi+mf-_eta[ix]*delta)
+0.125*lambda/mi/mf/mQ*(mi+mf+_eta[ix]*delta)));
_g1.push_back(_Nfi[ix]*_eta[ix]*(1.+0.25*delta*lambda*(1./mi/mq-1./mf/mQ)));
_g2.push_back(-0.25*msum*_Nfi[ix]*_eta[ix]*lambda*(1./mi/mq-1./mf/mQ));
_g3.push_back(-0.25*msum*_Nfi[ix]*_eta[ix]*lambda*(1./mi/mq+1./mf/mQ));
}
else if(inspin==2&&outspin==4)
{
_f1.push_back(2.*_Nfi[ix]/sqrt(3.)*(1.+0.5*lambda*(1./mq+1./mQ)));
_f2.push_back(_Nfi[ix]*msum/sqrt(3.)/mi*(1.+0.5*lambda*(1./mq+1./mQ)));
_f3.push_back(-_Nfi[ix]*msum*msum/mi/mf/sqrt(3.)*
(1.+0.5*lambda*(1./mq+1./mQ)));
_g1.push_back(-2./sqrt(3.)*_Nfi[ix]);
_g2.push_back(-_Nfi[ix]*msum/sqrt(3.)*lambda/mq/mi);
_g3.push_back(-_f3.back());
}
else
{throw InitException() << "Unknown spin combination in ChengHeavyBaryon"
<< "FormFactor::doinit() " << Exception::abortnow;}
}
for(unsigned int ix=0;ix<numberOfFactors();++ix)
{
int id0,id1;
particleID(ix,id0,id1);
tcPDPtr part0=getParticleData(id0); Energy m0=part0->mass();
tcPDPtr part1=getParticleData(id1); Energy m1=part1->mass();
if ( part1->iSpin() == 2 ) {
- Complex f1v,f2v,f3v,f4v,f1a,f2a,f3a,f4a; // dummy variables
+ Complex f1v,f2v,f3v,f1a,f2a,f3a; // dummy variables
SpinHalfSpinHalfFormFactor(ZERO,ix,id0,id1,m0,m1,f1v,f2v,f3v,f1a,f2a,f3a);
}
else {
Complex f1v,f2v,f3v,f4v,f1a,f2a,f3a,f4a; // dummy variables
SpinHalfSpinThreeHalfFormFactor(ZERO,ix,id0,id1,m0,m1,f1v,f2v,f3v,
f4v,f1a,f2a,f3a,f4a);
}
}
}
void ChengHeavyBaryonFormFactor::persistentOutput(PersistentOStream & os) const {
os << ounit(_mu,MeV) << ounit(_md,MeV) << ounit(_ms,MeV) << ounit(_mc,MeV) << ounit(_mb,MeV)
<< _Nfi << _eta << _f1 << _f2 << _f3
<< _g1 << _g2 << _g3 << ounit(_mVbc,MeV) << ounit(_mVbs,MeV) << ounit(_mVcs,MeV)
<< ounit(_mVbd,MeV) << ounit(_mVcu,MeV) << ounit(_mAbc,MeV)
<< ounit(_mAbs,MeV) << ounit(_mAcs,MeV) << ounit(_mAbd,MeV) << ounit(_mAcu,MeV);
}
void ChengHeavyBaryonFormFactor::persistentInput(PersistentIStream & is, int) {
is >> iunit(_mu,MeV) >> iunit(_md,MeV) >> iunit(_ms,MeV) >> iunit(_mc,MeV) >> iunit(_mb,MeV)
>> _Nfi >> _eta >> _f1 >> _f2 >> _f3
>> _g1 >> _g2 >> _g3 >> iunit(_mVbc,MeV) >> iunit(_mVbs,MeV) >> iunit(_mVcs,MeV)
>> iunit(_mVbd,MeV) >> iunit(_mVcu,MeV) >> iunit(_mAbc,MeV)
>> iunit(_mAbs,MeV) >> iunit(_mAcs,MeV) >> iunit(_mAbd,MeV) >> iunit(_mAcu,MeV);
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<ChengHeavyBaryonFormFactor,BaryonFormFactor>
describeHerwigChengHeavyBaryonFormFactor("Herwig::ChengHeavyBaryonFormFactor", "HwFormFactors.so");
void ChengHeavyBaryonFormFactor::Init() {
static ClassDocumentation<ChengHeavyBaryonFormFactor> documentation
("The ChengHeavyBaryonFormFactor class is the implementation"
" of the form-factors of PRD53, 1457 and PRD56, 2799 for the weak decay of"
"baryons containing a heavy quark. This model can be used for either"
"semi-leptonic decays, or with the factorization approximation for"
" non-leptonic weak decays",
"The weak decay of baryons containing a heavy quark used form factors from "
"\\cite{Cheng:1995fe,Cheng:1996cs}.",
"%\\cite{Cheng:1995fe}\n"
"\\bibitem{Cheng:1995fe}\n"
" H.~Y.~Cheng and B.~Tseng,\n"
" %``1/M corrections to baryonic form-factors in the quark model,''\n"
" Phys.\\ Rev.\\ D {\\bf 53} (1996) 1457\n"
" [Erratum-ibid.\\ D {\\bf 55} (1997) 1697]\n"
" [arXiv:hep-ph/9502391].\n"
" %%CITATION = PHRVA,D53,1457;%%\n"
"%\\cite{Cheng:1996cs}\n"
"\\bibitem{Cheng:1996cs}\n"
" H.~Y.~Cheng,\n"
" %``Nonleptonic weak decays of bottom baryons,''\n"
" Phys.\\ Rev.\\ D {\\bf 56} (1997) 2799\n"
" [arXiv:hep-ph/9612223].\n"
" %%CITATION = PHRVA,D56,2799;%%\n"
);
static Parameter<ChengHeavyBaryonFormFactor,Energy> interfaceUpMass
("DownMass",
"The consituent mass of the down quark",
&ChengHeavyBaryonFormFactor::_md, GeV, 0.322*GeV, ZERO, 10.0*GeV,
false, false, true);
static Parameter<ChengHeavyBaryonFormFactor,Energy> interfaceDownMass
("UpMass",
"The consituent mass of the up quark",
&ChengHeavyBaryonFormFactor::_mu, GeV, 0.338*GeV, ZERO, 10.0*GeV,
false, false, true);
static Parameter<ChengHeavyBaryonFormFactor,Energy> interfacStrangeMass
("StrangeMass",
"The consituent mass of the strange quark",
&ChengHeavyBaryonFormFactor::_ms, GeV, 0.510*GeV, ZERO, 10.0*GeV,
false, false, true);
static Parameter<ChengHeavyBaryonFormFactor,Energy> interfaceCharmMass
("CharmMass",
"The consituent mass of the charm quark",
&ChengHeavyBaryonFormFactor::_mc, GeV, 1.6*GeV, ZERO, 10.0*GeV,
false, false, true);
static Parameter<ChengHeavyBaryonFormFactor,Energy> interfaceBottomMass
("BottomMass",
"The consituent mass of the bottom quark",
&ChengHeavyBaryonFormFactor::_mb, GeV, 5.0*GeV, ZERO, 10.0*GeV,
false, false, true);
static Parameter<ChengHeavyBaryonFormFactor,Energy> interfaceVectorMassbc
("VectorMassbc",
"The vector mass for the b->c transitions.",
&ChengHeavyBaryonFormFactor::_mVbc, GeV, 6.34*GeV, ZERO, 10.0*GeV,
false, false, true);
static Parameter<ChengHeavyBaryonFormFactor,Energy> interfaceAxialMassbc
("AxialMassbc",
"The axial-vector mass for the b->c transitions.",
&ChengHeavyBaryonFormFactor::_mAbc, GeV, 6.73*GeV, ZERO, 10.0*GeV,
false, false, true);
static Parameter<ChengHeavyBaryonFormFactor,Energy> interfaceVectorMassbs
("VectorMassbs",
"The vector mass for the b->s transitions.",
&ChengHeavyBaryonFormFactor::_mVbs, GeV, 5.42*GeV, ZERO, 10.0*GeV,
false, false, true);
static Parameter<ChengHeavyBaryonFormFactor,Energy> interfaceAxialMassbs
("AxialMassbs",
"The axial-vector mass for the b->s transitions.",
&ChengHeavyBaryonFormFactor::_mAbs, GeV, 5.86*GeV, ZERO, 10.0*GeV,
false, false, true);
static Parameter<ChengHeavyBaryonFormFactor,Energy> interfaceVectorMassbd
("VectorMassbd",
"The vector mass for the b->d transitions.",
&ChengHeavyBaryonFormFactor::_mVbd, GeV, 5.32*GeV, ZERO, 10.0*GeV,
false, false, true);
static Parameter<ChengHeavyBaryonFormFactor,Energy> interfaceAxialMassbd
("AxialMassbd",
"The axial-vector mass for the b->d transitions.",
&ChengHeavyBaryonFormFactor::_mAbd, GeV, 5.71*GeV, ZERO, 10.0*GeV,
false, false, true);
static Parameter<ChengHeavyBaryonFormFactor,Energy> interfaceVectorMasscs
("VectorMasscs",
"The vector mass for the c->s transitions.",
&ChengHeavyBaryonFormFactor::_mVcs, GeV, 2.11*GeV, ZERO, 10.0*GeV,
false, false, true);
static Parameter<ChengHeavyBaryonFormFactor,Energy> interfaceAxialMasscs
("AxialMasscs",
"The axial-vector mass for the c->s transitions.",
&ChengHeavyBaryonFormFactor::_mAcs, GeV, 2.54*GeV, ZERO, 10.0*GeV,
false, false, true);
static Parameter<ChengHeavyBaryonFormFactor,Energy> interfaceVectorMasscu
("VectorMasscu",
"The vector mass for the c->u transitions.",
&ChengHeavyBaryonFormFactor::_mVcu, GeV, 2.01*GeV, ZERO, 10.0*GeV,
false, false, true);
static Parameter<ChengHeavyBaryonFormFactor,Energy> interfaceAxialMasscu
("AxialMasscu",
"The axial-vector mass for the c->u transitions.",
&ChengHeavyBaryonFormFactor::_mAcu, GeV, 2.42*GeV, ZERO, 10.0*GeV,
false, false, true);
static ParVector<ChengHeavyBaryonFormFactor,double> interfaceNfi
("Nfi",
"The prefactor for a given form factor",
&ChengHeavyBaryonFormFactor::_Nfi, -1, 1.0, -10.0, 10.0,
false, false, true);
static ParVector<ChengHeavyBaryonFormFactor,double> interfaceEta
("Eta",
"The eta parameter for the form factor",
&ChengHeavyBaryonFormFactor::_eta, -1, 0.0, -10.0, 10.0,
false, false, true);
}
// form factor for spin-1/2 to spin-1/2
void ChengHeavyBaryonFormFactor::
SpinHalfSpinHalfFormFactor(Energy2 q2,int iloc,int id0,int id1, Energy m0,Energy m1,
Complex & f1v,Complex & f2v,Complex & f3v,
Complex & f1a,Complex & f2a,Complex & f3a)
{
useMe();
id0=abs(id0);
id1=abs(id1);
// masses for the energy dependence of the form-factors
Energy mV(ZERO),mA(ZERO);
if((id0==4122&&id1==3122)||(id0==4232&&id1==3322)||(id0==4132&&id1==3312)||
(id0==4332&&id1==3334))
{mA=_mAcs;mV=_mVcs;}
else if((id0==4332&&id1==3322)||(id0==4332&&id1==3324))
{mA=_mAcu;mV=_mVcu;}
else if((id0==5122&&id1==4122)||(id0==5232&&id1==4232)||(id0==5132&&id1==4132)||
(id0==5332&&id1==4332)||(id0==5332&&id1==4334))
{mA=_mAbc;mV=_mVbc;}
else if((id0==5122&&id1==3122)||(id0==5132&&id1==3312)||(id0==5232&&id1==3322)||
(id0==5332&&id1==3334))
{mA=_mAbs;mV=_mVbs;}
else if((id0==5122&&id1==2112)||(id0==5132&&id1==3112)||(id0==5232&&id1==3212)||
(id0==5332&&id1==3312)||(id0==5232&&id1==3122)||(id0==5332&&id1==3314))
{mA=_mAbd;mV=_mVbd;}
Energy delta=m0-m1;
double Vfact = (1.-delta*delta/mV/mV)/(1.-q2/mV/mV);
Vfact *=Vfact;
double Afact = (1.-delta*delta/mA/mA)/(1.-q2/mA/mA);
Afact *=Afact;
f1v = _f1[iloc]*Vfact;
f2v = _f2[iloc]*Vfact;
f3v = _f3[iloc]*Vfact;
f1a =-_g1[iloc]*Afact;
f2a =-_g2[iloc]*Afact;
f3a =-_g3[iloc]*Afact;
}
// form factor for spin-1/2 to spin-3/2
void ChengHeavyBaryonFormFactor::
SpinHalfSpinThreeHalfFormFactor(Energy2 q2,int iloc, int id0, int id1,
Energy m0, Energy m1,
Complex & g1v,Complex & g2v,Complex & g3v,
Complex & g4v,Complex & g1a,Complex & g2a,
Complex & g3a,Complex & g4a)
{
useMe();
id0=abs(id0);
id1=abs(id1);
// masses for the energy dependence of the form-factors
Energy mV(ZERO),mA(ZERO);
if((id0==4122&&id1==3122)||(id0==4232&&id1==3322)||(id0==4132&&id1==3312)||
(id0==4332&&id1==3334))
{mA=_mAcs;mV=_mVcs;}
else if((id0==4332&&id1==3322)||(id0==4332&&id1==3324))
{mA=_mAcu;mV=_mVcu;}
else if((id0==5122&&id1==4122)||(id0==5232&&id1==4232)||(id0==5132&&id1==4132)||
(id0==5332&&id1==4332)||(id0==5332&&id1==4334))
{mA=_mAbc;mV=_mVbc;}
else if((id0==5122&&id1==3122)||(id0==5132&&id1==3312)||(id0==5232&&id1==3322)||
(id0==5332&&id1==3334))
{mA=_mAbs;mV=_mVbs;}
else if((id0==5122&&id1==2112)||(id0==5132&&id1==3112)||(id0==5232&&id1==3212)||
(id0==5332&&id1==3312)||(id0==5232&&id1==3122)||(id0==5332&&id1==3314))
{mA=_mAbd;mV=_mVbd;}
Energy delta=m0-m1;
double Vfact = (1.-delta*delta/mV/mV)/(1.-q2/mV/mV);
Vfact *=Vfact;
double Afact = (1.-delta*delta/mA/mA)/(1.-q2/mA/mA);
Afact *=Afact;
g1v = _f1[iloc]*Vfact;
g2v = _f2[iloc]*Vfact;
g3v = _f3[iloc]*Vfact;
g4v = 0.;
g1a =-_g1[iloc]*Afact;
g2a =-_g2[iloc]*Afact;
g3a =-_g3[iloc]*Afact;
g4a = 0.;
}
// output the information for the database
void ChengHeavyBaryonFormFactor::dataBaseOutput(ofstream& output,bool header,
bool create) const
{
if(header){output << "update decayers set parameters=\"";}
if(create)
{output << "create Herwig::ChengHeavyBaryonFormFactor " << name() << " \n";}
output << "newdef " << name() << ":DownMass " << _md/GeV << " \n";
output << "newdef " << name() << ":UpMass " << _mu/GeV << " \n";
output << "newdef " << name() << ":StrangeMass " << _ms/GeV << " \n";
output << "newdef " << name() << ":CharmMass " << _mc/GeV << " \n";
output << "newdef " << name() << ":BottomMass " << _mb/GeV << " \n";
output << "newdef " << name() << ":VectorMassbc " << _mVbc/GeV << " \n";
output << "newdef " << name() << ":AxialMassbc " << _mAbc/GeV << " \n";
output << "newdef " << name() << ":VectorMassbs " << _mVbs/GeV << " \n";
output << "newdef " << name() << ":AxialMassbs " << _mAbs/GeV << " \n";
output << "newdef " << name() << ":VectorMassbd " << _mVbd/GeV << " \n";
output << "newdef " << name() << ":AxialMassbd " << _mAbd/GeV << " \n";
output << "newdef " << name() << ":VectorMasscs " << _mVcs/GeV << " \n";
output << "newdef " << name() << ":AxialMasscs " << _mAcs/GeV << " \n";
output << "newdef " << name() << ":VectorMasscu " << _mVcu/GeV << " \n";
output << "newdef " << name() << ":AxialMasscu " << _mAcu/GeV << " \n";
for(unsigned int ix=0;ix<numberOfFactors();++ix)
{
if(ix<initialModes())
{
output << "newdef " << name() << ":Nfi " << ix << " "
<< _Nfi[ix] << endl;
output << "newdef " << name() << ":Eta " << ix << " "
<< _eta[ix] << endl;
}
else
{
output << "insert " << name() << ":Nfi " << ix << " "
<< _Nfi[ix] << endl;
output << "insert " << name() << ":Eta " << ix << " "
<< _eta[ix] << endl;
}
}
BaryonFormFactor::dataBaseOutput(output,false,false);
if(header){output << "\n\" where BINARY ThePEGName=\""
<< fullName() << "\";" << endl;}
}
diff --git a/Decay/Perturbative/SMTopDecayer.h b/Decay/Perturbative/SMTopDecayer.h
--- a/Decay/Perturbative/SMTopDecayer.h
+++ b/Decay/Perturbative/SMTopDecayer.h
@@ -1,408 +1,394 @@
// -*- C++ -*-
//
// SMTopDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_SMTopDecayer_H
#define HERWIG_SMTopDecayer_H
//
// This is the declaration of the SMTopDecayer class.
//
#include "Herwig/Decay/PerturbativeDecayer.h"
#include "ThePEG/Helicity/Vertex/AbstractFFVVertex.h"
#include "ThePEG/Helicity/Vertex/AbstractVVVVertex.h"
#include "Herwig/Decay/DecayPhaseSpaceMode.h"
#include "Herwig/Models/StandardModel/StandardModel.h"
#include "Herwig/Shower/ShowerAlpha.fh"
namespace Herwig {
using namespace ThePEG;
using namespace ThePEG::Helicity;
/**
* \ingroup Decay
*
* The SMTopDecayer performs decays of the top quark into
* the bottom quark and qqbar pairs or to the bottom quark and lepton
* neutrino pairs via W boson exchange.
*/
class SMTopDecayer: public PerturbativeDecayer {
public:
/**
* The default constructor.
*/
SMTopDecayer();
public:
/**
* Virtual members to be overridden by inheriting classes
* which implement hard corrections
*/
//@{
/**
* Has an old fashioned ME correction
*/
virtual bool hasMECorrection() {return true;}
/**
* Initialize the ME correction
*/
virtual void initializeMECorrection(RealEmissionProcessPtr , double & ,
double & );
/**
* Apply the soft matrix element correction
* @param parent The initial particle in the current branching
* @param progenitor The progenitor particle of the jet
* @param fs Whether the emission is initial or final-state
* @param highestpT The highest pT so far in the shower
* @param ids ids of the particles produced in the branching
* @param z The momentum fraction of the branching
* @param scale the evolution scale of the branching
* @param pT The transverse momentum of the branching
* @return If true the emission should be vetoed
*/
virtual bool softMatrixElementVeto(PPtr parent,
PPtr progenitor,
const bool & fs,
const Energy & highestpT,
const vector<tcPDPtr> & ids,
const double & z,
const Energy & scale,
const Energy & pT);
/**
* Has a POWHEG style correction
*/
virtual POWHEGType hasPOWHEGCorrection() {return FSR;}
//@}
public:
/**
* Which of the possible decays is required
*/
virtual int modeNumber(bool & , tcPDPtr , const tPDVector & ) const {return -1;}
/**
* Check if this decayer can perfom the decay for a particular mode.
* Uses the modeNumber member but can be overridden
* @param parent The decaying particle
* @param children The decay products
*/
virtual bool accept(tcPDPtr parent, const tPDVector & children) const;
/**
* For a given decay mode and a given particle instance, perform the
* decay and return the decay products. As this is the base class this
* is not implemented.
* @return The vector of particles produced in the decay.
*/
virtual ParticleVector decay(const Particle & parent,
const tPDVector & children) const;
/**
* Return the matrix element squared for a given mode and phase-space channel.
* @param ichan The channel we are calculating the matrix element for.
* @param part The decaying Particle.
* @param decay The particles produced in the decay.
* @param meopt Option for the calculation of the matrix element
* @return The matrix element squared for the phase-space configuration.
*/
virtual double me2(const int ichan, const Particle & part,
const ParticleVector & decay, MEOption meopt) const;
/**
* Method to return an object to calculate the 3 (or higher body) partial width
* @param dm The DecayMode
* @return A pointer to a WidthCalculatorBase object capable of calculating the width
*/
virtual WidthCalculatorBasePtr threeBodyMEIntegrator(const DecayMode & dm) const;
/**
* The differential three body decay rate with one integral performed.
* @param imode The mode for which the matrix element is needed.
* @param q2 The scale, \e i.e. the mass squared of the decaying particle.
* @param s The invariant mass which still needs to be integrate over.
* @param m1 The mass of the first outgoing particle.
* @param m2 The mass of the second outgoing particle.
* @param m3 The mass of the third outgoing particle.
* @return The differential rate \f$\frac{d\Gamma}{ds}\f$
*/
virtual InvEnergy threeBodydGammads(const int imode, const Energy2 q2,
const Energy2 s, const Energy m1,
const Energy m2, const Energy m3) const;
/**
* Output the setup information for the particle database
* @param os The stream to output the information to
* @param header Whether or not to output the information for MySQL
*/
virtual void dataBaseOutput(ofstream & os,bool header) const;
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:
/**
* The integrand for the integrate partial width
*/
Energy6 dGammaIntegrand(Energy2 mffb2, Energy2 mbf2, Energy mt, Energy mb,
Energy mf, Energy mfb, Energy mw) const;
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const {return new_ptr(*this);}
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const {return new_ptr(*this);}
//@}
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* Initialize this object after the setup phase before saving and
* EventGenerator to disk.
* @throws InitException if object could not be initialized properly.
*/
virtual void doinit();
/**
* Initialize this object. Called in the run phase just before
* a run begins.
*/
virtual void doinitrun();
//@}
protected:
/**
* This function determines the point (\f$x_{g}\f$) where the condition that
* \f$x_{a}\f$ be real supersedes that due to the external input
* \f$\tilde{\kappa}\f$ where, again, \f$\kappa\f$ pertains to emissions from the
* b.
*/
double xgbcut(double);
/**
* Full matrix element with a factor of \f$\frac{\alpha_SC_F}{x_g^2\pi}\f$ removed.
* @param xw The momentum fraction of the W boson
* @param xg The momentum fraction of the gluon.
*/
double me(double xw, double xg);
protected:
/**
* Calculate matrix element ratio R/B
*/
virtual double matrixElementRatio(const Particle & inpart, const ParticleVector & decay2,
const ParticleVector & decay3, MEOption meopt,
ShowerInteraction inter);
/**
* LO matrix element for \f$t\to b W^\pm\f$
*/
double loME(const Particle & inpart, const ParticleVector & decay);
/**
* LO matrix element for \f$t\to b W^\pm\f$
*/
double realME(const Particle & inpart, const ParticleVector & decay,
ShowerInteraction inter);
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
SMTopDecayer & operator=(const SMTopDecayer &) = delete;
/**
* Pointer to the W vertex
*/
AbstractFFVVertexPtr FFWVertex_;
/**
* Pointer to the gluon vertex
*/
AbstractFFVVertexPtr FFGVertex_;
/**
* Pointer to the photon vertex
*/
AbstractFFVVertexPtr FFPVertex_;
/**
* Pointer to the photon vertex
*/
AbstractVVVVertexPtr WWWVertex_;
/**
* Max weight for integration
*/
//@{
/**
* Weight \f$W\to q\bar{q}'\f$
*/
vector<double> _wquarkwgt;
/**
* Weight \f$W\to \ell \nu\f$
*/
vector<double> _wleptonwgt;
//@}
/**
* Pointer to the \f$W^\pm\f$
*/
PDPtr _wplus;
/**
* Spin density matrix for the decay
*/
mutable RhoDMatrix _rho;
/**
* 1st spinor for the decay
*/
mutable vector<SpinorWaveFunction > _inHalf;
/**
* 2nd spinor for the decay
*/
mutable vector<SpinorWaveFunction > _outHalf;
/**
* 1st barred spinor for the decay
*/
mutable vector<SpinorBarWaveFunction> _inHalfBar;
/**
* 2nd barred spinor for the decay
*/
mutable vector<SpinorBarWaveFunction> _outHalfBar;
/**
* The mass of the W boson
*/
Energy _ma;
/**
* The mass of the bottom quark
*/
Energy _mc;
/**
* The top mass
*/
Energy _mt;
/**
* The gluon mass.
*/
Energy _mg;
/**
* The mass ratio for the W.
*/
double _a;
/**
* The mass ratio for the bottom.
*/
double _c;
/**
* The mass ratio for the gluon.
*/
double _g;
/**
* Two times the energy fraction of a.
*/
double _ktb;
/**
* Two times the energy fraction of the gluon.
*/
double _ktc;
- /**
- * Two times the energy fraction of the gluon.
- */
- double _xg;
-
- /**
- * Two times the energy fraction of a.
- */
- double _xa;
-
- /**
- * Two times the energy fraction of c.
- */
- double _xc;
/**
* This determines the hard matrix element importance
* sampling in _xg. _xg_sampling=2.0 samples as 1/xg^2.
*/
double _xg_sampling;
/**
* The enhancement factor for initial-state radiation
*/
double _initialenhance;
/**
* The enhancement factor for final-state radiation
*/
double _finalenhance;
};
}
#endif /* HERWIG_SMTopDecayer_H */
diff --git a/Decay/Perturbative/SMWDecayer.h b/Decay/Perturbative/SMWDecayer.h
--- a/Decay/Perturbative/SMWDecayer.h
+++ b/Decay/Perturbative/SMWDecayer.h
@@ -1,502 +1,479 @@
// -*- C++ -*-
//
// SMWDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_SMWDecayer_H
#define HERWIG_SMWDecayer_H
//
// This is the declaration of the SMWDecayer class.
//
#include "Herwig/Decay/PerturbativeDecayer.h"
#include "ThePEG/Helicity/Vertex/Vector/FFVVertex.h"
#include "ThePEG/Helicity/Vertex/AbstractVVVVertex.h"
#include "Herwig/Decay/DecayPhaseSpaceMode.h"
namespace Herwig {
using namespace ThePEG;
using namespace ThePEG::Helicity;
/** \ingroup Decay
*
* The <code>SMWDecayer</code> is designed to perform the decay of the
* W boson to the Standard Model fermions, including the first order
* electroweak corrections.
*
* @see PerturbativeDecayer
*
*/
class SMWDecayer: public PerturbativeDecayer {
public:
/**
* Default constructor.
*/
SMWDecayer();
public:
/**
* Virtual members to be overridden by inheriting classes
* which implement hard corrections
*/
//@{
/**
* Has an old fashioned ME correction
*/
virtual bool hasMECorrection() {return true;}
/**
* Initialize the ME correction
*/
virtual void initializeMECorrection(RealEmissionProcessPtr , double & ,
double & );
/**
* Apply the soft matrix element correction
* @param parent The initial particle in the current branching
* @param progenitor The progenitor particle of the jet
* @param fs Whether the emission is initial or final-state
* @param highestpT The highest pT so far in the shower
* @param ids ids of the particles produced in the branching
* @param z The momentum fraction of the branching
* @param scale the evolution scale of the branching
* @param pT The transverse momentum of the branching
* @return If true the emission should be vetoed
*/
virtual bool softMatrixElementVeto(PPtr parent,
PPtr progenitor,
const bool & fs,
const Energy & highestpT,
const vector<tcPDPtr> & ids,
const double & z,
const Energy & scale,
const Energy & pT);
/**
* Has a POWHEG style correction
*/
virtual POWHEGType hasPOWHEGCorrection() {return FSR;}
public:
/**
* Which of the possible decays is required
* @param cc Is this mode the charge conjugate
* @param parent The decaying particle
* @param children The decay products
*/
virtual int modeNumber(bool & cc, tcPDPtr parent,
const tPDVector & children) const;
/**
* Return the matrix element squared for a given mode and phase-space channel.
* @param ichan The channel we are calculating the matrix element for.
* @param part The decaying Particle.
* @param decay The particles produced in the decay.
* @param meopt Option for the calculation of the matrix element
* @return The matrix element squared for the phase-space configuration.
*/
virtual double me2(const int ichan, const Particle & part,
const ParticleVector & decay,MEOption meopt) const;
/**
* Output the setup information for the particle database
* @param os The stream to output the information to
* @param header Whether or not to output the information for MySQL
*/
virtual void dataBaseOutput(ofstream & os,bool header) const;
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);
//@}
/**
* Standard Init function used to initialize the interfaces.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const {return new_ptr(*this);}
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const {return new_ptr(*this);}
//@}
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* Initialize this object after the setup phase before saving and
* EventGenerator to disk.
* @throws InitException if object could not be initialized properly.
*/
virtual void doinit();
/**
* Initialize this object. Called in the run phase just before
* a run begins.
*/
virtual void doinitrun();
//@}
protected:
/**
* Set the \f$\rho\f$ parameter
*/
void setRho(double);
/**
* Set the \f$\tilde{\kappa}\f$ parameters symmetrically
*/
void setKtildeSymm();
/**
* Set second \f$\tilde{\kappa}\f$, given the first.
*/
void setKtilde2();
/**
* Translate the variables from \f$x_q,x_{\bar{q}}\f$ to \f$\tilde{\kappa},z\f$
*/
//@{
/**
* Calculate \f$z\f$.
*/
double getZfromX(double, double);
/**
* Calculate \f$\tilde{\kappa}\f$.
*/
double getKfromX(double, double);
//@}
/**
* Calculate \f$x_{q},x_{\bar{q}}\f$ from \f$\tilde{\kappa},z\f$.
* @param kt \f$\tilde{\kappa}\f$
* @param z \f$z\f$
* @param x \f$x_{q}\f$
* @param xbar \f$x_{\bar{q}}\f$
*/
void getXXbar(double kt, double z, double & x, double & xbar);
/**
* Soft weight
*/
//@{
/**
* Soft quark weight calculated from \f$x_{q},x_{\bar{q}}\f$
* @param x \f$x_{q}\f$
* @param xbar \f$x_{\bar{q}}\f$
*/
double qWeight(double x, double xbar);
/**
* Soft antiquark weight calculated from \f$x_{q},x_{\bar{q}}\f$
* @param x \f$x_{q}\f$
* @param xbar \f$x_{\bar{q}}\f$
*/
double qbarWeight(double x, double xbar);
/**
* Soft quark weight calculated from \f$\tilde{q},z\f$
* @param qtilde \f$\tilde{q}\f$
* @param z \f$z\f$
*/
double qWeightX(Energy qtilde, double z);
/**
* Soft antiquark weight calculated from \f$\tilde{q},z\f$
* @param qtilde \f$\tilde{q}\f$
* @param z \f$z\f$
*/
double qbarWeightX(Energy qtilde, double z);
//@}
/**
* ????
*/
double u(double);
/**
* Vector and axial vector parts of the matrix element
*/
//@{
/**
* Vector part of the matrix element
*/
double MEV(double, double);
/**
* Axial vector part of the matrix element
*/
double MEA(double, double);
/**
* The matrix element, given \f$x_1\f$, \f$x_2\f$.
* @param x1 \f$x_1\f$
* @param x2 \f$x_2\f$
*/
double PS(double x1, double x2);
//@}
protected:
/**
* Real emission term, for use in generating the hardest emission
*/
double calculateRealEmission(double x1, double x2,
vector<PPtr> hardProcess,
double phi, double muj, double muk,
int iemit, bool subtract) const;
/**
* Calculate the ratio between NLO & LO ME
*/
double meRatio(vector<cPDPtr> partons,
vector<Lorentz5Momentum> momenta,
unsigned int iemitter,bool subtract) const;
/**
* Calculate matrix element ratio R/B
*/
virtual double matrixElementRatio(const Particle & inpart, const ParticleVector & decay2,
const ParticleVector & decay3, MEOption meopt,
ShowerInteraction inter);
/**
* Calculate the LO ME
*/
double loME(const vector<cPDPtr> & partons,
const vector<Lorentz5Momentum> & momenta) const;
/**
* Calculate the NLO real emission piece of ME
*/
InvEnergy2 realME(const vector<cPDPtr> & partons,
const vector<Lorentz5Momentum> & momenta,
ShowerInteraction inter) const;
private:
/**
* Private and non-existent assignment operator.
*/
SMWDecayer & operator=(const SMWDecayer &) = delete;
private:
/**
* Pointer to the fermion-antifermion W vertex
*/
AbstractFFVVertexPtr FFWVertex_;
/**
* Pointer to the fermion-antifermion G vertex
*/
AbstractFFVVertexPtr FFGVertex_;
/**
* Pointer to the fermion-antifermion G vertex
*/
AbstractFFVVertexPtr FFPVertex_;
/**
* Pointer to the fermion-antifermion G vertex
*/
AbstractVVVVertexPtr WWWVertex_;
/**
* maximum weights for the different integrations
*/
//@{
/**
* Weights for the W to quarks decays.
*/
vector<double> quarkWeight_;
/**
* Weights for the W to leptons decays.
*/
vector<double> leptonWeight_;
//@}
/**
* Spin density matrix for the decay
*/
mutable RhoDMatrix rho_;
/**
* Polarization vectors for the decay
*/
mutable vector<VectorWaveFunction> vectors_;
/**
* Spinors for the decay
*/
mutable vector<SpinorWaveFunction> wave_;
/**
* Barred spinors for the decay
*/
mutable vector<SpinorBarWaveFunction> wavebar_;
private:
/**
* CM energy
*/
Energy d_Q_;
/**
* Quark mass
*/
Energy d_m_;
/**
* The rho parameter
*/
double d_rho_;
/**
* The v parameter
*/
double d_v_;
/**
* The initial kappa-tilde values for radiation from the quark
*/
double d_kt1_;
/**
* The initial kappa-tilde values for radiation from the antiquark
*/
double d_kt2_;
/**
* Cut-off parameter
*/
static const double EPS_;
private:
/**
* The colour factor
*/
double CF_;
/**
* The W mass
*/
mutable Energy mW_;
- // TODO: delete this
- mutable double mu_;
-
- /**
- * The reduced mass of particle 1
- */
- mutable double mu1_;
- /**
- * The reduced mass of particle 1 squared
- */
- mutable double mu12_;
-
- /**
- * The reduceed mass of particle 2
- */
- mutable double mu2_;
-
- /**
- * The reduceed mass of particle 2 squared
- */
- mutable double mu22_;
-
-
/**
* The strong coupling
*/
mutable double aS_;
/**
* The scale
*/
mutable Energy2 scale_;
/**
* Stuff for the POWHEG correction
*/
//@{
/**
* ParticleData object for the gluon
*/
tcPDPtr gluon_;
/**
* The ParticleData objects for the fermions
*/
vector<tcPDPtr> partons_;
/**
* The fermion momenta
*/
vector<Lorentz5Momentum> quark_;
/**
* The momentum of the radiated gauge boson
*/
Lorentz5Momentum gauge_;
/**
* The W boson
*/
PPtr wboson_;
/**
* W mass squared
*/
Energy2 mw2_;
//@}
/**
* Whether ro return the LO or NLO result
*/
bool NLO_;
};
}
#endif /* HERWIG_SMWDecayer_H */
diff --git a/Decay/Radiation/IFDipole.h b/Decay/Radiation/IFDipole.h
--- a/Decay/Radiation/IFDipole.h
+++ b/Decay/Radiation/IFDipole.h
@@ -1,385 +1,381 @@
// -*- C++ -*-
//
// IFDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_IFDipole_H
#define HERWIG_IFDipole_H
//
// This is the declaration of the IFDipole class.
//
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig/Utilities/Kinematics.h"
#include "Herwig/Utilities/Maths.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Vectors/Lorentz5Vector.h"
#include "ThePEG/Interface/Interfaced.h"
#include "IFDipole.fh"
namespace Herwig {
using namespace ThePEG;
using ThePEG::Constants::pi;
/** \ingroup Decay
*
* The IFDipole class generates radiation from a final-final dipole for
* the generation of photons in decay by the SOPTHY algorithm.
*
* @see SOPTHY
* @see \ref IFDipoleInterfaces "The interfaces"
* defined for IFDipole.
*/
class IFDipole: public Interfaced {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
IFDipole() :
_alpha(), _emin(1.0*MeV), _emax(), _multiplicity(),
_map(2,0), _m(3), _chrg1(), _chrg2(), _qprf(2), _qnewprf(2),
_lprf(), _bigLprf(), _qlab(2), _qnewlab(2), _llab(), _bigLlab(),
_dipolewgt(), _yfswgt(), _jacobianwgt(), _mewgt(), _maxwgt(2.0),
- _mode(1), _maxtry(500), _energyopt(1), _betaopt(1), _dipoleopt()
+ _mode(1), _maxtry(500), _energyopt(1), _betaopt(1)
{}
//@}
public:
/**
* Member to generate the photons from the dipole
* @param p The decaying particle
* @param children The decay products
* @return The decay products with additional radiation
*/
virtual ParticleVector generatePhotons(const Particle & p,ParticleVector children);
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const {return new_ptr(*this);}
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const {return new_ptr(*this);}
//@}
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* Initialize this object after the setup phase before saving an
* EventGenerator to disk.
* @throws InitException if object could not be initialized properly.
*/
virtual void doinit();
//@}
protected:
/**
* Average crude photon multiplicity
* @param beta1 Velocity of the first charged particle, \f$\beta_1\f$.
* @param ombeta1 One minus the velocity of the first particle, \f$1-\beta_1\f$.
* @return The average photon multiplicity
*/
double nbar(double beta1,double ombeta1) {
return _alpha/pi*_chrg1*_chrg2/beta1*
log((1.+beta1)/ombeta1)*log(_emax/_emin);
}
/**
* Generate the momentum of a photon
* @param beta1 The velocity, \f$\beta_1\f$, of the first charged particle
* @param ombeta1 One minus the velocity, \f$1-\beta_1\f$, of the first
* charged particle which is supplied for numerical stability
* @return The contribution to the dipole weight
*/
double photon(double beta1,double ombeta1);
/**
* Calculate the exact weight for the dipole.
* @param beta1 Velocity of the first charged particle, \f$\beta_1\f$
* @param ombeta1 One minus the velocity of the first particle, \f$1-\beta_1\f$
* @param iphot The number of the photon for which the weight is required
* @return The weight
*/
double exactDipoleWeight(double beta1,double ombeta1,
unsigned int iphot) {
double ombc;
// if cos is greater than zero use result accurate as cos->1
if(_cosphot[iphot]>0.0)
ombc=ombeta1+beta1*sqr(_sinphot[iphot])/(1.+_cosphot[iphot]);
// if cos is less than zero use result accurate as cos->-1
else
ombc=1.-beta1*_cosphot[iphot];
return 1.0*sqr(beta1*_sinphot[iphot]/ombc);
}
/**
* The crude YFS form factor for calculating the weight
* @param b Velocity of the first charged particle, \f$\beta_1\f$
* @param omb One minus the velocity of the first particle, \f$1-\beta_1\f$
* @return The YFS form factor
*/
double crudeYFSFormFactor(double b,double omb) {
double Y =-_alpha/pi*_chrg1*_chrg2 / b * log((1.+b)/omb) * log(_m[0]/(2.*_emin));
return exp(Y);
}
/**
* The exact YFS form factor for calculating the weight
* @param beta1 Velocity of the first charged particle, \f$\beta_1\f$
* @param beta2 Velocity of the second charged particle, \f$\beta_2\f$.
* @param ombeta1 One minus the velocity of the first particle, \f$1-\beta_1\f$
* @param ombeta2 One minus the velocity of the second particle, \f$1-\beta_2\f$
* @return The YFS form factor
*/
double exactYFSFormFactor(double beta1,double ombeta1,
double beta2,double ombeta2);
/**
* Jacobian factor for the weight
*/
double jacobianWeight();
/**
* Matrix element weight
*/
double meWeight(ParticleVector children);
/**
* Member which generates the photons
* @param boost Boost vector to take the particles produced back from
* the decaying particle's rest frame to the lab
* @param children The decay products
*/
double makePhotons(Boost boost,ParticleVector children);
/**
* Compute a Lorentz transform from p to q
* @param p Original momentum
* @param q Final momentum
*/
LorentzRotation solveBoost(const Lorentz5Momentum & q,
const Lorentz5Momentum & p ) const;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFDipole & operator=(const IFDipole &) = delete;
private:
/**
* the fine structure constant at $q^2=0$
*/
double _alpha;
/**
* The minimum photon energy
*/
Energy _emin;
/**
* The maximum photon energy
*/
Energy _emax;
/**
* Photon multiplicity being generated
*/
unsigned int _multiplicity;
/**
* Map from arguments of lists such that
* _q???[_map[0]] is the charged child and
* _q???[_map[1]] is the neutral child.
*/
vector<int> _map;
/**
* Masses of the particles involved
*/
vector<Energy> _m;
/**
* charge of the parent particle
*/
double _chrg1;
/**
* charge of the (charged) child particle
*/
double _chrg2;
/**
* Momentum of the particles in the parent's rest frame
*/
//@{
/**
* Momenta of the charged particles in the parent's rest frame before radiation
*/
vector<Lorentz5Momentum> _qprf;
/**
* Momenta of the charged particles in the parent's rest frame after radiation
*/
vector<Lorentz5Momentum> _qnewprf;
/**
* Momenta of the photons in the parent rest frame
*/
vector<Lorentz5Momentum> _lprf;
/**
* Total momentum of the photons in the parent rest frame
*/
Lorentz5Momentum _bigLprf;
//@}
/**
* Momentum of the particles in the lab frame
*/
//@{
/**
* Momenta of the charged particles in the lab frame before radiation
*/
vector<Lorentz5Momentum> _qlab;
/**
* Momenta of the charged particles in the lab frame after radiation
*/
vector<Lorentz5Momentum> _qnewlab;
/**
* Momenta of the photons in the lab frame
*/
vector<Lorentz5Momentum> _llab;
/**
* Total momentum of the photons in the lab frame
*/
Lorentz5Momentum _bigLlab;
//@}
/**
* Reweighting factors due to differences between the true and crude
* distributions
*/
//@{
/**
* Reweighting factor for the real emission
*/
double _dipolewgt;
/**
* Reweighting factor for the YFS form-factor
*/
double _yfswgt;
/**
* Reweighting factor due to phase space
*/
double _jacobianwgt;
/**
* Reweighting factor due to matrix element corrections
*/
double _mewgt;
/**
* Maximum weight
*/
double _maxwgt;
//@}
/**
* Angles of the photons with respect to the first charged particle
* which are stored for numerical accuracy
*/
//@{
/**
* Cosine of the photon angles
*/
vector<double> _cosphot;
/**
* Sine of the photon angles
*/
vector<double> _sinphot;
//@}
/**
* Type of unweighting to perform
*/
unsigned int _mode;
/**
* Maximum number of attempts to generate a result
*/
unsigned int _maxtry;
/**
* Option for the energy cut-off
*/
unsigned int _energyopt;
/**
* Option for the inclusion of higher order corrections
*/
unsigned int _betaopt;
- /**
- * Option for the form of the primary distribution
- */
- unsigned int _dipoleopt;
};
}
#endif /* HERWIG_IFDipole_H */
diff --git a/Hadronization/ClusterFissioner.cc b/Hadronization/ClusterFissioner.cc
--- a/Hadronization/ClusterFissioner.cc
+++ b/Hadronization/ClusterFissioner.cc
@@ -1,1121 +1,1121 @@
// -*- C++ -*-
//
// ClusterFissioner.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// Thisk is the implementation of the non-inlined, non-templated member
// functions of the ClusterFissioner class.
//
#include "ClusterFissioner.h"
#include <ThePEG/Interface/ClassDocumentation.h>
#include <ThePEG/Interface/Reference.h>
#include <ThePEG/Interface/Parameter.h>
#include <ThePEG/Interface/Switch.h>
#include <ThePEG/Persistency/PersistentOStream.h>
#include <ThePEG/Persistency/PersistentIStream.h>
#include <ThePEG/PDT/EnumParticles.h>
#include "Herwig/Utilities/Kinematics.h"
#include "CheckId.h"
#include "Cluster.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include <ThePEG/Utilities/DescribeClass.h>
using namespace Herwig;
DescribeClass<ClusterFissioner,Interfaced>
describeClusterFissioner("Herwig::ClusterFissioner","");
ClusterFissioner::ClusterFissioner() :
_clMaxLight(3.35*GeV),
_clMaxBottom(3.35*GeV),
_clMaxCharm(3.35*GeV),
_clMaxExotic(3.35*GeV),
_clPowLight(2.0),
_clPowBottom(2.0),
_clPowCharm(2.0),
_clPowExotic(2.0),
_pSplitLight(1.0),
_pSplitBottom(1.0),
_pSplitCharm(1.0),
_pSplitExotic(1.0),
- _fissionCluster(0),
_fissionPwtUquark(1),
_fissionPwtDquark(1),
_fissionPwtSquark(0.5),
+ _fissionCluster(0),
_btClM(1.0*GeV),
_iopRem(1),
_kappa(1.0e15*GeV/meter),
_enhanceSProb(0),
_m0Fission(2.*GeV),
_massMeasure(0)
{}
IBPtr ClusterFissioner::clone() const {
return new_ptr(*this);
}
IBPtr ClusterFissioner::fullclone() const {
return new_ptr(*this);
}
void ClusterFissioner::persistentOutput(PersistentOStream & os) const {
os << _hadronsSelector << ounit(_clMaxLight,GeV)
<< ounit(_clMaxBottom,GeV) << ounit(_clMaxCharm,GeV)
<< ounit(_clMaxExotic,GeV) << _clPowLight << _clPowBottom
<< _clPowCharm << _clPowExotic << _pSplitLight
<< _pSplitBottom << _pSplitCharm << _pSplitExotic
<< _fissionCluster << _fissionPwtUquark << _fissionPwtDquark << _fissionPwtSquark
<< ounit(_btClM,GeV)
<< _iopRem << ounit(_kappa, GeV/meter)
<< _enhanceSProb << ounit(_m0Fission,GeV) << _massMeasure;
}
void ClusterFissioner::persistentInput(PersistentIStream & is, int) {
is >> _hadronsSelector >> iunit(_clMaxLight,GeV)
>> iunit(_clMaxBottom,GeV) >> iunit(_clMaxCharm,GeV)
>> iunit(_clMaxExotic,GeV) >> _clPowLight >> _clPowBottom
>> _clPowCharm >> _clPowExotic >> _pSplitLight
>> _pSplitBottom >> _pSplitCharm >> _pSplitExotic
>> _fissionCluster >> _fissionPwtUquark >> _fissionPwtDquark >> _fissionPwtSquark
>> iunit(_btClM,GeV) >> _iopRem
>> iunit(_kappa, GeV/meter)
>> _enhanceSProb >> iunit(_m0Fission,GeV) >> _massMeasure;
}
void ClusterFissioner::Init() {
static ClassDocumentation<ClusterFissioner> documentation
("Class responsibles for chopping up the clusters");
static Reference<ClusterFissioner,HadronSelector>
interfaceHadronSelector("HadronSelector",
"A reference to the HadronSelector object",
&Herwig::ClusterFissioner::_hadronsSelector,
false, false, true, false);
// ClMax for light, Bottom, Charm and exotic (e.g. Susy) quarks
static Parameter<ClusterFissioner,Energy>
interfaceClMaxLight ("ClMaxLight","cluster max mass for light quarks (unit [GeV])",
&ClusterFissioner::_clMaxLight, GeV, 3.35*GeV, ZERO, 10.0*GeV,
false,false,false);
static Parameter<ClusterFissioner,Energy>
interfaceClMaxBottom ("ClMaxBottom","cluster max mass for b quarks (unit [GeV])",
&ClusterFissioner::_clMaxBottom, GeV, 3.35*GeV, ZERO, 10.0*GeV,
false,false,false);
static Parameter<ClusterFissioner,Energy>
interfaceClMaxCharm ("ClMaxCharm","cluster max mass for c quarks (unit [GeV])",
&ClusterFissioner::_clMaxCharm, GeV, 3.35*GeV, ZERO, 10.0*GeV,
false,false,false);
static Parameter<ClusterFissioner,Energy>
interfaceClMaxExotic ("ClMaxExotic","cluster max mass for exotic quarks (unit [GeV])",
&ClusterFissioner::_clMaxExotic, GeV, 3.35*GeV, ZERO, 10.0*GeV,
false,false,false);
// ClPow for light, Bottom, Charm and exotic (e.g. Susy) quarks
static Parameter<ClusterFissioner,double>
interfaceClPowLight ("ClPowLight","cluster mass exponent for light quarks",
&ClusterFissioner::_clPowLight, 0, 2.0, 0.0, 10.0,false,false,false);
static Parameter<ClusterFissioner,double>
interfaceClPowBottom ("ClPowBottom","cluster mass exponent for b quarks",
&ClusterFissioner::_clPowBottom, 0, 2.0, 0.0, 10.0,false,false,false);
static Parameter<ClusterFissioner,double>
interfaceClPowCharm ("ClPowCharm","cluster mass exponent for c quarks",
&ClusterFissioner::_clPowCharm, 0, 2.0, 0.0, 10.0,false,false,false);
static Parameter<ClusterFissioner,double>
interfaceClPowExotic ("ClPowExotic","cluster mass exponent for exotic quarks",
&ClusterFissioner::_clPowExotic, 0, 2.0, 0.0, 10.0,false,false,false);
// PSplit for light, Bottom, Charm and exotic (e.g. Susy) quarks
static Parameter<ClusterFissioner,double>
interfacePSplitLight ("PSplitLight","cluster mass splitting param for light quarks",
&ClusterFissioner::_pSplitLight, 0, 1.0, 0.0, 10.0,false,false,false);
static Parameter<ClusterFissioner,double>
interfacePSplitBottom ("PSplitBottom","cluster mass splitting param for b quarks",
&ClusterFissioner::_pSplitBottom, 0, 1.0, 0.0, 10.0,false,false,false);
static Parameter<ClusterFissioner,double>
interfacePSplitCharm ("PSplitCharm","cluster mass splitting param for c quarks",
&ClusterFissioner::_pSplitCharm, 0, 1.0, 0.0, 10.0,false,false,false);
static Parameter<ClusterFissioner,double>
interfacePSplitExotic ("PSplitExotic","cluster mass splitting param for exotic quarks",
&ClusterFissioner::_pSplitExotic, 0, 1.0, 0.0, 10.0,false,false,false);
static Switch<ClusterFissioner,int> interfaceFission
("Fission",
"Option for different Fission options",
&ClusterFissioner::_fissionCluster, 1, false, false);
static SwitchOption interfaceFissionDefault
(interfaceFission,
"default",
"Normal cluster fission which depends on the hadron selector class.",
0);
static SwitchOption interfaceFissionNew
(interfaceFission,
"new",
"Alternative cluster fission which does not depend on the hadron selector class",
1);
static Parameter<ClusterFissioner,double> interfaceFissionPwtUquark
("FissionPwtUquark",
"Weight for fission in U quarks",
&ClusterFissioner::_fissionPwtUquark, 1, 0.0, 1.0,
false, false, Interface::limited);
static Parameter<ClusterFissioner,double> interfaceFissionPwtDquark
("FissionPwtDquark",
"Weight for fission in D quarks",
&ClusterFissioner::_fissionPwtDquark, 1, 0.0, 1.0,
false, false, Interface::limited);
static Parameter<ClusterFissioner,double> interfaceFissionPwtSquark
("FissionPwtSquark",
"Weight for fission in S quarks",
&ClusterFissioner::_fissionPwtSquark, 0.5, 0.0, 1.0,
false, false, Interface::limited);
static Switch<ClusterFissioner,int> interfaceRemnantOption
("RemnantOption",
"Option for the treatment of remnant clusters",
&ClusterFissioner::_iopRem, 1, false, false);
static SwitchOption interfaceRemnantOptionSoft
(interfaceRemnantOption,
"Soft",
"Both clusters produced in the fission of the beam cluster"
" are treated as soft clusters.",
0);
static SwitchOption interfaceRemnantOptionHard
(interfaceRemnantOption,
"Hard",
"Only the cluster containing the remnant is treated as a soft cluster.",
1);
static SwitchOption interfaceRemnantOptionVeryHard
(interfaceRemnantOption,
"VeryHard",
"Even remnant clusters are treated as hard, i.e. all clusters the same",
2);
static Parameter<ClusterFissioner,Energy> interfaceBTCLM
("SoftClusterFactor",
"Parameter for the mass spectrum of remnant clusters",
&ClusterFissioner::_btClM, GeV, 1.*GeV, 0.1*GeV, 10.0*GeV,
false, false, Interface::limited);
static Parameter<ClusterFissioner,Tension> interfaceStringTension
("StringTension",
"String tension used in vertex displacement calculation",
&ClusterFissioner::_kappa, GeV/meter,
1.0e15*GeV/meter, ZERO, ZERO,
false, false, Interface::lowerlim);
static Switch<ClusterFissioner,int> interfaceEnhanceSProb
("EnhanceSProb",
"Option for enhancing strangeness",
&ClusterFissioner::_enhanceSProb, 0, false, false);
static SwitchOption interfaceEnhanceSProbNo
(interfaceEnhanceSProb,
"No",
"No strangeness enhancement.",
0);
static SwitchOption interfaceEnhanceSProbScaled
(interfaceEnhanceSProb,
"Scaled",
"Scaled strangeness enhancement",
1);
static SwitchOption interfaceEnhanceSProbExponential
(interfaceEnhanceSProb,
"Exponential",
"Exponential strangeness enhancement",
2);
static Switch<ClusterFissioner,int> interfaceMassMeasure
("MassMeasure",
"Option to use different mass measures",
&ClusterFissioner::_massMeasure,0,false,false);
static SwitchOption interfaceMassMeasureMass
(interfaceMassMeasure,
"Mass",
"Mass Measure",
0);
static SwitchOption interfaceMassMeasureLambda
(interfaceMassMeasure,
"Lambda",
"Lambda Measure",
1);
static Parameter<ClusterFissioner,Energy> interfaceFissionMassScale
("FissionMassScale",
"Cluster fission mass scale",
&ClusterFissioner::_m0Fission, GeV, 2.0*GeV, 0.1*GeV, 50.*GeV,
false, false, Interface::limited);
}
tPVector ClusterFissioner::fission(ClusterVector & clusters, bool softUEisOn) {
// return if no clusters
if (clusters.empty()) return tPVector();
/*****************
* Loop over the (input) collection of cluster pointers, and store in
* the vector splitClusters all the clusters that need to be split
* (these are beam clusters, if soft underlying event is off, and
* heavy non-beam clusters).
********************/
stack<ClusterPtr> splitClusters;
for(ClusterVector::iterator it = clusters.begin() ;
it != clusters.end() ; ++it) {
/**************
* Skip 3-component clusters that have been redefined (as 2-component
* clusters) or not available clusters. The latter check is indeed
* redundant now, but it is used for possible future extensions in which,
* for some reasons, some of the clusters found by ClusterFinder are tagged
* straight away as not available.
**************/
if((*it)->isRedefined() || !(*it)->isAvailable()) continue;
// if the cluster is a beam cluster add it to the vector of clusters
// to be split or if it is heavy
if((*it)->isBeamCluster() || isHeavy(*it)) splitClusters.push(*it);
}
tPVector finalhadrons;
cut(splitClusters, clusters, finalhadrons, softUEisOn);
return finalhadrons;
}
void ClusterFissioner::cut(stack<ClusterPtr> & clusterStack,
ClusterVector &clusters, tPVector & finalhadrons,
bool softUEisOn) {
/**************************************************
* This method does the splitting of the cluster pointed by cluPtr
* and "recursively" by all of its cluster children, if heavy. All of these
* new children clusters are added (indeed the pointers to them) to the
* collection of cluster pointers collecCluPtr. The method works as follows.
* Initially the vector vecCluPtr contains just the input pointer to the
* cluster to be split. Then it will be filled "recursively" by all
* of the cluster's children that are heavy enough to require, in their turn,
* to be split. In each loop, the last element of the vector vecCluPtr is
* considered (only once because it is then removed from the vector).
* This approach is conceptually recursive, but avoid the overhead of
* a concrete recursive function. Furthermore it requires minimal changes
* in the case that the fission of an heavy cluster could produce more
* than two cluster children as assumed now.
*
* Draw the masses: for normal, non-beam clusters a power-like mass dist
* is used, whereas for beam clusters a fast-decreasing exponential mass
* dist is used instead (to avoid many iterative splitting which could
* produce an unphysical large transverse energy from a supposed soft beam
* remnant process).
****************************************/
// Here we recursively loop over clusters in the stack and cut them
while (!clusterStack.empty()) {
// take the last element of the vector
ClusterPtr iCluster = clusterStack.top(); clusterStack.pop();
// split it
cutType ct = iCluster->numComponents() == 2 ?
cutTwo(iCluster, finalhadrons, softUEisOn) :
cutThree(iCluster, finalhadrons, softUEisOn);
// There are cases when we don't want to split, even if it fails mass test
if(!ct.first.first || !ct.second.first) {
// if an unsplit beam cluster leave if for the underlying event
if(iCluster->isBeamCluster() && softUEisOn)
iCluster->isAvailable(false);
continue;
}
// check if clusters
ClusterPtr one = dynamic_ptr_cast<ClusterPtr>(ct.first.first);
ClusterPtr two = dynamic_ptr_cast<ClusterPtr>(ct.second.first);
// is a beam cluster must be split into two clusters
if(iCluster->isBeamCluster() && (!one||!two) && softUEisOn) {
iCluster->isAvailable(false);
continue;
}
// There should always be a intermediate quark(s) from the splitting
assert(ct.first.second && ct.second.second);
/// \todo sort out motherless quark pairs here. Watch out for 'quark in final state' errors
iCluster->addChild(ct.first.first);
// iCluster->addChild(ct.first.second);
// ct.first.second->addChild(ct.first.first);
iCluster->addChild(ct.second.first);
// iCluster->addChild(ct.second.second);
// ct.second.second->addChild(ct.second.first);
// Sometimes the clusters decay C -> H + C' rather then C -> C' + C''
if(one) {
clusters.push_back(one);
if(one->isBeamCluster() && softUEisOn)
one->isAvailable(false);
if(isHeavy(one) && one->isAvailable())
clusterStack.push(one);
}
if(two) {
clusters.push_back(two);
if(two->isBeamCluster() && softUEisOn)
two->isAvailable(false);
if(isHeavy(two) && two->isAvailable())
clusterStack.push(two);
}
}
}
namespace {
/**
* Check if can't make a hadron from the partons
*/
bool cantMakeHadron(tcPPtr p1, tcPPtr p2) {
return ! CheckId::canBeHadron(p1->dataPtr(), p2->dataPtr());
}
/**
* Check if can't make a diquark from the partons
*/
bool cantMakeDiQuark(tcPPtr p1, tcPPtr p2) {
long id1 = p1->id(), id2 = p2->id();
return ! (QuarkMatcher::Check(id1) && QuarkMatcher::Check(id2) && id1*id2>0);
}
}
ClusterFissioner::cutType
ClusterFissioner::cutTwo(ClusterPtr & cluster, tPVector & finalhadrons,
bool softUEisOn) {
// need to make sure only 2-cpt clusters get here
assert(cluster->numComponents() == 2);
tPPtr ptrQ1 = cluster->particle(0);
tPPtr ptrQ2 = cluster->particle(1);
Energy Mc = cluster->mass();
assert(ptrQ1);
assert(ptrQ2);
// And check if those particles are from a beam remnant
bool rem1 = cluster->isBeamRemnant(0);
bool rem2 = cluster->isBeamRemnant(1);
// workout which distribution to use
bool soft1(false),soft2(false);
switch (_iopRem) {
case 0:
soft1 = rem1 || rem2;
soft2 = rem2 || rem1;
break;
case 1:
soft1 = rem1;
soft2 = rem2;
break;
}
// Initialization for the exponential ("soft") mass distribution.
static const int max_loop = 1000;
int counter = 0;
Energy Mc1 = ZERO, Mc2 = ZERO,m1=ZERO,m2=ZERO,m=ZERO;
tcPDPtr toHadron1, toHadron2;
PPtr newPtr1 = PPtr ();
PPtr newPtr2 = PPtr ();
bool succeeded = false;
do
{
succeeded = false;
++counter;
if (_enhanceSProb == 0){
drawNewFlavour(newPtr1,newPtr2);
}
else {
Energy2 mass2 = clustermass(cluster);
drawNewFlavourEnhanced(newPtr1,newPtr2,mass2);
}
// check for right ordering
assert (ptrQ2);
assert (newPtr2);
assert (ptrQ2->dataPtr());
assert (newPtr2->dataPtr());
if(cantMakeHadron(ptrQ1, newPtr1) || cantMakeHadron(ptrQ2, newPtr2)) {
swap(newPtr1, newPtr2);
// check again
if(cantMakeHadron(ptrQ1, newPtr1) || cantMakeHadron(ptrQ2, newPtr2)) {
throw Exception()
<< "ClusterFissioner cannot split the cluster ("
<< ptrQ1->PDGName() << ' ' << ptrQ2->PDGName()
<< ") into hadrons.\n" << Exception::runerror;
}
}
// Check that new clusters can produce particles and there is enough
// phase space to choose the drawn flavour
m1 = ptrQ1->data().constituentMass();
m2 = ptrQ2->data().constituentMass();
m = newPtr1->data().constituentMass();
// Do not split in the case there is no phase space available
if(Mc < m1+m + m2+m) continue;
// power for splitting
double exp1=_pSplitLight;
double exp2=_pSplitLight;
if (CheckId::isExotic(ptrQ1->dataPtr())) exp1 = _pSplitExotic;
else if(CheckId::hasBottom(ptrQ1->dataPtr()))exp1 = _pSplitBottom;
else if(CheckId::hasCharm(ptrQ1->dataPtr())) exp1 = _pSplitCharm;
if (CheckId::isExotic(ptrQ2->dataPtr())) exp2 = _pSplitExotic;
else if(CheckId::hasBottom(ptrQ2->dataPtr())) exp2 = _pSplitBottom;
else if(CheckId::hasCharm(ptrQ2->dataPtr())) exp2 = _pSplitCharm;
// If, during the drawing of candidate masses, too many attempts fail
// (because the phase space available is tiny)
/// \todo run separate loop here?
Mc1 = drawChildMass(Mc,m1,m2,m,exp1,soft1);
Mc2 = drawChildMass(Mc,m2,m1,m,exp2,soft2);
if(Mc1 < m1+m || Mc2 < m+m2 || Mc1+Mc2 > Mc) continue;
/**************************
* New (not present in Fortran Herwig):
* check whether the fragment masses Mc1 and Mc2 are above the
* threshold for the production of the lightest pair of hadrons with the
* right flavours. If not, then set by hand the mass to the lightest
* single hadron with the right flavours, in order to solve correctly
* the kinematics, and (later in this method) create directly such hadron
* and add it to the children hadrons of the cluster that undergoes the
* fission (i.e. the one pointed by iCluPtr). Notice that in this special
* case, the heavy cluster that undergoes the fission has one single
* cluster child and one single hadron child. We prefer this approach,
* rather than to create a light cluster, with the mass set equal to
* the lightest hadron, and let then the class LightClusterDecayer to do
* the job to decay it to that single hadron, for two reasons:
* First, because the sum of the masses of the two constituents can be,
* in this case, greater than the mass of that hadron, hence it would
* be impossible to solve the kinematics for such two components, and
* therefore we would have a cluster whose components are undefined.
* Second, the algorithm is faster, because it avoids the reshuffling
* procedure that would be necessary if we used LightClusterDecayer
* to decay the light cluster to the lightest hadron.
****************************/
toHadron1 = _hadronsSelector->chooseSingleHadron(ptrQ1->dataPtr(), newPtr1->dataPtr(),Mc1);
if(toHadron1) Mc1 = toHadron1->mass();
toHadron2 = _hadronsSelector->chooseSingleHadron(ptrQ2->dataPtr(), newPtr2->dataPtr(),Mc2);
if(toHadron2) Mc2 = toHadron2->mass();
// if a beam cluster not allowed to decay to hadrons
if(cluster->isBeamCluster() && (toHadron1||toHadron2) && softUEisOn)
continue;
// Check if the decay kinematics is still possible: if not then
// force the one-hadron decay for the other cluster as well.
if(Mc1 + Mc2 > Mc) {
if(!toHadron1) {
toHadron1 = _hadronsSelector->chooseSingleHadron(ptrQ1->dataPtr(), newPtr1->dataPtr(),Mc-Mc2);
if(toHadron1) Mc1 = toHadron1->mass();
}
else if(!toHadron2) {
toHadron2 = _hadronsSelector->chooseSingleHadron(ptrQ2->dataPtr(), newPtr2->dataPtr(),Mc-Mc1);
if(toHadron2) Mc2 = toHadron2->mass();
}
}
succeeded = (Mc >= Mc1+Mc2);
}
while (!succeeded && counter < max_loop);
if(counter >= max_loop) {
static const PPtr null = PPtr();
return cutType(PPair(null,null),PPair(null,null));
}
// Determined the (5-components) momenta (all in the LAB frame)
Lorentz5Momentum pClu = cluster->momentum(); // known
Lorentz5Momentum p0Q1 = ptrQ1->momentum(); // known (mom Q1 before fission)
Lorentz5Momentum pClu1, pClu2, pQ1, pQone, pQtwo, pQ2; //unknown
pClu1.setMass(Mc1);
pClu2.setMass(Mc2);
pQ1.setMass(m1);
pQ2.setMass(m2);
pQone.setMass(m);
pQtwo.setMass(m);
calculateKinematics(pClu,p0Q1,toHadron1,toHadron2,
pClu1,pClu2,pQ1,pQone,pQtwo,pQ2); // out
/******************
* The previous methods have determined the kinematics and positions
* of C -> C1 + C2.
* In the case that one of the two product is light, that means either
* decayOneHadronClu1 or decayOneHadronClu2 is true, then the momenta
* of the components of that light product have not been determined,
* and a (light) cluster will not be created: the heavy father cluster
* decays, in this case, into a single (not-light) cluster and a
* single hadron. In the other, "normal", cases the father cluster
* decays into two clusters, each of which has well defined components.
* Notice that, in the case of components which point to particles, the
* momenta of the components is properly set to the new values, whereas
* we do not change the momenta of the pointed particles, because we
* want to keep all of the information (that is the new momentum of a
* component after the splitting, which is contained in the _momentum
* member of the Component class, and the (old) momentum of that component
* before the splitting, which is contained in the momentum of the
* pointed particle). Please not make confusion of this only apparent
* inconsistency!
********************/
LorentzPoint posC,pos1,pos2;
posC = cluster->vertex();
calculatePositions(pClu, posC, pClu1, pClu2, pos1, pos2);
cutType rval;
if(toHadron1) {
rval.first = produceHadron(toHadron1, newPtr1, pClu1, pos1);
finalhadrons.push_back(rval.first.first);
}
else {
rval.first = produceCluster(ptrQ1, newPtr1, pClu1, pos1, pQ1, pQone, rem1);
}
if(toHadron2) {
rval.second = produceHadron(toHadron2, newPtr2, pClu2, pos2);
finalhadrons.push_back(rval.second.first);
}
else {
rval.second = produceCluster(ptrQ2, newPtr2, pClu2, pos2, pQ2, pQtwo, rem2);
}
return rval;
}
ClusterFissioner::cutType
ClusterFissioner::cutThree(ClusterPtr & cluster, tPVector & finalhadrons,
bool softUEisOn) {
// need to make sure only 3-cpt clusters get here
assert(cluster->numComponents() == 3);
// extract quarks
tPPtr ptrQ[3] = {cluster->particle(0),cluster->particle(1),cluster->particle(2)};
assert( ptrQ[0] && ptrQ[1] && ptrQ[2] );
// find maximum mass pair
Energy mmax(ZERO);
Lorentz5Momentum pDiQuark;
int iq1(-1),iq2(-1);
Lorentz5Momentum psum;
for(int q1=0;q1<3;++q1) {
psum+= ptrQ[q1]->momentum();
for(int q2=q1+1;q2<3;++q2) {
Lorentz5Momentum ptest = ptrQ[q1]->momentum()+ptrQ[q2]->momentum();
ptest.rescaleMass();
Energy mass = ptest.m();
if(mass>mmax) {
mmax = mass;
pDiQuark = ptest;
iq1 = q1;
iq2 = q2;
}
}
}
// and the spectators
int iother(-1);
for(int ix=0;ix<3;++ix) if(ix!=iq1&&ix!=iq2) iother=ix;
assert(iq1>=0&&iq2>=0&&iother>=0);
// And check if those particles are from a beam remnant
bool rem1 = cluster->isBeamRemnant(iq1);
bool rem2 = cluster->isBeamRemnant(iq2);
// workout which distribution to use
bool soft1(false),soft2(false);
switch (_iopRem) {
case 0:
soft1 = rem1 || rem2;
soft2 = rem2 || rem1;
break;
case 1:
soft1 = rem1;
soft2 = rem2;
break;
}
// Initialization for the exponential ("soft") mass distribution.
static const int max_loop = 1000;
int counter = 0;
Energy Mc1 = ZERO, Mc2 = ZERO, m1=ZERO, m2=ZERO, m=ZERO;
tcPDPtr toHadron;
bool toDiQuark(false);
PPtr newPtr1 = PPtr(),newPtr2 = PPtr();
PDPtr diquark;
bool succeeded = false;
do {
succeeded = false;
++counter;
if (_enhanceSProb == 0) {
drawNewFlavour(newPtr1,newPtr2);
}
else {
Energy2 mass2 = clustermass(cluster);
drawNewFlavourEnhanced(newPtr1,newPtr2, mass2);
}
// randomly pick which will be (anti)diquark and which a mesonic cluster
if(UseRandom::rndbool()) {
swap(iq1,iq2);
swap(rem1,rem2);
}
// check first order
if(cantMakeHadron(ptrQ[iq1], newPtr1) || cantMakeDiQuark(ptrQ[iq2], newPtr2)) {
swap(newPtr1,newPtr2);
}
// check again
if(cantMakeHadron(ptrQ[iq1], newPtr1) || cantMakeDiQuark(ptrQ[iq2], newPtr2)) {
throw Exception()
<< "ClusterFissioner cannot split the cluster ("
<< ptrQ[iq1]->PDGName() << ' ' << ptrQ[iq2]->PDGName()
<< ") into a hadron and diquark.\n" << Exception::runerror;
}
// Check that new clusters can produce particles and there is enough
// phase space to choose the drawn flavour
m1 = ptrQ[iq1]->data().constituentMass();
m2 = ptrQ[iq2]->data().constituentMass();
m = newPtr1->data().constituentMass();
// Do not split in the case there is no phase space available
if(mmax < m1+m + m2+m) continue;
// power for splitting
double exp1(_pSplitLight),exp2(_pSplitLight);
if (CheckId::isExotic (ptrQ[iq1]->dataPtr())) exp1 = _pSplitExotic;
else if(CheckId::hasBottom(ptrQ[iq1]->dataPtr())) exp1 = _pSplitBottom;
else if(CheckId::hasCharm (ptrQ[iq1]->dataPtr())) exp1 = _pSplitCharm;
if (CheckId::isExotic (ptrQ[iq2]->dataPtr())) exp2 = _pSplitExotic;
else if(CheckId::hasBottom(ptrQ[iq2]->dataPtr())) exp2 = _pSplitBottom;
else if(CheckId::hasCharm (ptrQ[iq2]->dataPtr())) exp2 = _pSplitCharm;
// If, during the drawing of candidate masses, too many attempts fail
// (because the phase space available is tiny)
/// \todo run separate loop here?
Mc1 = drawChildMass(mmax,m1,m2,m,exp1,soft1);
Mc2 = drawChildMass(mmax,m2,m1,m,exp2,soft2);
if(Mc1 < m1+m || Mc2 < m+m2 || Mc1+Mc2 > mmax) continue;
// check if need to force meson clster to hadron
toHadron = _hadronsSelector->chooseSingleHadron(ptrQ[iq1]->dataPtr(), newPtr1->dataPtr(),Mc1);
if(toHadron) Mc1 = toHadron->mass();
// check if need to force diquark cluster to be on-shell
toDiQuark = false;
diquark = CheckId::makeDiquark(ptrQ[iq2]->dataPtr(), newPtr2->dataPtr());
if(Mc2 < diquark->constituentMass()) {
Mc2 = diquark->constituentMass();
toDiQuark = true;
}
// if a beam cluster not allowed to decay to hadrons
if(cluster->isBeamCluster() && toHadron && softUEisOn)
continue;
// Check if the decay kinematics is still possible: if not then
// force the one-hadron decay for the other cluster as well.
if(Mc1 + Mc2 > mmax) {
if(!toHadron) {
toHadron = _hadronsSelector->chooseSingleHadron(ptrQ[iq1]->dataPtr(), newPtr1->dataPtr(),mmax-Mc2);
if(toHadron) Mc1 = toHadron->mass();
}
else if(!toDiQuark) {
Mc2 = _hadronsSelector->massLightestHadron(ptrQ[iq2]->dataPtr(), newPtr2->dataPtr());
toDiQuark = true;
}
}
succeeded = (mmax >= Mc1+Mc2);
}
while (!succeeded && counter < max_loop);
// check no of tries
if(counter >= max_loop) return cutType();
// Determine the (5-components) momenta (all in the LAB frame)
Lorentz5Momentum p0Q1 = ptrQ[iq1]->momentum();
// to be determined
Lorentz5Momentum pClu1(Mc1), pClu2(Mc2), pQ1(m1), pQone(m), pQtwo(m), pQ2(m2);
calculateKinematics(pDiQuark,p0Q1,toHadron,toDiQuark,
pClu1,pClu2,pQ1,pQone,pQtwo,pQ2);
// positions of the new clusters
LorentzPoint pos1,pos2;
Lorentz5Momentum pBaryon = pClu2+ptrQ[iother]->momentum();
calculatePositions(cluster->momentum(), cluster->vertex(), pClu1, pBaryon, pos1, pos2);
// first the mesonic cluster/meson
cutType rval;
if(toHadron) {
rval.first = produceHadron(toHadron, newPtr1, pClu1, pos1);
finalhadrons.push_back(rval.first.first);
}
else {
rval.first = produceCluster(ptrQ[iq1], newPtr1, pClu1, pos1, pQ1, pQone, rem1);
}
if(toDiQuark) {
rem2 |= cluster->isBeamRemnant(iother);
PPtr newDiQuark = diquark->produceParticle(pClu2);
rval.second = produceCluster(newDiQuark, ptrQ[iother], pBaryon, pos2, pClu2,
ptrQ[iother]->momentum(), rem2);
}
else {
rval.second = produceCluster(ptrQ[iq2], newPtr2, pBaryon, pos2, pQ2, pQtwo, rem2,
ptrQ[iother],cluster->isBeamRemnant(iother));
}
cluster->isAvailable(false);
return rval;
}
ClusterFissioner::PPair
ClusterFissioner::produceHadron(tcPDPtr hadron, tPPtr newPtr, const Lorentz5Momentum &a,
const LorentzPoint &b) const {
PPair rval;
if(hadron->coloured()) {
rval.first = (_hadronsSelector->lightestHadron(hadron,newPtr->dataPtr()))->produceParticle();
}
else
rval.first = hadron->produceParticle();
rval.second = newPtr;
rval.first->set5Momentum(a);
rval.first->setVertex(b);
return rval;
}
ClusterFissioner::PPair ClusterFissioner::produceCluster(tPPtr ptrQ, tPPtr newPtr,
const Lorentz5Momentum & a,
const LorentzPoint & b,
const Lorentz5Momentum & c,
const Lorentz5Momentum & d,
bool isRem,
tPPtr spect, bool remSpect) const {
PPair rval;
rval.second = newPtr;
ClusterPtr cluster = !spect ? new_ptr(Cluster(ptrQ,rval.second)) : new_ptr(Cluster(ptrQ,rval.second,spect));
rval.first = cluster;
cluster->set5Momentum(a);
cluster->setVertex(b);
assert(cluster->particle(0)->id() == ptrQ->id());
cluster->particle(0)->set5Momentum(c);
cluster->particle(1)->set5Momentum(d);
cluster->setBeamRemnant(0,isRem);
if(remSpect) cluster->setBeamRemnant(2,remSpect);
return rval;
}
void ClusterFissioner::drawNewFlavour(PPtr& newPtrPos,PPtr& newPtrNeg) const {
// Flavour is assumed to be only u, d, s, with weights
// (which are not normalized probabilities) given
// by the same weights as used in HadronsSelector for
// the decay of clusters into two hadrons.
double prob_d;
double prob_u;
double prob_s;
switch(_fissionCluster){
case 0:
prob_d = _hadronsSelector->pwtDquark();
prob_u = _hadronsSelector->pwtUquark();
prob_s = _hadronsSelector->pwtSquark();
break;
case 1:
prob_d = _fissionPwtDquark;
prob_u = _fissionPwtUquark;
prob_s = _fissionPwtSquark;
break;
default :
assert(false);
}
int choice = UseRandom::rnd3(prob_u, prob_d, prob_s);
long idNew = 0;
switch (choice) {
case 0: idNew = ThePEG::ParticleID::u; break;
case 1: idNew = ThePEG::ParticleID::d; break;
case 2: idNew = ThePEG::ParticleID::s; break;
}
newPtrPos = getParticle(idNew);
newPtrNeg = getParticle(-idNew);
assert (newPtrPos);
assert(newPtrNeg);
assert (newPtrPos->dataPtr());
assert(newPtrNeg->dataPtr());
}
void ClusterFissioner::drawNewFlavourEnhanced(PPtr& newPtrPos,PPtr& newPtrNeg,
Energy2 mass2) const {
// Flavour is assumed to be only u, d, s, with weights
// (which are not normalized probabilities) given
// by the same weights as used in HadronsSelector for
// the decay of clusters into two hadrons.
double prob_d;
double prob_u;
double prob_s = 0.;
double scale = abs(double(sqr(_m0Fission)/mass2));
// Choose which splitting weights you wish to use
switch(_fissionCluster){
// 0: ClusterFissioner and ClusterDecayer use the same weights
case 0:
prob_d = _hadronsSelector->pwtDquark();
prob_u = _hadronsSelector->pwtUquark();
/* Strangeness enhancement:
Case 1: probability scaling
Case 2: Exponential scaling
*/
if (_enhanceSProb == 1)
prob_s = (_maxScale < scale) ? 0. : pow(_hadronsSelector->pwtSquark(),scale);
else if (_enhanceSProb == 2)
prob_s = (_maxScale < scale) ? 0. : exp(-scale);
break;
/* 1: ClusterFissioner uses its own unique set of weights,
i.e. decoupled from ClusterDecayer */
case 1:
prob_d = _fissionPwtDquark;
prob_u = _fissionPwtUquark;
if (_enhanceSProb == 1)
prob_s = (_maxScale < scale) ? 0. : pow(_fissionPwtSquark,scale);
else if (_enhanceSProb == 2)
prob_s = (_maxScale < scale) ? 0. : exp(-scale);
break;
}
int choice = UseRandom::rnd3(prob_u, prob_d, prob_s);
long idNew = 0;
switch (choice) {
case 0: idNew = ThePEG::ParticleID::u; break;
case 1: idNew = ThePEG::ParticleID::d; break;
case 2: idNew = ThePEG::ParticleID::s; break;
}
newPtrPos = getParticle(idNew);
newPtrNeg = getParticle(-idNew);
assert (newPtrPos);
assert(newPtrNeg);
assert (newPtrPos->dataPtr());
assert(newPtrNeg->dataPtr());
}
Energy2 ClusterFissioner::clustermass(const ClusterPtr & cluster){
Lorentz5Momentum pIn = cluster->momentum();
Energy2 endpointmass2 = sqr(cluster->particle(0)->mass() +
cluster->particle(1)->mass());
Energy2 singletm2 = pIn.m2();
// Return either the cluster mass, or the lambda measure
return (_massMeasure == 0) ? singletm2 : singletm2 - endpointmass2;
}
Energy ClusterFissioner::drawChildMass(const Energy M, const Energy m1,
const Energy m2, const Energy m,
const double expt, const bool soft) const {
/***************************
* This method, given in input the cluster mass Mclu of an heavy cluster C,
* made of consituents of masses m1 and m2, draws the masses Mclu1 and Mclu2
* of, respectively, the children cluster C1, made of constituent masses m1
* and m, and cluster C2, of mass Mclu2 and made of constituent masses m2
* and m. The mass is extracted from one of the two following mass
* distributions:
* --- power-like ("normal" distribution)
* d(Prob) / d(M^exponent) = const
* where the exponent can be different from the two children C1 (exp1)
* and C2 (exponent2).
* --- exponential ("soft" distribution)
* d(Prob) / d(M^2) = exp(-b*M)
* where b = 2.0 / average.
* Such distributions are limited below by the masses of
* the constituents quarks, and above from the mass of decaying cluster C.
* The choice of which of the two mass distributions to use for each of the
* two cluster children is dictated by iRemnant (see below).
* If the number of attempts to extract a pair of mass values that are
* kinematically acceptable is above some fixed number (max_loop, see below)
* the method gives up and returns false; otherwise, when it succeeds, it
* returns true.
*
* These distributions have been modified from HERWIG:
* Before these were:
* Mclu1 = m1 + (Mclu - m1 - m2)*pow( rnd(), 1.0/exponent1 );
* The new one coded here is a more efficient version, same density
* but taking into account 'in phase space from' beforehand
***************************/
// hard cluster
if(!soft) {
return pow(UseRandom::rnd(pow((M-m1-m2-m)*UnitRemoval::InvE, expt),
pow(m*UnitRemoval::InvE, expt)), 1./expt
)*UnitRemoval::E + m1;
}
// Otherwise it uses a soft mass distribution
else {
static const InvEnergy b = 2.0 / _btClM;
Energy max = M-m1-m2-2.0*m;
double rmin = b*max;
rmin = ( rmin < 50 ) ? exp(-rmin) : 0.;
double r1;
do {
r1 = UseRandom::rnd(rmin, 1.0) * UseRandom::rnd(rmin, 1.0);
}
while (r1 < rmin);
return m1 + m - log(r1)/b;
}
}
void ClusterFissioner::calculateKinematics(const Lorentz5Momentum & pClu,
const Lorentz5Momentum & p0Q1,
const bool toHadron1,
const bool toHadron2,
Lorentz5Momentum & pClu1,
Lorentz5Momentum & pClu2,
Lorentz5Momentum & pQ1,
Lorentz5Momentum & pQbar,
Lorentz5Momentum & pQ,
Lorentz5Momentum & pQ2bar) const {
/******************
* This method solves the kinematics of the two body cluster decay:
* C (Q1 Q2bar) ---> C1 (Q1 Qbar) + C2 (Q Q2bar)
* In input we receive the momentum of C, pClu, and the momentum
* of the quark Q1 (constituent of C), p0Q1, both in the LAB frame.
* Furthermore, two boolean variables inform whether the two fission
* products (C1, C2) decay immediately into a single hadron (in which
* case the cluster itself is identify with that hadron) and we do
* not have to solve the kinematics of the components (Q1,Qbar) for
* C1 and (Q,Q2bar) for C2.
* The output is given by the following momenta (all 5-components,
* and all in the LAB frame):
* pClu1 , pClu2 respectively of C1 , C2
* pQ1 , pQbar respectively of Q1 , Qbar in C1
* pQ , pQ2bar respectively of Q , Q2 in C2
* The assumption, suggested from the string model, is that, in C frame,
* C1 and its constituents Q1 and Qbar are collinear, and collinear to
* the direction of Q1 in C (that is before cluster decay); similarly,
* (always in the C frame) C2 and its constituents Q and Q2bar are
* collinear (and therefore anti-collinear with C1,Q1,Qbar).
* The solution is then obtained by using Lorentz boosts, as follows.
* The kinematics of C1 and C2 is solved in their parent C frame,
* and then boosted back in the LAB. The kinematics of Q1 and Qbar
* is solved in their parent C1 frame and then boosted back in the LAB;
* similarly, the kinematics of Q and Q2bar is solved in their parent
* C2 frame and then boosted back in the LAB. In each of the three
* "two-body decay"-like cases, we use the fact that the direction
* of the motion of the decay products is known in the rest frame of
* their parent. This is obvious for the first case in which the
* parent rest frame is C; but it is also true in the other two cases
* where the rest frames are C1 and C2. This is because C1 and C2
* are boosted w.r.t. C in the same direction where their components,
* respectively (Q1,Qbar) and (Q,Q2bar) move in C1 and C2 rest frame
* respectively.
* Of course, although the notation used assumed that C = (Q1 Q2bar)
* where Q1 is a quark and Q2bar an antiquark, indeed everything remain
* unchanged also in all following cases:
* Q1 quark, Q2bar antiquark; --> Q quark;
* Q1 antiquark , Q2bar quark; --> Q antiquark;
* Q1 quark, Q2bar diquark; --> Q quark
* Q1 antiquark, Q2bar anti-diquark; --> Q antiquark
* Q1 diquark, Q2bar quark --> Q antiquark
* Q1 anti-diquark, Q2bar antiquark; --> Q quark
**************************/
// Calculate the unit three-vector, in the C frame, along which
// all of the constituents and children clusters move.
Lorentz5Momentum u(p0Q1);
u.boost( -pClu.boostVector() ); // boost from LAB to C
// the unit three-vector is then u.vect().unit()
// Calculate the momenta of C1 and C2 in the (parent) C frame first,
// where the direction of C1 is u.vect().unit(), and then boost back in the
// LAB frame.
if (pClu.m() < pClu1.mass() + pClu2.mass() ) {
throw Exception() << "Impossible Kinematics in ClusterFissioner::calculateKinematics() (A)"
<< Exception::eventerror;
}
Kinematics::twoBodyDecay(pClu, pClu1.mass(), pClu2.mass(),
u.vect().unit(), pClu1, pClu2);
// In the case that cluster1 does not decay immediately into a single hadron,
// calculate the momenta of Q1 (as constituent of C1) and Qbar in the
// (parent) C1 frame first, where the direction of Q1 is u.vect().unit(),
// and then boost back in the LAB frame.
if(!toHadron1) {
if (pClu1.m() < pQ1.mass() + pQbar.mass() ) {
throw Exception() << "Impossible Kinematics in ClusterFissioner::calculateKinematics() (B)"
<< Exception::eventerror;
}
Kinematics::twoBodyDecay(pClu1, pQ1.mass(), pQbar.mass(),
u.vect().unit(), pQ1, pQbar);
}
// In the case that cluster2 does not decay immediately into a single hadron,
// Calculate the momenta of Q and Q2bar (as constituent of C2) in the
// (parent) C2 frame first, where the direction of Q is u.vect().unit(),
// and then boost back in the LAB frame.
if(!toHadron2) {
if (pClu2.m() < pQ.mass() + pQ2bar.mass() ) {
throw Exception() << "Impossible Kinematics in ClusterFissioner::calculateKinematics() (C)"
<< Exception::eventerror;
}
Kinematics::twoBodyDecay(pClu2, pQ.mass(), pQ2bar.mass(),
u.vect().unit(), pQ, pQ2bar);
}
}
void ClusterFissioner::calculatePositions(const Lorentz5Momentum & pClu,
const LorentzPoint & positionClu,
const Lorentz5Momentum & pClu1,
const Lorentz5Momentum & pClu2,
LorentzPoint & positionClu1,
LorentzPoint & positionClu2) const {
// Determine positions of cluster children.
// See Marc Smith's thesis, page 127, formulas (4.122) and (4.123).
Energy Mclu = pClu.m();
Energy Mclu1 = pClu1.m();
Energy Mclu2 = pClu2.m();
// Calculate the unit three-vector, in the C frame, along which
// children clusters move.
Lorentz5Momentum u(pClu1);
u.boost( -pClu.boostVector() ); // boost from LAB to C frame
// the unit three-vector is then u.vect().unit()
Energy pstarChild = Kinematics::pstarTwoBodyDecay(Mclu,Mclu1,Mclu2);
// First, determine the relative positions of the children clusters
// in the parent cluster reference frame.
Length x1 = ( 0.25*Mclu + 0.5*( pstarChild + (sqr(Mclu2) - sqr(Mclu1))/(2.0*Mclu)))/_kappa;
Length t1 = Mclu/_kappa - x1;
LorentzDistance distanceClu1( x1 * u.vect().unit(), t1 );
Length x2 = (-0.25*Mclu + 0.5*(-pstarChild + (sqr(Mclu2) - sqr(Mclu1))/(2.0*Mclu)))/_kappa;
Length t2 = Mclu/_kappa + x2;
LorentzDistance distanceClu2( x2 * u.vect().unit(), t2 );
// Then, transform such relative positions from the parent cluster
// reference frame to the Lab frame.
distanceClu1.boost( pClu.boostVector() );
distanceClu2.boost( pClu.boostVector() );
// Finally, determine the absolute positions in the Lab frame.
positionClu1 = positionClu + distanceClu1;
positionClu2 = positionClu + distanceClu2;
}
bool ClusterFissioner::isHeavy(tcClusterPtr clu) {
// default
double clpow = _clPowLight;
Energy clmax = _clMaxLight;
// particle data for constituents
tcPDPtr cptr[3]={tcPDPtr(),tcPDPtr(),tcPDPtr()};
for(int ix=0;ix<min(clu->numComponents(),3);++ix) {
cptr[ix]=clu->particle(ix)->dataPtr();
}
// different parameters for exotic, bottom and charm clusters
if(CheckId::isExotic(cptr[0],cptr[1],cptr[1])) {
clpow = _clPowExotic;
clmax = _clMaxExotic;
}
else if(CheckId::hasBottom(cptr[0],cptr[1],cptr[1])) {
clpow = _clPowBottom;
clmax = _clMaxBottom;
}
else if(CheckId::hasCharm(cptr[0],cptr[1],cptr[1])) {
clpow = _clPowCharm;
clmax = _clMaxCharm;
}
bool aboveCutoff = (
pow(clu->mass()*UnitRemoval::InvE , clpow)
>
pow(clmax*UnitRemoval::InvE, clpow)
+ pow(clu->sumConstituentMasses()*UnitRemoval::InvE, clpow)
);
// required test for SUSY clusters, since aboveCutoff alone
// cannot guarantee (Mc > m1 + m2 + 2*m) in cut()
static const Energy minmass
= getParticleData(ParticleID::d)->constituentMass();
bool canSplitMinimally
= clu->mass() > clu->sumConstituentMasses() + 2.0 * minmass;
return aboveCutoff && canSplitMinimally;
}
diff --git a/Hadronization/ClusterHadronizationHandler.cc b/Hadronization/ClusterHadronizationHandler.cc
--- a/Hadronization/ClusterHadronizationHandler.cc
+++ b/Hadronization/ClusterHadronizationHandler.cc
@@ -1,307 +1,307 @@
// -*- C++ -*-
//
// ClusterHadronizationHandler.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the ClusterHadronizationHandler class.
//
#include "ClusterHadronizationHandler.h"
#include <ThePEG/Interface/ClassDocumentation.h>
#include <ThePEG/Persistency/PersistentOStream.h>
#include <ThePEG/Persistency/PersistentIStream.h>
#include <ThePEG/Interface/Switch.h>
#include <ThePEG/Interface/Parameter.h>
#include <ThePEG/Interface/Reference.h>
#include <ThePEG/Handlers/EventHandler.h>
#include <ThePEG/Handlers/Hint.h>
#include <ThePEG/PDT/ParticleData.h>
#include <ThePEG/EventRecord/Particle.h>
#include <ThePEG/EventRecord/Step.h>
#include <ThePEG/PDT/PDT.h>
#include <ThePEG/PDT/EnumParticles.h>
#include <ThePEG/Utilities/Throw.h>
#include "Herwig/Utilities/EnumParticles.h"
#include "CluHadConfig.h"
#include "Cluster.h"
#include <ThePEG/Utilities/DescribeClass.h>
using namespace Herwig;
ClusterHadronizationHandler * ClusterHadronizationHandler::currentHandler_ = 0;
DescribeClass<ClusterHadronizationHandler,HadronizationHandler>
describeClusterHadronizationHandler("Herwig::ClusterHadronizationHandler","");
IBPtr ClusterHadronizationHandler::clone() const {
return new_ptr(*this);
}
IBPtr ClusterHadronizationHandler::fullclone() const {
return new_ptr(*this);
}
void ClusterHadronizationHandler::persistentOutput(PersistentOStream & os)
const {
os << _partonSplitter << _clusterFinder << _colourReconnector
<< _clusterFissioner << _lightClusterDecayer << _clusterDecayer
<< ounit(_minVirtuality2,GeV2) << ounit(_maxDisplacement,mm)
<< _underlyingEventHandler << _reduceToTwoComponents;
}
void ClusterHadronizationHandler::persistentInput(PersistentIStream & is, int) {
is >> _partonSplitter >> _clusterFinder >> _colourReconnector
>> _clusterFissioner >> _lightClusterDecayer >> _clusterDecayer
>> iunit(_minVirtuality2,GeV2) >> iunit(_maxDisplacement,mm)
>> _underlyingEventHandler >> _reduceToTwoComponents;
}
void ClusterHadronizationHandler::Init() {
static ClassDocumentation<ClusterHadronizationHandler> documentation
("This is the main handler class for the Cluster Hadronization",
"The hadronization was performed using the cluster model of \\cite{Webber:1983if}.",
"%\\cite{Webber:1983if}\n"
"\\bibitem{Webber:1983if}\n"
" B.~R.~Webber,\n"
" ``A QCD Model For Jet Fragmentation Including Soft Gluon Interference,''\n"
" Nucl.\\ Phys.\\ B {\\bf 238}, 492 (1984).\n"
" %%CITATION = NUPHA,B238,492;%%\n"
// main manual
);
static Reference<ClusterHadronizationHandler,PartonSplitter>
interfacePartonSplitter("PartonSplitter",
"A reference to the PartonSplitter object",
&Herwig::ClusterHadronizationHandler::_partonSplitter,
false, false, true, false);
static Reference<ClusterHadronizationHandler,ClusterFinder>
interfaceClusterFinder("ClusterFinder",
"A reference to the ClusterFinder object",
&Herwig::ClusterHadronizationHandler::_clusterFinder,
false, false, true, false);
static Reference<ClusterHadronizationHandler,ColourReconnector>
interfaceColourReconnector("ColourReconnector",
"A reference to the ColourReconnector object",
&Herwig::ClusterHadronizationHandler::_colourReconnector,
false, false, true, false);
static Reference<ClusterHadronizationHandler,ClusterFissioner>
interfaceClusterFissioner("ClusterFissioner",
"A reference to the ClusterFissioner object",
&Herwig::ClusterHadronizationHandler::_clusterFissioner,
false, false, true, false);
static Reference<ClusterHadronizationHandler,LightClusterDecayer>
interfaceLightClusterDecayer("LightClusterDecayer",
"A reference to the LightClusterDecayer object",
&Herwig::ClusterHadronizationHandler::_lightClusterDecayer,
false, false, true, false);
static Reference<ClusterHadronizationHandler,ClusterDecayer>
interfaceClusterDecayer("ClusterDecayer",
"A reference to the ClusterDecayer object",
&Herwig::ClusterHadronizationHandler::_clusterDecayer,
false, false, true, false);
static Parameter<ClusterHadronizationHandler,Energy2> interfaceMinVirtuality2
("MinVirtuality2",
"Minimum virtuality^2 of partons to use in calculating distances (unit [GeV2]).",
&ClusterHadronizationHandler::_minVirtuality2, GeV2, 0.1*GeV2, ZERO, 10.0*GeV2,false,false,false);
static Parameter<ClusterHadronizationHandler,Length> interfaceMaxDisplacement
("MaxDisplacement",
"Maximum displacement that is allowed for a particle (unit [millimeter]).",
&ClusterHadronizationHandler::_maxDisplacement, mm, 1.0e-10*mm,
0.0*mm, 1.0e-9*mm,false,false,false);
static Reference<ClusterHadronizationHandler,StepHandler> interfaceUnderlyingEventHandler
("UnderlyingEventHandler",
"Pointer to the handler for the Underlying Event. "
"Set to NULL to disable.",
&ClusterHadronizationHandler::_underlyingEventHandler, false, false, true, true, false);
static Switch<ClusterHadronizationHandler,bool> interfaceReduceToTwoComponents
("ReduceToTwoComponents",
"Whether or not to reduce three component baryon-number violating clusters to two components before cluster splitting or leave"
" this till after the cluster splitting",
&ClusterHadronizationHandler::_reduceToTwoComponents, true, false, false);
static SwitchOption interfaceReduceToTwoComponentsYes
(interfaceReduceToTwoComponents,
"BeforeSplitting",
"Reduce to two components",
true);
static SwitchOption interfaceReduceToTwoComponentsNo
(interfaceReduceToTwoComponents,
"AfterSplitting",
"Treat as three components",
false);
}
namespace {
void extractChildren(tPPtr p, set<PPtr> & all) {
if (p->children().empty()) return;
for (PVector::const_iterator child = p->children().begin();
child != p->children().end(); ++child) {
all.insert(*child);
extractChildren(*child, all);
}
}
}
void ClusterHadronizationHandler::
handle(EventHandler & ch, const tPVector & tagged,
const Hint &) {
useMe();
currentHandler_ = this;
PVector currentlist(tagged.begin(),tagged.end());
// set the scale for coloured particles to just above the gluon mass squared
// if less than this so they are classed as perturbative
Energy2 Q02 = 1.01*sqr(getParticleData(ParticleID::g)->constituentMass());
for(unsigned int ix=0;ix<currentlist.size();++ix) {
if(currentlist[ix]->scale()<Q02) currentlist[ix]->scale(Q02);
}
// split the gluons
_partonSplitter->split(currentlist);
// form the clusters
ClusterVector clusters =
_clusterFinder->formClusters(currentlist);
// reduce BV clusters to two components now if needed
if(_reduceToTwoComponents)
_clusterFinder->reduceToTwoComponents(clusters);
// perform colour reconnection if needed and then
// decay the clusters into one hadron
bool lightOK = false;
short tried = 0;
const ClusterVector savedclusters = clusters;
tPVector finalHadrons; // only needed for partonic decayer
while (!lightOK && tried++ < 10) {
// no colour reconnection with baryon-number-violating (BV) clusters
ClusterVector CRclusters, BVclusters;
CRclusters.reserve( clusters.size() );
BVclusters.reserve( clusters.size() );
for (size_t ic = 0; ic < clusters.size(); ++ic) {
ClusterPtr cl = clusters.at(ic);
bool hasClusterParent = false;
for (unsigned int ix=0; ix < cl->parents().size(); ++ix) {
if (cl->parents()[ix]->id() == ParticleID::Cluster) {
hasClusterParent = true;
break;
}
}
if (cl->numComponents() > 2 || hasClusterParent) BVclusters.push_back(cl);
else CRclusters.push_back(cl);
}
// colour reconnection
_colourReconnector->rearrange(CRclusters);
// tag new clusters as children of the partons to hadronize
_setChildren(CRclusters);
// forms diquarks
_clusterFinder->reduceToTwoComponents(CRclusters);
// recombine vectors of (possibly) reconnected and BV clusters
clusters.clear();
clusters.insert( clusters.end(), CRclusters.begin(), CRclusters.end() );
clusters.insert( clusters.end(), BVclusters.begin(), BVclusters.end() );
// fission of heavy clusters
// NB: during cluster fission, light hadrons might be produced straight away
finalHadrons = _clusterFissioner->fission(clusters,isSoftUnderlyingEventON());
// if clusters not previously reduced to two components do it now
if(!_reduceToTwoComponents)
_clusterFinder->reduceToTwoComponents(clusters);
lightOK = _lightClusterDecayer->decay(clusters,finalHadrons);
// if the decay of the light clusters was not successful, undo the cluster
// fission and decay steps and revert to the original state of the event
// record
if (!lightOK) {
clusters = savedclusters;
for_each(clusters.begin(),
clusters.end(),
- mem_fun(&Particle::undecay));
+ mem_fn(&Particle::undecay));
}
}
if (!lightOK) {
throw Exception("CluHad::handle(): tried LightClusterDecayer 10 times!",
Exception::eventerror);
}
// decay the remaining clusters
_clusterDecayer->decay(clusters,finalHadrons);
// *****************************************
// *****************************************
// *****************************************
StepPtr pstep = newStep();
set<PPtr> allDecendants;
for (tPVector::const_iterator it = tagged.begin();
it != tagged.end(); ++it) {
extractChildren(*it, allDecendants);
}
for(set<PPtr>::const_iterator it = allDecendants.begin();
it != allDecendants.end(); ++it) {
// this is a workaround because the set sometimes
// re-orders parents after their children
if ((*it)->children().empty())
pstep->addDecayProduct(*it);
else {
pstep->addDecayProduct(*it);
pstep->addIntermediate(*it);
}
}
// *****************************************
// *****************************************
// *****************************************
// soft underlying event if needed
if (isSoftUnderlyingEventON()) {
assert(_underlyingEventHandler);
ch.performStep(_underlyingEventHandler,Hint::Default());
}
}
// Sets parent child relationship of all clusters with two components
// Relationships for clusters with more than two components are set elsewhere in the Colour Reconnector
void ClusterHadronizationHandler::_setChildren(const ClusterVector & clusters) const {
// erase existing information about the partons' children
tPVector partons;
for ( const auto & cl : clusters ) {
if ( cl->numComponents() > 2 ) continue;
partons.push_back( cl->colParticle() );
partons.push_back( cl->antiColParticle() );
}
// erase all previous information about parent child relationship
- for_each(partons.begin(), partons.end(), mem_fun(&Particle::undecay));
+ for_each(partons.begin(), partons.end(), mem_fn(&Particle::undecay));
// give new parents to the clusters: their constituents
for ( const auto & cl : clusters ) {
if ( cl->numComponents() > 2 ) continue;
cl->colParticle()->addChild(cl);
cl->antiColParticle()->addChild(cl);
}
}
diff --git a/MatrixElement/Hadron/MEMinBias.cc b/MatrixElement/Hadron/MEMinBias.cc
--- a/MatrixElement/Hadron/MEMinBias.cc
+++ b/MatrixElement/Hadron/MEMinBias.cc
@@ -1,279 +1,280 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MEMinBias class.
//
#include "MEMinBias.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/SimplePhaseSpace.h"
//#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Handlers/StandardXComb.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Handlers/SamplerBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
inline bool checkValence(int i,int side,Ptr<StandardEventHandler>::tptr eh){
// Inline function to check for valence quarks of the beam.
// i: pdgid of quark
// side: beam side
// eh: pointer to the eventhandler
int beam= ( side == 0 ) ? eh->incoming().first->id() : eh->incoming().second->id();
vector<int> val;
if( beam == ParticleID::pplus || beam == ParticleID::n0 ) val = {1,2};
if( beam == ParticleID::pbarminus || beam == ParticleID::nbar0 ) val = { -1 , -2 };
- if( val.size() == 0 ) assert(false && ("MEMinBias: Valence Quarks not defined for pid "+beam));
+ if( val.size() == 0 )
+ {cerr<<"\n\n MEMinBias: Valence Quarks not defined for pid "<<beam;assert(false);}
for(auto v:val)if(v==i)return true;
return false;
}
void MEMinBias::getDiagrams() const {
int maxflav(2);
// Pomeron data
tcPDPtr pom = getParticleData(990);
Ptr<StandardEventHandler>::tptr eh = dynamic_ptr_cast<Ptr<StandardEventHandler>::tptr>(generator()->eventHandler());
for ( int i = 1; i <= maxflav; ++i ) {
for( int j=1; j <= i; ++j){
tcPDPtr q1 = getParticleData(i);
tcPDPtr q1b = q1->CC();
tcPDPtr q2 = getParticleData(j);
tcPDPtr q2b = q2->CC();
// For each flavour we add:
//qq -> qq
if(!onlyValQuarks_) add(new_ptr((Tree2toNDiagram(3), q1, pom, q2, 1, q1, 2, q2, -1)));
else if(checkValence(i,0,eh) && checkValence(j,1,eh) ) add(new_ptr((Tree2toNDiagram(3), q1, pom, q2, 1, q1, 2, q2, -1)));
//qqb -> qqb
if(!onlyValQuarks_) add(new_ptr((Tree2toNDiagram(3), q1, pom, q2b, 1, q1, 2, q2b, -2)));
else if(checkValence(i,0,eh) && checkValence(-j,1,eh) ) add(new_ptr((Tree2toNDiagram(3), q1, pom, q2b, 1, q1, 2, q2b, -2)));
//qbqb -> qbqb
if(!onlyValQuarks_) add(new_ptr((Tree2toNDiagram(3), q1b, pom, q2b, 1, q1b, 2, q2b, -3)));
else if(checkValence(-i,0,eh) && checkValence(-j,1,eh) ) add(new_ptr((Tree2toNDiagram(3), q1b, pom, q2b, 1, q1b, 2, q2b, -3)));
}
}
}
Energy2 MEMinBias::scale() const {
return sqr(Scale_);
}
int MEMinBias::nDim() const {
return 0;
}
void MEMinBias::setKinematics() {
HwMEBase::setKinematics(); // Always call the base class method first.
}
bool MEMinBias::generateKinematics(const double *) {
// generate the masses of the particles
for ( int i = 2, N = meMomenta().size(); i < N; ++i ) {
meMomenta()[i] = Lorentz5Momentum(mePartonData()[i]->generateMass());
}
Energy q = ZERO;
try {
q = SimplePhaseSpace::
getMagnitude(sHat(), meMomenta()[2].mass(), meMomenta()[3].mass());
} catch ( ImpossibleKinematics & e ) {
return false;
}
Energy pt = ZERO;
meMomenta()[2].setVect(Momentum3( pt, pt, q));
meMomenta()[3].setVect(Momentum3(-pt, -pt, -q));
meMomenta()[2].rescaleEnergy();
meMomenta()[3].rescaleEnergy();
jacobian(1.0);
return true;
}
double MEMinBias::correctionweight() const {
// Here we calculate the weight to restore the inelastic-diffractiveXSec
// given by the MPIHandler.
// First get the eventhandler to get the current cross sections.
static Ptr<StandardEventHandler>::tptr eh =
dynamic_ptr_cast<Ptr<StandardEventHandler>::tptr>(generator()->eventHandler());
// All diffractive processes make use of this ME.
// The static map can be used to collect all the sumOfWeights.
static map<XCombPtr,double> weightsmap;
weightsmap[lastXCombPtr()]=lastXComb().stats().sumWeights();
// Define static variable to keep trac of reweighting
static double rew_=1.;
static int countUpdateWeight=50;
static double sumRew=0.;
static double countN=0;
// if we produce events we count
if(eh->integratedXSec()>ZERO)sumRew+=rew_;
if(eh->integratedXSec()>ZERO)countN+=1.;
if(countUpdateWeight<countN){
// Summing all diffractive processes (various initial states)
double sum=0.;
for(auto xx:weightsmap){
sum+=xx.second;
}
double avRew=sumRew/countN;
CrossSection XS_have =eh->sampler()->maxXSec()/eh->sampler()->attempts()*sum;
CrossSection XS_wanted=MPIHandler_->inelasticXSec()-MPIHandler_->diffractiveXSec();
double deltaN=50;
// Cross section without reweighting: XS_norew
// XS_have = avcsNorm2*XS_norew (for large N)
// We want to determine the rew that allows to get the wanted XS.
// In deltaN points we want (left) and we get (right):
// XS_wanted*(countN+deltaN) = XS_have*countN + rew*deltaN*XS_norew
// Solve for rew:
rew_=avRew*(XS_wanted*(countN+deltaN)-XS_have*countN)/(XS_have*deltaN);
countUpdateWeight+=deltaN;
}
//Make sure we dont produce negative weights.
// TODO: write finalize method that checks if reweighting was performed correctly.
rew_=max(rew_,0.000001);
rew_=min(rew_,10000.0);
return rew_;
}
double MEMinBias::me2() const {
//tuned so it gives the correct normalization for xmin = 0.11
return csNorm_*(sqr(generator()->maximumCMEnergy())/GeV2);
}
CrossSection MEMinBias::dSigHatDR() const {
return me2()*jacobian()/sHat()*sqr(hbarc)*correctionweight();
}
unsigned int MEMinBias::orderInAlphaS() const {
return 2;
}
unsigned int MEMinBias::orderInAlphaEW() const {
return 0;
}
Selector<MEBase::DiagramIndex>
MEMinBias::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 *>
MEMinBias::colourGeometries(tcDiagPtr diag) const {
static ColourLines qq("1 4, 3 5");
static ColourLines qqb("1 4, -3 -5");
static ColourLines qbqb("-1 -4, -3 -5");
Selector<const ColourLines *> sel;
switch(diag->id()){
case -1:
sel.insert(1.0, &qq);
break;
case -2:
sel.insert(1.0, &qqb);
break;
case -3:
sel.insert(1.0, &qbqb);
break;
}
return sel;
}
IBPtr MEMinBias::clone() const {
return new_ptr(*this);
}
IBPtr MEMinBias::fullclone() const {
return new_ptr(*this);
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<MEMinBias,HwMEBase>
describeHerwigMEMinBias("Herwig::MEMinBias", "HwMEHadron.so");
void MEMinBias::persistentOutput(PersistentOStream & os) const {
os << csNorm_ << ounit(Scale_,GeV) << MPIHandler_;
}
void MEMinBias::persistentInput(PersistentIStream & is, int) {
is >> csNorm_ >> iunit(Scale_,GeV) >> MPIHandler_;
}
void MEMinBias::Init() {
static ClassDocumentation<MEMinBias> documentation
("There is no documentation for the MEMinBias class");
static Parameter<MEMinBias,double> interfacecsNorm
("csNorm",
"Normalization of the min-bias cross section.",
&MEMinBias::csNorm_,
1.0, 0.0, 100.0,
false, false, Interface::limited);
static Parameter<MEMinBias,Energy> interfaceScale
("Scale",
"Scale for the Min Bias matrix element.",
&MEMinBias::Scale_,GeV,
2.0*GeV, 0.0*GeV, 100.0*GeV,
false, false, Interface::limited);
static Reference<MEMinBias,UEBase> interfaceMPIHandler
("MPIHandler",
"The object that administers all additional scatterings.",
&MEMinBias::MPIHandler_, false, false, true, true);
static Switch<MEMinBias , bool> interfaceOnlyVal
("OnlyValence" ,
"Allow the dummy process to only extract valence quarks." ,
&MEMinBias::onlyValQuarks_ , false , false , false );
static SwitchOption interfaceOnlyValYes
( interfaceOnlyVal , "Yes" , "" , true );
static SwitchOption interfaceOnlyValNo
( interfaceOnlyVal , "No" , "" , false );
}
diff --git a/MatrixElement/Hadron/MEPP2Higgs.cc b/MatrixElement/Hadron/MEPP2Higgs.cc
--- a/MatrixElement/Hadron/MEPP2Higgs.cc
+++ b/MatrixElement/Hadron/MEPP2Higgs.cc
@@ -1,1441 +1,1442 @@
// -*- C++ -*-
//
// MEPP2Higgs.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MEPP2Higgs class.
//
#include "MEPP2Higgs.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/Handlers/StandardXComb.h"
#include "ThePEG/Cuts/Cuts.h"
#include "Herwig/MatrixElement/HardVertex.h"
#include "Herwig/Models/StandardModel/StandardModel.h"
#include "Herwig/Utilities/Maths.h"
#include "Herwig/Shower/RealEmissionProcess.h"
using namespace Herwig;
const complex<Energy2>
MEPP2Higgs::epsi_ = complex<Energy2>(ZERO,-1.e-10*GeV2);
MEPP2Higgs::MEPP2Higgs() : scaleopt_(1), mu_F_(100.*GeV),
shapeOption_(2), processOption_(1),
minFlavour_(4), maxFlavour_(5),
mh_(ZERO), wh_(ZERO),
minLoop_(6),maxLoop_(6),massOption_(0),
mu_R_opt_(1),mu_F_opt_(1),
channelwgtA_(0.45),channelwgtB_(0.15),
ggPow_(1.6), qgPow_(1.6), enhance_(1.1),
nover_(0), ntry_(0), ngen_(0), maxwgt_(0.),
power_(2.0), pregg_(7.), preqg_(3.),
pregqbar_(3.), minpT_(2.*GeV),
spinCorrelations_(true)
{}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<MEPP2Higgs,HwMEBase>
describeHerwigMEPP2Higgs("Herwig::MEPP2Higgs", "HwMEHadron.so");
void MEPP2Higgs::persistentOutput(PersistentOStream & os) const {
os << HGGVertex_ << HFFVertex_ << shapeOption_ << processOption_
<< minFlavour_ << maxFlavour_ << hmass_ << ounit(mh_,GeV)
<< ounit(wh_,GeV) << minLoop_ << maxLoop_ << massOption_
<< alpha_ << prefactor_ << power_ << pregg_ << preqg_
<< pregqbar_ << ounit( minpT_, GeV ) << ggPow_ << qgPow_
<< enhance_ << channelwgtA_ << channelwgtB_ << channelWeights_
<< mu_R_opt_ << mu_F_opt_ << spinCorrelations_;
}
void MEPP2Higgs::persistentInput(PersistentIStream & is, int) {
is >> HGGVertex_ >> HFFVertex_ >> shapeOption_ >> processOption_
>> minFlavour_ >> maxFlavour_ >> hmass_ >> iunit(mh_,GeV)
>> iunit(wh_,GeV) >> minLoop_ >> maxLoop_ >> massOption_
>> alpha_ >> prefactor_ >> power_ >> pregg_ >> preqg_
>> pregqbar_ >> iunit( minpT_, GeV ) >> ggPow_ >> qgPow_
>> enhance_ >> channelwgtA_ >> channelwgtB_ >> channelWeights_
>> mu_R_opt_ >> mu_F_opt_ >> spinCorrelations_;
}
void MEPP2Higgs::Init() {
static ClassDocumentation<MEPP2Higgs> documentation
("The MEPP2Higgs class implements the matrix elements for"
" Higgs production (with decay H->W-W+) in hadron-hadron collisions"
" including the generation of additional hard QCD radiation in "
"gg to h0 processes in the POWHEG scheme",
"Hard QCD radiation for $gg\\to h^0$ processes in the"
" POWHEG scheme \\cite{Hamilton:2009za}.",
"%\\cite{Hamilton:2009za}\n"
"\\bibitem{Hamilton:2009za}\n"
" K.~Hamilton, P.~Richardson and J.~Tully,\n"
" ``A Positive-Weight Next-to-Leading Order Monte Carlo Simulation for Higgs\n"
" Boson Production,''\n"
" JHEP {\\bf 0904}, 116 (2009)\n"
" [arXiv:0903.4345 [hep-ph]].\n"
" %%CITATION = JHEPA,0904,116;%%\n");
static Switch<MEPP2Higgs,unsigned int> interfaceFactorizationScaleOption
("FactorizationScaleOption",
"Option for the choice of factorization scale",
&MEPP2Higgs::scaleopt_, 1, false, false);
static SwitchOption interfaceDynamic
(interfaceFactorizationScaleOption,
"Dynamic",
"Dynamic factorization scale equal to the current sqrt(sHat())",
1);
static SwitchOption interfaceFixed
(interfaceFactorizationScaleOption,
"Fixed",
"Use a fixed factorization scale set with FactorizationScaleValue",
2);
static Parameter<MEPP2Higgs,Energy> interfaceFactorizationScaleValue
("FactorizationScaleValue",
"Value to use in the event of a fixed factorization scale",
&MEPP2Higgs::mu_F_, GeV, 100.0*GeV, 50.0*GeV, 500.0*GeV,
true, false, Interface::limited);
static Reference<MEPP2Higgs,ShowerAlpha> interfaceCoupling
("Coupling",
"Pointer to the object to calculate the coupling for the correction",
&MEPP2Higgs::alpha_, false, false, true, false, false);
static Switch<MEPP2Higgs,unsigned int> interfaceShapeOption
("ShapeScheme",
"Option for the treatment of the Higgs resonance shape",
&MEPP2Higgs::shapeOption_, 1, false, false);
static SwitchOption interfaceStandardShapeFixed
(interfaceShapeOption,
"FixedBreitWigner",
"Breit-Wigner s-channel resonanse",
1);
static SwitchOption interfaceStandardShapeRunning
(interfaceShapeOption,
"MassGenerator",
"Use the mass generator to give the shape",
2);
static Switch<MEPP2Higgs,unsigned int> interfaceProcess
("Process",
"Which subprocesses to include",
&MEPP2Higgs::processOption_, 1, false, false);
static SwitchOption interfaceProcessAll
(interfaceProcess,
"All",
"Include all subprocesses",
1);
static SwitchOption interfaceProcess1
(interfaceProcess,
"qqbar",
"Only include the incoming q qbar subprocess",
2);
static SwitchOption interfaceProcessgg
(interfaceProcess,
"gg",
"Only include the incoming gg subprocess",
3);
static Parameter<MEPP2Higgs,unsigned int> interfaceMinimumInLoop
("MinimumInLoop",
"The minimum flavour of the quarks to include in the loops",
&MEPP2Higgs::minLoop_, 6, 5, 6,
false, false, Interface::limited);
static Parameter<MEPP2Higgs,unsigned int> interfaceMaximumInLoop
("MaximumInLoop",
"The maximum flavour of the quarks to include in the loops",
&MEPP2Higgs::maxLoop_, 6, 5, 6,
false, false, Interface::limited);
static Switch<MEPP2Higgs,unsigned int> interfaceMassOption
("MassOption",
"Option for the treatment of the masses in the loop diagrams",
&MEPP2Higgs::massOption_, 0, false, false);
static SwitchOption interfaceMassOptionFull
(interfaceMassOption,
"Full",
"Include the full mass dependence",
0);
static SwitchOption interfaceMassOptionLarge
(interfaceMassOption,
"Large",
"Use the heavy mass limit",
1);
static Parameter<MEPP2Higgs,int> interfaceMinimumFlavour
("MinimumFlavour",
"The minimum flavour of the incoming quarks in the hard process",
&MEPP2Higgs::minFlavour_, 4, 3, 5,
false, false, Interface::limited);
static Parameter<MEPP2Higgs,int> interfaceMaximumFlavour
("MaximumFlavour",
"The maximum flavour of the incoming quarks in the hard process",
&MEPP2Higgs::maxFlavour_, 5, 3, 5,
false, false, Interface::limited);
static Parameter<MEPP2Higgs,double> interfaceQGChannelWeight
("QGChannelWeight",
"The relative weights of the g g and q g channels for selection."
" This is a technical parameter for the phase-space generation and "
"should not affect the results only the efficiency and fraction"
" of events with weight > 1.",
&MEPP2Higgs::channelwgtA_, 0.45, 0., 1.e10,
false, false, Interface::limited);
static Parameter<MEPP2Higgs,double> interfaceQbarGChannelWeight
("QbarGChannelWeight",
"The relative weights of the g g abd qbar g channels for selection."
" This is a technical parameter for the phase-space generation and "
"should not affect the results only the efficiency and fraction",
&MEPP2Higgs::channelwgtB_, 0.15, 0., 1.e10,
false, false, Interface::limited);
static Parameter<MEPP2Higgs,double> interfaceGGPower
("GGPower",
"Power for the phase-space sampling of the gg channel",
&MEPP2Higgs::ggPow_, 1.6, 1.0, 3.0,
false, false, Interface::limited);
static Parameter<MEPP2Higgs,double> interfaceQGPower
("QGPower",
"Power for the phase-space sampling of the qg and qbarg channels",
&MEPP2Higgs::qgPow_, 1.6, 1.0, 3.0,
false, false, Interface::limited);
static Parameter<MEPP2Higgs,double> interfaceEnhancementFactor
("InitialEnhancementFactor",
"The enhancement factor for initial-state radiation in the shower to ensure"
" the weight for the matrix element correction is less than one.",
&MEPP2Higgs::enhance_, 1.1, 1.0, 10.0,
false, false, Interface::limited);
static Parameter<MEPP2Higgs,double> interfacePower
("Power",
"The power for the sampling of the matrix elements",
&MEPP2Higgs::power_, 2.0, 1.0, 10.0,
false, false, Interface::limited);
static Parameter<MEPP2Higgs,double> interfacePrefactorgg
("Prefactorgg",
"The prefactor for the sampling of the q qbar channel",
&MEPP2Higgs::pregg_, 7.0, 0.0, 1000.0,
false, false, Interface::limited);
static Parameter<MEPP2Higgs,double> interfacePrefactorqg
("Prefactorqg",
"The prefactor for the sampling of the q g channel",
&MEPP2Higgs::preqg_, 3.0, 0.0, 1000.0,
false, false, Interface::limited);
static Parameter<MEPP2Higgs,double> interfacePrefactorgqbar
("Prefactorgqbar",
"The prefactor for the sampling of the g qbar channel",
&MEPP2Higgs::pregqbar_, 3.0, 0.0, 1000.0,
false, false, Interface::limited);
static Parameter<MEPP2Higgs, Energy> interfacePtMin
("minPt",
"The pt cut on hardest emision generation"
"2*(1-Beta)*exp(-sqr(intrinsicpT/RMS))/sqr(RMS)",
&MEPP2Higgs::minpT_, GeV, 2.*GeV, ZERO, 100000.0*GeV,
false, false, Interface::limited);
static Switch<MEPP2Higgs,unsigned int> interface_mu_R_Option
("mu_R_Option",
"Option to use pT or mT as the scale in alphaS",
&MEPP2Higgs::mu_R_opt_, 1, false, false);
static SwitchOption interface_mu_R_Option_mT
(interface_mu_R_Option,
"mT",
"Use mT as the scale in alpha_S",
0);
static SwitchOption interface_mu_R_Option_pT
(interface_mu_R_Option,
"pT",
"Use pT as the scale in alpha_S",
1);
static Switch<MEPP2Higgs,unsigned int> interface_mu_F_Option
("mu_F_Option",
"Option to use pT or mT as the factorization scale in the PDFs",
&MEPP2Higgs::mu_F_opt_, 1, false, false);
static SwitchOption interface_mu_F_Option_mT
(interface_mu_F_Option,
"mT",
"Use mT as the scale in the PDFs",
0);
static SwitchOption interface_mu_F_Option_pT
(interface_mu_F_Option,
"pT",
"Use pT as the scale in the PDFs",
1);
static Switch<MEPP2Higgs,bool> interfaceSpinCorrelations
("SpinCorrelations",
"Which on/off spin correlations in the hard process",
&MEPP2Higgs::spinCorrelations_, true, false, false);
static SwitchOption interfaceSpinCorrelationsYes
(interfaceSpinCorrelations,
"Yes",
"Switch correlations on",
true);
static SwitchOption interfaceSpinCorrelationsNo
(interfaceSpinCorrelations,
"No",
"Switch correlations off",
false);
}
void MEPP2Higgs::doinit() {
HwMEBase::doinit();
// get the vertex pointers from the SM object
tcHwSMPtr theSM = dynamic_ptr_cast<tcHwSMPtr>(standardModel());
// do the initialisation
if(!theSM) {
throw InitException() << "Wrong type of StandardModel object in MEPP2Higgs::doinit(),"
<< " the Herwig version must be used"
<< Exception::runerror;
}
HGGVertex_ = theSM->vertexHGG();
HFFVertex_ = theSM->vertexFFH();
// get the mass generator for the higgs
PDPtr h0 = getParticleData(ParticleID::h0);
mh_ = h0->mass();
wh_ = h0->generateWidth(mh_);
if(h0->massGenerator()) {
hmass_=dynamic_ptr_cast<GenericMassGeneratorPtr>(h0->massGenerator());
}
if(shapeOption_==2&&!hmass_) throw InitException()
<< "If using the mass generator for the line shape in MEPP2Higgs::doinit()"
<< "the mass generator must be an instance of the GenericMassGenerator class"
<< Exception::runerror;
// stuff for the ME correction
double total = 1.+channelwgtA_+channelwgtB_;
channelWeights_.push_back(1./total);
channelWeights_.push_back(channelWeights_.back()+channelwgtA_/total);
channelWeights_.push_back(channelWeights_.back()+channelwgtB_/total);
// insert the different prefactors in the vector for easy look up
prefactor_.push_back(pregg_);
prefactor_.push_back(preqg_);
prefactor_.push_back(preqg_);
prefactor_.push_back(pregqbar_);
prefactor_.push_back(pregqbar_);
}
void MEPP2Higgs::dofinish() {
HwMEBase::dofinish();
if(ntry_==0) return;
generator()->log() << "MEPP2Higgs when applying the hard correction "
<< "generated " << ntry_ << " trial emissions of which "
<< ngen_ << " were accepted\n";
if(nover_==0) return;
generator()->log() << "MEPP2Higgs when applying the hard correction "
<< nover_ << " weights larger than one were generated of which"
<< " the largest was " << maxwgt_ << "\n";
}
unsigned int MEPP2Higgs::orderInAlphaS() const {
return 2;
}
unsigned int MEPP2Higgs::orderInAlphaEW() const {
return 1;
}
Energy2 MEPP2Higgs::scale() const {
return scaleopt_ == 1 ? sHat() : sqr(mu_F_);
}
int MEPP2Higgs::nDim() const {
return 0;
}
bool MEPP2Higgs::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]);
}
void MEPP2Higgs::getDiagrams() const {
tcPDPtr h0=getParticleData(ParticleID::h0);
// gg -> H process
if(processOption_==1||processOption_==3) {
tcPDPtr g=getParticleData(ParticleID::g);
add(new_ptr((Tree2toNDiagram(2), g, g, 1, h0, -1)));
}
// q qbar -> H processes
if(processOption_==1||processOption_==2) {
for ( int i = minFlavour_; i <= maxFlavour_; ++i ) {
tcPDPtr q = getParticleData(i);
tcPDPtr qb = q->CC();
add(new_ptr((Tree2toNDiagram(2), q, qb, 1, h0, -2)));
}
}
}
CrossSection MEPP2Higgs::dSigHatDR() const {
using Constants::pi;
InvEnergy2 bwfact;
if(shapeOption_==1) {
bwfact = mePartonData()[2]->generateWidth(sqrt(sHat()))*sqrt(sHat())/pi/
(sqr(sHat()-sqr(mh_))+sqr(mh_*wh_));
}
else {
bwfact = hmass_->BreitWignerWeight(sqrt(sHat()));
}
double cs = me2() * jacobian() * pi * double(UnitRemoval::E4 * bwfact/sHat());
return UnitRemoval::InvE2 * sqr(hbarc) * cs;
}
double MEPP2Higgs::me2() const {
double output(0.0);
ScalarWaveFunction hout(meMomenta()[2],mePartonData()[2],outgoing);
// Safety code to garantee the reliable behaviour of Higgs shape limits
// (important for heavy and broad Higgs resonance).
Energy hmass = meMomenta()[2].m();
tcPDPtr h0 = mePartonData()[2];
Energy mass = h0->mass();
Energy halfmass = .5*mass;
if (.0*GeV > hmass) return 0.0;
// stricly speaking the condition is applicable if
// h0->widthUpCut() == h0->widthLoCut()...
if (h0->widthLoCut() > halfmass) {
if ( mass + h0->widthUpCut() < hmass ||
mass - h0->widthLoCut() > hmass ) return 0.0;
}
else {
if (mass + halfmass < hmass || halfmass > hmass) return 0.0;
}
if (mePartonData()[0]->id() == ParticleID::g &&
mePartonData()[1]->id() == ParticleID::g) {
VectorWaveFunction gin1(meMomenta()[0],mePartonData()[0],incoming);
VectorWaveFunction gin2(meMomenta()[1],mePartonData()[1],incoming);
vector<VectorWaveFunction> g1,g2;
for(unsigned int i = 0; i < 2; ++i) {
gin1.reset(2*i);
g1.push_back(gin1);
gin2.reset(2*i);
g2.push_back(gin2);
}
output = ggME(g1,g2,hout,false);
}
else {
if (mePartonData()[0]->id() == -mePartonData()[1]->id()) {
SpinorWaveFunction qin (meMomenta()[0],mePartonData()[0],incoming);
SpinorBarWaveFunction qbin(meMomenta()[1],mePartonData()[1],incoming);
vector<SpinorWaveFunction> fin;
vector<SpinorBarWaveFunction> ain;
for (unsigned int i = 0; i < 2; ++i) {
qin.reset(i);
fin.push_back(qin);
qbin.reset(i);
ain.push_back(qbin);
}
output = qqME(fin,ain,hout,false);
}
else assert(false);
}
return output;
}
Selector<MEBase::DiagramIndex> MEPP2Higgs::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 *> MEPP2Higgs::colourGeometries(tcDiagPtr diag) const {
// colour lines
static const ColourLines line1("1 -2,2 -1");
static const ColourLines line2("1 -2");
// select the colour flow
Selector<const ColourLines *> sel;
if (diag->id() == -1) {
sel.insert(1.0, &line1);
} else {
sel.insert(1.0, &line2);
}
// return the answer
return sel;
}
void MEPP2Higgs::constructVertex(tSubProPtr sub) {
if(!spinCorrelations_) return;
// 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]);
if(hard[0]->id() < hard[1]->id()) {
swap(hard[0],hard[1]);
}
// identify the process and calculate the matrix element
if(hard[0]->id() == ParticleID::g && hard[1]->id() == ParticleID::g) {
vector<VectorWaveFunction> g1,g2;
vector<SpinorBarWaveFunction> q;
vector<SpinorWaveFunction> qbar;
VectorWaveFunction (g1,hard[0],incoming,false,true,true);
VectorWaveFunction (g2,hard[1],incoming,false,true,true);
ScalarWaveFunction hout(hard[2],outgoing,true);
g1[1] = g1[2];
g2[1] = g2[2];
ggME(g1,g2,hout,true);
}
else {
vector<SpinorWaveFunction> q1;
vector<SpinorBarWaveFunction> q2;
SpinorWaveFunction (q1,hard[0],incoming,false,true);
SpinorBarWaveFunction (q2,hard[1],incoming,false,true);
ScalarWaveFunction hout(hard[2],outgoing,true);
qqME(q1,q2,hout,true);
}
// 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);
}
double MEPP2Higgs::ggME(vector<VectorWaveFunction> g1,
vector<VectorWaveFunction> g2,
ScalarWaveFunction & in,
bool calc) const {
ProductionMatrixElement newme(PDT::Spin1,PDT::Spin1,PDT::Spin0);
Energy2 s(sHat());
double me2(0.0);
for(int i = 0; i < 2; ++i) {
for(int j = 0; j < 2; ++j) {
Complex diag = HGGVertex_->evaluate(s,g1[i],g2[j],in);
me2 += norm(diag);
if(calc) newme(2*i, 2*j, 0) = diag;
}
}
if(calc) me_.reset(newme);
// initial colour and spin factors: colour -> (8/64) and spin -> (1/4)
return me2/32.;
}
double MEPP2Higgs::qqME(vector<SpinorWaveFunction> & fin,
vector<SpinorBarWaveFunction> & ain,
ScalarWaveFunction & in,
bool calc) const {
ProductionMatrixElement newme(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin0);
Energy2 s(scale());
double me2(0.0);
for(int i = 0; i < 2; ++i) {
for(int j = 0; j < 2; ++j) {
Complex diag = HFFVertex_->evaluate(s,fin[i],ain[j],in);
me2+=norm(diag);
if(calc) newme(i, j, 0) = diag;
}
}
if(calc) me_.reset(newme);
// final colour/spin factors
return me2/12.;
}
RealEmissionProcessPtr MEPP2Higgs::applyHardMatrixElementCorrection(RealEmissionProcessPtr born) {
useMe();
assert(born->bornOutgoing().size()==1);
if(born->bornIncoming()[0]->id()!=ParticleID::g)
return RealEmissionProcessPtr();
// get gluons and Higgs
// get the gluons
ParticleVector incoming;
vector<tcBeamPtr> beams;
for(unsigned int ix=0;ix<born->bornIncoming().size();++ix) {
incoming.push_back(born->bornIncoming()[ix]);
beams.push_back(dynamic_ptr_cast<tcBeamPtr>(born->hadrons()[ix]->dataPtr()));
}
pair<double,double> xnew=born->x();
if(incoming[0]->momentum().z()<ZERO) {
swap(incoming[0],incoming[1]);
swap(beams[0],beams[1]);
swap(xnew.first,xnew.second);
}
// get the Higgs
PPtr higgs;
higgs=born->bornOutgoing()[0];
// calculate the momenta
unsigned int iemit,itype;
vector<Lorentz5Momentum> pnew;
// if not accepted return
tPDPtr out;
if(!applyHard(incoming,beams,higgs,iemit,itype,pnew,xnew,out)) return RealEmissionProcessPtr();
// fix the momentum of the higgs
Boost boostv=born->bornOutgoing()[0]->momentum().findBoostToCM();
LorentzRotation trans(pnew[3].boostVector());
trans *=LorentzRotation(boostv);
born->transformation(trans);
born->outgoing().push_back(born->bornOutgoing()[0]->dataPtr()->produceParticle(pnew[3]));
born->emitted(3);
// if applying ME correction create the new particles
if(itype==0) {
// ensure gluon can be put on shell
Lorentz5Momentum ptest(pnew[2]);
if(ptest.boost(-(pnew[0]+pnew[1]).boostVector()).e() <
getParticleData(ParticleID::g)->constituentMass()) return RealEmissionProcessPtr();
// create the new gluon
PPtr newg= getParticleData(ParticleID::g)->produceParticle(pnew[2]);
PPtr newg1 = incoming[0]->dataPtr()->produceParticle(pnew[0]);
PPtr newg2 = incoming[1]->dataPtr()->produceParticle(pnew[1]);
// set emitter and spectator
if(born->bornIncoming()[0]->momentum().z()>ZERO) {
born->incoming().push_back(newg1);
born->incoming().push_back(newg2);
if(iemit==0) {
born->emitter(0);
born->spectator(1);
}
else {
born->emitter(1);
born->spectator(0);
}
}
else {
born->incoming().push_back(newg2);
born->incoming().push_back(newg1);
if(iemit==0) {
born->emitter(1);
born->spectator(0);
}
else {
born->emitter(0);
born->spectator(1);
}
}
bool colour = UseRandom::rndbool();
newg ->incomingColour(newg1,!colour);
newg ->incomingColour(newg2, colour);
newg1->colourConnect(newg2,!colour);
born->outgoing().push_back(newg);
}
else if(itype==1) {
// ensure outgoing quark can be put on-shell
Lorentz5Momentum ptest(pnew[2]);
if(ptest.boost(-(pnew[0]+pnew[1]).boostVector()).e() <
out->constituentMass()) return RealEmissionProcessPtr();
// create the new particles
PPtr newqout = out->produceParticle(pnew[2]);
PPtr newqin,newg;
if(iemit==0) {
newqin = out ->produceParticle(pnew[0]);
newg = incoming[1]->dataPtr()->produceParticle(pnew[1]);
}
else {
newg = incoming[0]->dataPtr()->produceParticle(pnew[0]);
newqin = out ->produceParticle(pnew[1]);
}
newqout->incomingColour(newg);
newg->colourConnect(newqin);
if((born->bornIncoming()[0]->momentum().z()>ZERO && iemit==0) ||
(born->bornIncoming()[0]->momentum().z()<ZERO && iemit==1)) {
born->incoming().push_back(newqin);
born->incoming().push_back(newg );
born->emitter(0);
born->spectator(1);
}
else {
born->incoming().push_back(newg );
born->incoming().push_back(newqin);
born->emitter(1);
born->spectator(0);
}
born->outgoing().push_back(newqout);
}
else if(itype==2) {
// ensure outgoing antiquark can be put on-shell
Lorentz5Momentum ptest(pnew[2]);
if(ptest.boost(-(pnew[0]+pnew[1]).boostVector()).e() <
incoming[0]->dataPtr()->constituentMass()) return RealEmissionProcessPtr();
// create the new particles
PPtr newqout = out->produceParticle(pnew[2]);
PPtr newqin,newg;
if(iemit==0) {
newqin = out ->produceParticle(pnew[0]);
newg = incoming[1]->dataPtr()->produceParticle(pnew[1]);
}
else {
newg = incoming[0]->dataPtr()->produceParticle(pnew[0]);
newqin = out ->produceParticle(pnew[1]);
}
newqout->incomingAntiColour(newg);
newg->colourConnect(newqin,true);
if((born->bornIncoming()[0]->momentum().z()>ZERO && iemit==0) ||
(born->bornIncoming()[0]->momentum().z()<ZERO && iemit==1)) {
born->incoming().push_back(newqin);
born->incoming().push_back(newg );
born->emitter(0);
born->spectator(1);
}
else {
born->incoming().push_back(newg );
born->incoming().push_back(newqin);
born->emitter(1);
born->spectator(0);
}
born->outgoing().push_back(newqout);
}
if(born->bornIncoming()[0]->momentum().z()<ZERO) {
swap(xnew.first,xnew.second);
}
born->x(xnew);
born->interaction(ShowerInteraction::QCD);
return born;
}
bool MEPP2Higgs::softMatrixElementVeto(PPtr parent,
PPtr progenitor,
const bool & fs,
const Energy & highestpT,
const vector<tcPDPtr> & ids,
const double & z,
const Energy & scale,
const Energy & pT) {
if(fs) return false;
// check if me correction should be applied
long id[2]={progenitor->id(),parent->id()};
// must have started as a gluon
if(id[0]!=ParticleID::g) return false;
// must be a gluon going into the hard process
if(ids[1]->id()!=ParticleID::g) return false;
// check if hardest so far
if(pT<highestpT) return false;
// compute the invariants
double kappa(sqr(scale)/mh2_);
Energy2 shat(mh2_/z*(1.+(1.-z)*kappa)),that(-(1.-z)*kappa*mh2_),uhat(-(1.-z)*shat);
// check which type of process
Energy2 me;
// g g
if(ids[0]->id()==ParticleID::g&&ids[2]->id()==ParticleID::g) {
double split = 6.*(z/(1.-z)+(1.-z)/z+z*(1.-z));
me = ggME(shat,that,uhat)/split;
}
// q g
else if(ids[0]->id() >= 1 && ids[0]->id() <= 5 && ids[2]->id()==ids[0]->id()) {
double split = 4./3./z*(1.+sqr(1.-z));
me = qgME(shat,uhat,that)/split;
}
// qbar g
else if(ids[0]->id() <= -1 && ids[0]->id() >= -5 && ids[2]->id()==ids[0]->id()) {
double split = 4./3./z*(1.+sqr(1.-z));
me = qbargME(shat,uhat,that)/split;
}
else {
return false;
}
InvEnergy2 pre = 0.125/Constants::pi/loME()*sqr(mh2_)*that/shat/(shat+uhat);
double wgt = -pre*me/enhance_;
if(wgt<.0||wgt>1.) generator()->log() << "Soft ME correction weight too large or "
<< "negative in MEPP2Higgs::"
<< "softMatrixElementVeto()\n soft weight "
<< " sbar = " << shat/mh2_
<< " tbar = " << that/mh2_
<< "weight = " << wgt << " for "
<< ids[0]->id() << " " << ids[1]->id() << " "
<< ids[2]->id() << "\n";
// return whether or not vetoed
return !UseRandom::rndbool(wgt);
}
RealEmissionProcessPtr MEPP2Higgs::generateHardest(RealEmissionProcessPtr born,
ShowerInteraction inter) {
if(inter==ShowerInteraction::QED) return RealEmissionProcessPtr();
useMe();
// get the particles to be showered
beams_.clear();
partons_.clear();
// find the incoming particles
ParticleVector incoming;
ParticleVector particlesToShower;
for(unsigned int ix=0;ix<born->bornIncoming().size();++ix) {
incoming.push_back( born->bornIncoming()[ix] );
beams_.push_back( dynamic_ptr_cast<tcBeamPtr>(born->hadrons()[ix]->dataPtr()));
partons_.push_back( born->bornIncoming()[ix]->dataPtr() );
particlesToShower.push_back( born->bornIncoming()[ix] );
}
// find the higgs boson
assert(born->bornOutgoing().size()==1);
PPtr higgs = born->bornOutgoing()[0];
// calculate the rapidity of the higgs
yh_ = 0.5 * log((higgs->momentum().e()+higgs->momentum().z())/
(higgs->momentum().e()-higgs->momentum().z()));
mass_=higgs->mass();
mh2_ = sqr(mass_);
vector<Lorentz5Momentum> pnew;
int emission_type(-1);
// generate the hard emission and return if no emission
if(!getEvent(pnew,emission_type)) {
born->pT()[ShowerInteraction::QCD] = minpT_;
return born;
}
// construct the HardTree object needed to perform the showers
ParticleVector newparticles(4);
// create the partons
int iemit=-1;
// create the jet
newparticles[3] = out_->produceParticle(pnew[3]);
// g g -> h g
if(emission_type==0) {
newparticles[0] = partons_[0]->produceParticle(pnew[0]);
newparticles[1] = partons_[1]->produceParticle(pnew[1]);
iemit = pnew[0].z()/pnew[3].z()>0. ? 0 : 1;
bool colour = UseRandom::rndbool();
newparticles[3]->incomingColour(newparticles[0],!colour);
newparticles[3]->incomingColour(newparticles[1], colour);
newparticles[0]-> colourConnect(newparticles[1],!colour);
}
// g q -> H q
else if(emission_type==1) {
newparticles[0] = partons_[0]->produceParticle(pnew[0]);
newparticles[1] = out_ ->produceParticle(pnew[1]);
iemit = 1;
newparticles[3]->incomingColour(newparticles[0]);
newparticles[0]->colourConnect (newparticles[1]);
}
// q g -> H q
else if(emission_type==2) {
newparticles[0] = out_ ->produceParticle(pnew[0]);
newparticles[1] = partons_[1]->produceParticle(pnew[1]);
iemit = 0;
newparticles[3]->incomingColour(newparticles[1]);
newparticles[1]->colourConnect (newparticles[0]);
}
// g qbar -> H qbar
else if(emission_type==3) {
newparticles[0] = partons_[0]->produceParticle(pnew[0]);
newparticles[1] = out_ ->produceParticle(pnew[1]);
iemit = 1;
newparticles[3]->incomingAntiColour(newparticles[0]);
newparticles[0]->colourConnect(newparticles[1],true);
}
// qbar g -> H qbar
else if(emission_type==4) {
newparticles[0] = out_ ->produceParticle(pnew[0]);
newparticles[1] = partons_[1]->produceParticle(pnew[1]);
iemit = 0;
newparticles[3]->incomingAntiColour(newparticles[1]);
newparticles[1]->colourConnect(newparticles[0],true);
}
unsigned int ispect = iemit==0 ? 1 : 0;
// create the boson
newparticles[2] = higgs->dataPtr()->produceParticle(pnew[2]);
born->emitter (iemit);
born->spectator(ispect);
born->emitted(3);
born->pT()[ShowerInteraction::QCD] = pt_;
pair<double,double> xnew;
for(unsigned int ix=0;ix<2;++ix) {
born->incoming().push_back(newparticles[ix]);
if(ix==0) xnew.first = newparticles[ix]->momentum().rho()/born->hadrons()[ix]->momentum().rho();
else xnew.second = newparticles[ix]->momentum().rho()/born->hadrons()[ix]->momentum().rho();
}
born->x(xnew);
for(unsigned int ix=0;ix<2;++ix)
born->outgoing().push_back(newparticles[ix+2]);
// return the answer
born->interaction(ShowerInteraction::QCD);
return born;
}
bool MEPP2Higgs::applyHard(ParticleVector gluons,
vector<tcBeamPtr> beams,PPtr higgs,
unsigned int & iemit, unsigned int & itype,
vector<Lorentz5Momentum> & pnew,
pair<double,double> & xout, tPDPtr & out) {
++ntry_;
// calculate the limits on s
Energy mh(higgs->mass());
mh2_=sqr(mh);
Energy2 smin=mh2_;
Energy2 s=
(generator()->currentEvent()->incoming().first->momentum()+
generator()->currentEvent()->incoming().second->momentum()).m2();
Energy2 smax(s);
// calculate the rapidity of the higgs
double yH = 0.5*log((higgs->momentum().e()+higgs->momentum().z())/
(higgs->momentum().e()-higgs->momentum().z()));
// if no phase-space return
if(smax<smin) return false;
// get the evolution scales (this needs improving)
double kappa[2]={1.,1.};
// get the momentum fractions for the leading order process
// and the values of the PDF's
double x[2]={xout.first,xout.second},fx[2]={-99.99e99,-99.99e99};
tcPDFPtr pdf[2];
for(unsigned int ix=0;ix<gluons.size();++ix) {
assert(beams[ix]);
pdf[ix]=beams[ix]->pdf();
assert(pdf[ix]);
fx[ix]=pdf[ix]->xfx(beams[ix],gluons[ix]->dataPtr(),mh2_,x[ix]);
}
// leading order ME
Energy4 lome = loME();
// select the type of process and generate the kinematics
double rn(UseRandom::rnd());
Energy2 shat(ZERO),uhat(ZERO),that(ZERO);
double weight(0.),xnew[2]={1.,1.};
// gg -> H g
if(rn<channelWeights_[0]) {
// generate the value of s according to 1/s^n
double rhomax(pow(smin/mh2_,1.-ggPow_)),rhomin(pow(smax/mh2_,1.-ggPow_));
double rho = rhomin+UseRandom::rnd()*(rhomax-rhomin);
shat = mh2_*pow(rho,1./(1.-ggPow_));
Energy2 jacobian = mh2_/(ggPow_-1.)*(rhomax-rhomin)*pow(shat/mh2_,ggPow_);
double sbar=shat/mh2_;
// calculate limits on that
Energy2 tmax=mh2_*kappa[0]*(1.-sbar)/(kappa[0]+sbar);
Energy2 tmin=shat*(1.-sbar)/(kappa[1]+sbar);
// calculate the limits on uhat
Energy2 umax(mh2_-shat-tmin),umin(mh2_-shat-tmax);
// check inside phase space
if(tmax<tmin||umax<umin) return false;
// generate t and u according to 1/t+1/u
// generate in 1/t
if(UseRandom::rndbool(0.5)) {
that=tmax*pow(tmin/tmax,UseRandom::rnd());
uhat=mh2_-shat-that;
jacobian *=log(tmin/tmax);
}
// generate in 1/u
else {
uhat=umax*pow(umin/umax,UseRandom::rnd());
that=mh2_-shat-uhat;
jacobian *=log(umin/umax);
}
Energy4 jacobian2 = jacobian * 2.*uhat*that/(shat-mh2_);
// new scale (this is mt^2=pt^2+mh^2)
Energy2 scale(uhat*that/shat+mh2_);
// the PDF's with the emitted gluon
double fxnew[2];
xnew[0]=exp(yH)/sqrt(s)*sqrt(shat*(mh2_-uhat)/(mh2_-that));
xnew[1]=shat/(s*xnew[0]);
if(xnew[0]<=0.||xnew[0]>=1.||xnew[1]<=0.||xnew[1]>=1.) return false;
for(unsigned int ix=0;ix<2;++ix)
fxnew[ix]=pdf[ix]->xfx(beams[ix],gluons[ix]->dataPtr(),scale,xnew[ix]);
// jacobian and me parts of the weight
weight = jacobian2*ggME(shat,uhat,that)/lome*mh2_/sqr(shat);
// pdf part of the weight
weight *=fxnew[0]*fxnew[1]*x[0]*x[1]/(fx[0]*fx[1]*xnew[0]*xnew[1]);
// finally coupling and different channel pieces
weight *= 1./16./sqr(Constants::pi)*alpha_->value(scale)/channelWeights_[0];
itype=0;
iemit = that>uhat ? 0 : 1;
out = getParticleData(ParticleID::g);
}
// incoming quark or antiquark
else {
// generate the value of s according to 1/s^n
double rhomax(pow(smin/mh2_,1.-qgPow_)),rhomin(pow(smax/mh2_,1.-qgPow_));
double rho = rhomin+UseRandom::rnd()*(rhomax-rhomin);
shat = mh2_*pow(rho,1./(1.-qgPow_));
Energy2 jacobian = mh2_/(qgPow_-1.)*(rhomax-rhomin)*pow(shat/mh2_,qgPow_);
double sbar=shat/mh2_;
// calculate limits on that
Energy2 tmax=mh2_*kappa[0]*(1.-sbar)/(kappa[0]+sbar);
Energy2 tmin=shat*(1.-sbar)/(kappa[1]+sbar);
// calculate the limits on uhat
Energy2 umax(mh2_-shat-tmin),umin(mh2_-shat-tmax);
// check inside phase space
if(tmax<tmin||umax<umin) return false;
// generate t
bool order(UseRandom::rndbool());
Energy4 jacobian2;
if(order) {
uhat=umax*pow(umin/umax,UseRandom::rnd());
that=mh2_-shat-uhat;
jacobian2 = jacobian * uhat*log(umax/umin);
}
else {
that=tmax*pow(tmin/tmax,UseRandom::rnd());
uhat=mh2_-shat-that;
jacobian2 = jacobian * that*log(tmax/tmin);
}
InvEnergy4 mewgt;
// new scale (this is mt^2=pt^2+mh^2)
Energy2 scale(uhat*that/shat+mh2_);
double fxnew[2];
xnew[0]=exp(yH)/sqrt(s)*sqrt(shat*(mh2_-uhat)/(mh2_-that));
xnew[1]=shat/(s*xnew[0]);
if(xnew[0]<=0.||xnew[0]>=1.||xnew[1]<=0.||xnew[1]>=1.) return false;
if(rn<channelWeights_[1]) {
itype = 1;
// q g -> H q
if(!order) {
out = quarkFlavour(pdf[0],scale,xnew[0],beams[0],fxnew[0],false);
fxnew[1]=pdf[1]->xfx(beams[1],gluons[1]->dataPtr(),scale,xnew[1]);
iemit = 0;
mewgt = out ? qgME(shat,uhat,that)/lome*mh2_/sqr(shat) : ZERO;
}
// g q -> H q
else {
fxnew[0]=pdf[0]->xfx(beams[0],gluons[0]->dataPtr(),scale,xnew[0]);
out = quarkFlavour(pdf[1],scale,xnew[1],beams[1],fxnew[1],false);
iemit = 1;
mewgt = out ? qgME(shat,that,uhat)/lome*mh2_/sqr(shat) : ZERO;
}
jacobian2 /= (channelWeights_[1]-channelWeights_[0]);
}
else {
itype=2;
// qbar g -> H qbar
if(!order) {
out = quarkFlavour(pdf[0],scale,xnew[0],beams[0],fxnew[0],true);
fxnew[1]=pdf[1]->xfx(beams[1],gluons[1]->dataPtr(),scale,xnew[1]);
iemit = 0;
mewgt = out ? qbargME(shat,uhat,that)/lome*mh2_/sqr(shat) : ZERO;
}
// g qbar -> H qbar
else {
fxnew[0]=pdf[0]->xfx(beams[0],gluons[0]->dataPtr(),scale,xnew[0]);
out = quarkFlavour(pdf[1],scale,xnew[1],beams[1],fxnew[1],true);
iemit = 1;
mewgt = out ? qbargME(shat,that,uhat)/lome*mh2_/sqr(shat) : ZERO;
}
jacobian2/=(channelWeights_[2]-channelWeights_[1]);
}
// weight (factor of 2 as pick q(bar)g or gq(bar)
weight = 2.*jacobian2*mewgt;
// pdf part of the weight
weight *=fxnew[0]*fxnew[1]*x[0]*x[1]/(fx[0]*fx[1]*xnew[0]*xnew[1]);
// finally coupling and different channel pieces
weight *= 1./16./sqr(Constants::pi)*alpha_->value(scale);
}
// if me correction should be applied
if(weight>1.) {
++nover_;
maxwgt_ = max( maxwgt_ , weight);
weight=1.;
}
if(UseRandom::rnd()>weight) return false;
++ngen_;
// construct the momenta
Energy roots = 0.5*sqrt(s);
Energy pt = sqrt(uhat*that/shat);
Energy mt = sqrt(uhat*that/shat+mh2_);
Lorentz5Momentum pin[2]={Lorentz5Momentum(ZERO,ZERO, xnew[0]*roots,xnew[0]*roots),
Lorentz5Momentum(ZERO,ZERO,-xnew[1]*roots,xnew[1]*roots)};
double phi = Constants::twopi*UseRandom::rnd();
Lorentz5Momentum pH(pt*cos(phi),pt*sin(phi),mt*sinh(yH),mt*cosh(yH));
Lorentz5Momentum pJ(pin[0]+pin[1]-pH);
// momenta to be returned
pnew.push_back(pin[0]);
pnew.push_back(pin[1]);
pnew.push_back(pJ);
pnew.push_back(pH);
xout.first = xnew[0];
xout.second = xnew[1];
return true;
}
Energy2 MEPP2Higgs::ggME(Energy2 s, Energy2 t, Energy2 u) {
Energy2 output;
if(massOption_==0) {
complex<Energy> me[2][2][2];
me[1][1][1] = ZERO;
me[1][1][0] = ZERO;
me[0][1][0] = ZERO;
me[0][1][1] = ZERO;
for(unsigned int ix=minLoop_; ix<=maxLoop_; ++ix ) {
Energy2 mf2=sqr(getParticleData(long(ix))->mass());
bi_[1]=B(s,mf2);
bi_[2]=B(u,mf2);
bi_[3]=B(t,mf2);
bi_[4]=B(mh2_,mf2);
bi_[1]=bi_[1]-bi_[4];
bi_[2]=bi_[2]-bi_[4];
bi_[3]=bi_[3]-bi_[4];
ci_[1]=C(s,mf2);
ci_[2]=C(u,mf2);
ci_[3]=C(t,mf2);
ci_[7]=C(mh2_,mf2);
ci_[4]=(s*ci_[1]-mh2_*ci_[7])/(s-mh2_);
ci_[5]=(u*ci_[2]-mh2_*ci_[7])/(u-mh2_);
ci_[6]=(t*ci_[3]-mh2_*ci_[7])/(t-mh2_);
di_[1]=D(t,u,s,mf2);
di_[2]=D(s,t,u,mf2);
di_[3]=D(s,u,t,mf2);
me[1][1][1]+=me1(s,u,t,mf2,1,2,3,4,5,6);
me[1][1][0]+=me2(s,u,t,mf2);
me[0][1][0]+=me1(u,s,t,mf2,2,1,3,5,4,6);
me[0][1][1]+=me1(t,u,s,mf2,3,2,1,6,5,4);
}
me[0][0][0]=-me[1][1][1];
me[0][0][1]=-me[1][1][0];
me[1][0][1]=-me[0][1][0];
me[1][0][0]=-me[0][1][1];
output = real(me[0][0][0]*conj(me[0][0][0])+
me[0][0][1]*conj(me[0][0][1])+
me[0][1][0]*conj(me[0][1][0])+
me[0][1][1]*conj(me[0][1][1])+
me[1][0][0]*conj(me[1][0][0])+
me[1][0][1]*conj(me[1][0][1])+
me[1][1][0]*conj(me[1][1][0])+
me[1][1][1]*conj(me[1][1][1]));
output *= 3./8.;
}
else {
output=32./3.*
(pow<4,1>(s)+pow<4,1>(t)+pow<4,1>(u)+pow<4,1>(mh2_))/s/t/u;
}
// spin and colour factors
return output/4./64.;
}
Energy2 MEPP2Higgs::qgME(Energy2 s, Energy2 t, Energy2 u) {
Energy2 output;
if(massOption_==0) {
complex<Energy2> A(ZERO);
Energy2 si(u-mh2_);
for(unsigned int ix=minLoop_;ix<=maxLoop_;++ix) {
Energy2 mf2=sqr(getParticleData(long(ix))->mass());
A += mf2*(2.+2.*double(u/si)*(B(u,mf2)-B(mh2_,mf2))
+double((4.*mf2-s-t)/si)*Complex(u*C(u,mf2)-mh2_*C(mh2_,mf2)));
}
output =-4.*(sqr(s)+sqr(t))/sqr(si)/u*real(A*conj(A));
}
else{
output =-4.*(sqr(s)+sqr(t))/u/9.;
}
// final colour/spin factors
return output/24.;
}
Energy2 MEPP2Higgs::qbargME(Energy2 s, Energy2 t, Energy2 u) {
Energy2 output;
if(massOption_==0) {
complex<Energy2> A(ZERO);
Energy2 si(u-mh2_);
for(unsigned int ix=minLoop_;ix<=maxLoop_;++ix) {
Energy2 mf2=sqr(getParticleData(long(ix))->mass());
A+=mf2*(2.+2.*double(u/si)*(B(u,mf2)-B(mh2_,mf2))
+double((4.*mf2-s-t)/si)*Complex(u*C(u,mf2)-mh2_*C(mh2_,mf2)));
}
output =-4.*(sqr(s)+sqr(t))/sqr(si)/u*real(A*conj(A));
}
else {
output =-4.*(sqr(s)+sqr(t))/u/9.;
}
// final colour/spin factors
return output/24.;
}
Energy4 MEPP2Higgs::loME() const {
Complex I(0);
if(massOption_==0) {
for(unsigned int ix=minLoop_;ix<=maxLoop_;++ix) {
double x = sqr(getParticleData(long(ix))->mass())/mh2_;
I += 3.*x*(2.+(4.*x-1.)*F(x));
}
}
else {
I = 1.;
}
return sqr(mh2_)/576./Constants::pi*norm(I);
}
tPDPtr MEPP2Higgs::quarkFlavour(tcPDFPtr pdf, Energy2 scale,
double x, tcBeamPtr beam,
double & pdfweight, bool anti) {
vector<double> weights;
vector<tPDPtr> partons;
pdfweight = 0.;
if(!anti) {
for(unsigned int ix=1;ix<=5;++ix) {
partons.push_back(getParticleData(long(ix)));
weights.push_back(max(0.,pdf->xfx(beam,partons.back(),scale,x)));
pdfweight += weights.back();
}
}
else {
for(unsigned int ix=1;ix<=5;++ix) {
partons.push_back(getParticleData(-long(ix)));
weights.push_back(max(0.,pdf->xfx(beam,partons.back(),scale,x)));
pdfweight += weights.back();
}
}
if(pdfweight==0.) return tPDPtr();
double wgt=UseRandom::rnd()*pdfweight;
for(unsigned int ix=0;ix<weights.size();++ix) {
if(wgt<=weights[ix]) return partons[ix];
wgt -= weights[ix];
}
assert(false);
return tPDPtr();
}
Complex MEPP2Higgs::B(Energy2 s,Energy2 mf2) const {
- Complex output,pii(0.,Constants::pi);
+ Complex output;
+ const Complex pii(0.,Constants::pi);
double rat=s/(4.*mf2);
if(s<ZERO)
output=2.-2.*sqrt(1.-1./rat)*log(sqrt(-rat)+sqrt(1.-rat));
else if(s>=ZERO&&rat<1.)
output=2.-2.*sqrt(1./rat-1.)*asin(sqrt(rat));
else
output=2.-sqrt(1.-1./rat)*(2.*log(sqrt(rat)+sqrt(rat-1.))-pii);
return output;
}
complex<InvEnergy2> MEPP2Higgs::C(Energy2 s,Energy2 mf2) const {
complex<InvEnergy2> output;
- Complex pii(0.,Constants::pi);
+ const Complex pii(0.,Constants::pi);
double rat=s/(4.*mf2);
if(s<ZERO)
output=2.*sqr(log(sqrt(-rat)+sqrt(1.-rat)))/s;
else if(s>=ZERO&&rat<1.)
output=-2.*sqr(asin(sqrt(rat)))/s;
else {
double cosh=log(sqrt(rat)+sqrt(rat-1.));
output=2.*(sqr(cosh)-sqr(Constants::pi)/4.-pii*cosh)/s;
}
return output;
}
Complex MEPP2Higgs::dIntegral(Energy2 a, Energy2 b, double y0) const {
Complex output;
if(b==ZERO) output=0.;
else {
Complex y1=0.5*(1.+sqrt(1.-4.*(a+epsi_)/b));
Complex y2=1.-y1;
Complex z1=y0/(y0-y1);
Complex z2=(y0-1.)/(y0-y1);
Complex z3=y0/(y0-y2);
Complex z4=(y0-1.)/(y0-y2);
output=Math::Li2(z1)-Math::Li2(z2)+Math::Li2(z3)-Math::Li2(z4);
}
return output;
}
complex<InvEnergy4> MEPP2Higgs::D(Energy2 s,Energy2 t, Energy2,
Energy2 mf2) const {
- Complex output,pii(0.,Constants::pi);
+ Complex output;
Energy4 st=s*t;
Energy4 root=sqrt(sqr(st)-4.*st*mf2*(s+t-mh2_));
double xp=0.5*(st+root)/st,xm=1-xp;
output = 2.*(-dIntegral(mf2,s,xp)-dIntegral(mf2,t,xp)
+dIntegral(mf2,mh2_,xp)+log(-xm/xp)
*(log((mf2+epsi_)/GeV2)-log((mf2+epsi_-s*xp*xm)/GeV2)
+log((mf2+epsi_-mh2_*xp*xm)/GeV2)-log((mf2+epsi_-t*xp*xm)/GeV2)));
return output/root;
}
complex<Energy> MEPP2Higgs::me1(Energy2 s,Energy2 t,Energy2 u, Energy2 mf2,
unsigned int i ,unsigned int j ,unsigned int k ,
unsigned int i1,unsigned int j1,unsigned int k1) const {
Energy2 s1(s-mh2_),t1(t-mh2_),u1(u-mh2_);
return mf2*4.*sqrt(2.*s*t*u)*
(-4.*(1./(u*t)+1./(u*u1)+1./(t*t1))
-4.*((2.*s+t)*bi_[k]/sqr(u1)+(2.*s+u)*bi_[j]/sqr(t1))/s
-(s-4.*mf2)*(s1*ci_[i1]+(u-s)*ci_[j1]+(t-s)*ci_[k1])/(s*t*u)
-8.*mf2*(ci_[j1]/(t*t1)+ci_[k1]/(u*u1))
+0.5*(s-4.*mf2)*(s*t*di_[k]+u*s*di_[j]-u*t*di_[i])/(s*t*u)
+4.*mf2*di_[i]/s
-2.*Complex(u*ci_[k]+t*ci_[j]+u1*ci_[k1]+t1*ci_[j1]-u*t*di_[i])/sqr(s));
}
complex<Energy> MEPP2Higgs::me2(Energy2 s,Energy2 t,Energy2 u,
Energy2 mf2) const {
Energy2 s1(s-mh2_),t1(t-mh2_),u1(u-mh2_);
return mf2*4.*sqrt(2.*s*t*u)*(4.*mh2_+(mh2_-4.*mf2)*(s1*ci_[4]+t1*ci_[5]+u1*ci_[6])
-0.5*(mh2_-4.*mf2)*(s*t*di_[3]+u*s*di_[2]+u*t*di_[1]) )/
(s*t*u);
}
Complex MEPP2Higgs::F(double x) const {
if(x<.25) {
double root = sqrt(1.-4.*x);
- Complex pii(0.,Constants::pi);
+ const Complex pii(0.,Constants::pi);
return 0.5*sqr(log((1.+root)/(1.-root))-pii);
}
else {
return -2.*sqr(asin(0.5/sqrt(x)));
}
}
bool MEPP2Higgs::getEvent(vector<Lorentz5Momentum> & pnew,
int & emis_type){
// maximum pt (half of centre-of-mass energy)
Energy maxp = 0.5*generator()->maximumCMEnergy();
// set pt of emission to zero
pt_=ZERO;
//Working Variables
Energy pt;
double yj;
// limits on the rapidity of the jet
double minyj = -8.0,maxyj = 8.0;
bool reject;
double wgt;
emis_type=-1;
tcPDPtr outParton;
for(int j=0;j<5;++j) {
pt = maxp;
do {
double a = alpha_->overestimateValue()*prefactor_[j]*(maxyj-minyj)/(power_-1.);
// generate next pt
pt=GeV/pow(pow(GeV/pt,power_-1)-log(UseRandom::rnd())/a,1./(power_-1.));
// generate rapidity of the jet
yj=UseRandom::rnd()*(maxyj-minyj)+ minyj;
// calculate rejection weight
wgt=getResult(j,pt,yj,outParton);
wgt/= prefactor_[j]*pow(GeV/pt,power_);
reject = UseRandom::rnd()>wgt;
//no emission event if p goes past p min - basically set to outside
//of the histogram bounds (hopefully hist object just ignores it)
if(pt<minpT_){
pt=ZERO;
reject = false;
}
if(wgt>1.0) {
ostringstream s;
s << "MEPP2Higgs::getEvent weight for channel " << j
<< "is " << wgt << " which is greater than 1";
generator()->logWarning( Exception(s.str(), Exception::warning) );
}
}
while(reject);
// set pt of emission etc
if(pt>pt_){
emis_type = j;
pt_=pt;
yj_=yj;
out_ = outParton;
}
}
//was this an (overall) no emission event?
if(pt_<minpT_){
pt_=ZERO;
emis_type = 5;
}
if(emis_type==5) return false;
// generate the momenta of the particles
// hadron-hadron cmf
Energy2 s=sqr(generator()->maximumCMEnergy());
// transverse energy
Energy et=sqrt(mh2_+sqr(pt_));
// first calculate all the kinematic variables
// longitudinal real correction fractions
double x = pt_*exp( yj_)/sqrt(s)+et*exp( yh_)/sqrt(s);
double y = pt_*exp(-yj_)/sqrt(s)+et*exp(-yh_)/sqrt(s);
// that and uhat
// Energy2 th = -sqrt(s)*x*pt_*exp(-yj_);
// Energy2 uh = -sqrt(s)*y*pt_*exp( yj_);
// Energy2 sh = x*y*s;
// reconstruct the momenta
// incoming momenta
pnew.push_back(Lorentz5Momentum(ZERO,ZERO,
x*0.5*sqrt(s), x*0.5*sqrt(s),ZERO));
pnew.push_back(Lorentz5Momentum(ZERO,ZERO,
-y*0.5*sqrt(s), y*0.5*sqrt(s),ZERO));
// outgoing momenta
double phi(Constants::twopi*UseRandom::rnd());
double sphi(sin(phi)),cphi(cos(phi));
pnew.push_back(Lorentz5Momentum( cphi*pt_, sphi*pt_, et*sinh(yh_),
et*cosh(yh_), mass_));
pnew.push_back(Lorentz5Momentum(-cphi*pt_,-sphi*pt_,pt_*sinh(yj_),
pt_*cosh(yj_),ZERO));
return true;
}
double MEPP2Higgs::getResult(int emis_type, Energy pt, double yj,
tcPDPtr & outParton) {
Energy2 s=sqr(generator()->maximumCMEnergy());
Energy2 scale = mh2_+sqr(pt);
Energy et=sqrt(scale);
scale = mu_F_opt_==0 ? mh2_+sqr(pt) : sqr(pt) ;
// longitudinal real correction fractions
double x = pt*exp( yj)/sqrt(s)+et*exp( yh_)/sqrt(s);
double y = pt*exp(-yj)/sqrt(s)+et*exp(-yh_)/sqrt(s);
// reject if outside region
if(x<0.||x>1.||y<0.||y>1.||x*y<mh2_/s) return 0.;
// longitudinal born fractions
double x1 = mass_*exp( yh_)/sqrt(s);
double y1 = mass_*exp(-yh_)/sqrt(s);
// mandelstam variables
Energy2 th = -sqrt(s)*x*pt*exp(-yj);
Energy2 uh = -sqrt(s)*y*pt*exp( yj);
Energy2 sh = mh2_-th-uh;
InvEnergy2 res = InvEnergy2();
// pdf part of the cross section
double pdf[4] = {99.99e99,99.99e99,99.99e99,99.99e99};
if(mu_F_opt_==0) { // As in original version ...
pdf[0]=beams_[0]->pdf()->xfx(beams_[0],partons_[0],mh2_,x1);
pdf[1]=beams_[1]->pdf()->xfx(beams_[1],partons_[1],mh2_,y1);
} else { // As in Nason and Ridolfi paper ...
pdf[0]=beams_[0]->pdf()->xfx(beams_[0],partons_[0],scale,x1);
pdf[1]=beams_[1]->pdf()->xfx(beams_[1],partons_[1],scale,y1);
}
// g g -> H g
if(emis_type==0) {
outParton = partons_[1];
pdf[2]=beams_[0]->pdf()->xfx(beams_[0],partons_[0],scale,x);
pdf[3]=beams_[1]->pdf()->xfx(beams_[1],partons_[1],scale,y);
res = ggME(sh,uh,th)/loME();
}
// q g -> H q
else if(emis_type==1) {
outParton = quarkFlavour(beams_[0]->pdf(),scale,x,beams_[0],pdf[2],false);
pdf[3]=beams_[1]->pdf()->xfx(beams_[1],partons_[1],scale,y);
res = outParton ? qgME(sh,uh,th)/loME() : ZERO;
}
// g q -> H q
else if(emis_type==2) {
pdf[2]=beams_[0]->pdf()->xfx(beams_[0],partons_[0],scale,x);
outParton = quarkFlavour(beams_[1]->pdf(),scale,y,beams_[1],pdf[3],false);
res = outParton ? qgME(sh,th,uh)/loME() : ZERO;
}
// qbar g -> H qbar
else if(emis_type==3) {
outParton = quarkFlavour(beams_[0]->pdf(),scale,x,beams_[0],pdf[2],true);
pdf[3]=beams_[1]->pdf()->xfx(beams_[1],partons_[1],scale,y);
res = outParton ? qbargME(sh,uh,th)/loME() : ZERO;
}
// g qbar -> H qbar
else if(emis_type==4) {
pdf[2]=beams_[0]->pdf()->xfx(beams_[0],partons_[0],scale,x);
outParton = quarkFlavour(beams_[1]->pdf(),scale,y,beams_[1],pdf[3],true);
res = outParton ? qbargME(sh,th,uh)/loME() : ZERO;
}
//deals with pdf zero issue at large x
if(pdf[0]<=0.||pdf[1]<=0.||pdf[2]<=0.||pdf[3]<=0.) {
res = ZERO;
}
else {
res *= pdf[2]*pdf[3]/pdf[0]/pdf[1]*mh2_/sh;
}
scale = mu_R_opt_==0 ? mh2_+sqr(pt) : sqr(pt) ;
return alpha_->ratio(scale)/8./sqr(Constants::pi)*mh2_/sh*GeV*pt*res;
}
void MEPP2Higgs::initializeMECorrection(RealEmissionProcessPtr born, double & initial,
double & final) {
final = 1.;
initial = born->bornIncoming()[0]->id()==ParticleID::g ?
enhance_ : 1.;
}
diff --git a/MatrixElement/Hadron/MEPP2ZH.h b/MatrixElement/Hadron/MEPP2ZH.h
--- a/MatrixElement/Hadron/MEPP2ZH.h
+++ b/MatrixElement/Hadron/MEPP2ZH.h
@@ -1,111 +1,105 @@
// -*- C++ -*-
#ifndef HERWIG_MEPP2ZH_H
#define HERWIG_MEPP2ZH_H
//
// This is the declaration of the MEPP2ZH class.
//
#include "Herwig/MatrixElement/MEfftoVH.h"
namespace Herwig {
using namespace ThePEG;
/**
* The MEPP2ZH class implements the matrix element
* for \f$q\bar{q}\to Z^0h^0\f$.
*
* @see \ref MEPP2ZHInterfaces "The interfaces"
* defined for MEPP2ZH.
*/
class MEPP2ZH: public MEfftoVH {
public:
/**
* The default constructor.
*/
MEPP2ZH();
/** @name Virtual functions required by the MEBase class. */
//@{
/**
* Add all possible diagrams with the add() function.
*/
virtual void getDiagrams() const;
//@}
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const { return new_ptr(*this); }
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const { return new_ptr(*this); }
//@}
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* Initialize this object after the setup phase before saving an
* EventGenerator to disk.
* @throws InitException if object could not be initialized properly.
*/
virtual void doinit();
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MEPP2ZH & operator=(const MEPP2ZH &) = delete;
-private:
-
- /**
- * The allowed flavours of the incoming quarks
- */
- int _maxflavour;
};
}
#endif /* HERWIG_MEPP2ZH_H */
diff --git a/MatrixElement/Lepton/MEee2VectorMeson.cc b/MatrixElement/Lepton/MEee2VectorMeson.cc
--- a/MatrixElement/Lepton/MEee2VectorMeson.cc
+++ b/MatrixElement/Lepton/MEee2VectorMeson.cc
@@ -1,228 +1,227 @@
// -*- C++ -*-
//
// MEee2VectorMeson.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MEee2VectorMeson class.
//
#include "MEee2VectorMeson.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/Cuts/Cuts.h"
#include "Herwig/PDT/GenericMassGenerator.h"
#include "ThePEG/Handlers/StandardXComb.h"
#include "Herwig/Models/StandardModel/StandardModel.h"
#include "Herwig/MatrixElement/HardVertex.h"
using namespace Herwig;
using namespace ThePEG;
using namespace ThePEG::Helicity;
void MEee2VectorMeson::getDiagrams() const {
tcPDPtr em = getParticleData(ParticleID::eminus);
tcPDPtr ep = getParticleData(ParticleID::eplus);
add(new_ptr((Tree2toNDiagram(2), em, ep, 1, vector_,-1)));
}
Energy2 MEee2VectorMeson::scale() const {
return sHat();
}
int MEee2VectorMeson::nDim() const {
return 0;
}
void MEee2VectorMeson::setKinematics() {
MEBase::setKinematics();
}
bool MEee2VectorMeson::generateKinematics(const double *) {
Lorentz5Momentum pout=meMomenta()[0]+meMomenta()[1];
pout.rescaleMass();
meMomenta()[2] = pout;
jacobian(1.0);
// check passes all the cuts
vector<LorentzMomentum> out(1,meMomenta()[2]);
tcPDVector tout(1,mePartonData()[2]);
return lastCuts().passCuts(tout, out, mePartonData()[0], mePartonData()[1]);
}
unsigned int MEee2VectorMeson::orderInAlphaS() const {
return 0;
}
unsigned int MEee2VectorMeson::orderInAlphaEW() const {
return 2;
}
Selector<const ColourLines *>
MEee2VectorMeson::colourGeometries(tcDiagPtr) const {
static ColourLines neutral ( " " );
Selector<const ColourLines *> sel;sel.insert(1.,&neutral);
return sel;
}
void MEee2VectorMeson::persistentOutput(PersistentOStream & os) const {
os << coupling_ << vector_ << massGen_ << lineShape_;
}
void MEee2VectorMeson::persistentInput(PersistentIStream & is, int) {
is >> coupling_ >> vector_ >> massGen_ >> lineShape_;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<MEee2VectorMeson,MEBase>
describeHerwigMEee2VectorMeson("Herwig::MEee2VectorMeson", "HwMELepton.so");
void MEee2VectorMeson::Init() {
static ClassDocumentation<MEee2VectorMeson> documentation
("The MEee2VectorMeson class implements the production of a vector meson"
" in e+e- collisions and is primilarly intended to test the hadron decay package");
static Switch<MEee2VectorMeson,bool> interfaceLineShape
("LineShape",
"Option for the vector meson lineshape",
&MEee2VectorMeson::lineShape_, false, false, false);
static SwitchOption interfaceLineShapeMassGenerator
(interfaceLineShape,
"MassGenerator",
"Use the mass generator if available",
true);
static SwitchOption interfaceLineShapeBreitWigner
(interfaceLineShape,
"BreitWigner",
"Use a Breit-Wigner with the naive running width",
false);
static Reference<MEee2VectorMeson,ParticleData> interfaceVectorMeson
("VectorMeson",
"The vector meson produced",
&MEee2VectorMeson::vector_, false, false, true, false, false);
static Parameter<MEee2VectorMeson,double> interfaceCoupling
("Coupling",
"The leptonic coupling of the vector meson",
&MEee2VectorMeson::coupling_, 0., 0.0, 100.0,
false, false, Interface::limited);
}
Selector<MEBase::DiagramIndex>
MEee2VectorMeson::diagrams(const DiagramVector &) const {
Selector<DiagramIndex> sel;sel.insert(1.0, 0);
return sel;
}
CrossSection MEee2VectorMeson::dSigHatDR() const {
InvEnergy2 wgt;
Energy M(vector_->mass()),G(vector_->width());
- Energy2 M2(sqr(M)),GM(G*M);
+ Energy2 M2(sqr(M));
if(massGen_&&lineShape_)
wgt = Constants::pi*massGen_->BreitWignerWeight(sqrt(sHat()));
else
wgt = sHat()*G/M/(sqr(sHat()-M2)+sqr(sHat()*G/M));
return sqr(4.*Constants::pi*SM().alphaEM(sHat()))*me2()*jacobian()*wgt*sqr(hbarc)*sqr(M2/sHat());
}
void MEee2VectorMeson::doinit() {
MEBase::doinit();
// mass generator
tMassGenPtr mass=vector_->massGenerator();
if(mass) {
massGen_=dynamic_ptr_cast<GenericMassGeneratorPtr>(mass);
}
}
double MEee2VectorMeson::me2() const {
double aver=0.;
// get the order right
int ielectron(0),ipositron(1);
if(mePartonData()[0]->id()!=11) swap(ielectron,ipositron);
// the vectors for the wavefunction to be passed to the matrix element
vector<SpinorWaveFunction> fin;
vector<SpinorBarWaveFunction> ain;
vector<VectorWaveFunction> vout;
for(unsigned int ihel=0;ihel<2;++ihel) {
fin.push_back(SpinorWaveFunction(meMomenta()[ielectron],
mePartonData()[ielectron],ihel,incoming));
ain.push_back(SpinorBarWaveFunction(meMomenta()[ipositron],
mePartonData()[ipositron],ihel,incoming));
}
for(unsigned int ihel=0;ihel<3;++ihel) {
vout.push_back(VectorWaveFunction(meMomenta()[2],mePartonData()[2],ihel,outgoing));
}
ProductionMatrixElement temp=HelicityME(fin,ain,vout,aver);
return aver;
}
// the helicity amplitude matrix element
ProductionMatrixElement MEee2VectorMeson::HelicityME(vector<SpinorWaveFunction> fin,
vector<SpinorBarWaveFunction> ain,
vector<VectorWaveFunction> vout,
double & aver) const {
ProductionMatrixElement output(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1);
Complex product;
// sum over helicities to get the matrix element
unsigned int inhel1,inhel2,outhel1;
aver = 0.;
LorentzPolarizationVectorE vec;
- Complex ii(0.,1.);
Energy ecms = sqrt(sHat());
for(inhel1=0;inhel1<2;++inhel1) {
for(inhel2=0;inhel2<2;++inhel2) {
vec = fin[inhel1].dimensionedWave().vectorCurrent(ain[inhel2].dimensionedWave());
vec /= coupling_;
for(outhel1=0;outhel1<3;++outhel1) {
product = vec.dot(vout[outhel1].wave())/ecms;
output(inhel1,inhel2,outhel1)=product;
aver += norm(product);
}
}
}
aver *= 0.25;
return output;
}
void MEee2VectorMeson::constructVertex(tSubProPtr sub) {
// 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]);
if(hard[0]->id()<hard[1]->id()) swap(hard[0],hard[1]);
vector<SpinorWaveFunction> fin;
vector<SpinorBarWaveFunction> ain;
vector<VectorWaveFunction> vout;
SpinorWaveFunction( fin ,hard[0],incoming,false,true);
SpinorBarWaveFunction(ain ,hard[1],incoming,false,true);
VectorWaveFunction(vout ,hard[2],outgoing,true,false,true);
double dummy;
ProductionMatrixElement prodme=HelicityME(fin,ain,vout,dummy);
// construct the vertex
HardVertexPtr hardvertex=new_ptr(HardVertex());
// set the matrix element for the vertex
hardvertex->ME(prodme);
// set the pointers and to and from the vertex
for(unsigned int ix=0;ix<3;++ix) {
(hard[ix]->spinInfo())->productionVertex(hardvertex);
}
}
diff --git a/MatrixElement/Lepton/MEee2gZ2ll.h b/MatrixElement/Lepton/MEee2gZ2ll.h
--- a/MatrixElement/Lepton/MEee2gZ2ll.h
+++ b/MatrixElement/Lepton/MEee2gZ2ll.h
@@ -1,366 +1,363 @@
// -*- C++ -*-
//
// MEee2gZ2ll.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_MEee2gZ2ll_H
#define HERWIG_MEee2gZ2ll_H
//
// This is the declaration of the MEee2gZ2ll class.
//
#include "Herwig/MatrixElement/HwMEBase.h"
#include "Herwig/Models/StandardModel/StandardModel.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "Herwig/MatrixElement/ProductionMatrixElement.h"
#include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
#include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
#include "Herwig/Shower/ShowerAlpha.h"
namespace Herwig {
using namespace ThePEG;
/**
* The MEee2gZ2ll class provides the matrix element for
* \f$e^+e^-\to\ell^+\ell^-\f$. N.B. for the production of \f$e^+e^-\f$
* only the \f$s\f$-channel Z and photon diagrams are included.
*
* @see \ref MEee2gZ2llInterfaces "The interfaces"
* defined for MEee2gZ2ll.
*/
class MEee2gZ2ll: public HwMEBase {
public:
/**
* The default constructor.
*/
MEee2gZ2ll() : allowed_(0), pTmin_(GeV),
preFactor_(6.) {
massOption(vector<unsigned int>(2,1));
}
/**
* Members for hard corrections to the emission of QCD radiation
*/
//@{
/**
* Has a POWHEG style correction
*/
virtual POWHEGType hasPOWHEGCorrection() {return FSR;}
/**
* Has an old fashioned ME correction
*/
virtual bool hasMECorrection() {return false;}
/**
* Apply the POWHEG style correction
*/
virtual RealEmissionProcessPtr generateHardest(RealEmissionProcessPtr,
ShowerInteraction);
//@}
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 the order in \f$\alpha_{EW}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInAlphaEW() const;
/**
* The matrix element for the kinematical configuration
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
* @return the matrix element scaled with sHat() to give a
* dimensionless number.
*/
virtual double me2() const;
/**
* Return the scale associated with the last set phase space point.
*/
virtual Energy2 scale() const;
/**
* Add all possible diagrams with the add() function.
*/
virtual void getDiagrams() const;
/**
* Get diagram selector. With the information previously supplied with the
* setKinematics method, a derived class may optionally
* override this method to weight the given diagrams with their
* (although certainly not physical) relative probabilities.
* @param dv the diagrams to be weighted.
* @return a Selector relating the given diagrams to their weights.
*/
virtual Selector<DiagramIndex> diagrams(const DiagramVector & dv) const;
/**
* Return a Selector with possible colour geometries for the selected
* diagram weighted by their relative probabilities.
* @param diag the diagram chosen.
* @return the possible colour geometries weighted by their
* relative probabilities.
*/
virtual Selector<const ColourLines *>
colourGeometries(tcDiagPtr diag) const;
/**
* Construct the vertex of spin correlations.
*/
virtual void constructVertex(tSubProPtr);
//@}
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const {return new_ptr(*this);}
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const {return new_ptr(*this);}
//@}
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* Initialize this object after the setup phase before saving an
* EventGenerator to disk.
* @throws InitException if object could not be initialized properly.
*/
virtual void doinit();
/**
* Rebind pointer to other Interfaced objects. Called in the setup phase
* after all objects used in an EventGenerator has been cloned so that
* the pointers will refer to the cloned objects afterwards.
* @param trans a TranslationMap relating the original objects to
* their respective clones.
* @throws RebindException if no cloned object was found for a given
* pointer.
*/
virtual void rebind(const TranslationMap & trans)
;
/**
* Return a vector of all pointers to Interfaced objects used in this
* object.
* @return a vector of pointers.
*/
virtual IVector getReferences();
//@}
protected:
/**
* Calculate the matrix element for \f$e^+e^-\to \ell^+ \ell^-\f$.
* @param partons The incoming and outgoing particles
* @param momenta The momenta of the incoming and outgoing particles
*/
double loME(const vector<cPDPtr> & partons,
const vector<Lorentz5Momentum> & momenta,
bool first) const;
/**
* Member to calculate the matrix element
* @param fin Spinors for incoming fermion
* @param ain Spinors for incoming antifermion
* @param fout Spinors for outgoing fermion
* @param aout Spinors for outgong antifermion
* @param me Spin summed Matrix element
* @param cont The continuum piece of the matrix element
* @param BW The Z piece of the matrix element
*/
ProductionMatrixElement HelicityME(vector<SpinorWaveFunction> & fin,
vector<SpinorBarWaveFunction> & ain,
vector<SpinorBarWaveFunction> & fout,
vector<SpinorWaveFunction> & aout,
double & me,
double & cont,
double & BW ) const;
/**
* The ratio of the matrix element for one additional jet over the
* leading order result. In practice
* \[\frac{\hat{s}|\overline{\mathcal{M}}|^2_2|D_{\rm emit}|}{4\pi C_F\alpha_S|\overline{\mathcal{M}}|^2_3\left(|D_{\rm emit}|+|D_{\rm spect}\right)}}\]
* is returned where \f$\|\overline{\mathcal{M}}|^2\f$ is
* the spin and colour summed/averaged matrix element.
* @param partons The incoming and outgoing particles
* @param momenta The momenta of the incoming and outgoing particles
* @param iemitter Whether the quark or antiquark is regardede as the emitter
* @param inter The type of interaction
*/
double meRatio(vector<cPDPtr> partons,
vector<Lorentz5Momentum> momenta,
unsigned int iemittor,
bool subtract=false) const;
/**
* Calculate the matrix element for \f$e^-e^-\to q \bar q g$.
* @param partons The incoming and outgoing particles
* @param momenta The momenta of the incoming and outgoing particles
* @param inter The type of interaction
*/
InvEnergy2 realME(const vector<cPDPtr> & partons,
const vector<Lorentz5Momentum> & momenta) const;
/**
* Generate the momenta for a hard configuration
*/
Energy generateHard(RealEmissionProcessPtr tree,
vector<Lorentz5Momentum> & emission,
unsigned int & iemit, unsigned int & ispect,
bool applyVeto);
protected:
/**
* Pointer to the fermion-antifermion Z vertex
*/
AbstractFFVVertexPtr FFZVertex() const {return FFZVertex_;}
/**
* Pointer to the fermion-antifermion photon vertex
*/
AbstractFFVVertexPtr FFPVertex() const {return FFPVertex_;}
/**
* Pointer to the particle data object for the Z
*/
PDPtr Z0() const {return Z0_;}
/**
* Pointer to the particle data object for the photon
*/
PDPtr gamma() const {return gamma_;}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MEee2gZ2ll & operator=(const MEee2gZ2ll &) = delete;
private:
/**
* Pointers to the vertices
*/
//@{
/**
* Pointer to the fermion-antifermion Z vertex
*/
AbstractFFVVertexPtr FFZVertex_;
/**
* Pointer to the fermion-antifermion photon vertex
*/
AbstractFFVVertexPtr FFPVertex_;
//@}
/**
* Pointer to the particle data object for the Z
*/
PDPtr Z0_;
/**
* Pointer to the particle data object for the photon
*/
PDPtr gamma_;
/**
* The allowed outgoing
*/
int allowed_;
- /**
- * The initial kappa-tilde values for radiation from the quark
- */
- double d_kt1_;
+
/**
* Pointer to the EM coupling
*/
ShowerAlphaPtr alphaQED_;
/**
* Variables for the POWHEG style corrections
*/
//@{
/**
* The cut off on pt, assuming massless quarks.
*/
Energy pTmin_;
/**
* Overestimate for the prefactor
*/
double preFactor_;
/**
* ParticleData objects for the partons
*/
vector<cPDPtr> partons_;
/**
* Momenta of the leading-order partons
*/
vector<Lorentz5Momentum> loMomenta_;
//@}
};
}
#endif /* HERWIG_MEee2gZ2ll_H */
diff --git a/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h
--- a/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h
+++ b/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h
@@ -1,183 +1,179 @@
// -*- C++ -*-
//
// FFMassiveInvertedTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FFMassiveInvertedTildeKinematics_H
#define HERWIG_FFMassiveInvertedTildeKinematics_H
//
// This is the declaration of the FFMassiveInvertedTildeKinematics class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer, Stephen Webster
*
* \brief FFMassiveInvertedTildeKinematics inverts the final-final tilde
* kinematics.
*
*/
class FFMassiveInvertedTildeKinematics: public Herwig::InvertedTildeKinematics {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
FFMassiveInvertedTildeKinematics();
/**
* The destructor.
*/
virtual ~FFMassiveInvertedTildeKinematics();
//@}
public:
/**
* Perform the mapping of the tilde kinematics for the
* last selected process and store all dimensionless
* variables in the subtractionParameters() vector.
* Return false, if the calculation of the real
* kinematics was impossible for the selected configuration
* and true on success.
*/
virtual bool doMap(const double *);
/**
* Return the pt associated to the last generated splitting.
*/
virtual Energy lastPt() const;
/**
* Return the momentum fraction associated to the last splitting.
*/
virtual double lastZ() const;
/**
* Return the upper bound on pt
*/
virtual Energy ptMax() const;
/**
* Given a pt, return the boundaries on z
* Note that allowing parton masses these bounds may be too loose
*/
virtual pair<double,double> zBounds(Energy pt, Energy hardPt = ZERO) const;
/**
* For generated pt and z, check if this point is
* kinematically allowed
*/
/*virtual*/ bool ptzAllowed(pair<Energy,double> ptz, vector<double>* values ) const;
/**
* Generate pt and z
*/
virtual pair<Energy,double> generatePtZ(double& jac, const double * r, vector<double>* values) const;
public:
/**
* Triangular / Kallen function
*/
template <class T>
inline T rootOfKallen (T a, T b, T c) const {
return sqrt( a*a + b*b + c*c - 2.*( a*b+a*c+b*c ) ); }
// TODO: remove in both
/**
* stolen from FFMassiveKinematics.h
* Perform a rotation on both momenta such that the first one will
* point along the (positive) z axis. Rotate back to the original
* reference frame by applying rotateUz(returnedVector) to each momentum.
*/
ThreeVector<double> rotateToZ (Lorentz5Momentum& pTarget, Lorentz5Momentum& p1) {
ThreeVector<double> oldAxis = pTarget.vect().unit();
double ct = oldAxis.z(); double st = sqrt( 1.-sqr(ct) ); // cos,sin(theta)
double cp = oldAxis.x()/st; double sp = oldAxis.y()/st; // cos,sin(phi)
pTarget.setZ( pTarget.vect().mag() ); pTarget.setX( 0.*GeV ); pTarget.setY( 0.*GeV );
Lorentz5Momentum p1old = p1;
p1.setX( sp*p1old.x() - cp*p1old.y() );
p1.setY( ct*cp*p1old.x() + ct*sp*p1old.y() - st*p1old.z() );
p1.setZ( st*cp*p1old.x() + st*sp*p1old.y() + ct*p1old.z() );
return oldAxis;
}
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;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FFMassiveInvertedTildeKinematics & operator=(const FFMassiveInvertedTildeKinematics &) = delete;
- /**
- * Option to use the full jacobian, including the z->zprime jacobian.
- **/
- bool theFullJacobian;
};
}
#endif /* HERWIG_FFMassiveInvertedTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Utility/DensityOperator.cc b/MatrixElement/Matchbox/Utility/DensityOperator.cc
--- a/MatrixElement/Matchbox/Utility/DensityOperator.cc
+++ b/MatrixElement/Matchbox/Utility/DensityOperator.cc
@@ -1,479 +1,479 @@
// -*- C++ -*-
//
// DensityOperator.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 The Herwig Collaboration
//
// Herwig is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the DensityOperator class.
//
#include "DensityOperator.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "Herwig/MatrixElement/Matchbox/Utility/MatchboxXCombData.h"
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxMEBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
DensityOperator::DensityOperator() : Nc(3.0), TR(0.5) { }
DensityOperator::~DensityOperator() {}
void DensityOperator::clear() {
theCorrelatorMap.clear();
}
// Prepare density operator if not done before
void DensityOperator::prepare(const cPDVector& mePartonData) {
// Take parton data and create key of type 33bar888 to use as key for basis
vector<PDT::Colour> mePartonDataColoured = theColourBasis->normalOrderMap(mePartonData);
if( theDensityOperatorMap.count( mePartonDataColoured ) == 0 ){
// Get basis dimension
size_t dim = theColourBasis->prepare( mePartonData, false );
// Allocate space for density matrix
theDensityOperatorMap.insert(make_pair(mePartonDataColoured,matrix<Complex> (dim,dim)));
}
}
// Fill the density matrix for the first time
void DensityOperator::fill(const Ptr<MatchboxXComb>::ptr MBXCombPtr,
const cPDVector& partons,
const vector<Lorentz5Momentum>& momenta){
// Map from helicity structure to amplitude vector in the color basis
const map<vector<int>,CVector>& amplitudeMap = MBXCombPtr->lastAmplitudes();
const cPDVector& mePartonData = MBXCombPtr->mePartonData();
// Get the dimension of the basis for the indexChange method
size_t dim = theColourBasis->prepare(mePartonData,false);
// Normal order partons according to ColourBasis
const vector<PDT::Colour> mePartonDataColoured = theColourBasis->normalOrderMap(mePartonData);
// Get the colour basis to colour basis map for this hard subprocess
map<cPDVector,map<size_t,size_t> >::iterator cb2cbit = theColourBasisToColourBasisMap.find(mePartonData);
// Fill the map with this hard subprocess if it doesn't have it yet
if ( cb2cbit == theColourBasisToColourBasisMap.end() ) {
// Get the index map for the partons as they are ordered in the MatchboxXComb
// object
const map<size_t,size_t>& mbIndexMap = theColourBasis->indexMap().at(mePartonData);
// Get the index map for the partons as they are ordered
// in the shower.
// Use prepare, as it might not have been done for this order of the partons
theColourBasis->prepare(partons,false);
const map<size_t,size_t>& showerIndexMap = theColourBasis->indexMap().at(partons);
// ensure the maps are of the same size
assert( mbIndexMap.size() == showerIndexMap.size() );
// Loop over both sets of partons to determine how the order between them
// differs, then translate the index to the colour basis and put the
// key-value pair into the map
map<size_t,size_t> cb2cbMap;
// Get the momenta for comparison
const vector<Lorentz5Momentum>& meMomenta = MBXCombPtr->matchboxME()->lastMEMomenta();
// Make sure there's the same number of momenta in both vectors
assert( momenta.size() == meMomenta.size() );
bool done;
// Boost the momenta to the same frame
const vector<Lorentz5Momentum> momentaCM = boostToRestFrame(momenta);
for ( size_t i = 0; i < momentaCM.size(); i++ ) {
// The cb2cb map is intended to translate how the indices
// are different in the colour basis due to the different
// orderings of the partons, so it should only bother
// with coloured particles.
if ( partons[i]->coloured() ) {
done = false;
for ( size_t j = 0; j < meMomenta.size(); j++ ) {
if ( !done ) {
if ( compareMomentum(momentaCM[i],meMomenta[j]) ) {
cb2cbMap[mbIndexMap.at(i)] = showerIndexMap.at(j);
done = true;
}
}
}
}
}
// Make sure all momenta have been identified
assert( cb2cbMap.size() == mePartonDataColoured.size() );
// Add the map to the cache
theColourBasisToColourBasisMap[mePartonData] = cb2cbMap;
// Get the iterator
cb2cbit = theColourBasisToColourBasisMap.find(mePartonData);
}
// With the cb2cb index map we can create the basis vector index map
const map<size_t,size_t> vectorMap = theColourBasis->indexChange(mePartonDataColoured,
dim,cb2cbit->second);
// Prepare density operator (allocate) for set of particles
prepare(mePartonData);
// Check that density operator (place holder for) exist in density operator map
map<vector<PDT::Colour>,matrix<Complex> >::iterator dOit = theDensityOperatorMap.find(mePartonDataColoured);
assert(dOit != theDensityOperatorMap.end());
// Initialize the density operator
matrix<Complex>& densOp = dOit->second;
for(unsigned int i = 0; i < (amplitudeMap.begin()->second).size(); i++){
for(unsigned int j = 0; j < (amplitudeMap.begin()->second).size(); j++){
densOp (i,j) = 0;
}
}
// Fill the density operator, ok to sum over helicities since the density operator
// exist at the probability level
CVector amplitude;
for ( map<vector<int>,CVector>::const_iterator itHel = amplitudeMap.begin();
itHel != amplitudeMap.end(); itHel++ ) {
amplitude = itHel->second;
for ( unsigned int i = 0; i < amplitude.size(); i++ ) {
for ( unsigned int j = 0; j < amplitude.size(); j++ ) {
// vectorMap is used such that densOp is filled according to the
// basis order defined by the input cPDVector partons.
densOp (vectorMap.at(i),vectorMap.at(j)) += amplitude(i)*std::conj(amplitude(j));
}
}
}
// Colour conservation check
colourConservation(mePartonData);
}
// Update density matrix after emitting or splitting a gluon
// The emissionsMap argument contains the relation of the indices in the smaller (before)
// and larger basis (after). the first 3-tuple contains the indices
// (emitter before, emitter after, emitted parton)
// The map contains the old and new indices of all other partons (not involved)
void DensityOperator::evolve(const map<pair<size_t,size_t>,Complex>& Vijk,
const cPDVector& before,
const cPDVector& after,
const map<std::tuple<size_t,size_t,size_t>,map<size_t,size_t> >& emissionsMap,
const bool splitAGluon,
const bool initialGluonSplitting) {
size_t dimBefore = theColourBasis->prepare( before, false );
size_t dimAfter = theColourBasis->prepare( after, false );
vector<PDT::Colour> beforeColoured = theColourBasis->normalOrderMap(before);
vector<PDT::Colour> afterColoured = theColourBasis->normalOrderMap(after);
const map<vector<PDT::Colour>,matrix<Complex> >::iterator dOit = theDensityOperatorMap.find(beforeColoured);
assert(dOit != theDensityOperatorMap.end());
const matrix<Complex>& densOpBefore = dOit->second;
prepare(after);
matrix<Complex>& densOpAfter = theDensityOperatorMap[afterColoured];
for(size_t i = 0; i < densOpAfter.size1(); i++){
for(size_t j = 0; j < densOpAfter.size2(); j++){
densOpAfter(i,j) = 0;
}
}
compressed_matrix<double> Tij;
matrix<Complex> TijMn (dimAfter,dimBefore);
compressed_matrix<double> Tk;
matrix<Complex> TijMnTkdagger (dimAfter,dimAfter);
Complex V;
// Compensate for sign from updated density matrix
// TODO Check signs again
double sign = -1.0;
if ( splitAGluon )
sign = 1.0;
// Loop over emitter legs ij and recoil legs k and add the contribution,
// for Vijk is assumed to contain the factor 4*pi*\alpha_s/pi.pj
typedef map<std::tuple<size_t,size_t,size_t>,map<size_t,size_t> > dictMap;
int ij,k;
// Loop over emitters
for(dictMap::const_iterator ijit = emissionsMap.begin();
ijit != emissionsMap.end(); ijit++) {
// get first element in 3-tuple, i.e., emitter before
ij = std::get<0>(ijit->first);
assert(before[ij]->coloured());
// Get rectangular matrices T_{ij} or S_{ij} taking us from the
// smaller to the larger basis depending on
// the involved particles before and after, the emitter index before ij,
// the emitter after and the emitted parton index
int i=std::get<1>(ijit->first); // emitter after
int j=std::get<2>(ijit->first);// emitted parton
Tij = theColourBasis->charge(before,after,
ij,i,j,ijit->second).first;
TijMn = prodSparseDense(Tij,densOpBefore);
// Loop over spectators
for(dictMap::const_iterator kit = emissionsMap.begin();
kit != emissionsMap.end(); kit++) {
k = std::get<0>(kit->first);
assert(before[k]->coloured());
// Standard case of gluon radiation
if ( ijit != kit || splitAGluon || initialGluonSplitting ) {
int k_after=std::get<1>(kit->first); // For color structure k now has role of emitter
int k_emission= std::get<2>(kit->first); // Emitted parton index
Tk = theColourBasis->charge(before,after,
k, k_after, k_emission, kit->second).first;
TijMnTkdagger = prodDenseSparse(TijMn,Tk);
// sign == -1.0 if it isn't a gluon splitting into a qqbar pair
V = sign*(1.0/colourNorm(before[ij]))*
Vijk.at(make_pair(ij,k));
densOpAfter += V*TijMnTkdagger;
}
}
}
// Check that the density operator does not vanish
assert( theColourBasis->me2(after,densOpAfter) != 0.0 );
colourConservation(after);
}
// The 3-tuple contains (emitter index, spectator index, emission pid)
double DensityOperator::colourMatrixElementCorrection(const std::tuple<size_t,size_t,long>& ikemission,
const cPDVector& particles) {
const int i = std::get<0>(ikemission);
const int k = std::get<1>(ikemission);
- const long emissionID = std::get<2>(ikemission);
+ //const long emissionID = std::get<2>(ikemission);
// Get the density operator
// normal order particles as in ColourBasis
vector<PDT::Colour> particlesColoured = theColourBasis->normalOrderMap(particles);
// ... and find corresponding density operator
const map<vector<PDT::Colour>,matrix<Complex> >::iterator particlesit = theDensityOperatorMap.find(particlesColoured);
assert(particlesit != theDensityOperatorMap.end());
const matrix<Complex>& densOp = particlesit->second;
double Ti2 = colourNorm(particles[i]);
// Emitter-spectator pair
const pair<size_t,size_t> ik = make_pair(i,k);
// Create key for color matrix element correction map
pair<vector<PDT::Colour>,pair<size_t,size_t> > particlesAndLegs = make_pair(particlesColoured,ik);
// Result
double res = 0;
// Check if it has already been calculated
// TODO: move this check earlier (we only need particlesColoured to check if it has been
// calculated).
// Check for color matrix element associated with key, and calculate if not done
const map<pair<vector<PDT::Colour>,pair<size_t,size_t> >,double >::const_iterator corrit = theCorrelatorMap.find(particlesAndLegs);
if ( corrit == theCorrelatorMap.end() ) {
double corrME2 = theColourBasis->colourCorrelatedME2(ik,particles,densOp);
double me2 = theColourBasis->me2(particles,densOp);
res = -(1/Ti2)*corrME2/me2;
if ( particles[i]->id() == ParticleID::g )
res *= 2.;
theCorrelatorMap.insert(make_pair(particlesAndLegs,res));
} else {
res = corrit->second;
}
return res;
}
double DensityOperator::colourNorm(const cPDPtr particle) {
if ( particle->id() == ParticleID::g ) {
return Nc; //is 3.0 for Nc = 3, TR = 1/2
} else if ( particle->iColour() == PDT::Colour3 || particle->iColour() == PDT::Colour3bar ) {
return TR*(Nc*Nc-1.)/Nc; // is 4.0/3.0 for Nc = 3, TR = 1/2
} else {
throw Exception() << "Colour matrix element corrections only work "
<< "on quark and gluon legs. "
<< Exception::runerror;
}
}
void DensityOperator::colourConservation(const cPDVector& particles) {
// To contain (emitter, spectator, emission pid)
std::tuple<size_t,size_t,long> ikemission;
// Normal order particles as defined in ColourBasis
const vector<PDT::Colour> particlesColoured = theColourBasis->normalOrderMap(particles);
vector<double> sum(particlesColoured.size(),0.0);
size_t iterm = 0;
// To compensate for the CMEC having a 1/(1+\delta(i is gluon)) factor
// in the splitting kernel
double gluonFactor = 1.0;
// Loop over "emitters" to check color conservation for
for ( size_t i = 0; i < particles.size(); i++ ) {
if ( particles[i]->coloured() ) {
for ( size_t k = 0; k < particles.size(); k++ ) {
if ( particles[k]->coloured() && i != k ) {
ikemission = std::make_tuple(i,k,ParticleID::g);
if ( particles[i]->id() != ParticleID::g ) {
gluonFactor = 1.0;
} else {
gluonFactor = 1./2.;
}
sum[iterm] += gluonFactor*colourMatrixElementCorrection(ikemission,particles);
}
}
iterm++;
}
}
for ( size_t i = 0; i < sum.size(); i++ )
assert( std::abs(sum[i]-1.0) < pow(10.0,-10.0));
}
matrix<Complex> DensityOperator::prodSparseDense(const compressed_matrix<double>& Tij,
const matrix<Complex>& Mn){
// Dimension before emission
size_t dimBefore = Tij.size2();
// Dimension after emission
size_t dimAfter = Tij.size1();
//Check matrix dimensions
assert( dimBefore == Mn.size1() );
// Allocate memory for the matrix
matrix<Complex> TijMn (dimAfter,dimBefore,0);
// Use iterators for the compressed matrix to iterate only over the non-zero
// elements.
size_t ii;
size_t jj;
for ( compressed_matrix<double>::const_iterator1 it1 = Tij.begin1();
it1 != Tij.end1(); it1++ ) {
for ( compressed_matrix<double>::const_iterator2 it2 = it1.begin();
it2 != it1.end(); it2++ ) {
ii = it2.index1();
jj = it2.index2();
for ( size_t kk = 0; kk < dimBefore; kk++ ) {
// *it2 is Tij(ii,jj)
TijMn(ii,kk) += (*it2)*Mn(jj,kk);
}
}
}
return TijMn;
}
matrix<Complex> DensityOperator::prodDenseSparse(const matrix<Complex>& TijMn,
const compressed_matrix<double>& Tk){
// The compressed matrix comes from the charge method, do not transpose yet
// Dimension after emission
size_t dimAfter = Tk.size1();//Since this method returns TijMn*Tk^\dagger
//Check matrix dimensions
assert( TijMn.size2() == Tk.size2() );
// Allocate memory for the matrix
matrix<Complex> TijMnTkdagger (dimAfter,dimAfter,0);
size_t jj;
size_t kk;
for ( compressed_matrix<double>::const_iterator1 it1 = Tk.begin1();
it1 != Tk.end1(); it1++ ) {
for ( compressed_matrix<double>::const_iterator2 it2 = it1.begin();
it2 != it1.end(); it2++ ) {
jj = it2.index2();//transposing Tk jj is index2(), not index1()
kk = it2.index1();//transposing Tk
for ( size_t ii = 0; ii < dimAfter; ii++ ) {
// *it2 is Tk(kk,jj) = trans(Tk)(jj,kk)
TijMnTkdagger(ii,kk) += TijMn(ii,jj)*(*it2);
}
}
}
return TijMnTkdagger;
}
vector<Lorentz5Momentum> DensityOperator::boostToRestFrame(const vector<Lorentz5Momentum>& momenta) {
// We need 2 initial particles
assert(momenta.size() >= 2);
// The boosted vectors
vector<Lorentz5Momentum> vboosted = momenta;
// The boost should be to the rest frame of the initial particles
Boost b = (momenta[0] + momenta[1]).findBoostToCM();
// Boost all of the vectors
for ( size_t i = 0; i < momenta.size(); i++ ) {
vboosted[i].boost(b);
}
return vboosted;
}
bool DensityOperator::compareMomentum(const Lorentz5Momentum& p, const Lorentz5Momentum& q) {
bool equal = true;
// Compares two momentum vectors p and q, if they are close enough (defined by the
// double eps below) it returns true. This is sufficient to distinguish particles
// in the matrix element as we are not interested in the matrix element for extremely
// collinear radiation (better described by the parton shower).
// Create the difference of the two vectors
const Lorentz5Momentum l = p - q;
// A relevant size that is guaranteed to be larger than 0
const Energy2 e2 = p.t()*p.t();
// Size of the difference that would be considered equal
const double eps = pow(10.,-15.);
if ( l.x()*l.x()/e2 > eps )
equal = false;
if ( l.y()*l.y()/e2 > eps )
equal = false;
if ( l.z()*l.z()/e2 > eps )
equal = false;
if ( l.t()*l.t()/e2 > eps )
equal = false;
return equal;
}
IBPtr DensityOperator::clone() const {
return new_ptr(*this);
}
IBPtr DensityOperator::fullclone() const {
return new_ptr(*this);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void DensityOperator::persistentOutput(PersistentOStream &) const {
// *** ATTENTION *** os << ; // Add all member variable which should be written persistently here.
}
void DensityOperator::persistentInput(PersistentIStream &, int) {
// *** ATTENTION *** is >> ; // Add all member variable which should be read persistently here.
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<DensityOperator,HandlerBase>
describeHerwigDensityOperator("Herwig::DensityOperator", "DensityOperator.so");
void DensityOperator::Init() {
static ClassDocumentation<DensityOperator> documentation
("There is no documentation for the DensityOperator class");
}
diff --git a/MatrixElement/Matchbox/Utility/Tree2toNGenerator.cc b/MatrixElement/Matchbox/Utility/Tree2toNGenerator.cc
--- a/MatrixElement/Matchbox/Utility/Tree2toNGenerator.cc
+++ b/MatrixElement/Matchbox/Utility/Tree2toNGenerator.cc
@@ -1,490 +1,490 @@
// -*- C++ -*-
//
// Tree2toNGenerator.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the Tree2toNGenerator class.
//
#include "Tree2toNGenerator.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Utilities/StringUtils.h"
using namespace Herwig;
Tree2toNGenerator::Tree2toNGenerator()
: maxOrderGs(0), maxOrderGem(0), prepared(false) {}
Tree2toNGenerator::~Tree2toNGenerator() {}
IBPtr Tree2toNGenerator::clone() const {
return new_ptr(*this);
}
IBPtr Tree2toNGenerator::fullclone() const {
return new_ptr(*this);
}
vector<Ptr<Tree2toNDiagram>::ptr> Tree2toNGenerator::
generate(const PDVector& legs,
unsigned int orderInGs,
unsigned int orderInGem) {
vector<Ptr<Tree2toNDiagram>::ptr> res;
list<vector<Vertex> > prog = clusterAll(legs,orderInGs,orderInGem);
int count = 1;
for ( auto & d : prog ) {
assert(d.size() == 1);
Tree2toNDiagram diag = d.front().generate(count);
if ( !spaceLikeAllowed.empty() ) {
map<tcPDPtr,int> counts;
for ( int k = 1; k < diag.nSpace()-1; ++k )
counts[diag.allPartons()[k]] += 1;
for ( auto & m : spaceLikeAllowed ) {
m.reset();
for ( auto const & c : counts )
m.add(c.first,c.second);
}
bool failed = false;
for ( auto const & m : spaceLikeAllowed) {
if ( !m.check() ) {
failed = true;
break;
}
}
if ( failed )
continue;
}
if ( !timeLikeAllowed.empty() ) {
map<tcPDPtr,int> counts;
int all = diag.allPartons().size();
for ( int k = diag.nSpace(); k < all; ++k ) {
if ( diag.children(k).first < 0 )
continue;
counts[diag.allPartons()[k]] += 1;
}
for ( auto & m : timeLikeAllowed ) {
m.reset();
for ( auto const & c : counts )
m.add(c.first,c.second);
}
bool failed = false;
for ( auto const & m : timeLikeAllowed ) {
if ( !m.check() ) {
failed = true;
break;
}
}
if ( failed )
continue;
}
bool internalVeto = false;
set<int> external;
int nex = diag.partons().size();
for ( int i = 0; i < nex; ++i ) {
external.insert(diag.diagramId(i));
}
int n = diag.allPartons().size();
for ( int i = 0; i < n; ++i ) {
if ( external.find(i) != external.end() )
continue;
if ( find(excludeInternal().begin(), excludeInternal().end(), diag.allPartons()[i])
!= excludeInternal().end() ) {
internalVeto = true;
break;
}
}
if ( internalVeto )
continue;
bool gotit = false;
for ( auto const & d : res) {
map<int,int> checkPermutation;
if ( diag.isSame(d,checkPermutation) ) {
gotit = true;
for ( auto const & p : checkPermutation )
if ( p.first != p.second )
gotit = false;
if ( gotit )
break;
}
}
if ( !gotit ) {
res.push_back(new_ptr(diag));
++count;
}
}
return res;
}
list<vector<Tree2toNGenerator::Vertex> > Tree2toNGenerator::
cluster(const vector<Tree2toNGenerator::Vertex>& children,
unsigned int orderInGs,
unsigned int orderInGem) const {
list<vector<Vertex> > res;
bool externalCluster = children[1].externalId != -1;
if ( children.size() == 3 ) {
for ( auto const & v : theVertices ) {
if ( v->getNpoint() != 3 )
continue;
if ( find(theExcludeVertices.begin(), theExcludeVertices.end(), v) !=
theExcludeVertices.end() )
continue;
bool noMatch =
- v->orderInGs() != orderInGs ||
- v->orderInGem() != orderInGem ||
+ v->orderInGs() != int(orderInGs) ||
+ v->orderInGem() != int(orderInGem) ||
!v->isIncoming(children[0].parent);
long idij = children[0].parent->id();
long idi = children[2].parent->id();
long idj = children[1].parent->id();
if ( externalCluster && children[1].parent->CC() )
idj = -idj;
if ( children[0].parent->CC() )
idij = -idij;
if ( !externalCluster )
noMatch |=
!v->isOutgoing(children[1].parent) ||
!v->isOutgoing(children[2].parent);
else
noMatch |=
!v->isIncoming(children[1].parent) ||
!v->isOutgoing(children[2].parent);
noMatch |=
!( v->allowed(idij,idi,idj) ||
v->allowed(idj,idij,idi) ||
v->allowed(idi,idj,idij) ||
v->allowed(idij,idj,idi) ||
v->allowed(idi,idij,idj) ||
v->allowed(idj,idi,idij) );
if ( noMatch )
continue;
Vertex last;
last.spacelike = true;
last.parent = children[0].parent;
last.externalId = 0;
last.children.push_back(children[1]);
last.children.push_back(children[2]);
res.push_back(vector<Vertex>(1,last));
// only one possible
break;
}
return res;
}
// spacelike clusterings (cluster on second one)
for ( size_t i = 2; i < children.size(); ++i ) {
for ( auto const & v : theVertices ) {
if ( v->getNpoint() != 3 )
continue;
if ( find(theExcludeVertices.begin(), theExcludeVertices.end(), v) !=
theExcludeVertices.end() )
continue;
bool noMatch = false;
noMatch |=
- v->orderInGs() != orderInGs ||
- v->orderInGem() != orderInGem;
+ v->orderInGs() != int(orderInGs) ||
+ v->orderInGem() != int(orderInGem);
if ( !externalCluster )
noMatch |=
!v->isOutgoing(children[1].parent) ||
!v->isOutgoing(children[i].parent);
else
noMatch |=
!v->isIncoming(children[1].parent) ||
!v->isOutgoing(children[i].parent);
if ( noMatch )
continue;
long idi = children[i].parent->id();
long idj = children[1].parent->id();
if ( externalCluster && children[1].parent->CC() )
idj = -idj;
for ( set<tPDPtr>::const_iterator pij =
v->outgoing().begin(); pij != v->outgoing().end() ; ++pij ) {
long idij = (**pij).id();
if ( v->allowed(idij,idi,idj) ||
v->allowed(idj,idij,idi) ||
v->allowed(idi,idj,idij) ||
v->allowed(idij,idj,idi) ||
v->allowed(idi,idij,idj) ||
v->allowed(idj,idi,idij) ) {
PDPtr dij = (**pij).CC() ? (**pij).CC() : *pij;
vector<Vertex> cled;
for ( size_t k = 0; k < children.size(); ++k ) {
if ( k != 1 && k != i )
cled.push_back(children[k]);
if ( k == 1 ) {
Vertex merge;
merge.children.push_back(children[1]);
merge.children.push_back(children[i]);
merge.parent = dij;
merge.spacelike = true;
cled.push_back(merge);
}
if ( k == i )
continue;
}
res.push_back(cled);
}
}
}
}
// timelike clusterings
for ( size_t i = 2; i < children.size(); ++i ) {
for ( size_t j = i+1; j < children.size(); ++j ) {
for ( auto const & v : theVertices ) {
if ( v->getNpoint() != 3 )
continue;
if ( find(theExcludeVertices.begin(), theExcludeVertices.end(), v) !=
theExcludeVertices.end() )
continue;
- if ( v->orderInGs() != orderInGs ||
- v->orderInGem() != orderInGem ||
+ if ( v->orderInGs() != int(orderInGs) ||
+ v->orderInGem() != int(orderInGem) ||
!v->isOutgoing(children[i].parent) ||
!v->isOutgoing(children[j].parent) )
continue;
long idi = children[i].parent->id();
long idj = children[j].parent->id();
for ( set<tPDPtr>::const_iterator pij =
v->outgoing().begin(); pij != v->outgoing().end() ; ++pij ) {
long idij = (**pij).id();
if ( v->allowed(idij,idi,idj) ||
v->allowed(idj,idij,idi) ||
v->allowed(idi,idj,idij) ||
v->allowed(idij,idj,idi) ||
v->allowed(idi,idij,idj) ||
v->allowed(idj,idi,idij) ) {
PDPtr dij = (**pij).CC() ? (**pij).CC() : *pij;
vector<Vertex> cled;
for ( size_t k = 0; k < children.size(); ++k ) {
if ( k != i && k != j )
cled.push_back(children[k]);
if ( k == i ) {
Vertex merge;
merge.children.push_back(children[i]);
merge.children.push_back(children[j]);
merge.parent = dij;
merge.spacelike = false;
cled.push_back(merge);
}
if ( k == j )
continue;
}
res.push_back(cled);
}
}
}
}
}
return res;
}
list<vector<Tree2toNGenerator::Vertex> > Tree2toNGenerator::
clusterAll(const list<vector<Tree2toNGenerator::Vertex> >& current,
unsigned int orderInGs,
unsigned int orderInGem) const {
list<vector<Vertex> > res;
for ( list<vector<Vertex> >::const_iterator c = current.begin();
c != current.end(); ++c ) {
if ( c->size() == 1 ) {
if ( orderInGs == 0 && orderInGem == 0 )
res.push_back(*c);
continue;
}
for ( unsigned int gs = 0; gs <= maxOrderGs; ++gs )
for ( unsigned int gem = 0; gem <= maxOrderGem; ++gem ) {
if ( gs == 0 && gem == 0 )
continue;
if ( gs > orderInGs || gem > orderInGem )
continue;
list<vector<Vertex> > next = cluster(*c,gs,gem);
if ( next.empty() )
continue;
list<vector<Vertex> > cled = clusterAll(next,orderInGs-gs,orderInGem-gem);
copy(cled.begin(),cled.end(),back_inserter(res));
}
}
return res;
}
list<vector<Tree2toNGenerator::Vertex> > Tree2toNGenerator::
clusterAll(const PDVector& external,
unsigned int orderInGs,
unsigned int orderInGem) {
if ( !prepared ) {
for ( auto & v : theVertices ) {
if ( find(theExcludeVertices.begin(), theExcludeVertices.end(), v) !=
theExcludeVertices.end() )
continue;
v->init();
maxOrderGs = max(maxOrderGs,v->orderInGs());
maxOrderGem = max(maxOrderGem,v->orderInGem());
}
for ( auto & m : spaceLikeAllowed)
m.rebind(this);
for ( auto & m : timeLikeAllowed )
m.rebind(this);
prepared = true;
}
vector<Vertex> legs;
for ( unsigned int k = 0; k < external.size(); ++k ) {
Vertex v;
v.parent = external[k];
v.externalId = k;
v.spacelike = k < 2;
legs.push_back(v);
}
list<vector<Vertex> > firstlegs;
firstlegs.push_back(legs);
return clusterAll(firstlegs,orderInGs,orderInGem);
}
string Tree2toNGenerator::doSpaceLikeRange(string range) {
if ( theRestrictLines.empty() )
return "No particle data specified to restrict internal lines.";
vector<string> bounds = StringUtils::split(range);
if ( bounds.empty() || bounds.size() > 2 )
return "Need to specify a minimum, or a minimum and maximum number of internal lines.";
pair<int,int> irange(0,-1);
istringstream in1(bounds[0]);
in1 >> irange.first;
if ( bounds.size() == 2 ) {
istringstream in2(bounds[1]);
in2 >> irange.second;
} else {
irange.second = irange.first;
}
if ( irange.second >= 0 && irange.first > irange.second )
return "invalid range specified";
spaceLikeAllowed.push_back(LineMatcher(theRestrictLines,irange));
return "";
}
string Tree2toNGenerator::doTimeLikeRange(string range) {
if ( theRestrictLines.empty() )
return "No particle data specified to restrict internal lines.";
vector<string> bounds = StringUtils::split(range);
if ( bounds.empty() || bounds.size() > 2 )
return "Need to specify a minimum, or a minimum and maximum number of internal lines.";
pair<int,int> irange(0,-1);
istringstream in1(bounds[0]);
in1 >> irange.first;
if ( bounds.size() == 2 ) {
istringstream in2(bounds[1]);
in2 >> irange.second;
} else {
irange.second = irange.first;
}
if ( irange.second >= 0 && irange.first > irange.second )
return "invalid range specified";
timeLikeAllowed.push_back(LineMatcher(theRestrictLines,irange));
return "";
}
string Tree2toNGenerator::doClearRestrictLines(string) {
theRestrictLines.clear();
return "";
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void Tree2toNGenerator::persistentOutput(PersistentOStream & os) const {
os << theVertices << theExcludeInternal << maxOrderGs << maxOrderGem << prepared
<< theExcludeVertices << spaceLikeAllowed << timeLikeAllowed;
}
void Tree2toNGenerator::persistentInput(PersistentIStream & is, int) {
is >> theVertices >> theExcludeInternal >> maxOrderGs >> maxOrderGem >> prepared
>> theExcludeVertices >> spaceLikeAllowed >> timeLikeAllowed;
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<Tree2toNGenerator,HandlerBase>
describeHerwigTree2toNGenerator("Herwig::Tree2toNGenerator", "Herwig.so");
void Tree2toNGenerator::Init() {
static ClassDocumentation<Tree2toNGenerator> documentation
("Generate Tree2toNDiagrams for a given process.");
static RefVector<Tree2toNGenerator,Helicity::VertexBase> interfaceVertices
("Vertices",
"All vertices to consider.",
&Tree2toNGenerator::theVertices, -1, false, false, true, false, false);
static RefVector<Tree2toNGenerator,Helicity::VertexBase> interfaceExcludeVertices
("ExcludeVertices",
"The vertices to exclude.",
&Tree2toNGenerator::theExcludeVertices, -1, false, false, true, false, false);
static RefVector<Tree2toNGenerator,ParticleData> interfaceExcludeInternal
("ExcludeInternal",
"Particles to be exluded from becoming internal lines.",
&Tree2toNGenerator::theExcludeInternal, -1, false, false, true, false, false);
static RefVector<Tree2toNGenerator,ParticleData> interfaceRestrictLines
("RestrictLines",
"Particles to be exluded from becoming internal lines.",
&Tree2toNGenerator::theRestrictLines, -1, false, false, true, false, false);
static Command<Tree2toNGenerator> interfaceSpaceLikeRange
("SpaceLikeRange",
"Limit the number of spacelike occurences of the specified particle.",
&Tree2toNGenerator::doSpaceLikeRange, false);
static Command<Tree2toNGenerator> interfaceTimeLikeRange
("TimeLikeRange",
"Limit the number of timelike occurences of the specified particle.",
&Tree2toNGenerator::doTimeLikeRange, false);
static Command<Tree2toNGenerator> interfaceClearRestrictLines
("ClearRestrictLines",
"Clear the container of lines to be considered for restrictions.",
&Tree2toNGenerator::doClearRestrictLines, false);
}
diff --git a/MatrixElement/Powheg/MEPP2WHPowheg.cc b/MatrixElement/Powheg/MEPP2WHPowheg.cc
--- a/MatrixElement/Powheg/MEPP2WHPowheg.cc
+++ b/MatrixElement/Powheg/MEPP2WHPowheg.cc
@@ -1,392 +1,392 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MEPP2WHPowheg class.
//
#include "MEPP2WHPowheg.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/PDT/DecayMode.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Handlers/StandardXComb.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/Repository/EventGenerator.h"
using namespace Herwig;
MEPP2WHPowheg::MEPP2WHPowheg()
: _gluon(), TR_(0.5), CF_(4./3.),
_contrib(1) ,_nlo_alphaS_opt(0), _fixed_alphaS(0.115895),
- _a(0.5) ,_p(0.7) , _eps(1.0e-8), _scaleopt(1),
+ _a(0.5) ,_p(0.7) , _scaleopt(1),
_fixedScale(100.*GeV), _scaleFact(1.)
{}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<MEPP2WHPowheg,MEPP2WH>
describeHerwigMEPP2WHPowheg("Herwig::MEPP2WHPowheg", "HwMEHadron.so HwPowhegMEHadron.so");
void MEPP2WHPowheg::persistentOutput(PersistentOStream & os) const {
os << _contrib << _nlo_alphaS_opt << _fixed_alphaS
<< _a << _p << _gluon
<< _scaleopt
<< ounit(_fixedScale,GeV) << _scaleFact;
}
void MEPP2WHPowheg::persistentInput(PersistentIStream & is, int) {
is >> _contrib >> _nlo_alphaS_opt >> _fixed_alphaS
>> _a >> _p >> _gluon
>> _scaleopt
>> iunit(_fixedScale,GeV) >> _scaleFact;
}
void MEPP2WHPowheg::Init() {
static ClassDocumentation<MEPP2WHPowheg> documentation
("The MEPP2WHPowheg class implements the matrix element for the Bjorken"
" process q qbar -> WH",
"The PP$\\to$W Higgs POWHEG matrix element is described in \\cite{Hamilton:2009za}.",
"%\\cite{Hamilton:2009za}\n"
"\\bibitem{Hamilton:2009za}\n"
" K.~Hamilton, P.~Richardson and J.~Tully,\n"
" ``A Positive-Weight Next-to-Leading Order Monte Carlo Simulation for Higgs\n"
" Boson Production,''\n"
" JHEP {\\bf 0904} (2009) 116\n"
" [arXiv:0903.4345 [hep-ph]].\n"
" %%CITATION = JHEPA,0904,116;%%\n"
);
static Switch<MEPP2WHPowheg,unsigned int> interfaceContribution
("Contribution",
"Which contributions to the cross section to include",
&MEPP2WHPowheg::_contrib, 1, false, false);
static SwitchOption interfaceContributionLeadingOrder
(interfaceContribution,
"LeadingOrder",
"Just generate the leading order cross section",
0);
static SwitchOption interfaceContributionPositiveNLO
(interfaceContribution,
"PositiveNLO",
"Generate the positive contribution to the full NLO cross section",
1);
static SwitchOption interfaceContributionNegativeNLO
(interfaceContribution,
"NegativeNLO",
"Generate the negative contribution to the full NLO cross section",
2);
static Switch<MEPP2WHPowheg,unsigned int> interfaceNLOalphaSopt
("NLOalphaSopt",
"Whether to use a fixed or a running QCD coupling for the NLO weight",
&MEPP2WHPowheg::_nlo_alphaS_opt, 0, false, false);
static SwitchOption interfaceNLOalphaSoptRunningAlphaS
(interfaceNLOalphaSopt,
"RunningAlphaS",
"Use the usual running QCD coupling evaluated at scale scale()",
0);
static SwitchOption interfaceNLOalphaSoptFixedAlphaS
(interfaceNLOalphaSopt,
"FixedAlphaS",
"Use a constant QCD coupling for comparison/debugging purposes",
1);
static Parameter<MEPP2WHPowheg,double> interfaceFixedNLOalphaS
("FixedNLOalphaS",
"The value of alphaS to use for the nlo weight if _nlo_alphaS_opt=1",
&MEPP2WHPowheg::_fixed_alphaS, 0.115895, 0., 1.0,
false, false, Interface::limited);
static Parameter<MEPP2WHPowheg,double> interfaceCorrectionCoefficient
("CorrectionCoefficient",
"The magnitude of the correction term to reduce the negative contribution",
&MEPP2WHPowheg::_a, 0.5, -10., 10.0,
false, false, Interface::limited);
static Parameter<MEPP2WHPowheg,double> interfaceCorrectionPower
("CorrectionPower",
"The power of the correction term to reduce the negative contribution",
&MEPP2WHPowheg::_p, 0.7, 0.0, 1.0,
false, false, Interface::limited);
static Switch<MEPP2WHPowheg,unsigned int> interfaceFactorizationScaleOption
("FactorizationScaleOption",
"Option for the scale to be used",
&MEPP2WHPowheg::_scaleopt, 1, false, false);
static SwitchOption interfaceScaleOptionFixed
(interfaceFactorizationScaleOption,
"Fixed",
"Use a fixed scale",
0);
static SwitchOption interfaceScaleOptionsHat
(interfaceFactorizationScaleOption,
"Dynamic",
"Use the mass of the vector boson-Higgs boson system",
1);
static Parameter<MEPP2WHPowheg,Energy> interfaceFactorizationScaleValue
("FactorizationScaleValue",
"The fixed scale to use if required",
&MEPP2WHPowheg::_fixedScale, GeV, 100.0*GeV, 10.0*GeV, 1000.0*GeV,
false, false, Interface::limited);
static Parameter<MEPP2WHPowheg,double> interfaceScaleFactor
("ScaleFactor",
"The factor used before sHat if using a running scale",
&MEPP2WHPowheg::_scaleFact, 1.0, 0.0, 10.0,
false, false, Interface::limited);
}
void MEPP2WHPowheg::doinit() {
// gluon ParticleData object
_gluon = getParticleData(ParticleID::g);
MEPP2WH::doinit();
}
Energy2 MEPP2WHPowheg::scale() const {
return _scaleopt == 0 ? sqr(_fixedScale) : _scaleFact*sHat();
}
int MEPP2WHPowheg::nDim() const {
return 7;
}
bool MEPP2WHPowheg::generateKinematics(const double * r) {
_xt=*(r+5);
_v =*(r+6);
return MEPP2WH::generateKinematics(r);
}
CrossSection MEPP2WHPowheg::dSigHatDR() const {
// Get Born momentum fractions xbar_a and xbar_b:
_xb_a = lastX1();
_xb_b = lastX2();
return MEPP2WH::dSigHatDR()*NLOweight();
}
double MEPP2WHPowheg::NLOweight() const {
// If only leading order is required return 1:
if(_contrib==0) return 1.;
useMe();
// Get particle data for QCD particles:
_parton_a=mePartonData()[0];
_parton_b=mePartonData()[1];
// get BeamParticleData objects for PDF's
_hadron_A=dynamic_ptr_cast<Ptr<BeamParticleData>::transient_const_pointer>
(lastParticles().first->dataPtr());
_hadron_B=dynamic_ptr_cast<Ptr<BeamParticleData>::transient_const_pointer>
(lastParticles().second->dataPtr());
// If necessary swap the particle data vectors so that _xb_a,
// mePartonData[0], beam[0] relate to the inbound quark:
if(!(lastPartons().first ->dataPtr()==_parton_a&&
lastPartons().second->dataPtr()==_parton_b)) {
swap(_xb_a ,_xb_b);
swap(_hadron_A,_hadron_B);
}
// calculate the PDF's for the Born process
_oldq = _hadron_A->pdf()->xfx(_hadron_A,_parton_a,scale(),_xb_a)/_xb_a;
_oldqbar = _hadron_B->pdf()->xfx(_hadron_B,_parton_b,scale(),_xb_b)/_xb_b;
// Calculate alpha_S
_alphaS2Pi = _nlo_alphaS_opt==1 ? _fixed_alphaS : SM().alphaS(scale());
_alphaS2Pi /= 2.*Constants::pi;
// Calculate the invariant mass of the dilepton pair
_mll2 = sHat();
_mu2 = scale();
// Calculate the integrand
// q qbar contribution
double wqqvirt = Vtilde_qq();
double wqqcollin = Ctilde_qq(x(_xt,1.),1.) + Ctilde_qq(x(_xt,0.),0.);
double wqqreal = Ftilde_qq(_xt,_v);
double wqq = wqqvirt+wqqcollin+wqqreal;
// q g contribution
double wqgcollin = Ctilde_qg(x(_xt,0.),0.);
double wqgreal = Ftilde_qg(_xt,_v);
double wqg = wqgreal+wqgcollin;
// g qbar contribution
double wgqbarcollin = Ctilde_gq(x(_xt,1.),1.);
double wgqbarreal = Ftilde_gq(_xt,_v);
double wgqbar = wgqbarreal+wgqbarcollin;
// total
double wgt = 1.+(wqq+wqg+wgqbar);
// KMH - 06/08 - This seems to give wrong NLO results for
// associated Higgs so I'm omitting it.
// //trick to try and reduce neg wgt contribution
// if(_xt<1.-_eps)
// wgt += _a*(1./pow(1.-_xt,_p)-(1.-pow(_eps,1.-_p))/(1.-_p)/(1.-_eps));
// return the answer
assert(isfinite(wgt));
return _contrib==1 ? max(0.,wgt) : max(0.,-wgt);
}
double MEPP2WHPowheg::x(double xt, double v) const {
double x0(xbar(v));
return x0+(1.-x0)*xt;
}
double MEPP2WHPowheg::x_a(double x, double v) const {
if(x==1.) return _xb_a;
if(v==0.) return _xb_a;
if(v==1.) return _xb_a/x;
return (_xb_a/sqrt(x))*sqrt((1.-(1.-x)*(1.-v))/(1.-(1.-x)*v));
}
double MEPP2WHPowheg::x_b(double x, double v) const {
if(x==1.) return _xb_b;
if(v==0.) return _xb_b/x;
if(v==1.) return _xb_b;
return (_xb_b/sqrt(x))*sqrt((1.-(1.-x)*v)/(1.-(1.-x)*(1.-v)));
}
double MEPP2WHPowheg::xbar(double v) const {
double xba2(sqr(_xb_a)), xbb2(sqr(_xb_b)), omv(-999.);
double xbar1(-999.), xbar2(-999.);
if(v==1.) return _xb_a;
if(v==0.) return _xb_b;
omv = 1.-v;
xbar1=4.* v*xba2/
(sqrt(sqr(1.+xba2)*4.*sqr(omv)+16.*(1.-2.*omv)*xba2)+2.*omv*(1.-_xb_a)*(1.+_xb_a));
xbar2=4.*omv*xbb2/
(sqrt(sqr(1.+xbb2)*4.*sqr( v)+16.*(1.-2.* v)*xbb2)+2.* v*(1.-_xb_b)*(1.+_xb_b));
return max(xbar1,xbar2);
}
double MEPP2WHPowheg::Ltilde_qq(double x, double v) const {
if(x==1.) return 1.;
double xa(x_a(x,v)),xb(x_b(x,v));
double newq = (_hadron_A->pdf()->xfx(_hadron_A,_parton_a,scale(), xa)/ xa);
double newqbar = (_hadron_B->pdf()->xfx(_hadron_B,_parton_b,scale(), xb)/ xb);
return( newq * newqbar / _oldq / _oldqbar );
}
double MEPP2WHPowheg::Ltilde_qg(double x, double v) const {
double xa(x_a(x,v)),xb(x_b(x,v));
double newq = (_hadron_A->pdf()->xfx(_hadron_A,_parton_a,scale(), xa)/ xa);
double newg2 = (_hadron_B->pdf()->xfx(_hadron_B,_gluon ,scale(), xb)/ xb);
return( newq * newg2 / _oldq / _oldqbar );
}
double MEPP2WHPowheg::Ltilde_gq(double x, double v) const {
double xa(x_a(x,v)),xb(x_b(x,v));
double newg1 = (_hadron_A->pdf()->xfx(_hadron_A,_gluon ,scale(), xa)/ xa);
double newqbar = (_hadron_B->pdf()->xfx(_hadron_B,_parton_b,scale(), xb)/ xb);
return( newg1 * newqbar / _oldq / _oldqbar );
}
double MEPP2WHPowheg::Vtilde_qq() const {
return _alphaS2Pi*CF_*(-3.*log(_mu2/_mll2)+(2.*sqr(Constants::pi)/3.)-8.);
}
double MEPP2WHPowheg::Ccalbar_qg(double x) const {
return (sqr(x)+sqr(1.-x))*(log(_mll2/(_mu2*x))+2.*log(1.-x))+2.*x*(1.-x);
}
double MEPP2WHPowheg::Ctilde_qg(double x, double v) const {
return _alphaS2Pi*TR_ * ((1.-xbar(v))/x) * Ccalbar_qg(x)*Ltilde_qg(x,v);
}
double MEPP2WHPowheg::Ctilde_gq(double x, double v) const {
return _alphaS2Pi*TR_ * ((1.-xbar(v))/x) * Ccalbar_qg(x)*Ltilde_gq(x,v);
}
double MEPP2WHPowheg::Ctilde_qq(double x, double v) const {
double wgt
= ((1.-x)/x+(1.+x*x)/(1.-x)/x*(2.*log(1.-x)-log(x)))*Ltilde_qq(x,v)
- 4.*log(1.-x)/(1.-x)
+ 2./(1.-xbar(v))*log(1.-xbar(v))*log(1.-xbar(v))
+ (2./(1.-xbar(v))*log(1.-xbar(v))-2./(1.-x)+(1.+x*x)/x/(1.-x)*Ltilde_qq(x,v))
*log(_mll2/_mu2);
return _alphaS2Pi*CF_*(1.-xbar(v))*wgt;
}
double MEPP2WHPowheg::Fcal_qq(double x, double v) const {
return (sqr(1.-x)*(1.-2.*v*(1.-v))+2.*x)/x*Ltilde_qq(x,v);
}
double MEPP2WHPowheg::Fcal_qg(double x, double v) const {
return ((1.-xbar(v))/x)*
(2.*x*(1.-x)*v+sqr((1.-x)*v)+sqr(x)+sqr(1.-x))*Ltilde_qg(x,v);
}
double MEPP2WHPowheg::Fcal_gq(double x, double v) const {
return ((1.-xbar(v))/x)*
(2.*x*(1.-x)*(1.-v)+sqr((1.-x)*(1.-v))+sqr(x)+sqr(1.-x))*Ltilde_gq(x,v);
}
double MEPP2WHPowheg::Ftilde_qg(double xt, double v) const {
return _alphaS2Pi*TR_*
( Fcal_qg(x(xt,v),v) - Fcal_qg(x(xt,0.),0.) )/v;
}
double MEPP2WHPowheg::Ftilde_gq(double xt, double v) const {
return _alphaS2Pi*TR_*
( Fcal_gq(x(xt,v),v) - Fcal_gq(x(xt,1.),1.) )/(1.-v);
}
double MEPP2WHPowheg::Ftilde_qq(double xt, double v) const {
double eps(1e-10);
// is emission into regular or singular region?
if(xt>=0. && xt<1.-eps && v>eps && v<1.-eps) {
// x<1, v>0, v<1 (regular emission, neither soft or collinear):
return _alphaS2Pi*CF_*
(( ( Fcal_qq(x(xt, v), v) - Fcal_qq(x(xt,1.),1.) ) / (1.-v)+
( Fcal_qq(x(xt, v), v) - Fcal_qq(x(xt,0.),0.) ) / v )/(1.-xt)
+ ( log(1.-xbar(v)) - log(1.-_xb_a))*2./(1.-v)
+ ( log(1.-xbar(v)) - log(1.-_xb_b))*2./v);
}
else {
// make sure emission is actually in the allowed phase space:
if(!(v>=0. && v<=1. && xt>=0. && xt<=1.)) {
ostringstream s;
s << "MEPP2WHPowheg::Ftilde_qq : \n" << "xt(" << xt << ") and / or v("
<< v << ") not in the phase space.";
generator()->logWarning(Exception(s.str(),Exception::warning));
return 0.;
}
// is emission soft singular?
if(xt>=1.-eps) {
// x=1:
if(v<=eps) {
// x==1, v=0 (soft and collinear with particle b):
return _alphaS2Pi*CF_*
( ( log(1.-xbar(v)) - log(1.-_xb_a))*2./(1.-v)
);
} else if(v>=1.-eps) {
// x==1, v=1 (soft and collinear with particle a):
return _alphaS2Pi*CF_*
( ( log(1.-xbar(v)) - log(1.-_xb_b))*2./v
);
} else {
// x==1, 0<v<1 (soft wide angle emission):
return _alphaS2Pi*CF_*
( ( log(1.-xbar(v)) - log(1.-_xb_a))*2./(1.-v)
+ ( log(1.-xbar(v)) - log(1.-_xb_b))*2./v
);
}
} else {
// x<1:
if(v<=eps) {
// x<1 but v=0 (collinear with particle b, but not soft):
return _alphaS2Pi*CF_*
( ( ( Fcal_qq(x(xt, v), v) - Fcal_qq(x(xt,1.),1.) ) / (1.-v)
)/(1.-xt)
+ ( log(1.-xbar(v)) - log(1.-_xb_a))*2./(1.-v)
);
} else if(v>=1.-eps) {
// x<1 but v=1 (collinear with particle a, but not soft):
return _alphaS2Pi*CF_*
( ( ( Fcal_qq(x(xt, v), v) - Fcal_qq(x(xt,0.),0.) ) / v
)/(1.-xt)
+ ( log(1.-xbar(v)) - log(1.-_xb_b))*2./v
);
}
}
}
return 0.;
}
diff --git a/MatrixElement/Powheg/MEPP2WHPowheg.h b/MatrixElement/Powheg/MEPP2WHPowheg.h
--- a/MatrixElement/Powheg/MEPP2WHPowheg.h
+++ b/MatrixElement/Powheg/MEPP2WHPowheg.h
@@ -1,386 +1,382 @@
// -*- C++ -*-
#ifndef HERWIG_MEPP2WHPowheg_H
#define HERWIG_MEPP2WHPowheg_H
//
// This is the declaration of the MEPP2WHPowheg class.
//
#include "Herwig/MatrixElement/Hadron/MEPP2WH.h"
#include "ThePEG/PDF/BeamParticleData.h"
namespace Herwig {
using namespace ThePEG;
/**
* The MEPP2WHPowheg class provides the next-to-leading order
* matrix elements for \f$W^\pm\f$ in assoication with a Higgs boson
* in the PoOWHEG scheme.
*
* @see \ref MEPP2WHPowhegInterfaces "The interfaces"
* defined for MEPP2WHPowheg.
*/
class MEPP2WHPowheg: public MEPP2WH {
public:
/**
* Default constructor
*/
MEPP2WHPowheg();
/** @name Virtual functions required by the MEBase class. */
//@{
/**
* Return the scale associated with the last set phase space point.
*/
virtual Energy2 scale() const;
/**
* The number of internal degreed of freedom used in the matrix
* element.
*/
virtual int nDim() const;
/**
* 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 bool generateKinematics(const double * r);
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(). Uses
* me().
*/
virtual CrossSection dSigHatDR() const;
//@}
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:
/**
* Calculate the correction weight with which leading-order
* configurations are re-weighted.
*/
double NLOweight() const;
/**
* Calculate the variable \f$x=M_{B}^2/s\f$ from the integration variables.
*/
double x(double xt, double v) const;
/**
* Calculate the momentum fraction of the first parton.
*/
double x_a(double x, double v) const;
/**
* Calculate the momentum fraction of second parton.
*/
double x_b(double x, double v) const;
/**
* Calculate the minimum of \f$x\f$.
*/
double xbar(double v) const;
/**
* Calculate the ratio of the radiative luminosity funcion to the
* Born luminosity function for the \f$qg\f$ initiated channel.
*/
double Ltilde_qg(double x, double v) const;
/**
* Calculate the ratio of the radiative luminosity funcion to the
* Born luminosity function for the \f$g\bar{q}\f$ initiated channel.
*/
double Ltilde_gq(double x, double v) const;
/**
* Calculate the ratio of the radiative luminosity funcion to the
* Born luminosity function for the \f$q\bar{q}\f$ initiated channel.
*/
double Ltilde_qq(double x, double v) const;
/**
* Calculate the soft-virtual contribution to the NLO weight.
*/
double Vtilde_qq() const;
/**
* Function for calculation of the \f$g\bar{q}\f$ and \f$g\bar{q}\f$
* initiated real contribution.
*/
double Ccalbar_qg(double x) const;
/**
* Function for calculation of the \f$qg\f$
* initiated real contribution.
*/
double Fcal_qg(double x, double v) const;
/**
* Function for calculation of the \f$g\bar{q}\f$ initiated real
* contribution.
*/
double Fcal_gq(double x, double v) const;
/**
* Function for calculation of the \f$q\bar{q}\f$ initiated real
* contribution.
*/
double Fcal_qq(double x, double v) const;
/**
* Function for calculation of the \f$qg\f$ initiated real
* contribution.
*/
double Ftilde_qg(double xt, double v) const;
/**
* Function for calculation of the \f$g\bar{q}\f$ initiated real
* contribution.
*/
double Ftilde_gq(double xt, double v) const;
/**
* Function for calculation of the \f$q\bar{q}\f$ initiated real
* contribution.
*/
double Ftilde_qq(double xt, double v) const;
/**
* Function for calculation of the \f$qg\f$ initiated real
* contribution.
*/
double Ctilde_qg(double x, double v) const;
/**
* Function for calculation of the \f$g\bar{q}\f$ initiated real
* contribution.
*/
double Ctilde_gq(double x, double v) const;
/**
* Function for calculation of the \f$q\bar{q}\f$ initiated real
* contribution.
*/
double Ctilde_qq(double x, double v) const;
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const { return new_ptr(*this); }
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const { return new_ptr(*this); }
//@}
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* Initialize this object after the setup phase before saving an
* EventGenerator to disk.
* @throws InitException if object could not be initialized properly.
*/
virtual void doinit();
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MEPP2WHPowheg & operator=(const MEPP2WHPowheg &) = delete;
private:
/**
* The momentum fraction of the first parton in the Born process
*/
mutable double _xb_a;
/**
* The momentum fraction of the second parton in the Born process
*/
mutable double _xb_b;
/**
* The ParticleData object for the first parton in the Born process
*/
mutable tcPDPtr _parton_a;
/**
* The ParticleData object for the second parton in the Born process
*/
mutable tcPDPtr _parton_b;
/**
* The BeamParticleData object for the first hadron
*/
mutable Ptr<BeamParticleData>::transient_const_pointer _hadron_A;
/**
* The BeamParticleData object for the second hadron
*/
mutable Ptr<BeamParticleData>::transient_const_pointer _hadron_B;
/**
* the ParticleData object for the gluon
*/
tcPDPtr _gluon;
/**
* The \f$T_R\f$ colour factor
*/
const double TR_;
/**
* The \f$C_F\f$ colour factor
*/
const double CF_;
/**
* The value of \f$\frac{\alpha_S}{2\pi}\f$ used for the calculation
*/
mutable double _alphaS2Pi;
/**
* The mass squared of the lepton pair
*/
mutable Energy2 _mll2;
/**
* The renormalization/factorization scale
*/
mutable Energy2 _mu2;
/**
* Parameters for the NLO weight
*/
//@{
/**
* Whether to generate the positive, negative or leading order contribution
*/
unsigned int _contrib;
/**
* Whether to use a fixed or a running QCD coupling for the NLO weight
*/
unsigned int _nlo_alphaS_opt;
/**
* The value of alphaS to use for the nlo weight if _nloalphaSopt=1
*/
double _fixed_alphaS;
/**
* The magnitude of the correction term to reduce the negative contribution
*/
double _a;
/**
* The power of the correction term to reduce the negative contribution
*/
double _p;
- /**
- * Cut-off for the correction function
- */
- double _eps;
//@}
/**
* Choice of the scale
*/
//@{
/**
* Type of scale
*/
unsigned int _scaleopt;
/**
* Fixed scale if used
*/
Energy _fixedScale;
/**
* Prefactor if variable scale used
*/
double _scaleFact;
//@}
/**
* Radiation variables
*/
//@{
/**
* The \f$\tilde{x}\f$ variable
*/
double _xt;
/**
* The \f$v\f$ angular variable
*/
double _v;
//@}
/**
* Values of the PDF's before radiation
*/
//@{
/**
* For the quark
*/
mutable double _oldq;
/**
* For the antiquark
*/
mutable double _oldqbar;
//@}
};
}
#endif /* HERWIG_MEPP2WHPowheg_H */
diff --git a/MatrixElement/Powheg/MEPP2ZHPowheg.cc b/MatrixElement/Powheg/MEPP2ZHPowheg.cc
--- a/MatrixElement/Powheg/MEPP2ZHPowheg.cc
+++ b/MatrixElement/Powheg/MEPP2ZHPowheg.cc
@@ -1,391 +1,391 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MEPP2ZHPowheg class.
//
#include "MEPP2ZHPowheg.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Handlers/StandardXComb.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/PDT/DecayMode.h"
using namespace Herwig;
MEPP2ZHPowheg::MEPP2ZHPowheg()
: _gluon(), TR_(0.5), CF_(4./3.),
_contrib(1) ,_nlo_alphaS_opt(0), _fixed_alphaS(0.115895),
- _a(0.5) ,_p(0.7) , _eps(1.0e-8), _scaleopt(1),
+ _a(0.5) ,_p(0.7) , _scaleopt(1),
_fixedScale(100.*GeV), _scaleFact(1.)
{}
void MEPP2ZHPowheg::persistentOutput(PersistentOStream & os) const {
os << _contrib << _nlo_alphaS_opt << _fixed_alphaS
<< _a << _p << _gluon
<< _scaleopt
<< ounit(_fixedScale,GeV) << _scaleFact;
}
void MEPP2ZHPowheg::persistentInput(PersistentIStream & is, int) {
is >> _contrib >> _nlo_alphaS_opt >> _fixed_alphaS
>> _a >> _p >> _gluon
>> _scaleopt
>> iunit(_fixedScale,GeV) >> _scaleFact;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<MEPP2ZHPowheg,MEPP2ZH>
describeHerwigMEPP2ZHPowheg("Herwig::MEPP2ZHPowheg", "HwMEHadron.so HwPowhegMEHadron.so");
void MEPP2ZHPowheg::Init() {
static ClassDocumentation<MEPP2ZHPowheg> documentation
("The MEPP2ZHPowheg class implements the matrix element for q qbar -> Z H",
"The PP$\\to$Z Higgs POWHEG matrix element is described in \\cite{Hamilton:2009za}.",
"\\bibitem{Hamilton:2009za}\n"
" K.~Hamilton, P.~Richardson and J.~Tully,\n"
" %``A Positive-Weight Next-to-Leading Order Monte Carlo Simulation for Higgs\n"
" %Boson Production,''\n"
" JHEP {\\bf 0904} (2009) 116\n"
" [arXiv:0903.4345 [hep-ph]].\n"
" %%CITATION = JHEPA,0904,116;%%\n"
);
static Switch<MEPP2ZHPowheg,unsigned int> interfaceContribution
("Contribution",
"Which contributions to the cross section to include",
&MEPP2ZHPowheg::_contrib, 1, false, false);
static SwitchOption interfaceContributionLeadingOrder
(interfaceContribution,
"LeadingOrder",
"Just generate the leading order cross section",
0);
static SwitchOption interfaceContributionPositiveNLO
(interfaceContribution,
"PositiveNLO",
"Generate the positive contribution to the full NLO cross section",
1);
static SwitchOption interfaceContributionNegativeNLO
(interfaceContribution,
"NegativeNLO",
"Generate the negative contribution to the full NLO cross section",
2);
static Switch<MEPP2ZHPowheg,unsigned int> interfaceNLOalphaSopt
("NLOalphaSopt",
"Whether to use a fixed or a running QCD coupling for the NLO weight",
&MEPP2ZHPowheg::_nlo_alphaS_opt, 0, false, false);
static SwitchOption interfaceNLOalphaSoptRunningAlphaS
(interfaceNLOalphaSopt,
"RunningAlphaS",
"Use the usual running QCD coupling evaluated at scale scale()",
0);
static SwitchOption interfaceNLOalphaSoptFixedAlphaS
(interfaceNLOalphaSopt,
"FixedAlphaS",
"Use a constant QCD coupling for comparison/debugging purposes",
1);
static Parameter<MEPP2ZHPowheg,double> interfaceFixedNLOalphaS
("FixedNLOalphaS",
"The value of alphaS to use for the nlo weight if _nlo_alphaS_opt=1",
&MEPP2ZHPowheg::_fixed_alphaS, 0.115895, 0., 1.0,
false, false, Interface::limited);
static Parameter<MEPP2ZHPowheg,double> interfaceCorrectionCoefficient
("CorrectionCoefficient",
"The magnitude of the correction term to reduce the negative contribution",
&MEPP2ZHPowheg::_a, 0.5, -10., 10.0,
false, false, Interface::limited);
static Parameter<MEPP2ZHPowheg,double> interfaceCorrectionPower
("CorrectionPower",
"The power of the correction term to reduce the negative contribution",
&MEPP2ZHPowheg::_p, 0.7, 0.0, 1.0,
false, false, Interface::limited);
static Switch<MEPP2ZHPowheg,unsigned int> interfaceFactorizationScaleOption
("FactorizationScaleOption",
"Option for the scale to be used",
&MEPP2ZHPowheg::_scaleopt, 1, false, false);
static SwitchOption interfaceScaleOptionFixed
(interfaceFactorizationScaleOption,
"Fixed",
"Use a fixed scale",
0);
static SwitchOption interfaceScaleOptionsHat
(interfaceFactorizationScaleOption,
"Dynamic",
"Use the mass of the vector boson-Higgs boson system",
1);
static Parameter<MEPP2ZHPowheg,Energy> interfaceFactorizationScaleValue
("FactorizationScaleValue",
"The fixed scale to use if required",
&MEPP2ZHPowheg::_fixedScale, GeV, 100.0*GeV, 10.0*GeV, 1000.0*GeV,
false, false, Interface::limited);
static Parameter<MEPP2ZHPowheg,double> interfaceScaleFactor
("ScaleFactor",
"The factor used before sHat if using a running scale",
&MEPP2ZHPowheg::_scaleFact, 1.0, 0.0, 10.0,
false, false, Interface::limited);
}
void MEPP2ZHPowheg::doinit() {
// gluon ParticleData object
_gluon = getParticleData(ParticleID::g);
MEPP2ZH::doinit();
}
Energy2 MEPP2ZHPowheg::scale() const {
return _scaleopt == 0 ? sqr(_fixedScale) : _scaleFact*sHat();
}
int MEPP2ZHPowheg::nDim() const {
return 7;
}
bool MEPP2ZHPowheg::generateKinematics(const double * r) {
_xt=*(r+5);
_v =*(r+6);
return MEPP2ZH::generateKinematics(r);
}
CrossSection MEPP2ZHPowheg::dSigHatDR() const {
// Get Born momentum fractions xbar_a and xbar_b:
_xb_a = lastX1();
_xb_b = lastX2();
return MEPP2ZH::dSigHatDR()*NLOweight();
}
double MEPP2ZHPowheg::NLOweight() const {
// If only leading order is required return 1:
if(_contrib==0) return 1.;
useMe();
// Get particle data for QCD particles:
_parton_a=mePartonData()[0];
_parton_b=mePartonData()[1];
// get BeamParticleData objects for PDF's
_hadron_A=dynamic_ptr_cast<Ptr<BeamParticleData>::transient_const_pointer>
(lastParticles().first->dataPtr());
_hadron_B=dynamic_ptr_cast<Ptr<BeamParticleData>::transient_const_pointer>
(lastParticles().second->dataPtr());
// If necessary swap the particle data vectors so that _xb_a,
// mePartonData[0], beam[0] relate to the inbound quark:
if(!(lastPartons().first ->dataPtr()==_parton_a&&
lastPartons().second->dataPtr()==_parton_b)) {
swap(_xb_a ,_xb_b);
swap(_hadron_A,_hadron_B);
}
// calculate the PDF's for the Born process
_oldq = _hadron_A->pdf()->xfx(_hadron_A,_parton_a,scale(),_xb_a)/_xb_a;
_oldqbar = _hadron_B->pdf()->xfx(_hadron_B,_parton_b,scale(),_xb_b)/_xb_b;
// Calculate alpha_S
_alphaS2Pi = _nlo_alphaS_opt==1 ? _fixed_alphaS : SM().alphaS(scale());
_alphaS2Pi /= 2.*Constants::pi;
// Calculate the invariant mass of the dilepton pair
_mll2 = sHat();
_mu2 = scale();
// Calculate the integrand
// q qbar contribution
double wqqvirt = Vtilde_qq();
double wqqcollin = Ctilde_qq(x(_xt,1.),1.) + Ctilde_qq(x(_xt,0.),0.);
double wqqreal = Ftilde_qq(_xt,_v);
double wqq = wqqvirt+wqqcollin+wqqreal;
// q g contribution
double wqgcollin = Ctilde_qg(x(_xt,0.),0.);
double wqgreal = Ftilde_qg(_xt,_v);
double wqg = wqgreal+wqgcollin;
// g qbar contribution
double wgqbarcollin = Ctilde_gq(x(_xt,1.),1.);
double wgqbarreal = Ftilde_gq(_xt,_v);
double wgqbar = wgqbarreal+wgqbarcollin;
// total
double wgt = 1.+(wqq+wqg+wgqbar);
// KMH - 06/08 - This seems to give wrong NLO results for
// associated Higgs so I'm omitting it.
// //trick to try and reduce neg wgt contribution
// if(_xt<1.-_eps)
// wgt += _a*(1./pow(1.-_xt,_p)-(1.-pow(_eps,1.-_p))/(1.-_p)/(1.-_eps));
// return the answer
assert(isfinite(wgt));
return _contrib==1 ? max(0.,wgt) : max(0.,-wgt);
}
double MEPP2ZHPowheg::x(double xt, double v) const {
double x0(xbar(v));
return x0+(1.-x0)*xt;
}
double MEPP2ZHPowheg::x_a(double x, double v) const {
if(x==1.) return _xb_a;
if(v==0.) return _xb_a;
if(v==1.) return _xb_a/x;
return (_xb_a/sqrt(x))*sqrt((1.-(1.-x)*(1.-v))/(1.-(1.-x)*v));
}
double MEPP2ZHPowheg::x_b(double x, double v) const {
if(x==1.) return _xb_b;
if(v==0.) return _xb_b/x;
if(v==1.) return _xb_b;
return (_xb_b/sqrt(x))*sqrt((1.-(1.-x)*v)/(1.-(1.-x)*(1.-v)));
}
double MEPP2ZHPowheg::xbar(double v) const {
double xba2(sqr(_xb_a)), xbb2(sqr(_xb_b)), omv(-999.);
double xbar1(-999.), xbar2(-999.);
if(v==1.) return _xb_a;
if(v==0.) return _xb_b;
omv = 1.-v;
xbar1=4.* v*xba2/
(sqrt(sqr(1.+xba2)*4.*sqr(omv)+16.*(1.-2.*omv)*xba2)+2.*omv*(1.-_xb_a)*(1.+_xb_a));
xbar2=4.*omv*xbb2/
(sqrt(sqr(1.+xbb2)*4.*sqr( v)+16.*(1.-2.* v)*xbb2)+2.* v*(1.-_xb_b)*(1.+_xb_b));
return max(xbar1,xbar2);
}
double MEPP2ZHPowheg::Ltilde_qq(double x, double v) const {
if(x==1.) return 1.;
double xa(x_a(x,v)),xb(x_b(x,v));
double newq = (_hadron_A->pdf()->xfx(_hadron_A,_parton_a,scale(), xa)/ xa);
double newqbar = (_hadron_B->pdf()->xfx(_hadron_B,_parton_b,scale(), xb)/ xb);
return( newq * newqbar / _oldq / _oldqbar );
}
double MEPP2ZHPowheg::Ltilde_qg(double x, double v) const {
double xa(x_a(x,v)),xb(x_b(x,v));
double newq = (_hadron_A->pdf()->xfx(_hadron_A,_parton_a,scale(), xa)/ xa);
double newg2 = (_hadron_B->pdf()->xfx(_hadron_B,_gluon ,scale(), xb)/ xb);
return( newq * newg2 / _oldq / _oldqbar );
}
double MEPP2ZHPowheg::Ltilde_gq(double x, double v) const {
double xa(x_a(x,v)),xb(x_b(x,v));
double newg1 = (_hadron_A->pdf()->xfx(_hadron_A,_gluon ,scale(), xa)/ xa);
double newqbar = (_hadron_B->pdf()->xfx(_hadron_B,_parton_b,scale(), xb)/ xb);
return( newg1 * newqbar / _oldq / _oldqbar );
}
double MEPP2ZHPowheg::Vtilde_qq() const {
return _alphaS2Pi*CF_*(-3.*log(_mu2/_mll2)+(2.*sqr(Constants::pi)/3.)-8.);
}
double MEPP2ZHPowheg::Ccalbar_qg(double x) const {
return (sqr(x)+sqr(1.-x))*(log(_mll2/(_mu2*x))+2.*log(1.-x))+2.*x*(1.-x);
}
double MEPP2ZHPowheg::Ctilde_qg(double x, double v) const {
return _alphaS2Pi*TR_ * ((1.-xbar(v))/x) * Ccalbar_qg(x)*Ltilde_qg(x,v);
}
double MEPP2ZHPowheg::Ctilde_gq(double x, double v) const {
return _alphaS2Pi*TR_ * ((1.-xbar(v))/x) * Ccalbar_qg(x)*Ltilde_gq(x,v);
}
double MEPP2ZHPowheg::Ctilde_qq(double x, double v) const {
double wgt
= ((1.-x)/x+(1.+x*x)/(1.-x)/x*(2.*log(1.-x)-log(x)))*Ltilde_qq(x,v)
- 4.*log(1.-x)/(1.-x)
+ 2./(1.-xbar(v))*log(1.-xbar(v))*log(1.-xbar(v))
+ (2./(1.-xbar(v))*log(1.-xbar(v))-2./(1.-x)+(1.+x*x)/x/(1.-x)*Ltilde_qq(x,v))
*log(_mll2/_mu2);
return _alphaS2Pi*CF_*(1.-xbar(v))*wgt;
}
double MEPP2ZHPowheg::Fcal_qq(double x, double v) const {
return (sqr(1.-x)*(1.-2.*v*(1.-v))+2.*x)/x*Ltilde_qq(x,v);
}
double MEPP2ZHPowheg::Fcal_qg(double x, double v) const {
return ((1.-xbar(v))/x)*
(2.*x*(1.-x)*v+sqr((1.-x)*v)+sqr(x)+sqr(1.-x))*Ltilde_qg(x,v);
}
double MEPP2ZHPowheg::Fcal_gq(double x, double v) const {
return ((1.-xbar(v))/x)*
(2.*x*(1.-x)*(1.-v)+sqr((1.-x)*(1.-v))+sqr(x)+sqr(1.-x))*Ltilde_gq(x,v);
}
double MEPP2ZHPowheg::Ftilde_qg(double xt, double v) const {
return _alphaS2Pi*TR_*
( Fcal_qg(x(xt,v),v) - Fcal_qg(x(xt,0.),0.) )/v;
}
double MEPP2ZHPowheg::Ftilde_gq(double xt, double v) const {
return _alphaS2Pi*TR_*
( Fcal_gq(x(xt,v),v) - Fcal_gq(x(xt,1.),1.) )/(1.-v);
}
double MEPP2ZHPowheg::Ftilde_qq(double xt, double v) const {
double eps(1e-10);
// is emission into regular or singular region?
if(xt>=0. && xt<1.-eps && v>eps && v<1.-eps) {
// x<1, v>0, v<1 (regular emission, neither soft or collinear):
return _alphaS2Pi*CF_*
(( ( Fcal_qq(x(xt, v), v) - Fcal_qq(x(xt,1.),1.) ) / (1.-v)+
( Fcal_qq(x(xt, v), v) - Fcal_qq(x(xt,0.),0.) ) / v )/(1.-xt)
+ ( log(1.-xbar(v)) - log(1.-_xb_a))*2./(1.-v)
+ ( log(1.-xbar(v)) - log(1.-_xb_b))*2./v);
}
else {
// make sure emission is actually in the allowed phase space:
if(!(v>=0. && v<=1. && xt>=0. && xt<=1.)) {
ostringstream s;
s << "MEPP2ZHPowheg::Ftilde_qq : \n" << "xt(" << xt << ") and / or v("
<< v << ") not in the phase space.";
generator()->logWarning(Exception(s.str(),Exception::warning));
return 0.;
}
// is emission soft singular?
if(xt>=1.-eps) {
// x=1:
if(v<=eps) {
// x==1, v=0 (soft and collinear with particle b):
return _alphaS2Pi*CF_*
( ( log(1.-xbar(v)) - log(1.-_xb_a))*2./(1.-v)
);
} else if(v>=1.-eps) {
// x==1, v=1 (soft and collinear with particle a):
return _alphaS2Pi*CF_*
( ( log(1.-xbar(v)) - log(1.-_xb_b))*2./v
);
} else {
// x==1, 0<v<1 (soft wide angle emission):
return _alphaS2Pi*CF_*
( ( log(1.-xbar(v)) - log(1.-_xb_a))*2./(1.-v)
+ ( log(1.-xbar(v)) - log(1.-_xb_b))*2./v
);
}
} else {
// x<1:
if(v<=eps) {
// x<1 but v=0 (collinear with particle b, but not soft):
return _alphaS2Pi*CF_*
( ( ( Fcal_qq(x(xt, v), v) - Fcal_qq(x(xt,1.),1.) ) / (1.-v)
)/(1.-xt)
+ ( log(1.-xbar(v)) - log(1.-_xb_a))*2./(1.-v)
);
} else if(v>=1.-eps) {
// x<1 but v=1 (collinear with particle a, but not soft):
return _alphaS2Pi*CF_*
( ( ( Fcal_qq(x(xt, v), v) - Fcal_qq(x(xt,0.),0.) ) / v
)/(1.-xt)
+ ( log(1.-xbar(v)) - log(1.-_xb_b))*2./v
);
}
}
}
return 0.;
}
diff --git a/MatrixElement/Powheg/MEPP2ZHPowheg.h b/MatrixElement/Powheg/MEPP2ZHPowheg.h
--- a/MatrixElement/Powheg/MEPP2ZHPowheg.h
+++ b/MatrixElement/Powheg/MEPP2ZHPowheg.h
@@ -1,384 +1,380 @@
// -*- C++ -*-
#ifndef HERWIG_MEPP2ZHPowheg_H
#define HERWIG_MEPP2ZHPowheg_H
//
// This is the declaration of the MEPP2ZHPowheg class.
//
#include "Herwig/MatrixElement/Hadron/MEPP2ZH.h"
#include "ThePEG/PDF/BeamParticleData.h"
namespace Herwig {
using namespace ThePEG;
/**
* The MEPP2ZHPowheg class implements the matrix element
* for \f$q\bar{q}\to Z^0h^0\f$.
*
* @see \ref MEPP2ZHPowhegInterfaces "The interfaces"
* defined for MEPP2ZHPowheg.
*/
class MEPP2ZHPowheg: public MEPP2ZH {
public:
/**
* The default constructor.
*/
MEPP2ZHPowheg();
/** @name Virtual functions required by the MEBase class. */
//@{
/**
* Return the scale associated with the last set phase space point.
*/
virtual Energy2 scale() const;
/**
* The number of internal degreed of freedom used in the matrix
* element.
*/
virtual int nDim() const;
/**
* 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 bool generateKinematics(const double * r);
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(). Uses
* me().
*/
virtual CrossSection dSigHatDR() const;
//@}
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:
/**
* Calculate the correction weight with which leading-order
* configurations are re-weighted.
*/
double NLOweight() const;
/**
* Calculate the variable \f$x=M_{B}^2/s\f$ from the integration variables.
*/
double x(double xt, double v) const;
/**
* Calculate the momentum fraction of the first parton.
*/
double x_a(double x, double v) const;
/**
* Calculate the momentum fraction of second parton.
*/
double x_b(double x, double v) const;
/**
* Calculate the minimum of \f$x\f$.
*/
double xbar(double v) const;
/**
* Calculate the ratio of the radiative luminosity funcion to the
* Born luminosity function for the \f$qg\f$ initiated channel.
*/
double Ltilde_qg(double x, double v) const;
/**
* Calculate the ratio of the radiative luminosity funcion to the
* Born luminosity function for the \f$g\bar{q}\f$ initiated channel.
*/
double Ltilde_gq(double x, double v) const;
/**
* Calculate the ratio of the radiative luminosity funcion to the
* Born luminosity function for the \f$q\bar{q}\f$ initiated channel.
*/
double Ltilde_qq(double x, double v) const;
/**
* Calculate the soft-virtual contribution to the NLO weight.
*/
double Vtilde_qq() const;
/**
* Function for calculation of the \f$g\bar{q}\f$ and \f$g\bar{q}\f$
* initiated real contribution.
*/
double Ccalbar_qg(double x) const;
/**
* Function for calculation of the \f$qg\f$
* initiated real contribution.
*/
double Fcal_qg(double x, double v) const;
/**
* Function for calculation of the \f$g\bar{q}\f$ initiated real
* contribution.
*/
double Fcal_gq(double x, double v) const;
/**
* Function for calculation of the \f$q\bar{q}\f$ initiated real
* contribution.
*/
double Fcal_qq(double x, double v) const;
/**
* Function for calculation of the \f$qg\f$ initiated real
* contribution.
*/
double Ftilde_qg(double xt, double v) const;
/**
* Function for calculation of the \f$g\bar{q}\f$ initiated real
* contribution.
*/
double Ftilde_gq(double xt, double v) const;
/**
* Function for calculation of the \f$q\bar{q}\f$ initiated real
* contribution.
*/
double Ftilde_qq(double xt, double v) const;
/**
* Function for calculation of the \f$qg\f$ initiated real
* contribution.
*/
double Ctilde_qg(double x, double v) const;
/**
* Function for calculation of the \f$g\bar{q}\f$ initiated real
* contribution.
*/
double Ctilde_gq(double x, double v) const;
/**
* Function for calculation of the \f$q\bar{q}\f$ initiated real
* contribution.
*/
double Ctilde_qq(double x, double v) const;
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const { return new_ptr(*this); }
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const { return new_ptr(*this); }
//@}
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* Initialize this object after the setup phase before saving an
* EventGenerator to disk.
* @throws InitException if object could not be initialized properly.
*/
virtual void doinit();
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MEPP2ZHPowheg & operator=(const MEPP2ZHPowheg &) = delete;
private:
/**
* The momentum fraction of the first parton in the Born process
*/
mutable double _xb_a;
/**
* The momentum fraction of the second parton in the Born process
*/
mutable double _xb_b;
/**
* The ParticleData object for the first parton in the Born process
*/
mutable tcPDPtr _parton_a;
/**
* The ParticleData object for the second parton in the Born process
*/
mutable tcPDPtr _parton_b;
/**
* The BeamParticleData object for the first hadron
*/
mutable Ptr<BeamParticleData>::transient_const_pointer _hadron_A;
/**
* The BeamParticleData object for the second hadron
*/
mutable Ptr<BeamParticleData>::transient_const_pointer _hadron_B;
/**
* the ParticleData object for the gluon
*/
tcPDPtr _gluon;
/**
* The \f$T_R\f$ colour factor
*/
const double TR_;
/**
* The \f$C_F\f$ colour factor
*/
const double CF_;
/**
* The value of \f$\frac{\alpha_S}{2\pi}\f$ used for the calculation
*/
mutable double _alphaS2Pi;
/**
* The mass squared of the lepton pair
*/
mutable Energy2 _mll2;
/**
* The renormalization/factorization scale
*/
mutable Energy2 _mu2;
/**
* Parameters for the NLO weight
*/
//@{
/**
* Whether to generate the positive, negative or leading order contribution
*/
unsigned int _contrib;
/**
* Whether to use a fixed or a running QCD coupling for the NLO weight
*/
unsigned int _nlo_alphaS_opt;
/**
* The value of alphaS to use for the nlo weight if _nloalphaSopt=1
*/
double _fixed_alphaS;
/**
* The magnitude of the correction term to reduce the negative contribution
*/
double _a;
/**
* The power of the correction term to reduce the negative contribution
*/
double _p;
- /**
- * Cut-off for the correction function
- */
- double _eps;
//@}
/**
* Choice of the scale
*/
//@{
/**
* Type of scale
*/
unsigned int _scaleopt;
/**
* Fixed scale if used
*/
Energy _fixedScale;
/**
* Prefactor if variable scale used
*/
double _scaleFact;
//@}
/**
* Radiation variables
*/
//@{
/**
* The \f$\tilde{x}\f$ variable
*/
double _xt;
/**
* The \f$v\f$ angular variable
*/
double _v;
//@}
/**
* Values of the PDF's before radiation
*/
//@{
/**
* For the quark
*/
mutable double _oldq;
/**
* For the antiquark
*/
mutable double _oldqbar;
//@}
};
}
#endif /* HERWIG_MEPP2ZHPowheg_H */
diff --git a/Models/ADD/ADDModelFFGGRVertex.cc b/Models/ADD/ADDModelFFGGRVertex.cc
--- a/Models/ADD/ADDModelFFGGRVertex.cc
+++ b/Models/ADD/ADDModelFFGGRVertex.cc
@@ -1,92 +1,91 @@
// -*- C++ -*-
//
// ADDModelFFGGRVertex.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the ADDModelFFGGRVertex class.
//
#include "ADDModelFFGGRVertex.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
using namespace ThePEG;
ADDModelFFGGRVertex::ADDModelFFGGRVertex()
: couplast_(0.), q2last_(ZERO), kappa_(ZERO), r_(ZERO) {
orderInGem(1);
orderInGs (1);
colourStructure(ColourStructure::SU3TFUND);
}
void ADDModelFFGGRVertex::doinit() {
for(int ix=1;ix<7;++ix) {
addToList(-ix,ix,21,39);
}
FFVTVertex::doinit();
tcHwADDPtr hwADD=dynamic_ptr_cast<tcHwADDPtr>(generator()->standardModel());
if(!hwADD) throw Exception()
<< "Must have ADDModel in ADDModelFFGGRVertex::doinit()"
<< Exception::runerror;
kappa_ = 2./hwADD->MPlanckBar();
r_ = sqr(hwADD->LambdaT())/hwADD->MPlanckBar();
}
void ADDModelFFGGRVertex::persistentOutput(PersistentOStream & os) const {
os << ounit(kappa_,InvGeV) << ounit(r_,GeV);
}
void ADDModelFFGGRVertex::persistentInput(PersistentIStream & is, int) {
is >> iunit(kappa_,InvGeV) >> iunit(r_,GeV);
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<ADDModelFFGGRVertex,FFVTVertex>
describeHerwigADDModelFFGGRVertex("Herwig::ADDModelFFGGRVertex", "HwADDModel.so");
void ADDModelFFGGRVertex::Init() {
static ClassDocumentation<ADDModelFFGGRVertex> documentation
("The ADDModelFFGGRVertexxs class is the implementation"
" of the two fermion vector coupling for the ADD model.");
}
#ifndef NDEBUG
void ADDModelFFGGRVertex::setCoupling(Energy2 q2,tcPDPtr aa,tcPDPtr,
tcPDPtr cc, tcPDPtr) {
#else
void ADDModelFFGGRVertex::setCoupling(Energy2 q2,tcPDPtr,tcPDPtr,
tcPDPtr, tcPDPtr) {
#endif
// work out the particles
assert(cc->id()==ParticleID::g && abs(aa->id()) <= 6);
- Complex coup;
// overall factor
if(q2last_!=q2||couplast_==0.) {
couplast_ = strongCoupling(q2);
q2last_=q2;
}
left (1.);
right(1.);
// set the coupling
norm(UnitRemoval::E * kappa_ * couplast_);
}
Complex ADDModelFFGGRVertex::propagator(int iopt, Energy2 q2,tcPDPtr part,
Energy mass, Energy width) {
if(part->id()!=ParticleID::Graviton)
return VertexBase::propagator(iopt,q2,part,mass,width);
else
return Complex(4.*Constants::pi*UnitRemoval::E2/sqr(r_));
}
diff --git a/Models/General/VVSLoopVertex.cc b/Models/General/VVSLoopVertex.cc
--- a/Models/General/VVSLoopVertex.cc
+++ b/Models/General/VVSLoopVertex.cc
@@ -1,134 +1,134 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the VVSLoopVertex class.
//
#include "VVSLoopVertex.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/Looptools/clooptools.h"
using namespace Herwig;
using namespace ThePEG;
namespace LT = Looptools;
IBPtr VVSLoopVertex::clone() const {
return new_ptr(*this);
}
IBPtr VVSLoopVertex::fullclone() const {
return new_ptr(*this);
}
void VVSLoopVertex::persistentOutput(PersistentOStream & os) const {
os << ounit(masses,GeV) << type << couplings << Npart_;
}
void VVSLoopVertex::persistentInput(PersistentIStream & is, int) {
is >> iunit(masses,GeV) >> type >> couplings >> Npart_;
}
void VVSLoopVertex::dofinish() {
if(loopToolsInit_) Looptools::ltexi();
GeneralVVSVertex::dofinish();
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<VVSLoopVertex,Helicity::GeneralVVSVertex>
describeHerwigVVSLoopVertex("Herwig::VVSLoopVertex", "Herwig.so");
void VVSLoopVertex::Init() {
static ClassDocumentation<VVSLoopVertex> documentation
("The VVSLoopVertex class calculates the tensor integral"
" coefficients using Looptools.");
}
void VVSLoopVertex::setCoupling(Energy2, tcPDPtr p1, tcPDPtr,tcPDPtr) {
if(!loopToolsInit_) {
Looptools::ltini();
loopToolsInit_ = true;
}
//Kinematic invariants
double ps2 = invariant(0,0) / MeV2;
double pv1s = invariant(1,1) / MeV2;
double pv2s = invariant(2,2) / MeV2;
Complex a(0.),b(0.),c(0.),d(0.),e(0.),f(0.);
for(unsigned int i = 0; i< Npart_;++i) {
double lmass = masses[i] / MeV;
double mls = sqr(lmass);
// left coupling for fermions or the total coupling
// for scalars or vectors
Complex lc = couplings[i].first;
// double p1p2 = 0.5*(ps2-pv1s-pv2s);
Complex C0A = LT::C0i(LT::cc0,pv2s,ps2,pv1s,mls,mls,mls);
long theC = LT::Cget(pv2s,ps2,pv1s, mls,mls,mls);
// Complex C1A = LT::Cval(LT::cc1,theC);
// Complex C2A = LT::Cval(LT::cc2,theC);
// Complex C11A = LT::Cval(LT::cc11,theC);
Complex C12A = LT::Cval(LT::cc12,theC);
// Complex C22A = LT::Cval(LT::cc22,theC);
// Complex C00A = LT::Cval(LT::cc00,theC);
Complex C0B = LT::C0i(LT::cc0,pv1s,ps2,pv2s,mls,mls,mls);
theC = LT::Cget(pv1s,ps2,pv2s, mls,mls,mls);
// Complex C1B = LT::Cval(LT::cc1,theC);
// Complex C2B = LT::Cval(LT::cc2,theC);
// Complex C11B = LT::Cval(LT::cc11,theC);
Complex C12B = LT::Cval(LT::cc12,theC);
// Complex C22B = LT::Cval(LT::cc22,theC);
// Complex C00B = LT::Cval(LT::cc00,theC);
if(type[i] == PDT::Spin1Half) {
Complex lpr = lc + couplings[i].second;
Complex loop = 2.*lpr*lmass*( - 4.*(C12A + C12B) + C0A + C0B );
a -= loop;
d += loop;
f += 2.*(lc - couplings[i].second)*lmass*(C0A+C0B);
// a += 2.*lpr*lmass*(2.*C12A-C0A+2.*C12B-C0B+
// (1. - pv1s*(C22A+C11B)- pv2s*(C11A+C22B) + mls*(C0A+C0B) )/p1p2);
// b += 8.*lpr*lmass*(2.*C22A + C2A +2.*C11B + C1B);
// c += 2.*lpr*lmass*(- 4.*(C12A + C12B) - 2.*(C2A + C1A + C2B + C1B) - C0A - C0B);
// d += 2.*lpr*lmass*( - 4.*(C12A + C12B) + C0A + C0B );
// e += 4.*lpr*lmass*( 2.*(C11A + C22B) + C1A + C2B);
}
else if(type[i] == PDT::Spin1) {
- Complex B0W(LT::B0(ps2 ,mls,mls));
+ //Complex B0W(LT::B0(ps2 ,mls,mls));
double mr(sqr(p1->mass()/masses[i]));
Complex loop = 2.*lc*( -(6.+mr)*(C12A+C12B) + 4.*(C0A +C0B));
a -= loop;
d += loop;
// a += lc*(-8.*(C0A+C0B) +(6.+mr)*(2.*(C00A+C00B)-B0W)/p1p2);
// b += lc*(6.+mr)*(2.*(C22A+C11B)+C2A+C1B);
// c += 0.5*lc*(6.+mr)*( - 4.*(C12A+C12B) - 2.*(C1A+C2A+C1B+C2B) - C0A - C0B );
// d += 2.*lc*( -(6.+mr)*(C12A+C12B) + 4.*(C0A +C0B));
// e += lc*(6.+mr)*( 2.*(C11A+C22B) + C1A + C2B );
}
else if(type[i] == PDT::Spin0) {
Complex loop = 4.*lc*(C12A+C12B);
a -= loop;
d += loop;
// a += -2.*lc*( 2.*(C00A+C00B) - LT::B0(ps2,mls,mls))/p1p2;
// b += -2.*lc* ( 2.*(C22A + C11B) + C2A + C1B);
// c += -lc*( - 4.*(C12A + C12B) - 2.*(C2A + C1A + C2B + C1B) - C0A - C0B);
// d += 4.*lc*(C12A+C12B);
// e += -lc*( 2.*(C11A + C22B) + C1A + C2B );
}
else {
throw Helicity::HelicityConsistencyError()
<< "SVVLoopVertex::setCoupling - Incorrect particle in SVV loop. "
<< "Spin: " << type[i]
<< Exception::runerror;
}
}
//Looptools defines integrals differently
double fact = 1./16./sqr(Constants::pi);
a00(fact*a);
a11(fact*b);
a12(fact*c);
a21(fact*d);
a22(fact*e);
aEp(fact*f);
}
diff --git a/Models/Susy/SSFFHVertex.h b/Models/Susy/SSFFHVertex.h
--- a/Models/Susy/SSFFHVertex.h
+++ b/Models/Susy/SSFFHVertex.h
@@ -1,171 +1,166 @@
// -*- C++ -*-
//
// SSFFHVertex.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_SSFFHVertex_H
#define HERWIG_SSFFHVertex_H
//
// This is the declaration of the SSFFHVertex class.
//
#include "ThePEG/Helicity/Vertex/Scalar/FFSVertex.h"
#include "MSSM.h"
namespace Herwig {
/**
* The is the coupling of higgs bosons in the MSSM to a pair
* of SM fermions.
*
* @see \ref SSFFHVertexInterfaces "The interfaces"
* defined for SSFFHVertex.
*/
class SSFFHVertex: public FFSVertex {
public:
/**
* The default constructor.
*/
SSFFHVertex();
/** @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();
/**
* Calculate the coupling for the vertex
* @param q2 The scale to at which evaluate the coupling.
* @param particle1 The first particle in the vertex.
* @param particle2 The second particle in the vertex.
* @param particle3 The third particle in the vertex.
*/
virtual void setCoupling(Energy2 q2, tcPDPtr particle1, tcPDPtr particle2,
tcPDPtr particle3);
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const {return new_ptr(*this);}
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const {return new_ptr(*this);}
//@}
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* Initialize this object after the setup phase before saving an
* EventGenerator to disk.
* @throws InitException if object could not be initialized properly.
*/
virtual void doinit();
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
SSFFHVertex & operator=(const SSFFHVertex &) = delete;
private:
/**
* Pointer to the SM object.
*/
tcMSSMPtr theMSSM;
/**
* The value of \f$\tan\beta\f$.
*/
double thetanb;
/**
* The mass of the \f$W\f$.
*/
Energy theMw;
/**
- * The value of \f$\sin\theta_W\f$
- */
- double theSw;
-
- /**
* The value of \f$\sin\alpha\f$
*/
double theSa;
/**
* The value of \f$\sin\beta\f$
*/
double theSb;
/**
* The value of \f$\cos\alpha\f$
*/
double theCa;
/**
* The value of \f$\cos\beta\f$
*/
double theCb;
/**
* The ID of the last fermion for which the vertex was evaluated
*/
pair<long,long> theFLast;
/**
* The value of \f$ \frac{e}{\sin\theta_W} \f$ when it was last evaluated.
*/
double theGlast;
/**
* The scale at which then coupling was last evaluated.
*/
Energy2 theq2last;
/**
* Values of the masses
*/
pair<Energy,Energy> theMassLast;
};
}
#endif /* HERWIG_SSFFHVertex_H */
diff --git a/PDF/HwRemDecayer.cc b/PDF/HwRemDecayer.cc
--- a/PDF/HwRemDecayer.cc
+++ b/PDF/HwRemDecayer.cc
@@ -1,1973 +1,1973 @@
// -*- C++ -*-
//
// HwRemDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the HwRemDecayer class.
//
#include "HwRemDecayer.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Utilities/UtilityBase.h"
#include "ThePEG/Utilities/SimplePhaseSpace.h"
#include "ThePEG/Utilities/Throw.h"
#include "Herwig/Shower/ShowerHandler.h"
using namespace Herwig;
namespace{
const bool dbg = false;
void reShuffle(Lorentz5Momentum &p1, Lorentz5Momentum &p2, Energy m1, Energy m2){
Lorentz5Momentum ptotal(p1+p2);
ptotal.rescaleMass();
if( ptotal.m() < m1+m2 ) {
if(dbg)
cerr << "Not enough energy to perform reshuffling \n";
throw HwRemDecayer::ExtraSoftScatterVeto();
}
Boost boostv = -ptotal.boostVector();
ptotal.boost(boostv);
p1.boost(boostv);
// set the masses and energies,
p1.setMass(m1);
p1.setE(0.5/ptotal.m()*(ptotal.m2()+sqr(m1)-sqr(m2)));
p1.rescaleRho();
// boost back to the lab
p1.boost(-boostv);
p2.boost(boostv);
// set the masses and energies,
p2.setMass(m2);
p2.setE(0.5/ptotal.m()*(ptotal.m2()+sqr(m2)-sqr(m1)));
p2.rescaleRho();
// boost back to the lab
p2.boost(-boostv);
}
}
void HwRemDecayer::initialize(pair<tRemPPtr, tRemPPtr> rems, tPPair beam, Step & step,
Energy forcedSplitScale) {
// the step
thestep = &step;
// valence content of the hadrons
theContent.first = getHadronContent(beam.first);
theContent.second = getHadronContent(beam.second);
// momentum extracted from the hadrons
theUsed.first = Lorentz5Momentum();
theUsed.second = Lorentz5Momentum();
theMaps.first.clear();
theMaps.second.clear();
theX.first = 0.0;
theX.second = 0.0;
theRems = rems;
_forcedSplitScale = forcedSplitScale;
// check remnants attached to the right hadrons
if( (theRems.first && parent(theRems.first ) != beam.first ) ||
(theRems.second && parent(theRems.second) != beam.second) )
throw Exception() << "Remnant order wrong in "
<< "HwRemDecayer::initialize(...)"
<< Exception::runerror;
return;
}
void HwRemDecayer::split(tPPtr parton, HadronContent & content,
tRemPPtr rem, Lorentz5Momentum & used,
PartnerMap &partners, tcPDFPtr pdf, bool first) {
theBeam = parent(rem);
theBeamData = dynamic_ptr_cast<Ptr<BeamParticleData>::const_pointer>
(theBeam->dataPtr());
double currentx = parton->momentum().rho()/theBeam->momentum().rho();
double check = rem==theRems.first ? theX.first : theX.second;
check += currentx;
if(1.0-check < 1e-3) throw ShowerHandler::ExtraScatterVeto();
bool anti;
Lorentz5Momentum lastp(parton->momentum());
int lastID(parton->id());
Energy oldQ(_forcedSplitScale);
_pdf = pdf;
//do nothing if already valence quark
if(first && content.isValenceQuark(parton)) {
//set the extracted value, because otherwise no RemID could be generated.
content.extract(lastID);
// add the particle to the colour partners
partners.push_back(make_pair(parton, tPPtr()));
//set the sign
anti = parton->hasAntiColour() && parton->id()!=ParticleID::g;
if(rem==theRems.first) theanti.first = anti;
else theanti.second = anti;
// add the x and return
if(rem==theRems.first) theX.first += currentx;
else theX.second += currentx;
return;
}
//or gluon for secondaries
else if(!first && lastID == ParticleID::g) {
partners.push_back(make_pair(parton, tPPtr()));
// add the x and return
if(rem==theRems.first) theX.first += currentx;
else theX.second += currentx;
return;
}
// if a sea quark.antiquark forced splitting to a gluon
// Create the new parton with its momentum and parent/child relationship set
PPtr newSea;
if( !(lastID == ParticleID::g ||
lastID == ParticleID::gamma) ) {
newSea = forceSplit(rem, -lastID, oldQ, currentx, lastp, used,content);
ColinePtr cl = new_ptr(ColourLine());
if(newSea->id() > 0) cl-> addColoured(newSea);
else cl->addAntiColoured(newSea);
// if a secondard scatter finished so return
if(!first || content.isValenceQuark(ParticleID::g) ){
partners.push_back(make_pair(parton, newSea));
// add the x and return
if(rem==theRems.first) theX.first += currentx;
else theX.second += currentx;
if(first) content.extract(ParticleID::g);
return;
}
}
// otherwise evolve back to valence
// final valence splitting
PPtr newValence = forceSplit(rem,
lastID!=ParticleID::gamma ?
ParticleID::g : ParticleID::gamma,
oldQ, currentx , lastp, used, content);
// extract from the hadron to allow remnant to be determined
content.extract(newValence->id());
// case of a gluon going into the hard subprocess
if( lastID == ParticleID::g ) {
partners.push_back(make_pair(parton, tPPtr()));
anti = newValence->hasAntiColour();
if(rem==theRems.first) theanti.first = anti;
else theanti.second = anti;
parton->colourLine(!anti)->addColoured(newValence, anti);
return;
}
else if( lastID == ParticleID::gamma) {
partners.push_back(make_pair(parton, newValence));
anti = newValence->hasAntiColour();
ColinePtr newLine(new_ptr(ColourLine()));
newLine->addColoured(newValence, anti);
if(rem==theRems.first) theanti.first = anti;
else theanti.second = anti;
// add the x and return
if(rem==theRems.first) theX.first += currentx;
else theX.second += currentx;
return;
}
//The valence quark will always be connected to the sea quark with opposite sign
tcPPtr particle;
if(lastID*newValence->id() < 0){
particle = parton;
partners.push_back(make_pair(newSea, tPPtr()));
}
else {
particle = newSea;
partners.push_back(make_pair(parton, tPPtr()));
}
anti = newValence->hasAntiColour();
if(rem==theRems.first) theanti.first = anti;
else theanti.second = anti;
if(particle->colourLine())
particle->colourLine()->addAntiColoured(newValence);
if(particle->antiColourLine())
particle->antiColourLine()->addColoured(newValence);
// add the x and return
if(rem==theRems.first) theX.first += currentx;
else theX.second += currentx;
return;
}
void HwRemDecayer::doSplit(pair<tPPtr, tPPtr> partons,
pair<tcPDFPtr, tcPDFPtr> pdfs,
bool first) {
if(theRems.first) {
ParticleVector children=theRems.first->children();
for(unsigned int ix=0;ix<children.size();++ix) {
if(children[ix]->dataPtr()==theRems.first->dataPtr())
theRems.first = dynamic_ptr_cast<RemPPtr>(children[ix]);
}
}
if(theRems.second) {
ParticleVector children=theRems.second->children();
for(unsigned int ix=0;ix<children.size();++ix) {
if(children[ix]->dataPtr()==theRems.second->dataPtr())
theRems.second = dynamic_ptr_cast<RemPPtr>(children[ix]);
}
}
// forced splitting for first parton
if(isPartonic(partons.first )) {
try {
split(partons.first, theContent.first, theRems.first,
theUsed.first, theMaps.first, pdfs.first, first);
}
catch(ShowerHandler::ExtraScatterVeto) {
throw ShowerHandler::ExtraScatterVeto();
}
}
// forced splitting for second parton
if(isPartonic(partons.second)) {
try {
split(partons.second, theContent.second, theRems.second,
theUsed.second, theMaps.second, pdfs.second, first);
// additional check for the remnants
// if can't do the rescale veto the emission
if(!first&&partons.first->data().coloured()&&
partons.second->data().coloured()) {
Lorentz5Momentum pnew[2]=
{theRems.first->momentum() - theUsed.first - partons.first->momentum(),
theRems.second->momentum() - theUsed.second - partons.second->momentum()};
pnew[0].setMass(getParticleData(theContent.first.RemID())->constituentMass());
pnew[0].rescaleEnergy();
pnew[1].setMass(getParticleData(theContent.second.RemID())->constituentMass());
pnew[1].rescaleEnergy();
for(unsigned int iy=0; iy<theRems.first->children().size(); ++iy)
pnew[0] += theRems.first->children()[iy]->momentum();
for(unsigned int iy=0; iy<theRems.second->children().size(); ++iy)
pnew[1] += theRems.second->children()[iy]->momentum();
Lorentz5Momentum ptotal=
theRems.first ->momentum()-partons.first ->momentum()+
theRems.second->momentum()-partons.second->momentum();
// add x limits
if(ptotal.m() < (pnew[0].m() + pnew[1].m()) ) {
if(partons.second->id() != ParticleID::g){
if(partons.second==theMaps.second.back().first)
theUsed.second -= theMaps.second.back().second->momentum();
else
theUsed.second -= theMaps.second.back().first->momentum();
thestep->removeParticle(theMaps.second.back().first);
thestep->removeParticle(theMaps.second.back().second);
}
theMaps.second.pop_back();
theX.second -= partons.second->momentum().rho()/
parent(theRems.second)->momentum().rho();
throw ShowerHandler::ExtraScatterVeto();
}
}
}
catch(ShowerHandler::ExtraScatterVeto){
if(!partons.first||!partons.second||
!theRems.first||!theRems.second)
throw ShowerHandler::ExtraScatterVeto();
//case of the first forcedSplitting worked fine
theX.first -= partons.first->momentum().rho()/
parent(theRems.first)->momentum().rho();
//case of the first interaction
//throw veto immediately, because event get rejected anyway.
if(first) throw ShowerHandler::ExtraScatterVeto();
//secondary interactions have to end on a gluon, if parton
//was NOT a gluon, the forced splitting particles must be removed
if(partons.first->id() != ParticleID::g) {
if(partons.first==theMaps.first.back().first)
theUsed.first -= theMaps.first.back().second->momentum();
else
theUsed.first -= theMaps.first.back().first->momentum();
thestep->removeParticle(theMaps.first.back().first);
thestep->removeParticle(theMaps.first.back().second);
}
theMaps.first.pop_back();
throw ShowerHandler::ExtraScatterVeto();
}
}
// veto if not enough energy for extraction
if( !first &&(theRems.first ->momentum().e() -
partons.first ->momentum().e() < 1.0e-3*MeV ||
theRems.second->momentum().e() -
partons.second->momentum().e() < 1.0e-3*MeV )) {
if(partons.first->id() != ParticleID::g) {
if(partons.first==theMaps.first.back().first)
theUsed.first -= theMaps.first.back().second->momentum();
else
theUsed.first -= theMaps.first.back().first->momentum();
thestep->removeParticle(theMaps.first.back().first);
thestep->removeParticle(theMaps.first.back().second);
}
theMaps.first.pop_back();
if(partons.second->id() != ParticleID::g) {
if(partons.second==theMaps.second.back().first)
theUsed.second -= theMaps.second.back().second->momentum();
else
theUsed.second -= theMaps.second.back().first->momentum();
thestep->removeParticle(theMaps.second.back().first);
thestep->removeParticle(theMaps.second.back().second);
}
theMaps.second.pop_back();
throw ShowerHandler::ExtraScatterVeto();
}
}
void HwRemDecayer::mergeColour(tPPtr pold, tPPtr pnew, bool anti) const {
ColinePtr clnew, clold;
//save the corresponding colour lines
clold = pold->colourLine(anti);
clnew = pnew->colourLine(!anti);
assert(clold);
// There is already a colour line (not the final diquark)
if(clnew){
if( (clnew->coloured().size() + clnew->antiColoured().size()) > 1 ){
if( (clold->coloured().size() + clold->antiColoured().size()) > 1 ){
//join the colour lines
//I don't use the join method, because potentially only (anti)coloured
//particles belong to one colour line
if(clold!=clnew){//procs are not already connected
while ( !clnew->coloured().empty() ) {
tPPtr p = clnew->coloured()[0];
clnew->removeColoured(p);
clold->addColoured(p);
}
while ( !clnew->antiColoured().empty() ) {
tPPtr p = clnew->antiColoured()[0];
clnew->removeAntiColoured(p);
clold->addAntiColoured(p);
}
}
}else{
//if pold is the only member on it's
//colour line, remove it.
clold->removeColoured(pold, anti);
//and add it to clnew
clnew->addColoured(pold, anti);
}
} else{//pnnew is the only member on it's colour line.
clnew->removeColoured(pnew, !anti);
clold->addColoured(pnew, !anti);
}
} else {//there is no coline at all for pnew
clold->addColoured(pnew, !anti);
}
}
void HwRemDecayer::fixColours(PartnerMap partners, bool anti,
double colourDisrupt) const {
PartnerMap::iterator prev;
tPPtr pnew, pold;
assert(partners.size()>=2);
PartnerMap::iterator it=partners.begin();
while(it != partners.end()) {
//skip the first one to have a partner
if(it==partners.begin()){
it++;
continue;
}
prev = it - 1;
//determine the particles to work with
pold = prev->first;
if(prev->second) {
if(!pold->coloured())
pold = prev->second;
else if(pold->hasAntiColour() != anti)
pold = prev->second;
}
assert(pold);
pnew = it->first;
if(it->second) {
if(it->second->colourLine(!anti)) //look for the opposite colour
pnew = it->second;
}
assert(pnew);
// Implement the disruption of colour connections
if( it != partners.end()-1 ) {//last one is diquark-has to be connected
//has to be inside the if statement, so that the probability is
//correctly counted:
if( UseRandom::rnd() < colourDisrupt ){
if(!it->second){//check, whether we have a gluon
mergeColour(pnew, pnew, anti);
}else{
if(pnew==it->first)//be careful about the order
mergeColour(it->second, it->first, anti);
else
mergeColour(it->first, it->second, anti);
}
it = partners.erase(it);
continue;
}
}
// regular merging
mergeColour(pold, pnew, anti);
//end of loop
it++;
}
return;
}
PPtr HwRemDecayer::forceSplit(const tRemPPtr rem, long child, Energy &lastQ,
double &lastx, Lorentz5Momentum &pf,
Lorentz5Momentum &p,
HadronContent & content) const {
static const double eps=1e-6;
// beam momentum
Lorentz5Momentum beam = theBeam->momentum();
// the last scale is minimum of last value and upper limit
Energy minQ=_range*_kinCutoff*sqrt(lastx)/(1-lastx);
if(minQ>lastQ) lastQ=minQ;
// generate the new value of qtilde
// weighted towards the lower value: dP/dQ = 1/Q -> Q(R) =
// Q0 (Qmax/Q0)^R
Energy q;
unsigned int ntry=0,maxtry=100;
double xExtracted = rem==theRems.first ? theX.first : theX.second;
double zmin= lastx/(1.-xExtracted) ,zmax,yy;
if(1-lastx<eps) throw ShowerHandler::ExtraScatterVeto();
do {
q = minQ*pow(lastQ/minQ,UseRandom::rnd());
yy = 1.+0.5*sqr(_kinCutoff/q);
zmax = yy - sqrt(sqr(yy)-1.);
++ntry;
}
while(zmax<zmin&&ntry<maxtry);
if(ntry==maxtry) throw ShowerHandler::ExtraScatterVeto();
if(zmax-zmin<eps) throw ShowerHandler::ExtraScatterVeto();
// now generate z as in FORTRAN HERWIG
// use y = ln(z/(1-z)) as integration variable
double ymin=log(zmin/(1.-zmin));
double ymax=log(zmax/(1.-zmax));
double dely=ymax-ymin;
unsigned int nz=_nbinmax;
dely/=nz;
yy=ymin+0.5*dely;
vector<int> ids;
if(child==21||child==22) {
ids=content.flav;
for(unsigned int ix=0;ix<ids.size();++ix) ids[ix] *= content.sign;
}
else {
ids.push_back(ParticleID::g);
}
// probabilities of the different types of possible splitting
map<long,pair<double,vector<double> > > partonprob;
double ptotal(0.);
for(unsigned int iflav=0;iflav<ids.size();++iflav) {
// only do each parton once
if(partonprob.find(ids[iflav])!=partonprob.end()) continue;
// particle data object
tcPDPtr in = getParticleData(ids[iflav]);
double psum(0.);
vector<double> prob;
for(unsigned int iz=0;iz<nz;++iz) {
double ez=exp(yy);
double wr=1.+ez;
double zr=wr/ez;
double wz=1./wr;
double zz=wz*ez;
double coup = child!=22 ?
_alphaS ->value(sqr(max(wz*q,_kinCutoff))) :
_alphaEM->value(sqr(max(wz*q,_kinCutoff)));
double az=wz*zz*coup;
// g -> q qbar
if(ids[iflav]==ParticleID::g) {
// calculate splitting function
// SP as q is always less than forcedSplitScale, the pdf scale is fixed
// pdfval = _pdf->xfx(theBeamData,in,sqr(q),lastx*zr);
double pdfval=_pdf->xfx(theBeamData,in,sqr(_forcedSplitScale),lastx*zr);
if(pdfval>0.) psum += pdfval*az*0.5*(sqr(zz)+sqr(wz));
}
// q -> q g
else {
// calculate splitting function
// SP as q is always less than forcedSplitScale, the pdf scale is fixed
// pdfval = _pdf->xfx(theBeamData,in,sqr(q),lastx*zr);
double pdfval=_pdf->xfx(theBeamData,in,sqr(_forcedSplitScale),lastx*zr);
if(pdfval>0.) psum += pdfval*az*4./3.*(1.+sqr(wz))*zr;
}
if(psum>0.) prob.push_back(psum);
yy+=dely;
}
if(psum>0.) partonprob[ids[iflav]] = make_pair(psum,prob);
ptotal+=psum;
}
// select the flavour
if(ptotal==0.) throw ShowerHandler::ExtraScatterVeto();
ptotal *= UseRandom::rnd();
map<long,pair<double,vector<double> > >::const_iterator pit;
for(pit=partonprob.begin();pit!=partonprob.end();++pit) {
if(pit->second.first>=ptotal) break;
else ptotal -= pit->second.first;
}
if(pit==partonprob.end())
throw Exception() << "Can't select parton for forced backward evolution in "
<< "HwRemDecayer::forceSplit" << Exception::eventerror;
// select z
unsigned int iz=0;
for(;iz<pit->second.second.size();++iz) {
if(pit->second.second[iz]>ptotal) break;
}
if(iz==pit->second.second.size()) --iz;
double ey=exp(ymin+dely*(float(iz+1)-UseRandom::rnd()));
double z=ey/(1.+ey);
Energy2 pt2=sqr((1.-z)*q)- z*sqr(_kinCutoff);
// create the particle
if(pit->first!=ParticleID::g) child=pit->first;
PPtr parton = getParticleData(child)->produceParticle();
Energy2 emittedm2 = sqr(parton->dataPtr()->constituentMass());
// Now boost pcm and pf to z only frame
Lorentz5Momentum p_ref = Lorentz5Momentum(ZERO, beam.vect());
Lorentz5Momentum n_ref = Lorentz5Momentum(ZERO, -beam.vect());
// generate phi and compute pt of branching
double phi = Constants::twopi*UseRandom::rnd();
Energy pt=sqrt(pt2);
Lorentz5Momentum qt = LorentzMomentum(pt*cos(phi), pt*sin(phi), ZERO, ZERO);
Axis axis(p_ref.vect().unit());
if(axis.perp2()>0.) {
LorentzRotation rot;
double sinth(sqrt(sqr(axis.x())+sqr(axis.y())));
rot.setRotate(acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.));
qt.transform(rot);
}
// compute alpha for previous particle
Energy2 p_dot_n = p_ref*n_ref;
double lastalpha = pf*n_ref/p_dot_n;
Lorentz5Momentum qtout=qt;
Energy2 qtout2=-qt*qt;
double alphaout=(1.-z)/z*lastalpha;
double betaout=0.5*(emittedm2+qtout2)/alphaout/p_dot_n;
Lorentz5Momentum k=alphaout*p_ref+betaout*n_ref+qtout;
k.rescaleMass();
parton->set5Momentum(k);
pf+=k;
lastQ=q;
lastx/=z;
p += parton->momentum();
thestep->addDecayProduct(rem,parton,false);
return parton;
}
void HwRemDecayer::setRemMasses() const {
// get the masses of the remnants
Energy mrem[2];
Lorentz5Momentum ptotal,pnew[2];
vector<tRemPPtr> theprocessed;
theprocessed.push_back(theRems.first);
theprocessed.push_back(theRems.second);
// one remnant in e.g. DIS
if(!theprocessed[0]||!theprocessed[1]) {
tRemPPtr rem = theprocessed[0] ? theprocessed[0] : theprocessed[1];
Lorentz5Momentum deltap(rem->momentum());
// find the diquark and momentum we still need in the energy
tPPtr diquark;
vector<PPtr> progenitors;
for(unsigned int ix=0;ix<rem->children().size();++ix) {
if(!DiquarkMatcher::Check(rem->children()[ix]->data())) {
progenitors.push_back(rem->children()[ix]);
deltap -= rem->children()[ix]->momentum();
}
else
diquark = rem->children()[ix];
}
// now find the total momentum of the hadronic final-state to
// reshuffle against
// find the hadron for this remnant
tPPtr hadron=rem;
do hadron=hadron->parents()[0];
while(!hadron->parents().empty());
// find incoming parton to hard process from this hadron
tPPtr hardin =
generator()->currentEvent()->primaryCollision()->incoming().first==hadron ?
generator()->currentEvent()->primarySubProcess()->incoming().first :
generator()->currentEvent()->primarySubProcess()->incoming().second;
tPPtr parent=hardin;
vector<PPtr> tempprog;
// find the outgoing particles emitted from the backward shower
do {
assert(!parent->parents().empty());
tPPtr newparent=parent->parents()[0];
if(newparent==hadron) break;
for(unsigned int ix=0;ix<newparent->children().size();++ix) {
if(newparent->children()[ix]!=parent)
findChildren(newparent->children()[ix],tempprog);
}
parent=newparent;
}
while(parent!=hadron);
// add to list of potential particles to reshuffle against in right order
for(unsigned int ix=tempprog.size();ix>0;--ix) progenitors.push_back(tempprog[ix-1]);
// final-state particles which are colour connected
tColinePair lines = make_pair(hardin->colourLine(),hardin->antiColourLine());
vector<PPtr> others;
for(ParticleVector::const_iterator
cit = generator()->currentEvent()->primarySubProcess()->outgoing().begin();
cit!= generator()->currentEvent()->primarySubProcess()->outgoing().end();++cit) {
// colour connected
if(lines.first&&lines.first==(**cit).colourLine()) {
findChildren(*cit,progenitors);
continue;
}
// anticolour connected
if(lines.second&&lines.second==(**cit).antiColourLine()) {
findChildren(*cit,progenitors);
continue;
}
// not connected
for(unsigned int ix=0;ix<(**cit).children().size();++ix)
others.push_back((**cit).children()[ix]);
}
// work out how much of the system needed for rescaling
unsigned int iloc=0;
Lorentz5Momentum psystem,ptotal;
do {
psystem+=progenitors[iloc]->momentum();
ptotal = psystem + deltap;
ptotal.rescaleMass();
psystem.rescaleMass();
++iloc;
if(ptotal.mass() > psystem.mass() + diquark->mass() &&
psystem.mass()>1*MeV && DISRemnantOpt_<2 && ptotal.e() > 0.*GeV ) break;
}
while(iloc<progenitors.size());
if(ptotal.mass() > psystem.mass() + diquark->mass()) --iloc;
if(iloc==progenitors.size()) {
// try touching the lepton in dis as a last restort
for(unsigned int ix=0;ix<others.size();++ix) {
progenitors.push_back(others[ix]);
psystem+=progenitors[iloc]->momentum();
ptotal = psystem + deltap;
ptotal.rescaleMass();
psystem.rescaleMass();
++iloc;
}
--iloc;
if(ptotal.mass() > psystem.mass() + diquark->mass()) {
if(DISRemnantOpt_==0||DISRemnantOpt_==2)
Throw<Exception>() << "Warning had to adjust the momentum of the"
<< " non-colour connected"
<< " final-state, e.g. the scattered lepton in DIS"
<< Exception::warning;
else
throw Exception() << "Can't set remnant momentum without adjusting "
<< "the momentum of the"
<< " non-colour connected"
<< " final-state, e.g. the scattered lepton in DIS"
<< " vetoing event"
<< Exception::eventerror;
}
else {
throw Exception() << "Can't put the remnant on-shell in HwRemDecayer::setRemMasses()"
<< Exception::eventerror;
}
}
psystem.rescaleMass();
LorentzRotation R = Utilities::getBoostToCM(make_pair(psystem, deltap));
Energy pz = SimplePhaseSpace::getMagnitude(sqr(ptotal.mass()),
psystem.mass(), diquark->mass());
LorentzRotation Rs(-(R*psystem).boostVector());
Rs.boost(0.0, 0.0, pz/sqrt(sqr(pz) + sqr(psystem.mass())));
Rs = Rs*R;
// put remnant on shell
deltap.transform(R);
deltap.setMass(diquark->mass());
deltap.setE(sqrt(sqr(diquark->mass())+sqr(pz)));
deltap.rescaleRho();
R.invert();
deltap.transform(R);
Rs = R*Rs;
// apply transformation to required particles to absorb recoil
for(unsigned int ix=0;ix<=iloc;++ix) {
progenitors[ix]->deepTransform(Rs);
}
diquark->set5Momentum(deltap);
}
// two remnants
else {
for(unsigned int ix=0;ix<2;++ix) {
if(!theprocessed[ix]) continue;
pnew[ix]=Lorentz5Momentum();
for(unsigned int iy=0;iy<theprocessed[ix]->children().size();++iy) {
pnew[ix]+=theprocessed[ix]->children()[iy]->momentum();
}
mrem[ix]=sqrt(pnew[ix].m2());
}
// now find the remnant remnant cmf frame
Lorentz5Momentum prem[2]={theprocessed[0]->momentum(),
theprocessed[1]->momentum()};
ptotal=prem[0]+prem[1];
ptotal.rescaleMass();
// boost momenta to this frame
if(ptotal.m()< (pnew[0].m()+pnew[1].m()))
throw Exception() << "Not enough energy in both remnants in "
<< "HwRemDecayer::setRemMasses() "
<< Exception::eventerror;
Boost boostv(-ptotal.boostVector());
ptotal.boost(boostv);
for(unsigned int ix=0;ix<2;++ix) {
prem[ix].boost(boostv);
// set the masses and energies,
prem[ix].setMass(mrem[ix]);
prem[ix].setE(0.5/ptotal.m()*(sqr(ptotal.m())+sqr(mrem[ix])-sqr(mrem[1-ix])));
prem[ix].rescaleRho();
// boost back to the lab
prem[ix].boost(-boostv);
// set the momenta of the remnants
theprocessed[ix]->set5Momentum(prem[ix]);
}
// boost the decay products
Lorentz5Momentum ptemp;
for(unsigned int ix=0;ix<2;++ix) {
Boost btorest(-pnew[ix].boostVector());
Boost bfmrest( prem[ix].boostVector());
for(unsigned int iy=0;iy<theprocessed[ix]->children().size();++iy) {
ptemp=theprocessed[ix]->children()[iy]->momentum();
ptemp.boost(btorest);
ptemp.boost(bfmrest);
theprocessed[ix]->children()[iy]->set5Momentum(ptemp);
}
}
}
}
void HwRemDecayer::initSoftInteractions(Energy ptmin, InvEnergy2 beta){
ptmin_ = ptmin;
beta_ = beta;
}
Energy HwRemDecayer::softPt() const {
Energy2 pt2(ZERO);
double xmin(0.0), xmax(1.0), x(0);
if(beta_ == ZERO){
return UseRandom::rnd(0.0,(double)(ptmin_/GeV))*GeV;
}
if(beta_ < ZERO){
xmin = 1.0;
xmax = exp( -beta_*sqr(ptmin_) );
}else{
xmin = exp( -beta_*sqr(ptmin_) );
xmax = 1.0;
}
x = UseRandom::rnd(xmin, xmax);
pt2 = 1.0/beta_ * log(1/x);
if( pt2 < ZERO || pt2 > sqr(ptmin_) )
throw Exception() << "HwRemDecayer::softPt generation of pt "
<< "outside allowed range [0," << ptmin_/GeV << "]."
<< Exception::runerror;
//ofstream myfile2("softPt.txt", ios::app );
//myfile2 << pt2/GeV2 <<" "<<sqrt(pt2)/GeV<< endl;
//myfile2.close();
return sqrt(pt2);
}
void HwRemDecayer::softKinematics(Lorentz5Momentum &r1, Lorentz5Momentum &r2,
Lorentz5Momentum &g1, Lorentz5Momentum &g2) const {
g1 = Lorentz5Momentum();
g2 = Lorentz5Momentum();
//All necessary variables for the two soft gluons
Energy pt(softPt()), pz(ZERO);
Energy2 pz2(ZERO);
double phi(UseRandom::rnd(2.*Constants::pi));
double x_g1(0.0), x_g2(0.0);
//Get the external momenta
tcPPair beam(generator()->currentEventHandler()->currentCollision()->incoming());
Lorentz5Momentum P1(beam.first->momentum()), P2(beam.second->momentum());
if(dbg){
cerr << "new event --------------------\n"
<< *(beam.first) << *(softRems_.first)
<< "-------------------\n"
<< *(beam.second) << *(softRems_.second) << endl;
}
//parton mass
Energy mp;
if(quarkPair_){
mp = getParticleData(ParticleID::u)->constituentMass();
}else{
mp = mg_;
}
//Get x_g1 and x_g2
//first limits
double xmin = sqr(ptmin_)/4.0/(P1+P2).m2();
double x1max = (r1.e()+abs(r1.z()))/(P1.e() + abs(P1.z()));
double x2max = (r2.e()+abs(r2.z()))/(P2.e() + abs(P2.z()));
double x1;
if(!multiPeriph_){
//now generate according to 1/x
x_g1 = xmin * exp(UseRandom::rnd(log(x1max/xmin)));
x_g2 = xmin * exp(UseRandom::rnd(log(x2max/xmin)));
}else{
if(valOfN_==0) return;
double param = (1/(2*valOfN_+1))*initTotRap_;
do{
// need 1-x instead of x to get the proper final momenta
x1 = UseRandom::rndGauss(gaussWidth_, 1 - (exp(param)-1)/exp(param));
}while(x1 < 0 || x1>=1.0);
x_g1 = x1max*x1;
x_g2 = x2max*x1;
}
if(dbg)
cerr << x1max << " " << x_g1 << endl << x2max << " " << x_g2 << endl;
Lorentz5Momentum ig1, ig2, cmf;
ig1 = x_g1*P1;
ig2 = x_g2*P2;
ig1.setMass(mp);
ig2.setMass(mp);
ig1.rescaleEnergy();
ig2.rescaleEnergy();
cmf = ig1 + ig2;
//boost vector from cmf to lab
Boost boostv(cmf.boostVector());
//outgoing gluons in cmf
g1.setMass(mp);
g2.setMass(mp);
g1.setX(pt*cos(phi));
g2.setX(-pt*cos(phi));
g1.setY(pt*sin(phi));
g2.setY(-pt*sin(phi));
pz2 = cmf.m2()/4 - sqr(mp) - (pt*pt);
if( pz2/GeV2 < 0.0 ){
if(dbg)
cerr << "EXCEPTION not enough energy...." << endl;
throw ExtraSoftScatterVeto();
}
if(!multiPeriph_){
if(UseRandom::rndbool()){
pz = sqrt(pz2);
}else
pz = -sqrt(pz2);
}else{
pz = pz2 > ZERO ? sqrt(pz2) : ZERO;
}
if(dbg)
cerr << "pz1 has been calculated to: " << pz/GeV << endl;
g1.setZ(pz);
g2.setZ(-pz);
g1.rescaleEnergy();
g2.rescaleEnergy();
if(dbg){
cerr << "check inv mass in cmf frame: " << (g1+g2).m()/GeV
<< " vs. lab frame: " << (ig1+ig2).m()/GeV << endl;
}
g1.boost(boostv);
g2.boost(boostv);
//recalc the remnant momenta
Lorentz5Momentum r1old(r1), r2old(r2);
r1 -= g1;
r2 -= g2;
try{
reShuffle(r1, r2, r1old.m(), r2old.m());
}catch(ExtraSoftScatterVeto){
r1 = r1old;
r2 = r2old;
throw ExtraSoftScatterVeto();
}
if(dbg){
cerr << "remnant 1,2 momenta: " << r1/GeV << "--" << r2/GeV << endl;
cerr << "remnant 1,2 masses: " << r1.m()/GeV << " " << r2.m()/GeV << endl;
cerr << "check momenta in the lab..." << (-r1old-r2old+r1+r2+g1+g2)/GeV << endl;
}
}
void HwRemDecayer::doSoftInteractions_old(unsigned int N) {
if(N == 0) return;
if(!softRems_.first || !softRems_.second)
throw Exception() << "HwRemDecayer::doSoftInteractions: no "
<< "Remnants available."
<< Exception::runerror;
if( ptmin_ == -1.*GeV )
throw Exception() << "HwRemDecayer::doSoftInteractions: init "
<< "code has not been called! call initSoftInteractions."
<< Exception::runerror;
Lorentz5Momentum g1, g2;
Lorentz5Momentum r1(softRems_.first->momentum()), r2(softRems_.second->momentum());
unsigned int tries(1), i(0);
for(i=0; i<N; i++){
//check how often this scattering has been regenerated
if(tries > maxtrySoft_) break;
if(dbg){
cerr << "new try \n" << *softRems_.first << *softRems_.second << endl;
}
try{
softKinematics(r1, r2, g1, g2);
}catch(ExtraSoftScatterVeto){
tries++;
i--;
continue;
}
PPair oldrems = softRems_;
PPair gluons = make_pair(addParticle(softRems_.first, ParticleID::g, g1),
addParticle(softRems_.second, ParticleID::g, g2));
//now reset the remnants with the new ones
softRems_.first = addParticle(softRems_.first, softRems_.first->id(), r1);
softRems_.second = addParticle(softRems_.second, softRems_.second->id(), r2);
//do the colour connections
pair<bool, bool> anti = make_pair(oldrems.first->hasAntiColour(),
oldrems.second->hasAntiColour());
ColinePtr cl1 = new_ptr(ColourLine());
ColinePtr cl2 = new_ptr(ColourLine());
// case 2:
oldrems.first->colourLine(anti.first)
->addColoured(gluons.second,anti.second);
cl2->addColoured(softRems_.first, anti.second);
cl2->addColoured(gluons.second, !anti.second);
oldrems.first->colourLine(anti.first)
->addColoured(gluons.second,anti.second);
oldrems.second->colourLine(anti.second)
->addColoured(gluons.first,anti.first);
cl1->addColoured(softRems_.second, anti.first);
cl1->addColoured(gluons.first, !anti.first);
cl2->addColoured(softRems_.first, anti.second);
cl2->addColoured(gluons.second, !anti.second);
//reset counter
tries = 1;
}
if(dbg)
cerr << "generated " << i << "th soft scatters\n";
}
// Solve the reshuffling equation to rescale the remnant momenta
double bisectReshuffling(const vector<PPtr>& particles,
Energy w,
double target = -16., double maxLevel = 80.) {
double level = 0;
double left = 0;
double right = 1;
double check = -1.;
double xi = -1;
while ( level < maxLevel ) {
xi = (left+right)*pow(0.5,level+1.);
check = 0.;
for (vector<PPtr>::const_iterator p = particles.begin(); p != particles.end(); ++p){
check += sqrt(sqr(xi)*((*p)->momentum().vect().mag2())+sqr((*p)->mass()))/w;
}
if ( check==1. || log10(abs(1.-check)) <= target )
break;
left *= 2.;
right *= 2.;
if ( check >= 1. ) {
right -= 1.;
++level;
}
if ( check < 1. ) {
left += 1.;
++level;
}
}
return xi;
}
LorentzRotation HwRemDecayer::rotate(const LorentzMomentum &p) const {
LorentzRotation R;
static const double ptcut = 1e-20;
Energy2 pt2 = sqr(p.x())+sqr(p.y());
Energy2 pp2 = sqr(p.z())+pt2;
double phi, theta;
if(pt2 <= pp2*ptcut) {
if(p.z() > ZERO) theta = 0.;
else theta = Constants::pi;
phi = 0.;
} else {
Energy pp = sqrt(pp2);
Energy pt = sqrt(pt2);
double ct = p.z()/pp;
double cf = p.x()/pt;
phi = -acos(cf);
theta = acos(ct);
}
// Rotate first around the z axis to put p in the x-z plane
// Then rotate around the Y axis to put p on the z axis
R.rotateZ(phi).rotateY(theta);
return R;
}
struct vectorSort{
bool operator() (Lorentz5Momentum i,Lorentz5Momentum j) {return(i.rapidity() < j.rapidity());}
} ySort;
void HwRemDecayer::doSoftInteractions_multiPeriph(unsigned int N) {
if(N == 0) return;
int Nmpi = N;
for(int j=0;j<Nmpi;j++){
///////////////////////
// TODO: parametrization of the ladder multiplicity (need to tune to 900GeV, 7Tev and 13Tev)
// Parameterize the ladder multiplicity to: ladderMult_ = A_0 * (s/1TeV^2)^alpha
// with the two tunable parameters A_0 =ladderNorm_ and alpha = ladderPower_
// Get the collision energy
- Energy energy(generator()->maximumCMEnergy());
+ //Energy energy(generator()->maximumCMEnergy());
//double reference = sqr(energy/TeV);
// double ladderMult_;
// Parametrization of the ladder multiplicity
// ladderMult_ = ladderNorm_ * pow( ( reference ) , ladderPower_ );
double avgN = 2.*ladderMult_*log((softRems_.first->momentum()
+softRems_.second->momentum()).m()/mg_) + ladderbFactor_;
initTotRap_ = abs(softRems_.first->momentum().rapidity())
+abs(softRems_.second->momentum().rapidity());
// Generate the poisson distribution with mean avgN
N=UseRandom::rndPoisson(avgN);
valOfN_=N;
if(N <= 1){
// j--; //TODO: Do we want to make all Nmpi soft MPIs?
// Compare to MaxTryMPI for hard mpis.
continue;
}
if(!softRems_.first || !softRems_.second)
throw Exception() << "HwRemDecayer::doSoftInteractions: no "
<< "Remnants available."
<< Exception::runerror;
if( ptmin_ == -1.*GeV )
throw Exception() << "HwRemDecayer::doSoftInteractions: init "
<< "code has not been called! call initSoftInteractions."
<< Exception::runerror;
// The remnants
PPtr rem1 = softRems_.first;
PPtr rem2 = softRems_.second;
// Vector for the ladder particles
vector<Lorentz5Momentum> ladderMomenta;
// Remnant momenta
Lorentz5Momentum r1(softRems_.first->momentum()), r2(softRems_.second->momentum());
Lorentz5Momentum cm =r1+r2;
// Initialize partons in the ladder
// The toy masses are needed for the correct calculation of the available energy
Lorentz5Momentum sumMomenta;
for(unsigned int i = 0; i < N; i++) {
// choose constituents
Energy newMass = ZERO;
Energy toyMass;
if(i<2){
// u and d have the same mass so its enough to use u
toyMass = getParticleData(ParticleID::u)->constituentMass();
}
else{
toyMass = getParticleData(ParticleID::g)->constituentMass();
}
Lorentz5Momentum cp(ZERO,ZERO,ZERO,newMass,newMass);
// dummy container for the momentum that is used for momentum conservation
Lorentz5Momentum dummy(ZERO,ZERO,ZERO,toyMass,toyMass);
ladderMomenta.push_back(cp);
sumMomenta+=dummy;
}
// Get the beam energy
tcPPair beam(generator()->currentEventHandler()->currentCollision()->incoming());
- Lorentz5Momentum P1(beam.first->momentum()), P2(beam.second->momentum());
+ //Lorentz5Momentum P1(beam.first->momentum()), P2(beam.second->momentum());
// Calculate available energy for the partons
- double x1,x2;
+ double x1;//,x2;
double param = (1./(valOfN_+1.))*initTotRap_;
do{
// Need 1-x instead of x to get the proper final momenta
// TODO: physical to use different x's (see comment below)
x1 = UseRandom::rndGauss( gaussWidth_ , exp(-param) );
// x2 = UseRandom::rndGauss( gaussWidth_ , exp(-param) );
}while(x1 < 0 || x1>=1.0); // x2 < 0 || x2>=1.0);
// Remnants 1 and 2 need to be rescaled later by this amount
Lorentz5Momentum ig1 = x1*r1;
Lorentz5Momentum ig2 = x1*r2; //TODO: x2*r2
// requires boost of Ladder in x1/x2-dependent
// frame.
// The available energy that is used to generate the ladder
// sumMomenta is the the sum of rest masses of the ladder partons
// the available energy goes all into the kinematics
Energy availableEnergy = (ig1+ig2).m() - sumMomenta.m();
// If not enough energy then continue
// The available energy has to be larger then the rest mass of the remnants
if ( availableEnergy < ZERO ) {
// j--; //TODO: Do we want to make all Nmpi soft MPIs?
continue;
}
unsigned int its(0);
// Generate the momenta of the partons in the ladder
if ( !(doPhaseSpaceGenerationGluons(ladderMomenta,availableEnergy,its)) ){
// j--; //TODO: Do we want to make all Nmpi soft MPIs?
continue;
}
// Add gluon mass and rescale
Lorentz5Momentum totalMomPartons;
Lorentz5Momentum totalMassLessPartons;
// Sort the ladder partons according to their rapidity and then choose which ones will be the quarks
sort(ladderMomenta.begin(),ladderMomenta.end(),ySort);
int countPartons=0;
long quarkID=0;
// Choose between up and down quarks
int choice = UseRandom::rnd2(1,1);
switch (choice) {
case 0: quarkID = ParticleID::u; break;
case 1: quarkID = ParticleID::d; break;
}
for (auto &p:ladderMomenta){
totalMomPartons+=p;
// Set the mass of the gluons and the two quarks in the ladder
- if(countPartons==0 || countPartons==(ladderMomenta.size()-1)){
+ if(countPartons==0 || countPartons==int(ladderMomenta.size()-1)){
p.setMass( getParticleData(quarkID)->constituentMass() );
}else{
p.setMass( getParticleData(ParticleID::g)->constituentMass() );
}
p.rescaleEnergy();
countPartons++;
}
// Continue if energy conservation is violated
if ( abs(availableEnergy - totalMomPartons.m()) > 1e-8*GeV){
// j--; //TODO: Do we want to make all Nmpi soft MPIs?
continue;
}
// Boost momenta into CM frame
const Boost boostv(-totalMomPartons.boostVector());
Lorentz5Momentum totalMomentumAfterBoost;
for ( unsigned int i=0; i<ladderMomenta.size(); i++){
ladderMomenta[i].boost(boostv);
totalMomentumAfterBoost +=ladderMomenta[i];
}
const Boost boostvR(-cm.boostVector());
r1.boost(boostvR);
r2.boost(boostvR);
// Remainig energy after generation of soft ladder
Energy remainingEnergy = cm.m() - totalMomentumAfterBoost.m();
// Continue if not enough energy
if(remainingEnergy<ZERO) {
// j--; //TODO: Do we want to make all Nmpi soft MPIs?
continue;
}
vector<PPtr> remnants;
rem1->set5Momentum(r1);
rem2->set5Momentum(r2);
remnants.push_back(rem1);
remnants.push_back(rem2);
vector<PPtr> reshuffledRemnants;
Lorentz5Momentum totalMomentumAll;
// Bisect reshuffling for rescaling of remnants
double xi_remnants = bisectReshuffling(remnants,remainingEnergy);
// Rescale remnants
for ( auto &rems: remnants ) {
Lorentz5Momentum reshuffledMomentum;
reshuffledMomentum = xi_remnants*rems->momentum();
reshuffledMomentum.setMass(getParticleData(softRems_.first->id())->constituentMass());
reshuffledMomentum.rescaleEnergy();
reshuffledMomentum.boost(-boostvR);
rems->set5Momentum(reshuffledMomentum);
totalMomentumAll+=reshuffledMomentum;
}
// Then the other particles
for ( auto &p:ladderMomenta ) {
p.boost(-boostvR);
totalMomentumAll+=p;
}
// sort again
sort(ladderMomenta.begin(),ladderMomenta.end(),ySort);
// Do the colour connections
// Original rems are the ones which are connected to other parts of the event
PPair oldRems_ = softRems_;
pair<bool, bool> anti = make_pair(oldRems_.first->hasAntiColour(),
oldRems_.second->hasAntiColour());
// Replace first remnant
softRems_.first = addParticle(softRems_.first, softRems_.first->id(),
remnants[0]->momentum());
// Connect the old remnant to the new remnant
oldRems_.first->colourLine(anti.first)->addColoured(softRems_.first, anti.first);
// Replace second remnant
softRems_.second = addParticle(softRems_.second, softRems_.second->id(),
remnants[1]->momentum());
// This connects the old remnants to the new remnants
oldRems_.second->colourLine(anti.second)->addColoured(softRems_.second, anti.second);
// Add all partons to the first remnant for the event record
vector<PPtr> partons;
vector<PPtr> quarks;
int count=0;
// Choose the colour connections and position of quark antiquark
// Choose between R1-q-g..g-qbar-R2 or R1-qbar-g...g-q-R2
// (place of quark antiquarks in the ladder)
int quarkPosition = UseRandom::rnd2(1,1);
for (auto &p:ladderMomenta){
if(p.mass()==getParticleData(ParticleID::u)->constituentMass()){
if(count==0){
if(quarkPosition==0){
quarks.push_back(addParticle(softRems_.first, quarkID, p));
count++;
}else{
quarks.push_back(addParticle(softRems_.first, -quarkID, p));
count++;
}
}else{
if(quarkPosition==0){
quarks.push_back(addParticle(softRems_.first, -quarkID, p));
}else{
quarks.push_back(addParticle(softRems_.first, quarkID, p));
}
}
}else{
partons.push_back(addParticle(softRems_.first, ParticleID::g, p));
}
softRems_.first = addParticle(softRems_.first, softRems_.first->id(),
softRems_.first->momentum());
oldRems_.first->colourLine(anti.first)->addColoured(softRems_.first, anti.first);
}
// Need to differenciate between the two quark positions, this defines the
// colour connections to the new remnants and old remnants
if(quarkPosition==0){
// ladder self contained
if(partons.size()==0 && quarks.size()>0){
ColinePtr clq = new_ptr(ColourLine());
clq->addColoured(quarks[0]);
clq->addAntiColoured(quarks[1]);
}
ColinePtr clfirst = new_ptr(ColourLine());
ColinePtr cllast = new_ptr(ColourLine());
if(partons.size()>0){
clfirst->addColoured(quarks[0]);
clfirst->addAntiColoured(partons[0]);
cllast->addAntiColoured(quarks[1]);
cllast->addColoured(partons[partons.size()-1]);
//now the remaining gluons
for (unsigned int i=0; i<partons.size()-1; i++){
ColinePtr cl = new_ptr(ColourLine());
cl->addColoured(partons[i]);
cl->addAntiColoured(partons[i+1]);
}
}
} else {
if(partons.size()==0 && quarks.size()>0){
ColinePtr clq = new_ptr(ColourLine());
clq->addAntiColoured(quarks[0]);
clq->addColoured(quarks[1]);
}
ColinePtr clfirst = new_ptr(ColourLine());
ColinePtr cllast = new_ptr(ColourLine());
if(partons.size()>0){
clfirst->addAntiColoured(quarks[0]);
clfirst->addColoured(partons[0]);
cllast->addColoured(quarks[1]);
cllast->addAntiColoured(partons[partons.size()-1]);
//now the remaining gluons
for (unsigned int i=0; i<partons.size()-1; i++){
ColinePtr cl = new_ptr(ColourLine());
cl->addAntiColoured(partons[i]);
cl->addColoured(partons[i+1]);
}
}
}// end colour connection loop
}// end Nmpi loop
}//end function
// Do the phase space generation here is 1 to 1 the same from UA5 model
bool HwRemDecayer::doPhaseSpaceGenerationGluons(vector<Lorentz5Momentum> &softGluons, Energy CME, unsigned int &its)
const{
// Define the parameters
unsigned int _maxtries = 300;
double alog = log(CME*CME/GeV2);
unsigned int ncl = softGluons.size();
// calculate the slope parameters for the different clusters
// outside loop to save time
vector<Lorentz5Momentum> mom(ncl);
// Sets the slopes depending on the constituent quarks of the cluster
for(unsigned int ix=0;ix<ncl;++ix)
{
mom[ix]=softGluons[ix];
}
// generate the momenta
double eps = 1e-10/double(ncl);
vector<double> xi(ncl);
vector<Energy> tempEnergy(ncl);
Energy sum1(ZERO);
double yy(0.);
// We want to make sure that the first Pt is from the
// desired pt-distribution. If we select the first pt in the
// trial loop we introduce a bias.
Energy firstPt=softPt();
while(its < _maxtries) {
++its;
Energy sumx = ZERO;
Energy sumy = ZERO;
unsigned int iterations(0);
unsigned int _maxtriesNew = 100;
while(iterations < _maxtriesNew) {
iterations++;
Energy sumxIt = ZERO;
Energy sumyIt = ZERO;
bool success=false;
Energy pTmax=ZERO;
for(unsigned int i = 0; i<ncl; ++i) {
// Different options for soft pt sampling
//1) pT1>pT2...pTN
//2) pT1>pT2>..>pTN
//3) flat
//4) y dependent
//5) Frist then flat
int triesPt=0;
Energy pt;
- Energy ptTest;
+ //Energy ptTest;
switch(PtDistribution_) {
case 0: //default softPt()
pt=softPt();
break;
case 1: //pTordered
if(i==0){
pt=softPt();
pTmax=pt;
}else{
do{
pt=softPt();
}while(pt>pTmax);
}
break;
case 2: //strongly pT ordered
if ( i==0 ) {
pt=softPt();
pTmax=pt;
} else {
do {
if ( triesPt==20 ) {
pt=pTmax;
break;
}
pt=softPt();
triesPt++;
} while ( pt>pTmax );
pTmax=pt;
}
break;
case 3: //flat
pt = UseRandom::rnd(0.0,(double)(ptmin_/GeV))*GeV;
break;
case 4: //flat below first pT
if ( i==0 ) {
pt = firstPt;
} else {
pt = firstPt * UseRandom::rnd();
}
break;
case 5: //flat but rising below first pT
if ( i==0 ) {
pt=firstPt;
} else {
pt = firstPt * pow(UseRandom::rnd(),1/2);
}
}
Energy2 ptp = pt*pt;
if(ptp <= ZERO) pt = - sqrt(-ptp);
else pt = sqrt(ptp);
// randomize azimuth
Energy px,py;
//randomize the azimuth, but the last one should cancel all others
if(i<ncl-1){
randAzm(pt,px,py);
// set transverse momentum
mom[i].setX(px);
mom[i].setY(py);
sumxIt += px;
sumyIt += py;
}else{
//calculate azimuth angle s.t
// double factor;
Energy pTdummy;
pTdummy = sqrt(sumxIt*sumxIt+sumyIt*sumyIt);
if( pTdummy < ptmin_ ){
px=-sumxIt;
py=-sumyIt;
mom[i].setX(px);
mom[i].setY(py);
sumxIt+=px;
sumyIt+=py;
sumx = sumxIt;
sumy = sumyIt;
success=true;
}
}
}
if(success){
break;
}
}
sumx /= ncl;
sumy /= ncl;
// find the sum of the transverse mass
Energy sumtm=ZERO;
for(unsigned int ix = 0; ix<ncl; ++ix) {
mom[ix].setX(mom[ix].x()-sumx);
mom[ix].setY(mom[ix].y()-sumy);
Energy2 pt2 = mom[ix].perp2();
// Use the z component of the clusters momentum for temporary storage
mom[ix].setZ(sqrt(pt2+mom[ix].mass2()));
sumtm += mom[ix].z();
}
// if transverse mass greater the CMS try again
if(sumtm > CME) continue;
// randomize the mom vector to get the first and the compensating parton
// at all possible positions:
long (*p_irnd)(long) = UseRandom::irnd;
random_shuffle(mom.begin(),mom.end(),p_irnd);
for(unsigned int i = 0; i<ncl; i++) xi[i] = randUng(0.6,1.0);
// sort into ascending order
sort(xi.begin(), xi.end());
double ximin = xi[0];
double ximax = xi.back()-ximin;
xi[0] = 0.;
for(unsigned int i = ncl-2; i>=1; i--) xi[i+1] = (xi[i]-ximin)/ximax;
xi[1] = 1.;
yy= log(CME*CME/(mom[0].z()*mom[1].z()));
bool suceeded=false;
Energy sum2,sum3,sum4;
for(unsigned int j = 0; j<10; j++) {
sum1 = sum2 = sum3 = sum4 = ZERO;
for(unsigned int i = 0; i<ncl; i++) {
Energy tm = mom[i].z();
double ex = exp(yy*xi[i]);
sum1 += tm*ex;
sum2 += tm/ex;
sum3 += (tm*ex)*xi[i];
sum4 += (tm/ex)*xi[i];
}
double fy = alog-log(sum1*sum2/GeV2);
double dd = (sum3*sum2 - sum1*sum4)/(sum1*sum2);
double dyy = fy/dd;
if(abs(dyy/yy) < eps) {
yy += dyy;
suceeded=true;
break;
}
yy += dyy;
}
if(suceeded){
break;
}
if(its > 100) eps *= 10.;
}
if(its==_maxtries){
return false;
}
// throw Exception() << "Can't generate soft underlying event in "
// << "UA5Handler::generateCylindricalPS"
// << Exception::eventerror;
double zz = log(CME/sum1);
for(unsigned int i = 0; i<ncl; i++) {
Energy tm = mom[i].z();
double E1 = exp(zz + yy*xi[i]);
mom[i].setZ(0.5*tm*(1./E1-E1));
mom[i].setE( 0.5*tm*(1./E1+E1));
softGluons[i]=mom[i];
}
return true;
}
void HwRemDecayer::finalize(double colourDisrupt, unsigned int softInt){
PPair diquarks;
//Do the final Rem->Diquark or Rem->quark "decay"
if(theRems.first) {
diquarks.first = finalSplit(theRems.first, theContent.first.RemID(),
theUsed.first);
theMaps.first.push_back(make_pair(diquarks.first, tPPtr()));
}
if(theRems.second) {
diquarks.second = finalSplit(theRems.second, theContent.second.RemID(),
theUsed.second);
theMaps.second.push_back(make_pair(diquarks.second, tPPtr()));
}
setRemMasses();
if(theRems.first) {
fixColours(theMaps.first, theanti.first, colourDisrupt);
if(theContent.first.hadron->id()==ParticleID::pomeron&&
pomeronStructure_==0) fixColours(theMaps.first, !theanti.first, colourDisrupt);
}
if(theRems.second) {
fixColours(theMaps.second, theanti.second, colourDisrupt);
if(theContent.second.hadron->id()==ParticleID::pomeron&&
pomeronStructure_==0) fixColours(theMaps.second, !theanti.second, colourDisrupt);
}
if( !theRems.first || !theRems.second ) return;
//stop here if we don't have two remnants
softRems_ = diquarks;
doSoftInteractions(softInt);
}
HwRemDecayer::HadronContent
HwRemDecayer::getHadronContent(tcPPtr hadron) const {
HadronContent hc;
hc.hadron = hadron->dataPtr();
long id(hadron->id());
// baryon
if(BaryonMatcher::Check(hadron->data())) {
hc.sign = id < 0? -1: 1;
hc.flav.push_back((id = abs(id)/10)%10);
hc.flav.push_back((id /= 10)%10);
hc.flav.push_back((id /= 10)%10);
hc.extracted = -1;
}
else if(hadron->data().id()==ParticleID::gamma ||
(hadron->data().id()==ParticleID::pomeron && pomeronStructure_==1)) {
hc.sign = 1;
for(int ix=1;ix<6;++ix) {
hc.flav.push_back( ix);
hc.flav.push_back(-ix);
}
}
else if(hadron->data().id()==ParticleID::pomeron ) {
hc.sign = 1;
hc.flav.push_back(ParticleID::g);
hc.flav.push_back(ParticleID::g);
}
else if(hadron->data().id()==ParticleID::reggeon ) {
hc.sign = 1;
for(int ix=1;ix<3;++ix) {
hc.flav.push_back( ix);
hc.flav.push_back(-ix);
}
}
hc.pomeronStructure = pomeronStructure_;
return hc;
}
long HwRemDecayer::HadronContent::RemID() const{
if(extracted == -1)
throw Exception() << "Try to build a Diquark id without "
<< "having extracted something in "
<< "HwRemDecayer::RemID(...)"
<< Exception::runerror;
//the hadron was a meson or photon
if(flav.size()==2) return sign*flav[(extracted+1)%2];
long remId;
int id1(sign*flav[(extracted+1)%3]),
id2(sign*flav[(extracted+2)%3]),
sign(0), spin(0);
if (abs(id1) > abs(id2)) swap(id1, id2);
sign = (id1 < 0) ? -1 : 1; // Needed for the spin 0/1 part
remId = id2*1000+id1*100;
// Now decide if we have spin 0 diquark or spin 1 diquark
if(id1 == id2) spin = 3; // spin 1
else spin = 1; // otherwise spin 0
remId += sign*spin;
return remId;
}
tPPtr HwRemDecayer::addParticle(tcPPtr parent, long id, Lorentz5Momentum p) const {
PPtr newp = new_ptr(Particle(getParticleData(id)));
newp->set5Momentum(p);
// Add the new remnant to the step, but don't do colour connections
thestep->addDecayProduct(parent,newp,false);
return newp;
}
void HwRemDecayer::findChildren(tPPtr part,vector<PPtr> & particles) const {
if(part->children().empty()) particles.push_back(part);
else {
for(unsigned int ix=0;ix<part->children().size();++ix)
findChildren(part->children()[ix],particles);
}
}
ParticleVector HwRemDecayer::decay(const DecayMode &,
const Particle &, Step &) const {
throw Exception() << "HwRemDecayer::decay(...) "
<< "must not be called explicitely."
<< Exception::runerror;
}
void HwRemDecayer::persistentOutput(PersistentOStream & os) const {
os << ounit(_kinCutoff, GeV) << _range << _zbin << _ybin
<< _nbinmax << _alphaS << _alphaEM << DISRemnantOpt_
<< maxtrySoft_ << colourDisrupt_ << ladderPower_<< ladderNorm_ << ladderMult_ << ladderbFactor_ << pomeronStructure_
<< ounit(mg_,GeV) << ounit(ptmin_,GeV) << ounit(beta_,sqr(InvGeV))
<< allowTop_ << multiPeriph_ << valOfN_ << initTotRap_ << PtDistribution_;
}
void HwRemDecayer::persistentInput(PersistentIStream & is, int) {
is >> iunit(_kinCutoff, GeV) >> _range >> _zbin >> _ybin
>> _nbinmax >> _alphaS >> _alphaEM >> DISRemnantOpt_
>> maxtrySoft_ >> colourDisrupt_ >> ladderPower_ >> ladderNorm_ >> ladderMult_ >> ladderbFactor_ >> pomeronStructure_
>> iunit(mg_,GeV) >> iunit(ptmin_,GeV) >> iunit(beta_,sqr(InvGeV))
>> allowTop_ >> multiPeriph_ >> valOfN_ >> initTotRap_ >> PtDistribution_;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<HwRemDecayer,RemnantDecayer>
describeHerwigHwRemDecayer("Herwig::HwRemDecayer", "HwShower.so");
void HwRemDecayer::Init() {
static ClassDocumentation<HwRemDecayer> documentation
("The HwRemDecayer class decays the remnant for Herwig");
static Parameter<HwRemDecayer,double> interfaceZBinSize
("ZBinSize",
"The size of the vbins in z for the interpolation of the splitting function.",
&HwRemDecayer::_zbin, 0.05, 0.001, 0.1,
false, false, Interface::limited);
static Parameter<HwRemDecayer,int> interfaceMaxBin
("MaxBin",
"Maximum number of z bins",
&HwRemDecayer::_nbinmax, 100, 10, 1000,
false, false, Interface::limited);
static Reference<HwRemDecayer,ShowerAlpha> interfaceAlphaS
("AlphaS",
"Pointer to object to calculate the strong coupling",
&HwRemDecayer::_alphaS, false, false, true, false, false);
static Reference<HwRemDecayer,ShowerAlpha> interfaceAlphaEM
("AlphaEM",
"Pointer to object to calculate the electromagnetic coupling",
&HwRemDecayer::_alphaEM, false, false, true, false, false);
static Parameter<HwRemDecayer,Energy> interfaceKinCutoff
("KinCutoff",
"Parameter kinCutoff used to constrain qtilde",
&HwRemDecayer::_kinCutoff, GeV, 0.75*GeV, 0.5*GeV, 10.0*GeV,
false, false, Interface::limited);
static Parameter<HwRemDecayer,double> interfaceEmissionRange
("EmissionRange",
"Factor above the minimum possible value in which the forced splitting is allowed.",
&HwRemDecayer::_range, 1.1, 1.0, 10.0,
false, false, Interface::limited);
static Switch<HwRemDecayer,unsigned int> interfaceDISRemnantOption
("DISRemnantOption",
"Options for the treatment of the remnant in DIS",
&HwRemDecayer::DISRemnantOpt_, 0, false, false);
static SwitchOption interfaceDISRemnantOptionDefault
(interfaceDISRemnantOption,
"Default",
"Use the minimum number of particles needed to take the recoil"
" and allow the lepton to be used if needed",
0);
static SwitchOption interfaceDISRemnantOptionNoLepton
(interfaceDISRemnantOption,
"NoLepton",
"Use the minimum number of particles needed to take the recoil but"
" veto events where the lepton kinematics would need to be altered",
1);
static SwitchOption interfaceDISRemnantOptionAllParticles
(interfaceDISRemnantOption,
"AllParticles",
"Use all particles in the colour connected system to take the recoil"
" and use the lepton if needed.",
2);
static SwitchOption interfaceDISRemnantOptionAllParticlesNoLepton
(interfaceDISRemnantOption,
"AllParticlesNoLepton",
"Use all the particles in the colour connected system to take the"
" recoil but don't use the lepton.",
3);
static Parameter<HwRemDecayer,unsigned int> interfaceMaxTrySoft
("MaxTrySoft",
"The maximum number of regeneration attempts for an additional soft scattering",
&HwRemDecayer::maxtrySoft_, 10, 0, 100,
false, false, Interface::limited);
static Parameter<HwRemDecayer,double> interfacecolourDisrupt
("colourDisrupt",
"Fraction of connections to additional soft subprocesses, which are colour disrupted.",
&HwRemDecayer::colourDisrupt_,
1.0, 0.0, 1.0,
false, false, Interface::limited);
static Parameter<HwRemDecayer,double> interaceladderPower
("ladderPower",
"The power factor in the ladder parameterization.",
&HwRemDecayer::ladderPower_,
1.0, -5.0, 10.0,
false, false, Interface::limited);
static Parameter<HwRemDecayer,double> interfaceladderNorm
("ladderNorm",
"The normalization factor in the ladder parameterization",
&HwRemDecayer::ladderNorm_,
1.0, 0.0, 10.0,
false, false, Interface::limited);
static Parameter<HwRemDecayer,double> interfaceladderMult
("ladderMult",
"The ladder multiplicity factor ",
&HwRemDecayer::ladderMult_,
1.0, 0.0, 10.0,
false, false, Interface::limited);
static Parameter<HwRemDecayer,double> interfaceladderbFactor
("ladderbFactor",
"The additive factor in the multiperipheral ladder multiplicity.",
&HwRemDecayer::ladderbFactor_,
1.0, 0.0, 10.0,
false, false, Interface::limited);
static Parameter<HwRemDecayer,double> interfacegaussWidth
("gaussWidth",
"The gaussian width of the fluctuation of longitudinal momentum fraction.",
&HwRemDecayer::gaussWidth_,
0.1, 0.0, 1.0,
false, false, Interface::limited);
static Switch<HwRemDecayer,unsigned int> interfacePomeronStructure
("PomeronStructure",
"Option for the treatment of the valance structure of the pomeron",
&HwRemDecayer::pomeronStructure_, 0, false, false);
static SwitchOption interfacePomeronStructureGluon
(interfacePomeronStructure,
"Gluon",
"Assume the pomeron is a two gluon state",
0);
static SwitchOption interfacePomeronStructureQQBar
(interfacePomeronStructure,
"QQBar",
"Assumne the pomeron is q qbar as for the photon,"
" this option is not recommended and is provide for compatiblity with POMWIG",
1);
static Switch<HwRemDecayer,bool> interfaceAllowTop
("AllowTop",
"Allow top quarks in the hadron",
&HwRemDecayer::allowTop_, false, false, false);
static SwitchOption interfaceAllowTopNo
(interfaceAllowTop,
"No",
"Don't allow them",
false);
static SwitchOption interfaceAllowTopYes
(interfaceAllowTop,
"Yes",
"Allow them",
true);
static Switch<HwRemDecayer,bool> interfaceMultiPeriph
("MultiPeriph",
"Use multiperipheral kinematics",
&HwRemDecayer::multiPeriph_, false, false, false);
static SwitchOption interfaceMultiPeriphNo
(interfaceMultiPeriph,
"No",
"Don't use multiperipheral",
false);
static SwitchOption interfaceMultiPeriphYes
(interfaceMultiPeriph,
"Yes",
"Use multiperipheral kinematics",
true);
static Switch<HwRemDecayer,unsigned int> interfacePtDistribution
("PtDistribution",
"Options for different pT generation methods",
&HwRemDecayer::PtDistribution_, 0, false, false);
static SwitchOption interfacePtDistributionDefault
(interfacePtDistribution,
"Default",
"Default generation of pT",
0);
static SwitchOption interfacePtDistributionOrdered
(interfacePtDistribution,
"Ordered",
"Ordered generation of pT,where the first pT is the hardest",
1);
static SwitchOption interfacePtDistributionStronglyOrdered
(interfacePtDistribution,
"StronglyOrdered",
"Strongly ordered generation of pT",
2);
static SwitchOption interfacePtDistributionFlat
(interfacePtDistribution,
"Flat",
"Sample from a flat pT distribution",
3);
static SwitchOption interfacePtDistributionFlatOrdered
(interfacePtDistribution,
"FlatOrdered",
"First pT normal, then flat",
4);
static SwitchOption interfacePtDistributionFlatOrdered2
(interfacePtDistribution,
"FlatOrdered2",
"First pT normal, then flat but steep",
5);
}
bool HwRemDecayer::canHandle(tcPDPtr particle, tcPDPtr parton) const {
if(! (StandardQCDPartonMatcher::Check(*parton) || parton->id()==ParticleID::gamma) ) {
if(abs(parton->id())==ParticleID::t) {
if(!allowTop_)
throw Exception() << "Top is not allow as a parton in the remant handling, please "
<< "use a PDF which does not contain top for the remnant"
<< " handling (preferred) or allow top in the remnant using\n"
<< " set " << fullName() << ":AllowTop Yes\n"
<< Exception::runerror;
}
else
return false;
}
return HadronMatcher::Check(*particle) || particle->id()==ParticleID::gamma
|| particle->id()==ParticleID::pomeron || particle->id()==ParticleID::reggeon;
}
bool HwRemDecayer::isPartonic(tPPtr parton) const {
if(parton->parents().empty()) return false;
tPPtr parent = parton->parents()[0];
bool partonic = false;
for(unsigned int ix=0;ix<parent->children().size();++ix) {
if(dynamic_ptr_cast<tRemPPtr>(parent->children()[ix])) {
partonic = true;
break;
}
}
return partonic;
}
diff --git a/Shower/Dipole/Base/Dipole.cc b/Shower/Dipole/Base/Dipole.cc
--- a/Shower/Dipole/Base/Dipole.cc
+++ b/Shower/Dipole/Base/Dipole.cc
@@ -1,455 +1,455 @@
// -*- C++ -*-
//
// Dipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the Dipole class.
//
#include "Dipole.h"
#include "Herwig/Shower/Dipole/Utility/DipolePartonSplitter.h"
using namespace Herwig;
Dipole::Dipole()
: theParticles(), thePDFs(),
theFractions(1.0,1.0), theIndices(),
theDecaying(false,false),
theOffShell(false,false),
theScales(0.0*GeV,0.0*GeV) {}
Dipole::Dipole(const pair<PPtr,PPtr>& newParticles,
const pair<PDF,PDF>& newPDFs,
pair<double,double> newFractions,
pair<Energy,Energy> newScales)
: theParticles(newParticles),
thePDFs(newPDFs),
theFractions(newFractions), theIndices(),
theDecaying(false,false),
theOffShell(false,false),
theScales(newScales) {
theIndices.first = DipoleIndex(theParticles.first->dataPtr(),
theParticles.second->dataPtr(),
newPDFs.first,newPDFs.second,
theDecaying.first,theDecaying.second,
theOffShell.first,theOffShell.second);
theIndices.second = theIndices.first;
theIndices.second.swap();
}
Dipole::Dipole(const pair<PPtr,PPtr>& newParticles,
const pair<PDF,PDF>& newPDFs,
pair<double,double> newFractions,
pair<bool,bool> decaying,
pair<bool,bool> offShell,
pair<Energy,Energy> newScales)
: theParticles(newParticles),
thePDFs(newPDFs),
theFractions(newFractions), theIndices(),
theDecaying(decaying),
theOffShell(offShell),
theScales(newScales) {
theIndices.first = DipoleIndex(theParticles.first->dataPtr(),
theParticles.second->dataPtr(),
newPDFs.first,newPDFs.second,
theDecaying.first,theDecaying.second,
theOffShell.first,theOffShell.second);
theIndices.second = theIndices.first;
theIndices.second.swap();
}
void Dipole::update() {
theIndices.first = DipoleIndex(theParticles.first->dataPtr(),
theParticles.second->dataPtr(),
thePDFs.first,thePDFs.second,
theDecaying.first,theDecaying.second,
theOffShell.first,theOffShell.second);
theIndices.second = theIndices.first;
theIndices.second.swap();
assert(DipolePartonSplitter::colourConnected(theParticles.first,
theParticles.second));
}
pair<Dipole,Dipole> Dipole::split(DipoleSplittingInfo& dsplit,
bool colourSpectator,
- bool subleadingNc) const {
+ bool ) const {
// check contracts
assert(dsplit.splittingKinematics());
assert(dsplit.emitterData() && dsplit.emissionData() && dsplit.spectatorData());
if ( !colourSpectator ) {
assert(index(dsplit.configuration()) == dsplit.index());
assert(emitterX(dsplit.configuration()) == dsplit.emitterX());
assert(spectatorX(dsplit.configuration()) == dsplit.spectatorX());
} else {
assert(emitterX(dsplit.configuration()) == dsplit.emitterX());
assert(emitterPDF(dsplit.configuration()) == dsplit.index().emitterPDF());
assert((dsplit.configuration().first ?
theParticles.first->dataPtr() :
theParticles.second->dataPtr())
== dsplit.index().emitterData());
}
// generate full kinematics
dsplit.splittingKinematics()->generateKinematics(
emitter(dsplit.configuration())->momentum(),
spectator(dsplit.configuration())->momentum(),
dsplit);
// Treat the case of decay splittings as backward evolution.
// i.e. Put the new emitter and new emission or new spectator
// and new emission respectively into the new dipoles.
bool emitter_decay = dsplit.index().incomingDecayEmitter();
if ( emitter_decay )
assert(false);
bool spectator_decay = dsplit.index().incomingDecaySpectator();
tPPtr oldSpectator = spectator(dsplit.configuration());
PPtr newSpectator;
// get a new spectator
if ( !colourSpectator ) {
newSpectator =
dsplit.spectatorData()->produceParticle(
dsplit.splittingKinematics()->lastSpectatorMomentum());
DipolePartonSplitter::change(oldSpectator,
newSpectator,
spectatorPDF(dsplit.configuration()).pdf(), spectator_decay);
dsplit.spectator(oldSpectator);
dsplit.splitSpectator(newSpectator);
} else {
newSpectator = oldSpectator;
}
// perform the splitting
tPPtr oldEmitter = emitter(dsplit.configuration());
PPtr newEmitter, newEmission;
double z = dsplit.lastZ();
// Do not swap momenta for splittings different from g->gg or
// initial state emitters
bool noSwap = !(dsplit.emitterData()->id() == ParticleID::g
&& dsplit.emissionData()->id() == ParticleID::g )
|| dsplit.index().initialStateEmitter();
if ( noSwap || z > UseRandom::rnd(1.0) ) {
newEmitter =
dsplit.emitterData()->produceParticle(
dsplit.splittingKinematics()->lastEmitterMomentum());
newEmission =
dsplit.emissionData()->produceParticle(
dsplit.splittingKinematics()->lastEmissionMomentum());
} else {
newEmitter =
dsplit.emitterData()->produceParticle(
dsplit.splittingKinematics()->lastEmissionMomentum());
newEmission =
dsplit.emissionData()->produceParticle(
dsplit.splittingKinematics()->lastEmitterMomentum());
}
newEmitter->scale(sqr(dsplit.lastPt()));
newEmission->scale(sqr(dsplit.lastPt()));
newSpectator->scale(oldSpectator->scale());
DipolePartonSplitter::split(oldEmitter,newEmitter,newEmission,
oldSpectator,emitterPDF(dsplit.configuration()).pdf(), emitter_decay);
dsplit.emitter(oldEmitter);
dsplit.splitEmitter(newEmitter);
dsplit.emission(newEmission);
double emitter_x = emitterX(dsplit.configuration()) / dsplit.lastEmitterZ();
double spectator_x = spectatorX(dsplit.configuration()) / dsplit.lastSpectatorZ();
PDF emitter_pdf = emitterPDF(dsplit.configuration());
PDF spectator_pdf = spectatorPDF(dsplit.configuration());
// Communicate off-shell parton flags
// Note that as gluons aren't off-shell, the only possibility
// in qcd splittings is gluon emissions off an off-shell emitter
// -> off-shell emitter => off-shell new emitter
bool emitter_off_shell = dsplit.index().offShellEmitter();
bool spectator_off_shell = dsplit.index().offShellSpectator();
// now check how we need to arrange the children
// assignment is 0 = emitter, 1 = emission, 2 = spectator
int left = 0;
int middle = 1;
int right = 2;
if (dsplit.configuration().first) {
// spectator is unique
right = 2;
// middle is the one connecting to the spectator
if (DipolePartonSplitter::colourConnected(newSpectator,newEmission)) {
middle = 1;
left = 0;
} else {
assert(DipolePartonSplitter::colourConnected(newSpectator,newEmitter));
middle = 0;
left = 1;
}
} else {
// spectator is unique
left = 2;
// middle is the one connecting to the spectator
if (DipolePartonSplitter::colourConnected(newSpectator,newEmission)) {
middle = 1;
right = 0;
} else {
assert(DipolePartonSplitter::colourConnected(newSpectator,newEmitter));
middle = 0;
right = 1;
}
}
pair<PPtr,PPtr> left_particles;
pair<PPtr,PPtr> right_particles;
pair<PDF,PDF> left_pdfs;
pair<PDF,PDF> right_pdfs;
pair<double,double> left_fractions;
pair<double,double> right_fractions;
// Pairs containing indicators for decayed particles
pair<bool,bool> left_decays = {false,false};
pair<bool,bool> right_decays = {false,false};
// Pairs containing indicators for off-shell particles
pair<bool, bool> left_off_shells = {false,false};
pair<bool, bool> right_off_shells = {false,false};
switch (left) {
case 0:
if (emitter_decay) {
assert(false);
left_decays.first = emitter_decay;
}
left_particles.first = newEmitter;
left_pdfs.first = emitter_pdf;
left_fractions.first = emitter_x;
left_off_shells.first = emitter_off_shell;
break;
case 1:
left_particles.first = newEmission;
left_pdfs.first = PDF();
left_fractions.first = 1.;
left_decays.first = false;
left_off_shells.first = false;
break;
case 2:
left_particles.first = newSpectator;
left_pdfs.first = spectator_pdf;
left_fractions.first = spectator_x;
left_decays.first = spectator_decay;
left_off_shells.first = spectator_off_shell;
break;
}
switch (middle) {
case 0:
if (emitter_decay) {
assert(false);
left_decays.second = emitter_decay;
}
left_particles.second = newEmitter;
left_pdfs.second = emitter_pdf;
left_fractions.second = emitter_x;
left_off_shells.second = emitter_off_shell;
break;
case 1:
left_particles.second = newEmission;
left_pdfs.second = PDF();
left_fractions.second = 1.;
left_decays.second = false;
left_off_shells.second = false;
break;
case 2:
left_decays.second = spectator_decay;
left_particles.second = newSpectator;
left_pdfs.second = spectator_pdf;
left_fractions.second = spectator_x;
left_off_shells.second = spectator_off_shell;
break;
}
right_particles.first = left_particles.second;
right_pdfs.first = left_pdfs.second;
right_fractions.first = left_fractions.second;
right_decays.first = left_decays.second;
right_off_shells.first = left_off_shells.second;
switch (right) {
case 0:
if (emitter_decay) {
assert(false);
right_decays.second = emitter_decay;
}
right_particles.second = newEmitter;
right_pdfs.second = emitter_pdf;
right_fractions.second = emitter_x;
right_off_shells.second = emitter_off_shell;
break;
case 1:
right_particles.second = newEmission;
right_pdfs.second = PDF();
right_fractions.second = 1.;
right_decays.second = false;
right_off_shells.second = false;
break;
case 2:
right_particles.second = newSpectator;
right_pdfs.second = spectator_pdf;
right_fractions.second = spectator_x;
right_decays.second = spectator_decay;
right_off_shells.second = spectator_off_shell;
break;
}
Energy scale = dsplit.lastPt();
return { Dipole(left_particles, left_pdfs, left_fractions,
left_decays, left_off_shells, {scale,scale}),
Dipole(right_particles, right_pdfs, right_fractions,
right_decays, right_off_shells, {scale,scale})};
}
void Dipole::tmpsplit(DipoleSplittingInfo& dsplit,
bool colourSpectator) const {
// generate full kinematics
dsplit.splittingKinematics()->generateKinematics(emitter(dsplit.configuration())->momentum(),
spectator(dsplit.configuration())->momentum(),
dsplit);
tPPtr oldSpectator = spectator(dsplit.configuration());
PPtr newSpectator;
// get a new spectator
if ( !colourSpectator ) {
newSpectator =
dsplit.spectatorData()->produceParticle(dsplit.splittingKinematics()->lastSpectatorMomentum());
dsplit.spectator(oldSpectator);
dsplit.splitSpectator(newSpectator);
} else {
newSpectator = oldSpectator;
}
// perform the splitting
tPPtr oldEmitter = emitter(dsplit.configuration());
PPtr newEmitter =
dsplit.emitterData()->produceParticle(dsplit.splittingKinematics()->lastEmitterMomentum());
PPtr newEmission =
dsplit.emissionData()->produceParticle(dsplit.splittingKinematics()->lastEmissionMomentum());
dsplit.emitter(oldEmitter);
dsplit.splitEmitter(newEmitter);
dsplit.emission(newEmission);
}
void Dipole::recoil (DipoleSplittingInfo& dsplit) {
// check contracts
assert(dsplit.splittingKinematics());
assert(dsplit.spectatorData());
assert(spectatorX(dsplit.spectatorConfiguration())
== dsplit.spectatorX());
assert(spectatorPDF(dsplit.spectatorConfiguration())
== dsplit.index().spectatorPDF());
assert((dsplit.spectatorConfiguration().first ?
theParticles.first->dataPtr() :
theParticles.second->dataPtr())
== dsplit.index().spectatorData());
tPPtr oldSpectator = spectator(dsplit.spectatorConfiguration());
PPtr newSpectator =
dsplit.spectatorData()->produceParticle(
dsplit.splittingKinematics()->lastSpectatorMomentum());
DipolePartonSplitter::change(oldSpectator,newSpectator,
spectatorPDF(dsplit.spectatorConfiguration()).pdf());
newSpectator->scale(sqr(dsplit.lastPt()));
dsplit.spectator(oldSpectator);
dsplit.splitSpectator(newSpectator);
if ( dsplit.spectatorConfiguration().first ) {
theParticles.second = newSpectator;
theFractions.second /= dsplit.lastSpectatorZ();
} else {
theParticles.first = newSpectator;
theFractions.first /= dsplit.lastSpectatorZ();
}
}
void Dipole::print(ostream& os) const {
os << "--- ";
// Check for decays first
if ( theDecaying.first || theDecaying.second) {
assert(!(theDecaying.first && theDecaying.second));
if ( theDecaying.first && !theDecaying.second )
os << "Decay IF";
else if ( theDecaying.second && !theDecaying.first )
os << "Decay FI";
}
else if ( !thePDFs.first.pdf() && !thePDFs.second.pdf() )
os << "FF";
else if ( thePDFs.first.pdf() && !thePDFs.second.pdf() )
os << "IF";
else if ( !thePDFs.first.pdf() && thePDFs.second.pdf() )
os << "FI";
else
os << "II";
os << " Dipole ------------------------------------------------------------------\n";
if ( !theParticles.first || !theParticles.second ) {
os << " *** This Dipole has not been setup properly. ***\n";
} else {
os << " particles\n"
<< *theParticles.first
<< *theParticles.second;
os << " scales/GeV = ("
<< (theScales.first/GeV) << ","
<< (theScales.second/GeV) << ") fractions = ("
<< theFractions.first << "," << theFractions.second << ")\n";
}
os << "--------------------------------------------------------------------------------\n";
os << flush;
}
diff --git a/Shower/Dipole/Colorea/HelAmps_sm.cc b/Shower/Dipole/Colorea/HelAmps_sm.cc
--- a/Shower/Dipole/Colorea/HelAmps_sm.cc
+++ b/Shower/Dipole/Colorea/HelAmps_sm.cc
@@ -1,1027 +1,1024 @@
//==========================================================================
// This file has been automatically generated for C++ Standalone by
// MadGraph5_aMC@NLO v. 2.5.4, 2017-03-28
// By the MadGraph5_aMC@NLO Development Team
// Visit launchpad.net/madgraph5 and amcatnlo.web.cern.ch
//==========================================================================
#include "HelAmps_sm.h"
#include <complex>
#include <cmath>
#include <iostream>
#include <cstdlib>
using namespace std;
namespace MG5_sm_COLOREA
{
void ixxxxx(double p[4], double fmass, int nhel, int nsf, complex<double> fi[6])
{
complex<double> chi[2];
double sf[2], sfomega[2], omega[2], pp, pp3, sqp0p3, sqm[2];
int ip, im, nh;
fi[0] = complex<double> (-p[0] * nsf, -p[3] * nsf);
fi[1] = complex<double> (-p[1] * nsf, -p[2] * nsf);
nh = nhel * nsf;
if (fmass != 0.0)
{
pp = min(p[0], sqrt(p[1] * p[1] + p[2] * p[2] + p[3] * p[3]));
if (pp == 0.0)
{
sqm[0] = sqrt(std::abs(fmass));
sqm[1] = Sgn(sqm[0], fmass);
ip = (1 + nh)/2;
im = (1 - nh)/2;
fi[2] = ip * sqm[ip];
fi[3] = im * nsf * sqm[ip];
fi[4] = ip * nsf * sqm[im];
fi[5] = im * sqm[im];
}
else
{
sf[0] = (1 + nsf + (1 - nsf) * nh) * 0.5;
sf[1] = (1 + nsf - (1 - nsf) * nh) * 0.5;
omega[0] = sqrt(p[0] + pp);
omega[1] = fmass/omega[0];
ip = (1 + nh)/2;
im = (1 - nh)/2;
sfomega[0] = sf[0] * omega[ip];
sfomega[1] = sf[1] * omega[im];
pp3 = max(pp + p[3], 0.0);
chi[0] = complex<double> (sqrt(pp3 * 0.5/pp), 0);
if (pp3 == 0.0)
{
chi[1] = complex<double> (-nh, 0);
}
else
{
chi[1] = complex<double> (nh * p[1], p[2])/sqrt(2.0 * pp * pp3);
}
fi[2] = sfomega[0] * chi[im];
fi[3] = sfomega[0] * chi[ip];
fi[4] = sfomega[1] * chi[im];
fi[5] = sfomega[1] * chi[ip];
}
}
else
{
if (p[1] == 0.0 and p[2] == 0.0 and p[3] < 0.0)
{
sqp0p3 = 0.0;
}
else
{
sqp0p3 = sqrt(max(p[0] + p[3], 0.0)) * nsf;
}
chi[0] = complex<double> (sqp0p3, 0.0);
if (sqp0p3 == 0.0)
{
chi[1] = complex<double> (-nhel * sqrt(2.0 * p[0]), 0.0);
}
else
{
chi[1] = complex<double> (nh * p[1], p[2])/sqp0p3;
}
if (nh == 1)
{
fi[2] = complex<double> (0.0, 0.0);
fi[3] = complex<double> (0.0, 0.0);
fi[4] = chi[0];
fi[5] = chi[1];
}
else
{
fi[2] = chi[1];
fi[3] = chi[0];
fi[4] = complex<double> (0.0, 0.0);
fi[5] = complex<double> (0.0, 0.0);
}
}
return;
}
double Sgn(double a, double b)
{
return (b < 0)? - abs(a):abs(a);
}
void txxxxx(double p[4], double tmass, int nhel, int nst, complex<double>
tc[18])
{
complex<double> ft[6][4], ep[4], em[4], e0[4];
double pt, pt2, pp, pzpt, emp, sqh, sqs;
int i, j;
sqh = sqrt(0.5);
sqs = sqrt(0.5/3);
pt2 = p[1] * p[1] + p[2] * p[2];
pp = min(p[0], sqrt(pt2 + p[3] * p[3]));
pt = min(pp, sqrt(pt2));
ft[4][0] = complex<double> (p[0] * nst, p[3] * nst);
ft[5][0] = complex<double> (p[1] * nst, p[2] * nst);
// construct eps+
if(nhel >= 0)
{
if(pp == 0)
{
ep[0] = complex<double> (0, 0);
ep[1] = complex<double> (-sqh, 0);
ep[2] = complex<double> (0, nst * sqh);
ep[3] = complex<double> (0, 0);
}
else
{
ep[0] = complex<double> (0, 0);
ep[3] = complex<double> (pt/pp * sqh, 0);
if(pt != 0)
{
pzpt = p[3]/(pp * pt) * sqh;
ep[1] = complex<double> (-p[1] * pzpt, -nst * p[2]/pt * sqh);
ep[2] = complex<double> (-p[2] * pzpt, nst * p[1]/pt * sqh);
}
else
{
ep[1] = complex<double> (-sqh, 0);
ep[2] = complex<double> (0, nst * Sgn(sqh, p[3]));
}
}
}
// construct eps-
if(nhel <= 0)
{
if(pp == 0)
{
em[0] = complex<double> (0, 0);
em[1] = complex<double> (sqh, 0);
em[2] = complex<double> (0, nst * sqh);
em[3] = complex<double> (0, 0);
}
else
{
em[0] = complex<double> (0, 0);
em[3] = complex<double> (-pt/pp * sqh, 0);
if(pt != 0)
{
pzpt = -p[3]/(pp * pt) * sqh;
em[1] = complex<double> (-p[1] * pzpt, -nst * p[2]/pt * sqh);
em[2] = complex<double> (-p[2] * pzpt, nst * p[1]/pt * sqh);
}
else
{
em[1] = complex<double> (sqh, 0);
em[2] = complex<double> (0, nst * Sgn(sqh, p[3]));
}
}
}
// construct eps0
if(std::labs(nhel) <= 1)
{
if(pp == 0)
{
e0[0] = complex<double> (0, 0);
e0[1] = complex<double> (0, 0);
e0[2] = complex<double> (0, 0);
e0[3] = complex<double> (1, 0);
}
else
{
emp = p[0]/(tmass * pp);
e0[0] = complex<double> (pp/tmass, 0);
e0[3] = complex<double> (p[3] * emp, 0);
if(pt != 0)
{
e0[1] = complex<double> (p[1] * emp, 0);
e0[2] = complex<double> (p[2] * emp, 0);
}
else
{
e0[1] = complex<double> (0, 0);
e0[2] = complex<double> (0, 0);
}
}
}
if(nhel == 2)
{
for(j = 0; j < 4; j++ )
{
for(i = 0; i < 4; i++ )
ft[i][j] = ep[i] * ep[j];
}
}
else if(nhel == -2)
{
for(j = 0; j < 4; j++ )
{
for(i = 0; i < 4; i++ )
ft[i][j] = em[i] * em[j];
}
}
else if(tmass == 0)
{
for(j = 0; j < 4; j++ )
{
for(i = 0; i < 4; i++ )
ft[i][j] = 0;
}
}
else if(tmass != 0)
{
if(nhel == 1)
{
for(j = 0; j < 4; j++ )
{
for(i = 0; i < 4; i++ )
ft[i][j] = sqh * (ep[i] * e0[j] + e0[i] * ep[j]);
}
}
else if(nhel == 0)
{
for(j = 0; j < 4; j++ )
{
for(i = 0; i < 4; i++ )
ft[i][j] = sqs * (ep[i] * em[j] + em[i] * ep[j]
+ 2.0 * e0[i] * e0[j]);
}
}
else if(nhel == -1)
{
for(j = 0; j < 4; j++ )
{
for(i = 0; i < 4; i++ )
ft[i][j] = sqh * (em[i] * e0[j] + e0[i] * em[j]);
}
}
else
{
std::cerr << "Invalid helicity in txxxxx.\n";
std::exit(1);
}
}
tc[0] = ft[4][0];
tc[1] = ft[5][0];
for(j = 0; j < 4; j++ )
{
for(i = 0; i < 4; i++ )
tc[j * 4 + i + 2] = ft[j][i];
}
}
void vxxxxx(double p[4], double vmass, int nhel, int nsv, complex<double> vc[6])
{
double hel, hel0, pt, pt2, pp, pzpt, emp, sqh;
int nsvahl;
sqh = sqrt(0.5);
hel = double(nhel);
nsvahl = nsv * std::abs(hel);
pt2 = (p[1] * p[1]) + (p[2] * p[2]);
pp = min(p[0], sqrt(pt2 + (p[3] * p[3])));
pt = min(pp, sqrt(pt2));
vc[0] = complex<double> (p[0] * nsv, p[3] * nsv);
vc[1] = complex<double> (p[1] * nsv, p[2] * nsv);
if (vmass != 0.0)
{
hel0 = 1.0 - std::abs(hel);
if(pp == 0.0)
{
vc[2] = complex<double> (0.0, 0.0);
vc[3] = complex<double> (-hel * sqh, 0.0);
vc[4] = complex<double> (0.0, nsvahl * sqh);
vc[5] = complex<double> (hel0, 0.0);
}
else
{
emp = p[0]/(vmass * pp);
vc[2] = complex<double> (hel0 * pp/vmass, 0.0);
vc[5] = complex<double> (hel0 * p[3] * emp + hel * pt/pp * sqh, 0.0);
if (pt != 0.0)
{
pzpt = p[3]/(pp * pt) * sqh * hel;
vc[3] = complex<double> (hel0 * p[1] * emp - p[1] * pzpt, -nsvahl *
p[2]/pt * sqh);
vc[4] = complex<double> (hel0 * p[2] * emp - p[2] * pzpt, nsvahl *
p[1]/pt * sqh);
}
else
{
vc[3] = complex<double> (-hel * sqh, 0.0);
vc[4] = complex<double> (0.0, nsvahl * Sgn(sqh, p[3]));
}
}
}
else
{
pp = p[0];
pt = sqrt((p[1] * p[1]) + (p[2] * p[2]));
vc[2] = complex<double> (0.0, 0.0);
vc[5] = complex<double> (hel * pt/pp * sqh, 0.0);
if (pt != 0.0)
{
pzpt = p[3]/(pp * pt) * sqh * hel;
vc[3] = complex<double> (-p[1] * pzpt, -nsv * p[2]/pt * sqh);
vc[4] = complex<double> (-p[2] * pzpt, nsv * p[1]/pt * sqh);
}
else
{
vc[3] = complex<double> (-hel * sqh, 0.0);
vc[4] = complex<double> (0.0, nsv * Sgn(sqh, p[3]));
}
}
return;
}
void sxxxxx(double p[4], int nss, complex<double> sc[3])
{
sc[2] = complex<double> (1.00, 0.00);
sc[0] = complex<double> (p[0] * nss, p[3] * nss);
sc[1] = complex<double> (p[1] * nss, p[2] * nss);
return;
}
void oxxxxx(double p[4], double fmass, int nhel, int nsf, complex<double> fo[6])
{
complex<double> chi[2];
double sf[2], sfomeg[2], omega[2], pp, pp3, sqp0p3, sqm[2];
int nh, ip, im;
fo[0] = complex<double> (p[0] * nsf, p[3] * nsf);
fo[1] = complex<double> (p[1] * nsf, p[2] * nsf);
nh = nhel * nsf;
if (fmass != 0.000)
{
pp = min(p[0], sqrt((p[1] * p[1]) + (p[2] * p[2]) + (p[3] * p[3])));
if (pp == 0.000)
{
sqm[0] = sqrt(std::abs(fmass));
sqm[1] = Sgn(sqm[0], fmass);
ip = -((1 - nh)/2) * nhel;
im = (1 + nh)/2 * nhel;
fo[2] = im * sqm[std::abs(ip)];
fo[3] = ip * nsf * sqm[std::abs(ip)];
fo[4] = im * nsf * sqm[std::abs(im)];
fo[5] = ip * sqm[std::abs(im)];
}
else
{
pp = min(p[0], sqrt((p[1] * p[1]) + (p[2] * p[2]) + (p[3] * p[3])));
sf[0] = double(1 + nsf + (1 - nsf) * nh) * 0.5;
sf[1] = double(1 + nsf - (1 - nsf) * nh) * 0.5;
omega[0] = sqrt(p[0] + pp);
omega[1] = fmass/omega[0];
ip = (1 + nh)/2;
im = (1 - nh)/2;
sfomeg[0] = sf[0] * omega[ip];
sfomeg[1] = sf[1] * omega[im];
pp3 = max(pp + p[3], 0.00);
chi[0] = complex<double> (sqrt(pp3 * 0.5/pp), 0.00);
if (pp3 == 0.00)
{
chi[1] = complex<double> (-nh, 0.00);
}
else
{
chi[1] = complex<double> (nh * p[1], -p[2])/sqrt(2.0 * pp * pp3);
}
fo[2] = sfomeg[1] * chi[im];
fo[3] = sfomeg[1] * chi[ip];
fo[4] = sfomeg[0] * chi[im];
fo[5] = sfomeg[0] * chi[ip];
}
}
else
{
if((p[1] == 0.00) and (p[2] == 0.00) and (p[3] < 0.00))
{
sqp0p3 = 0.00;
}
else
{
sqp0p3 = sqrt(max(p[0] + p[3], 0.00)) * nsf;
}
chi[0] = complex<double> (sqp0p3, 0.00);
if(sqp0p3 == 0.000)
{
chi[1] = complex<double> (-nhel, 0.00) * sqrt(2.0 * p[0]);
}
else
{
chi[1] = complex<double> (nh * p[1], -p[2])/sqp0p3;
}
if(nh == 1)
{
fo[2] = chi[0];
fo[3] = chi[1];
fo[4] = complex<double> (0.00, 0.00);
fo[5] = complex<double> (0.00, 0.00);
}
else
{
fo[2] = complex<double> (0.00, 0.00);
fo[3] = complex<double> (0.00, 0.00);
fo[4] = chi[1];
fo[5] = chi[0];
}
}
return;
}
void FFV1P0_3(std::complex<double> F1[], std::complex<double> F2[],
std::complex<double> COUP, double M3, double W3, std::complex<double> V3[])
{
static std::complex<double> cI = std::complex<double> (0., 1.);
double P3[4];
std::complex<double> denom;
V3[0] = +F1[0] + F2[0];
V3[1] = +F1[1] + F2[1];
P3[0] = -V3[0].real();
P3[1] = -V3[1].real();
P3[2] = -V3[1].imag();
P3[3] = -V3[0].imag();
denom = COUP/((P3[0] * P3[0]) - (P3[1] * P3[1]) - (P3[2] * P3[2]) - (P3[3] *
P3[3]) - M3 * (M3 - cI * W3));
V3[2] = denom * (-cI) * (F1[2] * F2[4] + F1[3] * F2[5] + F1[4] * F2[2] +
F1[5] * F2[3]);
V3[3] = denom * (-cI) * (F1[4] * F2[3] + F1[5] * F2[2] - F1[2] * F2[5] -
F1[3] * F2[4]);
V3[4] = denom * (-cI) * (-cI * (F1[2] * F2[5] + F1[5] * F2[2]) + cI * (F1[3]
* F2[4] + F1[4] * F2[3]));
V3[5] = denom * (-cI) * (F1[3] * F2[5] + F1[4] * F2[2] - F1[2] * F2[4] -
F1[5] * F2[3]);
}
void FFV2_2(std::complex<double> F1[], std::complex<double> V3[],
std::complex<double> COUP, double M2, double W2, std::complex<double> F2[])
{
static std::complex<double> cI = std::complex<double> (0., 1.);
double P2[4];
std::complex<double> denom;
F2[0] = +F1[0] + V3[0];
F2[1] = +F1[1] + V3[1];
P2[0] = -F2[0].real();
P2[1] = -F2[1].real();
P2[2] = -F2[1].imag();
P2[3] = -F2[0].imag();
denom = COUP/((P2[0] * P2[0]) - (P2[1] * P2[1]) - (P2[2] * P2[2]) - (P2[3] *
P2[3]) - M2 * (M2 - cI * W2));
F2[2] = denom * cI * (F1[2] * (P2[0] * (V3[2] + V3[5]) + (P2[1] * (-1.) *
(V3[3] + cI * (V3[4])) + (P2[2] * (+cI * (V3[3]) - V3[4]) - P2[3] *
(V3[2] + V3[5])))) + F1[3] * (P2[0] * (V3[3] - cI * (V3[4])) + (P2[1] *
(V3[5] - V3[2]) + (P2[2] * (-cI * (V3[5]) + cI * (V3[2])) + P2[3] * (+cI
* (V3[4]) - V3[3])))));
F2[3] = denom * cI * (F1[2] * (P2[0] * (V3[3] + cI * (V3[4])) + (P2[1] *
(-1.) * (V3[2] + V3[5]) + (P2[2] * (-1.) * (+cI * (V3[2] + V3[5])) +
P2[3] * (V3[3] + cI * (V3[4]))))) + F1[3] * (P2[0] * (V3[2] - V3[5]) +
(P2[1] * (+cI * (V3[4]) - V3[3]) + (P2[2] * (-1.) * (V3[4] + cI *
(V3[3])) + P2[3] * (V3[2] - V3[5])))));
F2[4] = denom * - cI * M2 * (F1[2] * (-1.) * (V3[2] + V3[5]) + F1[3] * (+cI *
(V3[4]) - V3[3]));
F2[5] = denom * cI * M2 * (F1[2] * (V3[3] + cI * (V3[4])) + F1[3] * (V3[2] -
V3[5]));
}
void FFV2_5_2(std::complex<double> F1[], std::complex<double> V3[],
std::complex<double> COUP1, std::complex<double> COUP2, double M2, double
W2, std::complex<double> F2[])
{
std::complex<double> Ftmp[6];
- std::complex<double> denom;
int i;
FFV2_2(F1, V3, COUP1, M2, W2, F2);
FFV5_2(F1, V3, COUP2, M2, W2, Ftmp);
i = 2;
while (i < 6)
{
F2[i] = F2[i] + Ftmp[i];
i++;
}
}
void FFV1_2(std::complex<double> F1[], std::complex<double> V3[],
std::complex<double> COUP, double M2, double W2, std::complex<double> F2[])
{
static std::complex<double> cI = std::complex<double> (0., 1.);
double P2[4];
std::complex<double> denom;
F2[0] = +F1[0] + V3[0];
F2[1] = +F1[1] + V3[1];
P2[0] = -F2[0].real();
P2[1] = -F2[1].real();
P2[2] = -F2[1].imag();
P2[3] = -F2[0].imag();
denom = COUP/((P2[0] * P2[0]) - (P2[1] * P2[1]) - (P2[2] * P2[2]) - (P2[3] *
P2[3]) - M2 * (M2 - cI * W2));
F2[2] = denom * cI * (F1[2] * (P2[0] * (V3[2] + V3[5]) + (P2[1] * (-1.) *
(V3[3] + cI * (V3[4])) + (P2[2] * (+cI * (V3[3]) - V3[4]) - P2[3] *
(V3[2] + V3[5])))) + (F1[3] * (P2[0] * (V3[3] - cI * (V3[4])) + (P2[1] *
(V3[5] - V3[2]) + (P2[2] * (-cI * (V3[5]) + cI * (V3[2])) + P2[3] * (+cI
* (V3[4]) - V3[3])))) + M2 * (F1[4] * (V3[2] - V3[5]) + F1[5] * (+cI *
(V3[4]) - V3[3]))));
F2[3] = denom * (-cI) * (F1[2] * (P2[0] * (-1.) * (V3[3] + cI * (V3[4])) +
(P2[1] * (V3[2] + V3[5]) + (P2[2] * (+cI * (V3[2] + V3[5])) - P2[3] *
(V3[3] + cI * (V3[4]))))) + (F1[3] * (P2[0] * (V3[5] - V3[2]) + (P2[1] *
(V3[3] - cI * (V3[4])) + (P2[2] * (V3[4] + cI * (V3[3])) + P2[3] * (V3[5]
- V3[2])))) + M2 * (F1[4] * (V3[3] + cI * (V3[4])) - F1[5] * (V3[2] +
V3[5]))));
F2[4] = denom * (-cI) * (F1[4] * (P2[0] * (V3[5] - V3[2]) + (P2[1] * (V3[3] +
cI * (V3[4])) + (P2[2] * (V3[4] - cI * (V3[3])) + P2[3] * (V3[5] -
V3[2])))) + (F1[5] * (P2[0] * (V3[3] - cI * (V3[4])) + (P2[1] * (-1.) *
(V3[2] + V3[5]) + (P2[2] * (+cI * (V3[2] + V3[5])) + P2[3] * (V3[3] - cI
* (V3[4]))))) + M2 * (F1[2] * (-1.) * (V3[2] + V3[5]) + F1[3] * (+cI *
(V3[4]) - V3[3]))));
F2[5] = denom * cI * (F1[4] * (P2[0] * (-1.) * (V3[3] + cI * (V3[4])) +
(P2[1] * (V3[2] - V3[5]) + (P2[2] * (-cI * (V3[5]) + cI * (V3[2])) +
P2[3] * (V3[3] + cI * (V3[4]))))) + (F1[5] * (P2[0] * (V3[2] + V3[5]) +
(P2[1] * (+cI * (V3[4]) - V3[3]) + (P2[2] * (-1.) * (V3[4] + cI *
(V3[3])) - P2[3] * (V3[2] + V3[5])))) + M2 * (F1[2] * (V3[3] + cI *
(V3[4])) + F1[3] * (V3[2] - V3[5]))));
}
void FFV2_0(std::complex<double> F1[], std::complex<double> F2[],
std::complex<double> V3[], std::complex<double> COUP, std::complex<double>
& vertex)
{
static std::complex<double> cI = std::complex<double> (0., 1.);
std::complex<double> TMP9;
TMP9 = (F1[2] * (F2[4] * (V3[2] + V3[5]) + F2[5] * (V3[3] + cI * (V3[4]))) +
F1[3] * (F2[4] * (V3[3] - cI * (V3[4])) + F2[5] * (V3[2] - V3[5])));
vertex = COUP * - cI * TMP9;
}
void FFV2_5_0(std::complex<double> F1[], std::complex<double> F2[],
std::complex<double> V3[], std::complex<double> COUP1, std::complex<double>
COUP2, std::complex<double> & vertex)
{
std::complex<double> tmp;
FFV2_0(F1, F2, V3, COUP1, vertex);
FFV5_0(F1, F2, V3, COUP2, tmp);
vertex = vertex + tmp;
}
void FFV5_1(std::complex<double> F2[], std::complex<double> V3[],
std::complex<double> COUP, double M1, double W1, std::complex<double> F1[])
{
static std::complex<double> cI = std::complex<double> (0., 1.);
double P1[4];
std::complex<double> denom;
F1[0] = +F2[0] + V3[0];
F1[1] = +F2[1] + V3[1];
P1[0] = -F1[0].real();
P1[1] = -F1[1].real();
P1[2] = -F1[1].imag();
P1[3] = -F1[0].imag();
denom = COUP/((P1[0] * P1[0]) - (P1[1] * P1[1]) - (P1[2] * P1[2]) - (P1[3] *
P1[3]) - M1 * (M1 - cI * W1));
F1[2] = denom * 4. * cI * (F2[2] * (P1[0] * (V3[5] - V3[2]) + (P1[1] * (V3[3]
- cI * (V3[4])) + (P1[2] * (V3[4] + cI * (V3[3])) + P1[3] * (V3[5] -
V3[2])))) + (+1./4. * (M1 * (F2[5] * (V3[3] + cI * (V3[4])) + 4. * (F2[4]
* 1./4. * (V3[2] + V3[5])))) + F2[3] * (P1[0] * (V3[3] + cI * (V3[4])) +
(P1[1] * (-1.) * (V3[2] + V3[5]) + (P1[2] * (-1.) * (+cI * (V3[2] +
V3[5])) + P1[3] * (V3[3] + cI * (V3[4])))))));
F1[3] = denom * 4. * cI * (F2[2] * (P1[0] * (V3[3] - cI * (V3[4])) + (P1[1] *
(V3[5] - V3[2]) + (P1[2] * (-cI * (V3[5]) + cI * (V3[2])) + P1[3] * (+cI
* (V3[4]) - V3[3])))) + (+1./4. * (M1 * (F2[5] * (V3[2] - V3[5]) + 4. *
(F2[4] * 1./4. * (V3[3] - cI * (V3[4]))))) + F2[3] * (P1[0] * (-1.) *
(V3[2] + V3[5]) + (P1[1] * (V3[3] + cI * (V3[4])) + (P1[2] * (V3[4] - cI
* (V3[3])) + P1[3] * (V3[2] + V3[5]))))));
F1[4] = denom * (-cI) * (F2[4] * (P1[0] * (V3[2] + V3[5]) + (P1[1] * (+cI *
(V3[4]) - V3[3]) + (P1[2] * (-1.) * (V3[4] + cI * (V3[3])) - P1[3] *
(V3[2] + V3[5])))) + (F2[5] * (P1[0] * (V3[3] + cI * (V3[4])) + (P1[1] *
(V3[5] - V3[2]) + (P1[2] * (-cI * (V3[2]) + cI * (V3[5])) - P1[3] *
(V3[3] + cI * (V3[4]))))) + M1 * (F2[2] * 4. * (V3[5] - V3[2]) + 4. *
(F2[3] * (V3[3] + cI * (V3[4]))))));
F1[5] = denom * cI * (F2[4] * (P1[0] * (+cI * (V3[4]) - V3[3]) + (P1[1] *
(V3[2] + V3[5]) + (P1[2] * (-1.) * (+cI * (V3[2] + V3[5])) + P1[3] * (+cI
* (V3[4]) - V3[3])))) + (F2[5] * (P1[0] * (V3[5] - V3[2]) + (P1[1] *
(V3[3] + cI * (V3[4])) + (P1[2] * (V3[4] - cI * (V3[3])) + P1[3] * (V3[5]
- V3[2])))) + M1 * (F2[2] * 4. * (+cI * (V3[4]) - V3[3]) + 4. * (F2[3] *
(V3[2] + V3[5])))));
}
void FFV1_0(std::complex<double> F1[], std::complex<double> F2[],
std::complex<double> V3[], std::complex<double> COUP, std::complex<double>
& vertex)
{
static std::complex<double> cI = std::complex<double> (0., 1.);
std::complex<double> TMP13;
TMP13 = (F1[2] * (F2[4] * (V3[2] + V3[5]) + F2[5] * (V3[3] + cI * (V3[4]))) +
(F1[3] * (F2[4] * (V3[3] - cI * (V3[4])) + F2[5] * (V3[2] - V3[5])) +
(F1[4] * (F2[2] * (V3[2] - V3[5]) - F2[3] * (V3[3] + cI * (V3[4]))) +
F1[5] * (F2[2] * (+cI * (V3[4]) - V3[3]) + F2[3] * (V3[2] + V3[5])))));
vertex = COUP * - cI * TMP13;
}
void VVVV4P0_1(std::complex<double> V2[], std::complex<double> V3[],
std::complex<double> V4[], std::complex<double> COUP, double M1, double W1,
std::complex<double> V1[])
{
static std::complex<double> cI = std::complex<double> (0., 1.);
std::complex<double> TMP12;
std::complex<double> TMP11;
double P1[4];
std::complex<double> denom;
V1[0] = +V2[0] + V3[0] + V4[0];
V1[1] = +V2[1] + V3[1] + V4[1];
P1[0] = -V1[0].real();
P1[1] = -V1[1].real();
P1[2] = -V1[1].imag();
P1[3] = -V1[0].imag();
TMP11 = (V2[2] * V4[2] - V2[3] * V4[3] - V2[4] * V4[4] - V2[5] * V4[5]);
TMP12 = (V3[2] * V4[2] - V3[3] * V4[3] - V3[4] * V4[4] - V3[5] * V4[5]);
denom = COUP/((P1[0] * P1[0]) - (P1[1] * P1[1]) - (P1[2] * P1[2]) - (P1[3] *
P1[3]) - M1 * (M1 - cI * W1));
V1[2] = denom * (-cI * (V3[2] * TMP11) + cI * (V2[2] * TMP12));
V1[3] = denom * (-cI * (V3[3] * TMP11) + cI * (V2[3] * TMP12));
V1[4] = denom * (-cI * (V3[4] * TMP11) + cI * (V2[4] * TMP12));
V1[5] = denom * (-cI * (V3[5] * TMP11) + cI * (V2[5] * TMP12));
}
void VVVV3P0_1(std::complex<double> V2[], std::complex<double> V3[],
std::complex<double> V4[], std::complex<double> COUP, double M1, double W1,
std::complex<double> V1[])
{
static std::complex<double> cI = std::complex<double> (0., 1.);
std::complex<double> TMP12;
double P1[4];
std::complex<double> TMP6;
std::complex<double> denom;
V1[0] = +V2[0] + V3[0] + V4[0];
V1[1] = +V2[1] + V3[1] + V4[1];
P1[0] = -V1[0].real();
P1[1] = -V1[1].real();
P1[2] = -V1[1].imag();
P1[3] = -V1[0].imag();
TMP6 = (V3[2] * V2[2] - V3[3] * V2[3] - V3[4] * V2[4] - V3[5] * V2[5]);
TMP12 = (V3[2] * V4[2] - V3[3] * V4[3] - V3[4] * V4[4] - V3[5] * V4[5]);
denom = COUP/((P1[0] * P1[0]) - (P1[1] * P1[1]) - (P1[2] * P1[2]) - (P1[3] *
P1[3]) - M1 * (M1 - cI * W1));
V1[2] = denom * (-cI * (TMP6 * V4[2]) + cI * (V2[2] * TMP12));
V1[3] = denom * (-cI * (TMP6 * V4[3]) + cI * (V2[3] * TMP12));
V1[4] = denom * (-cI * (TMP6 * V4[4]) + cI * (V2[4] * TMP12));
V1[5] = denom * (-cI * (TMP6 * V4[5]) + cI * (V2[5] * TMP12));
}
void VVV1_0(std::complex<double> V1[], std::complex<double> V2[],
std::complex<double> V3[], std::complex<double> COUP, std::complex<double>
& vertex)
{
static std::complex<double> cI = std::complex<double> (0., 1.);
std::complex<double> TMP2;
std::complex<double> TMP1;
double P1[4];
std::complex<double> TMP0;
double P2[4];
std::complex<double> TMP7;
double P3[4];
std::complex<double> TMP6;
std::complex<double> TMP5;
std::complex<double> TMP4;
std::complex<double> TMP3;
std::complex<double> TMP8;
P1[0] = V1[0].real();
P1[1] = V1[1].real();
P1[2] = V1[1].imag();
P1[3] = V1[0].imag();
P2[0] = V2[0].real();
P2[1] = V2[1].real();
P2[2] = V2[1].imag();
P2[3] = V2[0].imag();
P3[0] = V3[0].real();
P3[1] = V3[1].real();
P3[2] = V3[1].imag();
P3[3] = V3[0].imag();
TMP8 = (V1[2] * P3[0] - V1[3] * P3[1] - V1[4] * P3[2] - V1[5] * P3[3]);
TMP5 = (V2[2] * P3[0] - V2[3] * P3[1] - V2[4] * P3[2] - V2[5] * P3[3]);
TMP4 = (P1[0] * V2[2] - P1[1] * V2[3] - P1[2] * V2[4] - P1[3] * V2[5]);
TMP7 = (V1[2] * P2[0] - V1[3] * P2[1] - V1[4] * P2[2] - V1[5] * P2[3]);
TMP6 = (V3[2] * V2[2] - V3[3] * V2[3] - V3[4] * V2[4] - V3[5] * V2[5]);
TMP1 = (V2[2] * V1[2] - V2[3] * V1[3] - V2[4] * V1[4] - V2[5] * V1[5]);
TMP0 = (V3[2] * P1[0] - V3[3] * P1[1] - V3[4] * P1[2] - V3[5] * P1[3]);
TMP3 = (V3[2] * V1[2] - V3[3] * V1[3] - V3[4] * V1[4] - V3[5] * V1[5]);
TMP2 = (V3[2] * P2[0] - V3[3] * P2[1] - V3[4] * P2[2] - V3[5] * P2[3]);
vertex = COUP * (TMP1 * (-cI * (TMP0) + cI * (TMP2)) + (TMP3 * (-cI * (TMP5)
+ cI * (TMP4)) + TMP6 * (-cI * (TMP7) + cI * (TMP8))));
}
void FFV2_3(std::complex<double> F1[], std::complex<double> F2[],
std::complex<double> COUP, double M3, double W3, std::complex<double> V3[])
{
static std::complex<double> cI = std::complex<double> (0., 1.);
std::complex<double> denom;
std::complex<double> TMP10;
double P3[4];
double OM3;
OM3 = 0.;
if (M3 != 0.)
OM3 = 1./(M3 * M3);
V3[0] = +F1[0] + F2[0];
V3[1] = +F1[1] + F2[1];
P3[0] = -V3[0].real();
P3[1] = -V3[1].real();
P3[2] = -V3[1].imag();
P3[3] = -V3[0].imag();
TMP10 = (F1[2] * (F2[4] * (P3[0] + P3[3]) + F2[5] * (P3[1] + cI * (P3[2]))) +
F1[3] * (F2[4] * (P3[1] - cI * (P3[2])) + F2[5] * (P3[0] - P3[3])));
denom = COUP/((P3[0] * P3[0]) - (P3[1] * P3[1]) - (P3[2] * P3[2]) - (P3[3] *
P3[3]) - M3 * (M3 - cI * W3));
V3[2] = denom * (-cI) * (F1[2] * F2[4] + F1[3] * F2[5] - P3[0] * OM3 *
TMP10);
V3[3] = denom * (-cI) * (-F1[2] * F2[5] - F1[3] * F2[4] - P3[1] * OM3 *
TMP10);
V3[4] = denom * (-cI) * (-cI * (F1[2] * F2[5]) + cI * (F1[3] * F2[4]) - P3[2]
* OM3 * TMP10);
V3[5] = denom * (-cI) * (F1[3] * F2[5] - F1[2] * F2[4] - P3[3] * OM3 *
TMP10);
}
void FFV2_4_3(std::complex<double> F1[], std::complex<double> F2[],
std::complex<double> COUP1, std::complex<double> COUP2, double M3, double
W3, std::complex<double> V3[])
{
- std::complex<double> denom;
- int i;
+ int i;
std::complex<double> Vtmp[6];
FFV2_3(F1, F2, COUP1, M3, W3, V3);
FFV4_3(F1, F2, COUP2, M3, W3, Vtmp);
i = 2;
while (i < 6)
{
V3[i] = V3[i] + Vtmp[i];
i++;
}
}
void FFV5_2(std::complex<double> F1[], std::complex<double> V3[],
std::complex<double> COUP, double M2, double W2, std::complex<double> F2[])
{
static std::complex<double> cI = std::complex<double> (0., 1.);
double P2[4];
std::complex<double> denom;
F2[0] = +F1[0] + V3[0];
F2[1] = +F1[1] + V3[1];
P2[0] = -F2[0].real();
P2[1] = -F2[1].real();
P2[2] = -F2[1].imag();
P2[3] = -F2[0].imag();
denom = COUP/((P2[0] * P2[0]) - (P2[1] * P2[1]) - (P2[2] * P2[2]) - (P2[3] *
P2[3]) - M2 * (M2 - cI * W2));
F2[2] = denom * cI * (F1[2] * (P2[0] * (V3[2] + V3[5]) + (P2[1] * (-1.) *
(V3[3] + cI * (V3[4])) + (P2[2] * (+cI * (V3[3]) - V3[4]) - P2[3] *
(V3[2] + V3[5])))) + (F1[3] * (P2[0] * (V3[3] - cI * (V3[4])) + (P2[1] *
(V3[5] - V3[2]) + (P2[2] * (-cI * (V3[5]) + cI * (V3[2])) + P2[3] * (+cI
* (V3[4]) - V3[3])))) + M2 * (F1[4] * 4. * (V3[2] - V3[5]) + 4. * (F1[5]
* (+cI * (V3[4]) - V3[3])))));
F2[3] = denom * cI * (F1[2] * (P2[0] * (V3[3] + cI * (V3[4])) + (P2[1] *
(-1.) * (V3[2] + V3[5]) + (P2[2] * (-1.) * (+cI * (V3[2] + V3[5])) +
P2[3] * (V3[3] + cI * (V3[4]))))) + (F1[3] * (P2[0] * (V3[2] - V3[5]) +
(P2[1] * (+cI * (V3[4]) - V3[3]) + (P2[2] * (-1.) * (V3[4] + cI *
(V3[3])) + P2[3] * (V3[2] - V3[5])))) + M2 * (F1[4] * (-4.) * (V3[3] + cI
* (V3[4])) + 4. * (F1[5] * (V3[2] + V3[5])))));
F2[4] = denom * (-4. * cI) * (F1[4] * (P2[0] * (V3[5] - V3[2]) + (P2[1] *
(V3[3] + cI * (V3[4])) + (P2[2] * (V3[4] - cI * (V3[3])) + P2[3] * (V3[5]
- V3[2])))) + (+1./4. * (M2 * (F1[3] * (+cI * (V3[4]) - V3[3]) + 4. *
(F1[2] * (-1./4.) * (V3[2] + V3[5])))) + F1[5] * (P2[0] * (V3[3] - cI *
(V3[4])) + (P2[1] * (-1.) * (V3[2] + V3[5]) + (P2[2] * (+cI * (V3[2] +
V3[5])) + P2[3] * (V3[3] - cI * (V3[4])))))));
F2[5] = denom * (-4. * cI) * (F1[4] * (P2[0] * (V3[3] + cI * (V3[4])) +
(P2[1] * (V3[5] - V3[2]) + (P2[2] * (-cI * (V3[2]) + cI * (V3[5])) -
P2[3] * (V3[3] + cI * (V3[4]))))) + (+1./4. * (M2 * (F1[3] * (V3[5] -
V3[2]) + 4. * (F1[2] * (-1./4.) * (V3[3] + cI * (V3[4]))))) + F1[5] *
(P2[0] * (-1.) * (V3[2] + V3[5]) + (P2[1] * (V3[3] - cI * (V3[4])) +
(P2[2] * (V3[4] + cI * (V3[3])) + P2[3] * (V3[2] + V3[5]))))));
}
void FFV2_1(std::complex<double> F2[], std::complex<double> V3[],
std::complex<double> COUP, double M1, double W1, std::complex<double> F1[])
{
static std::complex<double> cI = std::complex<double> (0., 1.);
double P1[4];
std::complex<double> denom;
F1[0] = +F2[0] + V3[0];
F1[1] = +F2[1] + V3[1];
P1[0] = -F1[0].real();
P1[1] = -F1[1].real();
P1[2] = -F1[1].imag();
P1[3] = -F1[0].imag();
denom = COUP/((P1[0] * P1[0]) - (P1[1] * P1[1]) - (P1[2] * P1[2]) - (P1[3] *
P1[3]) - M1 * (M1 - cI * W1));
F1[2] = denom * cI * M1 * (F2[4] * (V3[2] + V3[5]) + F2[5] * (V3[3] + cI *
(V3[4])));
F1[3] = denom * - cI * M1 * (F2[4] * (+cI * (V3[4]) - V3[3]) + F2[5] * (V3[5]
- V3[2]));
F1[4] = denom * (-cI) * (F2[4] * (P1[0] * (V3[2] + V3[5]) + (P1[1] * (+cI *
(V3[4]) - V3[3]) + (P1[2] * (-1.) * (V3[4] + cI * (V3[3])) - P1[3] *
(V3[2] + V3[5])))) + F2[5] * (P1[0] * (V3[3] + cI * (V3[4])) + (P1[1] *
(V3[5] - V3[2]) + (P1[2] * (-cI * (V3[2]) + cI * (V3[5])) - P1[3] *
(V3[3] + cI * (V3[4]))))));
F1[5] = denom * (-cI) * (F2[4] * (P1[0] * (V3[3] - cI * (V3[4])) + (P1[1] *
(-1.) * (V3[2] + V3[5]) + (P1[2] * (+cI * (V3[2] + V3[5])) + P1[3] *
(V3[3] - cI * (V3[4]))))) + F2[5] * (P1[0] * (V3[2] - V3[5]) + (P1[1] *
(-1.) * (V3[3] + cI * (V3[4])) + (P1[2] * (+cI * (V3[3]) - V3[4]) + P1[3]
* (V3[2] - V3[5])))));
}
void FFV2_5_1(std::complex<double> F2[], std::complex<double> V3[],
std::complex<double> COUP1, std::complex<double> COUP2, double M1, double
W1, std::complex<double> F1[])
{
- std::complex<double> denom;
- int i;
+ int i;
std::complex<double> Ftmp[6];
FFV2_1(F2, V3, COUP1, M1, W1, F1);
FFV5_1(F2, V3, COUP2, M1, W1, Ftmp);
i = 2;
while (i < 6)
{
F1[i] = F1[i] + Ftmp[i];
i++;
}
}
void FFV5_0(std::complex<double> F1[], std::complex<double> F2[],
std::complex<double> V3[], std::complex<double> COUP, std::complex<double>
& vertex)
{
static std::complex<double> cI = std::complex<double> (0., 1.);
std::complex<double> TMP15;
std::complex<double> TMP16;
TMP15 = (F1[2] * (F2[4] * (V3[2] + V3[5]) + F2[5] * (V3[3] + cI * (V3[4]))) +
F1[3] * (F2[4] * (V3[3] - cI * (V3[4])) + F2[5] * (V3[2] - V3[5])));
TMP16 = (F1[4] * (F2[2] * (V3[2] - V3[5]) - F2[3] * (V3[3] + cI * (V3[4]))) +
F1[5] * (F2[2] * (+cI * (V3[4]) - V3[3]) + F2[3] * (V3[2] + V3[5])));
vertex = COUP * (-1.) * (+cI * (TMP15) + 4. * cI * (TMP16));
}
void FFV1_1(std::complex<double> F2[], std::complex<double> V3[],
std::complex<double> COUP, double M1, double W1, std::complex<double> F1[])
{
static std::complex<double> cI = std::complex<double> (0., 1.);
double P1[4];
std::complex<double> denom;
F1[0] = +F2[0] + V3[0];
F1[1] = +F2[1] + V3[1];
P1[0] = -F1[0].real();
P1[1] = -F1[1].real();
P1[2] = -F1[1].imag();
P1[3] = -F1[0].imag();
denom = COUP/((P1[0] * P1[0]) - (P1[1] * P1[1]) - (P1[2] * P1[2]) - (P1[3] *
P1[3]) - M1 * (M1 - cI * W1));
F1[2] = denom * cI * (F2[2] * (P1[0] * (V3[5] - V3[2]) + (P1[1] * (V3[3] - cI
* (V3[4])) + (P1[2] * (V3[4] + cI * (V3[3])) + P1[3] * (V3[5] - V3[2]))))
+ (F2[3] * (P1[0] * (V3[3] + cI * (V3[4])) + (P1[1] * (-1.) * (V3[2] +
V3[5]) + (P1[2] * (-1.) * (+cI * (V3[2] + V3[5])) + P1[3] * (V3[3] + cI *
(V3[4]))))) + M1 * (F2[4] * (V3[2] + V3[5]) + F2[5] * (V3[3] + cI *
(V3[4])))));
F1[3] = denom * (-cI) * (F2[2] * (P1[0] * (+cI * (V3[4]) - V3[3]) + (P1[1] *
(V3[2] - V3[5]) + (P1[2] * (-cI * (V3[2]) + cI * (V3[5])) + P1[3] *
(V3[3] - cI * (V3[4]))))) + (F2[3] * (P1[0] * (V3[2] + V3[5]) + (P1[1] *
(-1.) * (V3[3] + cI * (V3[4])) + (P1[2] * (+cI * (V3[3]) - V3[4]) - P1[3]
* (V3[2] + V3[5])))) + M1 * (F2[4] * (+cI * (V3[4]) - V3[3]) + F2[5] *
(V3[5] - V3[2]))));
F1[4] = denom * (-cI) * (F2[4] * (P1[0] * (V3[2] + V3[5]) + (P1[1] * (+cI *
(V3[4]) - V3[3]) + (P1[2] * (-1.) * (V3[4] + cI * (V3[3])) - P1[3] *
(V3[2] + V3[5])))) + (F2[5] * (P1[0] * (V3[3] + cI * (V3[4])) + (P1[1] *
(V3[5] - V3[2]) + (P1[2] * (-cI * (V3[2]) + cI * (V3[5])) - P1[3] *
(V3[3] + cI * (V3[4]))))) + M1 * (F2[2] * (V3[5] - V3[2]) + F2[3] *
(V3[3] + cI * (V3[4])))));
F1[5] = denom * cI * (F2[4] * (P1[0] * (+cI * (V3[4]) - V3[3]) + (P1[1] *
(V3[2] + V3[5]) + (P1[2] * (-1.) * (+cI * (V3[2] + V3[5])) + P1[3] * (+cI
* (V3[4]) - V3[3])))) + (F2[5] * (P1[0] * (V3[5] - V3[2]) + (P1[1] *
(V3[3] + cI * (V3[4])) + (P1[2] * (V3[4] - cI * (V3[3])) + P1[3] * (V3[5]
- V3[2])))) + M1 * (F2[2] * (+cI * (V3[4]) - V3[3]) + F2[3] * (V3[2] +
V3[5]))));
}
void FFV4_3(std::complex<double> F1[], std::complex<double> F2[],
std::complex<double> COUP, double M3, double W3, std::complex<double> V3[])
{
static std::complex<double> cI = std::complex<double> (0., 1.);
std::complex<double> denom;
std::complex<double> TMP10;
double P3[4];
double OM3;
std::complex<double> TMP14;
OM3 = 0.;
if (M3 != 0.)
OM3 = 1./(M3 * M3);
V3[0] = +F1[0] + F2[0];
V3[1] = +F1[1] + F2[1];
P3[0] = -V3[0].real();
P3[1] = -V3[1].real();
P3[2] = -V3[1].imag();
P3[3] = -V3[0].imag();
TMP14 = (F1[4] * (F2[2] * (P3[0] - P3[3]) - F2[3] * (P3[1] + cI * (P3[2]))) +
F1[5] * (F2[2] * (+cI * (P3[2]) - P3[1]) + F2[3] * (P3[0] + P3[3])));
TMP10 = (F1[2] * (F2[4] * (P3[0] + P3[3]) + F2[5] * (P3[1] + cI * (P3[2]))) +
F1[3] * (F2[4] * (P3[1] - cI * (P3[2])) + F2[5] * (P3[0] - P3[3])));
denom = COUP/((P3[0] * P3[0]) - (P3[1] * P3[1]) - (P3[2] * P3[2]) - (P3[3] *
P3[3]) - M3 * (M3 - cI * W3));
V3[2] = denom * (-2. * cI) * (OM3 * - 1./2. * P3[0] * (TMP10 + 2. * (TMP14))
+ (+1./2. * (F1[2] * F2[4] + F1[3] * F2[5]) + F1[4] * F2[2] + F1[5] *
F2[3]));
V3[3] = denom * (-2. * cI) * (OM3 * - 1./2. * P3[1] * (TMP10 + 2. * (TMP14))
+ (-1./2. * (F1[2] * F2[5] + F1[3] * F2[4]) + F1[4] * F2[3] + F1[5] *
F2[2]));
V3[4] = denom * 2. * cI * (OM3 * 1./2. * P3[2] * (TMP10 + 2. * (TMP14)) +
(+1./2. * cI * (F1[2] * F2[5]) - 1./2. * cI * (F1[3] * F2[4]) - cI *
(F1[4] * F2[3]) + cI * (F1[5] * F2[2])));
V3[5] = denom * 2. * cI * (OM3 * 1./2. * P3[3] * (TMP10 + 2. * (TMP14)) +
(+1./2. * (F1[2] * F2[4]) - 1./2. * (F1[3] * F2[5]) - F1[4] * F2[2] +
F1[5] * F2[3]));
}
void VVVV1P0_1(std::complex<double> V2[], std::complex<double> V3[],
std::complex<double> V4[], std::complex<double> COUP, double M1, double W1,
std::complex<double> V1[])
{
static std::complex<double> cI = std::complex<double> (0., 1.);
std::complex<double> TMP11;
double P1[4];
std::complex<double> TMP6;
std::complex<double> denom;
V1[0] = +V2[0] + V3[0] + V4[0];
V1[1] = +V2[1] + V3[1] + V4[1];
P1[0] = -V1[0].real();
P1[1] = -V1[1].real();
P1[2] = -V1[1].imag();
P1[3] = -V1[0].imag();
TMP6 = (V3[2] * V2[2] - V3[3] * V2[3] - V3[4] * V2[4] - V3[5] * V2[5]);
TMP11 = (V2[2] * V4[2] - V2[3] * V4[3] - V2[4] * V4[4] - V2[5] * V4[5]);
denom = COUP/((P1[0] * P1[0]) - (P1[1] * P1[1]) - (P1[2] * P1[2]) - (P1[3] *
P1[3]) - M1 * (M1 - cI * W1));
V1[2] = denom * (-cI * (TMP6 * V4[2]) + cI * (V3[2] * TMP11));
V1[3] = denom * (-cI * (TMP6 * V4[3]) + cI * (V3[3] * TMP11));
V1[4] = denom * (-cI * (TMP6 * V4[4]) + cI * (V3[4] * TMP11));
V1[5] = denom * (-cI * (TMP6 * V4[5]) + cI * (V3[5] * TMP11));
}
void VVV1P0_1(std::complex<double> V2[], std::complex<double> V3[],
std::complex<double> COUP, double M1, double W1, std::complex<double> V1[])
{
static std::complex<double> cI = std::complex<double> (0., 1.);
std::complex<double> TMP2;
double P1[4];
std::complex<double> TMP0;
double P2[4];
double P3[4];
std::complex<double> TMP6;
std::complex<double> TMP5;
std::complex<double> TMP4;
std::complex<double> denom;
P2[0] = V2[0].real();
P2[1] = V2[1].real();
P2[2] = V2[1].imag();
P2[3] = V2[0].imag();
P3[0] = V3[0].real();
P3[1] = V3[1].real();
P3[2] = V3[1].imag();
P3[3] = V3[0].imag();
V1[0] = +V2[0] + V3[0];
V1[1] = +V2[1] + V3[1];
P1[0] = -V1[0].real();
P1[1] = -V1[1].real();
P1[2] = -V1[1].imag();
P1[3] = -V1[0].imag();
TMP5 = (V2[2] * P3[0] - V2[3] * P3[1] - V2[4] * P3[2] - V2[5] * P3[3]);
TMP4 = (P1[0] * V2[2] - P1[1] * V2[3] - P1[2] * V2[4] - P1[3] * V2[5]);
TMP6 = (V3[2] * V2[2] - V3[3] * V2[3] - V3[4] * V2[4] - V3[5] * V2[5]);
TMP0 = (V3[2] * P1[0] - V3[3] * P1[1] - V3[4] * P1[2] - V3[5] * P1[3]);
TMP2 = (V3[2] * P2[0] - V3[3] * P2[1] - V3[4] * P2[2] - V3[5] * P2[3]);
denom = COUP/((P1[0] * P1[0]) - (P1[1] * P1[1]) - (P1[2] * P1[2]) - (P1[3] *
P1[3]) - M1 * (M1 - cI * W1));
V1[2] = denom * (TMP6 * (-cI * (P2[0]) + cI * (P3[0])) + (V2[2] * (-cI *
(TMP0) + cI * (TMP2)) + V3[2] * (-cI * (TMP5) + cI * (TMP4))));
V1[3] = denom * (TMP6 * (-cI * (P2[1]) + cI * (P3[1])) + (V2[3] * (-cI *
(TMP0) + cI * (TMP2)) + V3[3] * (-cI * (TMP5) + cI * (TMP4))));
V1[4] = denom * (TMP6 * (-cI * (P2[2]) + cI * (P3[2])) + (V2[4] * (-cI *
(TMP0) + cI * (TMP2)) + V3[4] * (-cI * (TMP5) + cI * (TMP4))));
V1[5] = denom * (TMP6 * (-cI * (P2[3]) + cI * (P3[3])) + (V2[5] * (-cI *
(TMP0) + cI * (TMP2)) + V3[5] * (-cI * (TMP5) + cI * (TMP4))));
}
} // end namespace MG5_sm_COLOREA
diff --git a/Shower/Dipole/Colorea/eeuugg.cc b/Shower/Dipole/Colorea/eeuugg.cc
--- a/Shower/Dipole/Colorea/eeuugg.cc
+++ b/Shower/Dipole/Colorea/eeuugg.cc
@@ -1,292 +1,291 @@
//==========================================================================
// This file has been automatically generated for C++ Standalone by
// MadGraph5_aMC@NLO v. 2.5.4, 2017-03-28
// By the MadGraph5_aMC@NLO Development Team
// Visit launchpad.net/madgraph5 and amcatnlo.web.cern.ch
//==========================================================================
// and was then modified by J. Bellm.
#include "eeuugg.h"
#include "HelAmps_sm.h"
#include <iostream>
using namespace MG5_sm_COLOREA;
//==========================================================================
// Class member functions for calculating the matrix elements for
// Process: e+ e- > u u~ g g WEIGHTED<=6 @1
//--------------------------------------------------------------------------
// Initialize process.
vector<int> eeuugg::producePermutation(double r,vector < double * > & momenta){
setMomenta(momenta);
sigmaKin();
static const int res[2][5] = {
{5, 6, 3, 4, 0},
{6, 5, 3, 4, 0}};
double jampsum=0.;
for( int i=0;i<2;i++) jampsum+=jamp2[0][i];
// std::cout<<"\njampsum "<<jampsum<<std::flush;
double cur=0.;
for(int i=0;i<2;i++){
// std::cout<<"\njamp2[0][i] "<<jamp2[0][i]<<std::flush;
cur+=jamp2[0][i];
if( cur/jampsum > r )return std::vector<int>(res[i], res[i] + sizeof res[i] / sizeof res[i][0]);
}
std::cerr<<"\nproducePermutation: Upps.. Something went wrong!!\n"<<std::flush;
return std::vector<int>();
}
void eeuugg::initProc(string param_card_name)
{
cout<<"\nColorea: Init process eeuugg for rearrangement (arXiv:1801.06113).";
// Instantiate the model class and set parameters that stay fixed during run
pars = Parameters_sm::getInstance();
SLHAReader_COLOREA slha(param_card_name);
pars->setIndependentParameters(slha);
pars->setIndependentCouplings();
// pars->printIndependentParameters();
// pars->printIndependentCouplings();
// Set external particle masses for this matrix element
mME.push_back(pars->ZERO);
mME.push_back(pars->ZERO);
mME.push_back(pars->ZERO);
mME.push_back(pars->ZERO);
mME.push_back(pars->ZERO);
mME.push_back(pars->ZERO);
jamp2[0] = new double[2];
}
//--------------------------------------------------------------------------
// Evaluate |M|^2, part independent of incoming flavour.
void eeuugg::sigmaKin()
{
// Set the parameters which change event by event
pars->setDependentParameters();
pars->setDependentCouplings();
static bool firsttime = true;
if (firsttime)
{
// pars->printDependentParameters();
// pars->printDependentCouplings();
firsttime = false;
}
// Reset color flows
for(int i = 0; i < 2; i++ )
jamp2[0][i] = 0.;
// Local variables and constants
const int ncomb = 64;
static bool goodhel[ncomb] = {ncomb * false};
static int ntry = 0, sum_hel = 0, ngood = 0;
static int igood[ncomb];
static int jhel;
double t[nprocesses];
// Helicities for the process
static const int helicities[ncomb][nexternal] = {{-1, -1, -1, -1, -1, -1},
{-1, -1, -1, -1, -1, 1}, {-1, -1, -1, -1, 1, -1}, {-1, -1, -1, -1, 1, 1},
{-1, -1, -1, 1, -1, -1}, {-1, -1, -1, 1, -1, 1}, {-1, -1, -1, 1, 1, -1},
{-1, -1, -1, 1, 1, 1}, {-1, -1, 1, -1, -1, -1}, {-1, -1, 1, -1, -1, 1},
{-1, -1, 1, -1, 1, -1}, {-1, -1, 1, -1, 1, 1}, {-1, -1, 1, 1, -1, -1},
{-1, -1, 1, 1, -1, 1}, {-1, -1, 1, 1, 1, -1}, {-1, -1, 1, 1, 1, 1}, {-1,
1, -1, -1, -1, -1}, {-1, 1, -1, -1, -1, 1}, {-1, 1, -1, -1, 1, -1}, {-1,
1, -1, -1, 1, 1}, {-1, 1, -1, 1, -1, -1}, {-1, 1, -1, 1, -1, 1}, {-1, 1,
-1, 1, 1, -1}, {-1, 1, -1, 1, 1, 1}, {-1, 1, 1, -1, -1, -1}, {-1, 1, 1,
-1, -1, 1}, {-1, 1, 1, -1, 1, -1}, {-1, 1, 1, -1, 1, 1}, {-1, 1, 1, 1,
-1, -1}, {-1, 1, 1, 1, -1, 1}, {-1, 1, 1, 1, 1, -1}, {-1, 1, 1, 1, 1, 1},
{1, -1, -1, -1, -1, -1}, {1, -1, -1, -1, -1, 1}, {1, -1, -1, -1, 1, -1},
{1, -1, -1, -1, 1, 1}, {1, -1, -1, 1, -1, -1}, {1, -1, -1, 1, -1, 1}, {1,
-1, -1, 1, 1, -1}, {1, -1, -1, 1, 1, 1}, {1, -1, 1, -1, -1, -1}, {1, -1,
1, -1, -1, 1}, {1, -1, 1, -1, 1, -1}, {1, -1, 1, -1, 1, 1}, {1, -1, 1, 1,
-1, -1}, {1, -1, 1, 1, -1, 1}, {1, -1, 1, 1, 1, -1}, {1, -1, 1, 1, 1, 1},
{1, 1, -1, -1, -1, -1}, {1, 1, -1, -1, -1, 1}, {1, 1, -1, -1, 1, -1}, {1,
1, -1, -1, 1, 1}, {1, 1, -1, 1, -1, -1}, {1, 1, -1, 1, -1, 1}, {1, 1, -1,
1, 1, -1}, {1, 1, -1, 1, 1, 1}, {1, 1, 1, -1, -1, -1}, {1, 1, 1, -1, -1,
1}, {1, 1, 1, -1, 1, -1}, {1, 1, 1, -1, 1, 1}, {1, 1, 1, 1, -1, -1}, {1,
1, 1, 1, -1, 1}, {1, 1, 1, 1, 1, -1}, {1, 1, 1, 1, 1, 1}};
// Denominators: spins, colors and identical particles
const int denominators[nprocesses] = {8};
ntry = ntry + 1;
// Reset the matrix elements
for(int i = 0; i < nprocesses; i++ )
{
matrix_element[i] = 0.;
}
// Define permutation
int perm[nexternal];
for(int i = 0; i < nexternal; i++ )
{
perm[i] = i;
}
if (sum_hel == 0 || ntry < 10)
{
// Calculate the matrix element for all helicities
for(int ihel = 0; ihel < ncomb; ihel++ )
{
if (goodhel[ihel] || ntry < 2)
{
calculate_wavefunctions(perm, helicities[ihel]);
t[0] = matrix_1_epem_uuxgg();
double tsum = 0;
for(int iproc = 0; iproc < nprocesses; iproc++ )
{
matrix_element[iproc] += t[iproc];
tsum += t[iproc];
}
// Store which helicities give non-zero result
if (tsum != 0. && !goodhel[ihel])
{
goodhel[ihel] = true;
ngood++;
igood[ngood] = ihel;
}
}
}
jhel = 0;
sum_hel = min(sum_hel, ngood);
}
else
{
// Only use the "good" helicities
for(int j = 0; j < sum_hel; j++ )
{
jhel++;
if (jhel >= ngood)
jhel = 0;
double hwgt = double(ngood)/double(sum_hel);
int ihel = igood[jhel];
calculate_wavefunctions(perm, helicities[ihel]);
t[0] = matrix_1_epem_uuxgg();
for(int iproc = 0; iproc < nprocesses; iproc++ )
{
matrix_element[iproc] += t[iproc] * hwgt;
}
}
}
for (int i = 0; i < nprocesses; i++ )
matrix_element[i] /= denominators[i];
}
//--------------------------------------------------------------------------
// Evaluate |M|^2 for each subprocess
void eeuugg::calculate_wavefunctions(const int perm[], const int hel[])
{
// Calculate wavefunctions for all processes
// Calculate all wavefunctions
oxxxxx(p[perm[0]], mME[0], hel[0], -1, w[0]);
ixxxxx(p[perm[1]], mME[1], hel[1], +1, w[1]);
oxxxxx(p[perm[2]], mME[2], hel[2], +1, w[2]);
ixxxxx(p[perm[3]], mME[3], hel[3], -1, w[3]);
vxxxxx(p[perm[4]], mME[4], hel[4], +1, w[4]);
vxxxxx(p[perm[5]], mME[5], hel[5], +1, w[5]);
FFV1P0_3(w[1], w[0], pars->GC_3, pars->ZERO, pars->ZERO, w[6]);
FFV1_1(w[2], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[7]);
FFV1_2(w[3], w[6], pars->GC_2, pars->ZERO, pars->ZERO, w[8]);
FFV2_4_3(w[1], w[0], pars->GC_50, pars->GC_59, pars->mdl_MZ, pars->mdl_WZ,
w[9]);
FFV2_5_2(w[3], w[9], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[10]);
FFV1_2(w[3], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[11]);
FFV1_1(w[2], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[12]);
FFV1_2(w[3], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[13]);
FFV1_1(w[2], w[6], pars->GC_2, pars->ZERO, pars->ZERO, w[14]);
FFV2_5_1(w[2], w[9], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[15]);
VVV1P0_1(w[4], w[5], pars->GC_10, pars->ZERO, pars->ZERO, w[16]);
// Calculate all amplitudes
// Amplitude(s) for diagram number 0
FFV1_0(w[8], w[7], w[5], pars->GC_11, amp[0]);
FFV1_0(w[10], w[7], w[5], pars->GC_11, amp[1]);
FFV1_0(w[11], w[7], w[6], pars->GC_2, amp[2]);
FFV2_5_0(w[11], w[7], w[9], pars->GC_51, pars->GC_58, amp[3]);
FFV1_0(w[8], w[12], w[4], pars->GC_11, amp[4]);
FFV1_0(w[10], w[12], w[4], pars->GC_11, amp[5]);
FFV1_0(w[13], w[12], w[6], pars->GC_2, amp[6]);
FFV2_5_0(w[13], w[12], w[9], pars->GC_51, pars->GC_58, amp[7]);
FFV1_0(w[13], w[14], w[5], pars->GC_11, amp[8]);
FFV1_0(w[13], w[15], w[5], pars->GC_11, amp[9]);
FFV1_0(w[11], w[14], w[4], pars->GC_11, amp[10]);
FFV1_0(w[11], w[15], w[4], pars->GC_11, amp[11]);
FFV1_0(w[3], w[14], w[16], pars->GC_11, amp[12]);
FFV1_0(w[8], w[2], w[16], pars->GC_11, amp[13]);
FFV1_0(w[3], w[15], w[16], pars->GC_11, amp[14]);
FFV1_0(w[10], w[2], w[16], pars->GC_11, amp[15]);
}
double eeuugg::matrix_1_epem_uuxgg()
{
//int i, j;
// Local variables
//const int ngraphs = 16;
//const int ncolor = 2;
- std::complex<double> ztemp;
std::complex<double> jamp[2];
// The color matrix;
//static const double denom[ncolor] = {3, 3};
//static const double cf[ncolor][ncolor] = {{16, -2}, {-2, 16}};
// Calculate color flows
jamp[0] = +amp[0] + amp[1] + amp[2] + amp[3] + amp[10] + amp[11] -
std::complex<double> (0, 1) * amp[12] - std::complex<double> (0, 1) *
amp[13] - std::complex<double> (0, 1) * amp[14] - std::complex<double>
(0, 1) * amp[15];
jamp[1] = +amp[4] + amp[5] + amp[6] + amp[7] + amp[8] + amp[9] +
std::complex<double> (0, 1) * amp[12] + std::complex<double> (0, 1) *
amp[13] + std::complex<double> (0, 1) * amp[14] + std::complex<double>
(0, 1) * amp[15];
// Store the leading color flows for choice of color
for(int i = 0; i < 2; i++ )
jamp2[0][i] += real(jamp[i] * conj(jamp[i]));
return -1.;
}
double eeuugg::get_jamp2(int i)
{
return jamp2[0][i];
}
int eeuugg::colorstring(int i, int j)
{
static const double res[2][5] = {
{5, 6, 3, 4, 0},
{6, 5, 3, 4, 0}};
return res[i][j];
}
int eeuugg::NCol()
{
const int ncolor = 2;
return ncolor;
}
diff --git a/Shower/Dipole/Colorea/eeuuggg.cc b/Shower/Dipole/Colorea/eeuuggg.cc
--- a/Shower/Dipole/Colorea/eeuuggg.cc
+++ b/Shower/Dipole/Colorea/eeuuggg.cc
@@ -1,532 +1,531 @@
//==========================================================================
// This file has been automatically generated for C++ Standalone by
// MadGraph5_aMC@NLO v. 2.5.4, 2017-03-28
// By the MadGraph5_aMC@NLO Development Team
// Visit launchpad.net/madgraph5 and amcatnlo.web.cern.ch
//==========================================================================
// and was then modified by J. Bellm.
#include "eeuuggg.h"
#include "HelAmps_sm.h"
#include <iostream>
using namespace MG5_sm_COLOREA;
//==========================================================================
// Class member functions for calculating the matrix elements for
// Process: e+ e- > u u~ g g g WEIGHTED<=7 @1
//--------------------------------------------------------------------------
// Initialize process.
vector<int> eeuuggg::producePermutation(double r,vector < double * > & momenta){
static bool initialized=false;
if (!initialized){
initProc("param_card.dat");
initialized=true;
}
setMomenta(momenta);
sigmaKin();
static const int res[6][6] = {
{5, 6, 7, 3, 4, 0},
{5, 7, 6, 3, 4, 0},
{6, 5, 7, 3, 4, 0},
{6, 7, 5, 3, 4, 0},
{7, 5, 6, 3, 4, 0},
{7, 6, 5, 3, 4, 0}};
double jampsum=0.;
for( int i=0;i<6;i++) jampsum+=jamp2[0][i];
double cur=0.;
for(int i=0;i<6;i++){
cur+=jamp2[0][i];
if( cur/jampsum > r )return std::vector<int>(res[i], res[i] + sizeof res[i] / sizeof res[i][0]);
}
//std::cout<<"producePermutation: Upps.. Something went wrong!!";
return std::vector<int>();
}
void eeuuggg::initProc(string param_card_name)
{
// Instantiate the model class and set parameters that stay fixed during run
cout<<"\nColorea: Init process eeuuggg for rearrangement (arXiv:1801.06113).";
pars = Parameters_sm::getInstance();
SLHAReader_COLOREA slha(param_card_name);
pars->setIndependentParameters(slha);
pars->setIndependentCouplings();
// pars->printIndependentParameters();
// pars->printIndependentCouplings();
// Set external particle masses for this matrix element
mME.push_back(pars->ZERO);
mME.push_back(pars->ZERO);
mME.push_back(pars->ZERO);
mME.push_back(pars->ZERO);
mME.push_back(pars->ZERO);
mME.push_back(pars->ZERO);
mME.push_back(pars->ZERO);
jamp2[0] = new double[6];
}
//--------------------------------------------------------------------------
// Evaluate |M|^2, part independent of incoming flavour.
void eeuuggg::sigmaKin()
{
// Set the parameters which change event by event
pars->setDependentParameters();
pars->setDependentCouplings();
static bool firsttime = true;
if (firsttime)
{
// pars->printDependentParameters();
// pars->printDependentCouplings();
firsttime = false;
}
// Reset color flows
for(int i = 0; i < 6; i++ )
jamp2[0][i] = 0.;
// Local variables and constants
const int ncomb = 128;
static bool goodhel[ncomb] = {ncomb * false};
static int ntry = 0, sum_hel = 0, ngood = 0;
static int igood[ncomb];
static int jhel;
// std::complex<double> * * wfs;
double t[nprocesses];
// Helicities for the process
static const int helicities[ncomb][nexternal] = {{-1, -1, -1, -1, -1, -1,
-1}, {-1, -1, -1, -1, -1, -1, 1}, {-1, -1, -1, -1, -1, 1, -1}, {-1, -1,
-1, -1, -1, 1, 1}, {-1, -1, -1, -1, 1, -1, -1}, {-1, -1, -1, -1, 1, -1,
1}, {-1, -1, -1, -1, 1, 1, -1}, {-1, -1, -1, -1, 1, 1, 1}, {-1, -1, -1,
1, -1, -1, -1}, {-1, -1, -1, 1, -1, -1, 1}, {-1, -1, -1, 1, -1, 1, -1},
{-1, -1, -1, 1, -1, 1, 1}, {-1, -1, -1, 1, 1, -1, -1}, {-1, -1, -1, 1, 1,
-1, 1}, {-1, -1, -1, 1, 1, 1, -1}, {-1, -1, -1, 1, 1, 1, 1}, {-1, -1, 1,
-1, -1, -1, -1}, {-1, -1, 1, -1, -1, -1, 1}, {-1, -1, 1, -1, -1, 1, -1},
{-1, -1, 1, -1, -1, 1, 1}, {-1, -1, 1, -1, 1, -1, -1}, {-1, -1, 1, -1, 1,
-1, 1}, {-1, -1, 1, -1, 1, 1, -1}, {-1, -1, 1, -1, 1, 1, 1}, {-1, -1, 1,
1, -1, -1, -1}, {-1, -1, 1, 1, -1, -1, 1}, {-1, -1, 1, 1, -1, 1, -1},
{-1, -1, 1, 1, -1, 1, 1}, {-1, -1, 1, 1, 1, -1, -1}, {-1, -1, 1, 1, 1,
-1, 1}, {-1, -1, 1, 1, 1, 1, -1}, {-1, -1, 1, 1, 1, 1, 1}, {-1, 1, -1,
-1, -1, -1, -1}, {-1, 1, -1, -1, -1, -1, 1}, {-1, 1, -1, -1, -1, 1, -1},
{-1, 1, -1, -1, -1, 1, 1}, {-1, 1, -1, -1, 1, -1, -1}, {-1, 1, -1, -1, 1,
-1, 1}, {-1, 1, -1, -1, 1, 1, -1}, {-1, 1, -1, -1, 1, 1, 1}, {-1, 1, -1,
1, -1, -1, -1}, {-1, 1, -1, 1, -1, -1, 1}, {-1, 1, -1, 1, -1, 1, -1},
{-1, 1, -1, 1, -1, 1, 1}, {-1, 1, -1, 1, 1, -1, -1}, {-1, 1, -1, 1, 1,
-1, 1}, {-1, 1, -1, 1, 1, 1, -1}, {-1, 1, -1, 1, 1, 1, 1}, {-1, 1, 1, -1,
-1, -1, -1}, {-1, 1, 1, -1, -1, -1, 1}, {-1, 1, 1, -1, -1, 1, -1}, {-1,
1, 1, -1, -1, 1, 1}, {-1, 1, 1, -1, 1, -1, -1}, {-1, 1, 1, -1, 1, -1, 1},
{-1, 1, 1, -1, 1, 1, -1}, {-1, 1, 1, -1, 1, 1, 1}, {-1, 1, 1, 1, -1, -1,
-1}, {-1, 1, 1, 1, -1, -1, 1}, {-1, 1, 1, 1, -1, 1, -1}, {-1, 1, 1, 1,
-1, 1, 1}, {-1, 1, 1, 1, 1, -1, -1}, {-1, 1, 1, 1, 1, -1, 1}, {-1, 1, 1,
1, 1, 1, -1}, {-1, 1, 1, 1, 1, 1, 1}, {1, -1, -1, -1, -1, -1, -1}, {1,
-1, -1, -1, -1, -1, 1}, {1, -1, -1, -1, -1, 1, -1}, {1, -1, -1, -1, -1,
1, 1}, {1, -1, -1, -1, 1, -1, -1}, {1, -1, -1, -1, 1, -1, 1}, {1, -1, -1,
-1, 1, 1, -1}, {1, -1, -1, -1, 1, 1, 1}, {1, -1, -1, 1, -1, -1, -1}, {1,
-1, -1, 1, -1, -1, 1}, {1, -1, -1, 1, -1, 1, -1}, {1, -1, -1, 1, -1, 1,
1}, {1, -1, -1, 1, 1, -1, -1}, {1, -1, -1, 1, 1, -1, 1}, {1, -1, -1, 1,
1, 1, -1}, {1, -1, -1, 1, 1, 1, 1}, {1, -1, 1, -1, -1, -1, -1}, {1, -1,
1, -1, -1, -1, 1}, {1, -1, 1, -1, -1, 1, -1}, {1, -1, 1, -1, -1, 1, 1},
{1, -1, 1, -1, 1, -1, -1}, {1, -1, 1, -1, 1, -1, 1}, {1, -1, 1, -1, 1, 1,
-1}, {1, -1, 1, -1, 1, 1, 1}, {1, -1, 1, 1, -1, -1, -1}, {1, -1, 1, 1,
-1, -1, 1}, {1, -1, 1, 1, -1, 1, -1}, {1, -1, 1, 1, -1, 1, 1}, {1, -1, 1,
1, 1, -1, -1}, {1, -1, 1, 1, 1, -1, 1}, {1, -1, 1, 1, 1, 1, -1}, {1, -1,
1, 1, 1, 1, 1}, {1, 1, -1, -1, -1, -1, -1}, {1, 1, -1, -1, -1, -1, 1},
{1, 1, -1, -1, -1, 1, -1}, {1, 1, -1, -1, -1, 1, 1}, {1, 1, -1, -1, 1,
-1, -1}, {1, 1, -1, -1, 1, -1, 1}, {1, 1, -1, -1, 1, 1, -1}, {1, 1, -1,
-1, 1, 1, 1}, {1, 1, -1, 1, -1, -1, -1}, {1, 1, -1, 1, -1, -1, 1}, {1, 1,
-1, 1, -1, 1, -1}, {1, 1, -1, 1, -1, 1, 1}, {1, 1, -1, 1, 1, -1, -1}, {1,
1, -1, 1, 1, -1, 1}, {1, 1, -1, 1, 1, 1, -1}, {1, 1, -1, 1, 1, 1, 1}, {1,
1, 1, -1, -1, -1, -1}, {1, 1, 1, -1, -1, -1, 1}, {1, 1, 1, -1, -1, 1,
-1}, {1, 1, 1, -1, -1, 1, 1}, {1, 1, 1, -1, 1, -1, -1}, {1, 1, 1, -1, 1,
-1, 1}, {1, 1, 1, -1, 1, 1, -1}, {1, 1, 1, -1, 1, 1, 1}, {1, 1, 1, 1, -1,
-1, -1}, {1, 1, 1, 1, -1, -1, 1}, {1, 1, 1, 1, -1, 1, -1}, {1, 1, 1, 1,
-1, 1, 1}, {1, 1, 1, 1, 1, -1, -1}, {1, 1, 1, 1, 1, -1, 1}, {1, 1, 1, 1,
1, 1, -1}, {1, 1, 1, 1, 1, 1, 1}};
// Denominators: spins, colors and identical particles
const int denominators[nprocesses] = {24};
ntry = ntry + 1;
// Reset the matrix elements
for(int i = 0; i < nprocesses; i++ )
{
matrix_element[i] = 0.;
}
// Define permutation
int perm[nexternal];
for(int i = 0; i < nexternal; i++ )
{
perm[i] = i;
}
if (sum_hel == 0 || ntry < 10)
{
// Calculate the matrix element for all helicities
for(int ihel = 0; ihel < ncomb; ihel++ )
{
if (goodhel[ihel] || ntry < 2)
{
calculate_wavefunctions(perm, helicities[ihel]);
t[0] = matrix_1_epem_uuxggg();
double tsum = 0;
for(int iproc = 0; iproc < nprocesses; iproc++ )
{
matrix_element[iproc] += t[iproc];
tsum += t[iproc];
}
// Store which helicities give non-zero result
if (tsum != 0. && !goodhel[ihel])
{
goodhel[ihel] = true;
ngood++;
igood[ngood] = ihel;
}
}
}
jhel = 0;
sum_hel = min(sum_hel, ngood);
}
else
{
// Only use the "good" helicities
for(int j = 0; j < sum_hel; j++ )
{
jhel++;
if (jhel >= ngood)
jhel = 0;
double hwgt = double(ngood)/double(sum_hel);
int ihel = igood[jhel];
calculate_wavefunctions(perm, helicities[ihel]);
t[0] = matrix_1_epem_uuxggg();
for(int iproc = 0; iproc < nprocesses; iproc++ )
{
matrix_element[iproc] += t[iproc] * hwgt;
}
}
}
for (int i = 0; i < nprocesses; i++ )
matrix_element[i] /= denominators[i];
}
//==========================================================================
// Private class member functions
//--------------------------------------------------------------------------
// Evaluate |M|^2 for each subprocess
void eeuuggg::calculate_wavefunctions(const int perm[], const int hel[])
{
// Calculate wavefunctions for all processes
// int i;//, j;
// Calculate all wavefunctions
oxxxxx(p[perm[0]], mME[0], hel[0], -1, w[0]);
ixxxxx(p[perm[1]], mME[1], hel[1], +1, w[1]);
oxxxxx(p[perm[2]], mME[2], hel[2], +1, w[2]);
ixxxxx(p[perm[3]], mME[3], hel[3], -1, w[3]);
vxxxxx(p[perm[4]], mME[4], hel[4], +1, w[4]);
vxxxxx(p[perm[5]], mME[5], hel[5], +1, w[5]);
vxxxxx(p[perm[6]], mME[6], hel[6], +1, w[6]);
FFV1P0_3(w[1], w[0], pars->GC_3, pars->ZERO, pars->ZERO, w[7]);
FFV1_1(w[2], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[8]);
FFV1_2(w[3], w[7], pars->GC_2, pars->ZERO, pars->ZERO, w[9]);
FFV1_1(w[8], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[10]);
FFV1_1(w[8], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[11]);
FFV2_4_3(w[1], w[0], pars->GC_50, pars->GC_59, pars->mdl_MZ, pars->mdl_WZ,
w[12]);
FFV2_5_2(w[3], w[12], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[13]);
FFV1_2(w[3], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[14]);
FFV1_1(w[8], w[7], pars->GC_2, pars->ZERO, pars->ZERO, w[15]);
FFV1_2(w[14], w[7], pars->GC_2, pars->ZERO, pars->ZERO, w[16]);
FFV2_5_1(w[8], w[12], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[17]);
FFV2_5_2(w[14], w[12], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[18]);
FFV1_2(w[3], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[19]);
FFV1_2(w[19], w[7], pars->GC_2, pars->ZERO, pars->ZERO, w[20]);
FFV2_5_2(w[19], w[12], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[21]);
VVV1P0_1(w[5], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[22]);
FFV1_1(w[2], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[23]);
FFV1_1(w[23], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[24]);
FFV1_1(w[23], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[25]);
FFV1_2(w[3], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[26]);
FFV1_1(w[23], w[7], pars->GC_2, pars->ZERO, pars->ZERO, w[27]);
FFV1_2(w[26], w[7], pars->GC_2, pars->ZERO, pars->ZERO, w[28]);
FFV2_5_1(w[23], w[12], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[29]);
FFV2_5_2(w[26], w[12], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[30]);
VVV1P0_1(w[4], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[31]);
FFV1_1(w[2], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[32]);
FFV1_1(w[32], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[33]);
FFV1_1(w[32], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[34]);
FFV1_1(w[32], w[7], pars->GC_2, pars->ZERO, pars->ZERO, w[35]);
FFV2_5_1(w[32], w[12], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[36]);
VVV1P0_1(w[4], w[5], pars->GC_10, pars->ZERO, pars->ZERO, w[37]);
FFV1_1(w[2], w[7], pars->GC_2, pars->ZERO, pars->ZERO, w[38]);
FFV1_2(w[26], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[39]);
FFV1_2(w[26], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[40]);
FFV2_5_1(w[2], w[12], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[41]);
FFV1_2(w[14], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[42]);
FFV1_2(w[14], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[43]);
FFV1_2(w[19], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[44]);
FFV1_2(w[19], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[45]);
FFV1_2(w[3], w[37], pars->GC_11, pars->ZERO, pars->ZERO, w[46]);
VVV1P0_1(w[37], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[47]);
FFV1_1(w[2], w[37], pars->GC_11, pars->ZERO, pars->ZERO, w[48]);
FFV1_2(w[3], w[31], pars->GC_11, pars->ZERO, pars->ZERO, w[49]);
VVV1P0_1(w[31], w[5], pars->GC_10, pars->ZERO, pars->ZERO, w[50]);
FFV1_1(w[2], w[31], pars->GC_11, pars->ZERO, pars->ZERO, w[51]);
FFV1_2(w[3], w[22], pars->GC_11, pars->ZERO, pars->ZERO, w[52]);
VVV1P0_1(w[4], w[22], pars->GC_10, pars->ZERO, pars->ZERO, w[53]);
FFV1_1(w[2], w[22], pars->GC_11, pars->ZERO, pars->ZERO, w[54]);
VVVV1P0_1(w[4], w[5], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[55]);
VVVV3P0_1(w[4], w[5], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[56]);
VVVV4P0_1(w[4], w[5], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[57]);
// Calculate all amplitudes
// Amplitude(s) for diagram number 0
FFV1_0(w[9], w[10], w[6], pars->GC_11, amp[0]);
FFV1_0(w[9], w[11], w[5], pars->GC_11, amp[1]);
FFV1_0(w[13], w[10], w[6], pars->GC_11, amp[2]);
FFV1_0(w[13], w[11], w[5], pars->GC_11, amp[3]);
FFV1_0(w[14], w[15], w[6], pars->GC_11, amp[4]);
FFV1_0(w[16], w[8], w[6], pars->GC_11, amp[5]);
FFV1_0(w[14], w[17], w[6], pars->GC_11, amp[6]);
FFV1_0(w[18], w[8], w[6], pars->GC_11, amp[7]);
FFV1_0(w[19], w[15], w[5], pars->GC_11, amp[8]);
FFV1_0(w[20], w[8], w[5], pars->GC_11, amp[9]);
FFV1_0(w[19], w[17], w[5], pars->GC_11, amp[10]);
FFV1_0(w[21], w[8], w[5], pars->GC_11, amp[11]);
FFV1_0(w[3], w[15], w[22], pars->GC_11, amp[12]);
FFV1_0(w[9], w[8], w[22], pars->GC_11, amp[13]);
FFV1_0(w[3], w[17], w[22], pars->GC_11, amp[14]);
FFV1_0(w[13], w[8], w[22], pars->GC_11, amp[15]);
FFV1_0(w[9], w[24], w[6], pars->GC_11, amp[16]);
FFV1_0(w[9], w[25], w[4], pars->GC_11, amp[17]);
FFV1_0(w[13], w[24], w[6], pars->GC_11, amp[18]);
FFV1_0(w[13], w[25], w[4], pars->GC_11, amp[19]);
FFV1_0(w[26], w[27], w[6], pars->GC_11, amp[20]);
FFV1_0(w[28], w[23], w[6], pars->GC_11, amp[21]);
FFV1_0(w[26], w[29], w[6], pars->GC_11, amp[22]);
FFV1_0(w[30], w[23], w[6], pars->GC_11, amp[23]);
FFV1_0(w[19], w[27], w[4], pars->GC_11, amp[24]);
FFV1_0(w[20], w[23], w[4], pars->GC_11, amp[25]);
FFV1_0(w[19], w[29], w[4], pars->GC_11, amp[26]);
FFV1_0(w[21], w[23], w[4], pars->GC_11, amp[27]);
FFV1_0(w[3], w[27], w[31], pars->GC_11, amp[28]);
FFV1_0(w[9], w[23], w[31], pars->GC_11, amp[29]);
FFV1_0(w[3], w[29], w[31], pars->GC_11, amp[30]);
FFV1_0(w[13], w[23], w[31], pars->GC_11, amp[31]);
FFV1_0(w[9], w[33], w[5], pars->GC_11, amp[32]);
FFV1_0(w[9], w[34], w[4], pars->GC_11, amp[33]);
FFV1_0(w[13], w[33], w[5], pars->GC_11, amp[34]);
FFV1_0(w[13], w[34], w[4], pars->GC_11, amp[35]);
FFV1_0(w[26], w[35], w[5], pars->GC_11, amp[36]);
FFV1_0(w[28], w[32], w[5], pars->GC_11, amp[37]);
FFV1_0(w[26], w[36], w[5], pars->GC_11, amp[38]);
FFV1_0(w[30], w[32], w[5], pars->GC_11, amp[39]);
FFV1_0(w[14], w[35], w[4], pars->GC_11, amp[40]);
FFV1_0(w[16], w[32], w[4], pars->GC_11, amp[41]);
FFV1_0(w[14], w[36], w[4], pars->GC_11, amp[42]);
FFV1_0(w[18], w[32], w[4], pars->GC_11, amp[43]);
FFV1_0(w[3], w[35], w[37], pars->GC_11, amp[44]);
FFV1_0(w[9], w[32], w[37], pars->GC_11, amp[45]);
FFV1_0(w[3], w[36], w[37], pars->GC_11, amp[46]);
FFV1_0(w[13], w[32], w[37], pars->GC_11, amp[47]);
FFV1_0(w[39], w[38], w[6], pars->GC_11, amp[48]);
FFV1_0(w[40], w[38], w[5], pars->GC_11, amp[49]);
FFV1_0(w[39], w[41], w[6], pars->GC_11, amp[50]);
FFV1_0(w[40], w[41], w[5], pars->GC_11, amp[51]);
FFV1_0(w[26], w[38], w[22], pars->GC_11, amp[52]);
FFV1_0(w[28], w[2], w[22], pars->GC_11, amp[53]);
FFV1_0(w[26], w[41], w[22], pars->GC_11, amp[54]);
FFV1_0(w[30], w[2], w[22], pars->GC_11, amp[55]);
FFV1_0(w[42], w[38], w[6], pars->GC_11, amp[56]);
FFV1_0(w[43], w[38], w[4], pars->GC_11, amp[57]);
FFV1_0(w[42], w[41], w[6], pars->GC_11, amp[58]);
FFV1_0(w[43], w[41], w[4], pars->GC_11, amp[59]);
FFV1_0(w[14], w[38], w[31], pars->GC_11, amp[60]);
FFV1_0(w[16], w[2], w[31], pars->GC_11, amp[61]);
FFV1_0(w[14], w[41], w[31], pars->GC_11, amp[62]);
FFV1_0(w[18], w[2], w[31], pars->GC_11, amp[63]);
FFV1_0(w[44], w[38], w[5], pars->GC_11, amp[64]);
FFV1_0(w[45], w[38], w[4], pars->GC_11, amp[65]);
FFV1_0(w[44], w[41], w[5], pars->GC_11, amp[66]);
FFV1_0(w[45], w[41], w[4], pars->GC_11, amp[67]);
FFV1_0(w[19], w[38], w[37], pars->GC_11, amp[68]);
FFV1_0(w[20], w[2], w[37], pars->GC_11, amp[69]);
FFV1_0(w[19], w[41], w[37], pars->GC_11, amp[70]);
FFV1_0(w[21], w[2], w[37], pars->GC_11, amp[71]);
FFV1_0(w[46], w[38], w[6], pars->GC_11, amp[72]);
FFV1_0(w[3], w[38], w[47], pars->GC_11, amp[73]);
FFV1_0(w[9], w[48], w[6], pars->GC_11, amp[74]);
FFV1_0(w[9], w[2], w[47], pars->GC_11, amp[75]);
FFV1_0(w[46], w[41], w[6], pars->GC_11, amp[76]);
FFV1_0(w[3], w[41], w[47], pars->GC_11, amp[77]);
FFV1_0(w[13], w[48], w[6], pars->GC_11, amp[78]);
FFV1_0(w[13], w[2], w[47], pars->GC_11, amp[79]);
FFV1_0(w[49], w[38], w[5], pars->GC_11, amp[80]);
FFV1_0(w[3], w[38], w[50], pars->GC_11, amp[81]);
FFV1_0(w[9], w[51], w[5], pars->GC_11, amp[82]);
FFV1_0(w[9], w[2], w[50], pars->GC_11, amp[83]);
FFV1_0(w[49], w[41], w[5], pars->GC_11, amp[84]);
FFV1_0(w[3], w[41], w[50], pars->GC_11, amp[85]);
FFV1_0(w[13], w[51], w[5], pars->GC_11, amp[86]);
FFV1_0(w[13], w[2], w[50], pars->GC_11, amp[87]);
FFV1_0(w[52], w[38], w[4], pars->GC_11, amp[88]);
FFV1_0(w[3], w[38], w[53], pars->GC_11, amp[89]);
FFV1_0(w[9], w[54], w[4], pars->GC_11, amp[90]);
FFV1_0(w[9], w[2], w[53], pars->GC_11, amp[91]);
FFV1_0(w[52], w[41], w[4], pars->GC_11, amp[92]);
FFV1_0(w[3], w[41], w[53], pars->GC_11, amp[93]);
FFV1_0(w[13], w[54], w[4], pars->GC_11, amp[94]);
FFV1_0(w[13], w[2], w[53], pars->GC_11, amp[95]);
FFV1_0(w[3], w[38], w[55], pars->GC_11, amp[96]);
FFV1_0(w[3], w[38], w[56], pars->GC_11, amp[97]);
FFV1_0(w[3], w[38], w[57], pars->GC_11, amp[98]);
FFV1_0(w[9], w[2], w[55], pars->GC_11, amp[99]);
FFV1_0(w[9], w[2], w[56], pars->GC_11, amp[100]);
FFV1_0(w[9], w[2], w[57], pars->GC_11, amp[101]);
FFV1_0(w[3], w[41], w[55], pars->GC_11, amp[102]);
FFV1_0(w[3], w[41], w[56], pars->GC_11, amp[103]);
FFV1_0(w[3], w[41], w[57], pars->GC_11, amp[104]);
FFV1_0(w[13], w[2], w[55], pars->GC_11, amp[105]);
FFV1_0(w[13], w[2], w[56], pars->GC_11, amp[106]);
FFV1_0(w[13], w[2], w[57], pars->GC_11, amp[107]);
}
double eeuuggg::matrix_1_epem_uuxggg()
{
int i;//, j;
// Local variables
// const int ngraphs = 108;
const int ncolor = 6;
- std::complex<double> ztemp;
std::complex<double> jamp[ncolor];
// The color matrix;
// static const double denom[ncolor] = {9, 9, 9, 9, 9, 9};
// static const double cf[ncolor][ncolor] = {{64, -8, -8, 1, 1, 10}, {-8, 64, 1,
// 10, -8, 1}, {-8, 1, 64, -8, 10, 1}, {1, 10, -8, 64, 1, -8}, {1, -8, 10,
// 1, 64, -8}, {10, 1, 1, -8, -8, 64}};
// Calculate color flows
jamp[0] = +amp[0] + amp[2] + amp[8] + amp[9] + amp[10] + amp[11] -
std::complex<double> (0, 1) * amp[12] - std::complex<double> (0, 1) *
amp[13] - std::complex<double> (0, 1) * amp[14] - std::complex<double>
(0, 1) * amp[15] + amp[65] + amp[67] - std::complex<double> (0, 1) *
amp[68] - std::complex<double> (0, 1) * amp[69] - std::complex<double>
(0, 1) * amp[70] - std::complex<double> (0, 1) * amp[71] - amp[73] -
std::complex<double> (0, 1) * amp[74] - amp[75] - amp[77] -
std::complex<double> (0, 1) * amp[78] - amp[79] - std::complex<double>
(0, 1) * amp[88] - amp[89] - amp[91] - std::complex<double> (0, 1) *
amp[92] - amp[93] - amp[95] + amp[98] - amp[96] + amp[101] - amp[99] +
amp[104] - amp[102] + amp[107] - amp[105];
jamp[1] = +amp[1] + amp[3] + amp[4] + amp[5] + amp[6] + amp[7] +
std::complex<double> (0, 1) * amp[12] + std::complex<double> (0, 1) *
amp[13] + std::complex<double> (0, 1) * amp[14] + std::complex<double>
(0, 1) * amp[15] + amp[57] + amp[59] - std::complex<double> (0, 1) *
amp[60] - std::complex<double> (0, 1) * amp[61] - std::complex<double>
(0, 1) * amp[62] - std::complex<double> (0, 1) * amp[63] - amp[81] -
std::complex<double> (0, 1) * amp[82] - amp[83] - amp[85] -
std::complex<double> (0, 1) * amp[86] - amp[87] + std::complex<double>
(0, 1) * amp[88] + amp[89] + amp[91] + std::complex<double> (0, 1) *
amp[92] + amp[93] + amp[95] + amp[96] + amp[97] + amp[99] + amp[100] +
amp[102] + amp[103] + amp[105] + amp[106];
jamp[2] = +amp[16] + amp[18] + amp[24] + amp[25] + amp[26] + amp[27] -
std::complex<double> (0, 1) * amp[28] - std::complex<double> (0, 1) *
amp[29] - std::complex<double> (0, 1) * amp[30] - std::complex<double>
(0, 1) * amp[31] + amp[64] + amp[66] + std::complex<double> (0, 1) *
amp[68] + std::complex<double> (0, 1) * amp[69] + std::complex<double>
(0, 1) * amp[70] + std::complex<double> (0, 1) * amp[71] + amp[73] +
std::complex<double> (0, 1) * amp[74] + amp[75] + amp[77] +
std::complex<double> (0, 1) * amp[78] + amp[79] - std::complex<double>
(0, 1) * amp[80] + amp[81] + amp[83] - std::complex<double> (0, 1) *
amp[84] + amp[85] + amp[87] - amp[98] - amp[97] - amp[101] - amp[100] -
amp[104] - amp[103] - amp[107] - amp[106];
jamp[3] = +amp[17] + amp[19] + amp[20] + amp[21] + amp[22] + amp[23] +
std::complex<double> (0, 1) * amp[28] + std::complex<double> (0, 1) *
amp[29] + std::complex<double> (0, 1) * amp[30] + std::complex<double>
(0, 1) * amp[31] + amp[49] + amp[51] - std::complex<double> (0, 1) *
amp[52] - std::complex<double> (0, 1) * amp[53] - std::complex<double>
(0, 1) * amp[54] - std::complex<double> (0, 1) * amp[55] +
std::complex<double> (0, 1) * amp[80] - amp[81] - amp[83] +
std::complex<double> (0, 1) * amp[84] - amp[85] - amp[87] + amp[89] -
std::complex<double> (0, 1) * amp[90] + amp[91] + amp[93] -
std::complex<double> (0, 1) * amp[94] + amp[95] + amp[96] + amp[97] +
amp[99] + amp[100] + amp[102] + amp[103] + amp[105] + amp[106];
jamp[4] = +amp[32] + amp[34] + amp[40] + amp[41] + amp[42] + amp[43] -
std::complex<double> (0, 1) * amp[44] - std::complex<double> (0, 1) *
amp[45] - std::complex<double> (0, 1) * amp[46] - std::complex<double>
(0, 1) * amp[47] + amp[56] + amp[58] + std::complex<double> (0, 1) *
amp[60] + std::complex<double> (0, 1) * amp[61] + std::complex<double>
(0, 1) * amp[62] + std::complex<double> (0, 1) * amp[63] -
std::complex<double> (0, 1) * amp[72] + amp[73] + amp[75] -
std::complex<double> (0, 1) * amp[76] + amp[77] + amp[79] + amp[81] +
std::complex<double> (0, 1) * amp[82] + amp[83] + amp[85] +
std::complex<double> (0, 1) * amp[86] + amp[87] - amp[98] - amp[97] -
amp[101] - amp[100] - amp[104] - amp[103] - amp[107] - amp[106];
jamp[5] = +amp[33] + amp[35] + amp[36] + amp[37] + amp[38] + amp[39] +
std::complex<double> (0, 1) * amp[44] + std::complex<double> (0, 1) *
amp[45] + std::complex<double> (0, 1) * amp[46] + std::complex<double>
(0, 1) * amp[47] + amp[48] + amp[50] + std::complex<double> (0, 1) *
amp[52] + std::complex<double> (0, 1) * amp[53] + std::complex<double>
(0, 1) * amp[54] + std::complex<double> (0, 1) * amp[55] +
std::complex<double> (0, 1) * amp[72] - amp[73] - amp[75] +
std::complex<double> (0, 1) * amp[76] - amp[77] - amp[79] - amp[89] +
std::complex<double> (0, 1) * amp[90] - amp[91] - amp[93] +
std::complex<double> (0, 1) * amp[94] - amp[95] + amp[98] - amp[96] +
amp[101] - amp[99] + amp[104] - amp[102] + amp[107] - amp[105];
// Store the leading color flows for choice of color
for(i = 0; i < ncolor; i++ )
jamp2[0][i] += real(jamp[i] * conj(jamp[i]));
return -1.;
}
double eeuuggg::get_jamp2(int i)
{
return jamp2[0][i];
}
int eeuuggg::colorstring(int i, int j)
{
static const double res[6][6] = {
{5, 6, 7, 3, 4, 0},
{5, 7, 6, 3, 4, 0},
{6, 5, 7, 3, 4, 0},
{6, 7, 5, 3, 4, 0},
{7, 5, 6, 3, 4, 0},
{7, 6, 5, 3, 4, 0}};
return res[i][j];
}
int eeuuggg::NCol()
{
const int ncolor = 6;
return ncolor;
}
diff --git a/Shower/Dipole/Colorea/eeuugggg.cc b/Shower/Dipole/Colorea/eeuugggg.cc
--- a/Shower/Dipole/Colorea/eeuugggg.cc
+++ b/Shower/Dipole/Colorea/eeuugggg.cc
@@ -1,3120 +1,3119 @@
//==========================================================================
// This file has been automatically generated for C++ Standalone by
// MadGraph5_aMC@NLO v. 2.5.4, 2017-03-28
// By the MadGraph5_aMC@NLO Development Team
// Visit launchpad.net/madgraph5 and amcatnlo.web.cern.ch
//==========================================================================
// and was then modified by J. Bellm.
#include "eeuugggg.h"
#include "HelAmps_sm.h"
#include <iostream>
using namespace MG5_sm_COLOREA;
//==========================================================================
// Class member functions for calculating the matrix elements for
// Process: e+ e- > u u~ g g g g WEIGHTED<=8 @1
//--------------------------------------------------------------------------
// Initialize process.
vector<int> eeuugggg::producePermutation(double r,vector < double * > & momenta){
static bool initialized=false;
if (!initialized){
initProc("param_card.dat");
initialized=true;
}
setMomenta(momenta);
sigmaKin();
static const int res[24][8] = {
{5, 6, 7, 8, 3, 4, 0, 0},
{5, 6, 8, 7, 3, 4, 0, 0},
{5, 7, 6, 8, 3, 4, 0, 0},
{5, 7, 8, 6, 3, 4, 0, 0},
{5, 8, 6, 7, 3, 4, 0, 0},
{5, 8, 7, 6, 3, 4, 0, 0},
{6, 5, 7, 8, 3, 4, 0, 0},
{6, 5, 8, 7, 3, 4, 0, 0},
{6, 7, 5, 8, 3, 4, 0, 0},
{6, 7, 8, 5, 3, 4, 0, 0},
{6, 8, 5, 7, 3, 4, 0, 0},
{6, 8, 7, 5, 3, 4, 0, 0},
{7, 5, 6, 8, 3, 4, 0, 0},
{7, 5, 8, 6, 3, 4, 0, 0},
{7, 6, 5, 8, 3, 4, 0, 0},
{7, 6, 8, 5, 3, 4, 0, 0},
{7, 8, 5, 6, 3, 4, 0, 0},
{7, 8, 6, 5, 3, 4, 0, 0},
{8, 5, 6, 7, 3, 4, 0, 0},
{8, 5, 7, 6, 3, 4, 0, 0},
{8, 6, 5, 7, 3, 4, 0, 0},
{8, 6, 7, 5, 3, 4, 0, 0},
{8, 7, 5, 6, 3, 4, 0, 0},
{8, 7, 6, 5, 3, 4, 0, 0}};
double jampsum=0.;
for( int i=0;i<24;i++) jampsum+=jamp2[0][i];
double cur=0.;
for(int i=0;i<24;i++){
cur+=jamp2[0][i];
if( cur/jampsum > r )return std::vector<int>(res[i], res[i] + sizeof res[i] / sizeof res[i][0]);
}
//std::cout<<"producePermutation: Upps.. Something went wrong!!";
return std::vector<int>();
}
void eeuugggg::initProc(string param_card_name)
{
cout<<"\nColorea: Init process eeuugggg for rearrangement (arXiv:1801.06113).";
// Instantiate the model class and set parameters that stay fixed during run
pars = Parameters_sm::getInstance();
SLHAReader_COLOREA slha(param_card_name);
pars->setIndependentParameters(slha);
pars->setIndependentCouplings();
// pars->printIndependentParameters();
// pars->printIndependentCouplings();
// Set external particle masses for this matrix element
mME.push_back(pars->ZERO);
mME.push_back(pars->ZERO);
mME.push_back(pars->ZERO);
mME.push_back(pars->ZERO);
mME.push_back(pars->ZERO);
mME.push_back(pars->ZERO);
mME.push_back(pars->ZERO);
mME.push_back(pars->ZERO);
jamp2[0] = new double[24];
}
//--------------------------------------------------------------------------
// Evaluate |M|^2, part independent of incoming flavour.
void eeuugggg::sigmaKin()
{
// Set the parameters which change event by event
pars->setDependentParameters();
pars->setDependentCouplings();
static bool firsttime = true;
if (firsttime)
{
// pars->printDependentParameters();
// pars->printDependentCouplings();
firsttime = false;
}
// Reset color flows
for(int i = 0; i < 24; i++ )
jamp2[0][i] = 0.;
// Local variables and constants
const int ncomb = 256;
static bool goodhel[ncomb] = {ncomb * false};
static int ntry = 0, sum_hel = 0, ngood = 0;
static int igood[ncomb];
static int jhel;
// std::complex<double> * * wfs;
double t[nprocesses];
// Helicities for the process
static const int helicities[ncomb][nexternal] = {{-1, -1, -1, -1, -1, -1, -1,
-1}, {-1, -1, -1, -1, -1, -1, -1, 1}, {-1, -1, -1, -1, -1, -1, 1, -1},
{-1, -1, -1, -1, -1, -1, 1, 1}, {-1, -1, -1, -1, -1, 1, -1, -1}, {-1, -1,
-1, -1, -1, 1, -1, 1}, {-1, -1, -1, -1, -1, 1, 1, -1}, {-1, -1, -1, -1,
-1, 1, 1, 1}, {-1, -1, -1, -1, 1, -1, -1, -1}, {-1, -1, -1, -1, 1, -1,
-1, 1}, {-1, -1, -1, -1, 1, -1, 1, -1}, {-1, -1, -1, -1, 1, -1, 1, 1},
{-1, -1, -1, -1, 1, 1, -1, -1}, {-1, -1, -1, -1, 1, 1, -1, 1}, {-1, -1,
-1, -1, 1, 1, 1, -1}, {-1, -1, -1, -1, 1, 1, 1, 1}, {-1, -1, -1, 1, -1,
-1, -1, -1}, {-1, -1, -1, 1, -1, -1, -1, 1}, {-1, -1, -1, 1, -1, -1, 1,
-1}, {-1, -1, -1, 1, -1, -1, 1, 1}, {-1, -1, -1, 1, -1, 1, -1, -1}, {-1,
-1, -1, 1, -1, 1, -1, 1}, {-1, -1, -1, 1, -1, 1, 1, -1}, {-1, -1, -1, 1,
-1, 1, 1, 1}, {-1, -1, -1, 1, 1, -1, -1, -1}, {-1, -1, -1, 1, 1, -1, -1,
1}, {-1, -1, -1, 1, 1, -1, 1, -1}, {-1, -1, -1, 1, 1, -1, 1, 1}, {-1, -1,
-1, 1, 1, 1, -1, -1}, {-1, -1, -1, 1, 1, 1, -1, 1}, {-1, -1, -1, 1, 1, 1,
1, -1}, {-1, -1, -1, 1, 1, 1, 1, 1}, {-1, -1, 1, -1, -1, -1, -1, -1},
{-1, -1, 1, -1, -1, -1, -1, 1}, {-1, -1, 1, -1, -1, -1, 1, -1}, {-1, -1,
1, -1, -1, -1, 1, 1}, {-1, -1, 1, -1, -1, 1, -1, -1}, {-1, -1, 1, -1, -1,
1, -1, 1}, {-1, -1, 1, -1, -1, 1, 1, -1}, {-1, -1, 1, -1, -1, 1, 1, 1},
{-1, -1, 1, -1, 1, -1, -1, -1}, {-1, -1, 1, -1, 1, -1, -1, 1}, {-1, -1,
1, -1, 1, -1, 1, -1}, {-1, -1, 1, -1, 1, -1, 1, 1}, {-1, -1, 1, -1, 1, 1,
-1, -1}, {-1, -1, 1, -1, 1, 1, -1, 1}, {-1, -1, 1, -1, 1, 1, 1, -1}, {-1,
-1, 1, -1, 1, 1, 1, 1}, {-1, -1, 1, 1, -1, -1, -1, -1}, {-1, -1, 1, 1,
-1, -1, -1, 1}, {-1, -1, 1, 1, -1, -1, 1, -1}, {-1, -1, 1, 1, -1, -1, 1,
1}, {-1, -1, 1, 1, -1, 1, -1, -1}, {-1, -1, 1, 1, -1, 1, -1, 1}, {-1, -1,
1, 1, -1, 1, 1, -1}, {-1, -1, 1, 1, -1, 1, 1, 1}, {-1, -1, 1, 1, 1, -1,
-1, -1}, {-1, -1, 1, 1, 1, -1, -1, 1}, {-1, -1, 1, 1, 1, -1, 1, -1}, {-1,
-1, 1, 1, 1, -1, 1, 1}, {-1, -1, 1, 1, 1, 1, -1, -1}, {-1, -1, 1, 1, 1,
1, -1, 1}, {-1, -1, 1, 1, 1, 1, 1, -1}, {-1, -1, 1, 1, 1, 1, 1, 1}, {-1,
1, -1, -1, -1, -1, -1, -1}, {-1, 1, -1, -1, -1, -1, -1, 1}, {-1, 1, -1,
-1, -1, -1, 1, -1}, {-1, 1, -1, -1, -1, -1, 1, 1}, {-1, 1, -1, -1, -1, 1,
-1, -1}, {-1, 1, -1, -1, -1, 1, -1, 1}, {-1, 1, -1, -1, -1, 1, 1, -1},
{-1, 1, -1, -1, -1, 1, 1, 1}, {-1, 1, -1, -1, 1, -1, -1, -1}, {-1, 1, -1,
-1, 1, -1, -1, 1}, {-1, 1, -1, -1, 1, -1, 1, -1}, {-1, 1, -1, -1, 1, -1,
1, 1}, {-1, 1, -1, -1, 1, 1, -1, -1}, {-1, 1, -1, -1, 1, 1, -1, 1}, {-1,
1, -1, -1, 1, 1, 1, -1}, {-1, 1, -1, -1, 1, 1, 1, 1}, {-1, 1, -1, 1, -1,
-1, -1, -1}, {-1, 1, -1, 1, -1, -1, -1, 1}, {-1, 1, -1, 1, -1, -1, 1,
-1}, {-1, 1, -1, 1, -1, -1, 1, 1}, {-1, 1, -1, 1, -1, 1, -1, -1}, {-1, 1,
-1, 1, -1, 1, -1, 1}, {-1, 1, -1, 1, -1, 1, 1, -1}, {-1, 1, -1, 1, -1, 1,
1, 1}, {-1, 1, -1, 1, 1, -1, -1, -1}, {-1, 1, -1, 1, 1, -1, -1, 1}, {-1,
1, -1, 1, 1, -1, 1, -1}, {-1, 1, -1, 1, 1, -1, 1, 1}, {-1, 1, -1, 1, 1,
1, -1, -1}, {-1, 1, -1, 1, 1, 1, -1, 1}, {-1, 1, -1, 1, 1, 1, 1, -1},
{-1, 1, -1, 1, 1, 1, 1, 1}, {-1, 1, 1, -1, -1, -1, -1, -1}, {-1, 1, 1,
-1, -1, -1, -1, 1}, {-1, 1, 1, -1, -1, -1, 1, -1}, {-1, 1, 1, -1, -1, -1,
1, 1}, {-1, 1, 1, -1, -1, 1, -1, -1}, {-1, 1, 1, -1, -1, 1, -1, 1}, {-1,
1, 1, -1, -1, 1, 1, -1}, {-1, 1, 1, -1, -1, 1, 1, 1}, {-1, 1, 1, -1, 1,
-1, -1, -1}, {-1, 1, 1, -1, 1, -1, -1, 1}, {-1, 1, 1, -1, 1, -1, 1, -1},
{-1, 1, 1, -1, 1, -1, 1, 1}, {-1, 1, 1, -1, 1, 1, -1, -1}, {-1, 1, 1, -1,
1, 1, -1, 1}, {-1, 1, 1, -1, 1, 1, 1, -1}, {-1, 1, 1, -1, 1, 1, 1, 1},
{-1, 1, 1, 1, -1, -1, -1, -1}, {-1, 1, 1, 1, -1, -1, -1, 1}, {-1, 1, 1,
1, -1, -1, 1, -1}, {-1, 1, 1, 1, -1, -1, 1, 1}, {-1, 1, 1, 1, -1, 1, -1,
-1}, {-1, 1, 1, 1, -1, 1, -1, 1}, {-1, 1, 1, 1, -1, 1, 1, -1}, {-1, 1, 1,
1, -1, 1, 1, 1}, {-1, 1, 1, 1, 1, -1, -1, -1}, {-1, 1, 1, 1, 1, -1, -1,
1}, {-1, 1, 1, 1, 1, -1, 1, -1}, {-1, 1, 1, 1, 1, -1, 1, 1}, {-1, 1, 1,
1, 1, 1, -1, -1}, {-1, 1, 1, 1, 1, 1, -1, 1}, {-1, 1, 1, 1, 1, 1, 1, -1},
{-1, 1, 1, 1, 1, 1, 1, 1}, {1, -1, -1, -1, -1, -1, -1, -1}, {1, -1, -1,
-1, -1, -1, -1, 1}, {1, -1, -1, -1, -1, -1, 1, -1}, {1, -1, -1, -1, -1,
-1, 1, 1}, {1, -1, -1, -1, -1, 1, -1, -1}, {1, -1, -1, -1, -1, 1, -1, 1},
{1, -1, -1, -1, -1, 1, 1, -1}, {1, -1, -1, -1, -1, 1, 1, 1}, {1, -1, -1,
-1, 1, -1, -1, -1}, {1, -1, -1, -1, 1, -1, -1, 1}, {1, -1, -1, -1, 1, -1,
1, -1}, {1, -1, -1, -1, 1, -1, 1, 1}, {1, -1, -1, -1, 1, 1, -1, -1}, {1,
-1, -1, -1, 1, 1, -1, 1}, {1, -1, -1, -1, 1, 1, 1, -1}, {1, -1, -1, -1,
1, 1, 1, 1}, {1, -1, -1, 1, -1, -1, -1, -1}, {1, -1, -1, 1, -1, -1, -1,
1}, {1, -1, -1, 1, -1, -1, 1, -1}, {1, -1, -1, 1, -1, -1, 1, 1}, {1, -1,
-1, 1, -1, 1, -1, -1}, {1, -1, -1, 1, -1, 1, -1, 1}, {1, -1, -1, 1, -1,
1, 1, -1}, {1, -1, -1, 1, -1, 1, 1, 1}, {1, -1, -1, 1, 1, -1, -1, -1},
{1, -1, -1, 1, 1, -1, -1, 1}, {1, -1, -1, 1, 1, -1, 1, -1}, {1, -1, -1,
1, 1, -1, 1, 1}, {1, -1, -1, 1, 1, 1, -1, -1}, {1, -1, -1, 1, 1, 1, -1,
1}, {1, -1, -1, 1, 1, 1, 1, -1}, {1, -1, -1, 1, 1, 1, 1, 1}, {1, -1, 1,
-1, -1, -1, -1, -1}, {1, -1, 1, -1, -1, -1, -1, 1}, {1, -1, 1, -1, -1,
-1, 1, -1}, {1, -1, 1, -1, -1, -1, 1, 1}, {1, -1, 1, -1, -1, 1, -1, -1},
{1, -1, 1, -1, -1, 1, -1, 1}, {1, -1, 1, -1, -1, 1, 1, -1}, {1, -1, 1,
-1, -1, 1, 1, 1}, {1, -1, 1, -1, 1, -1, -1, -1}, {1, -1, 1, -1, 1, -1,
-1, 1}, {1, -1, 1, -1, 1, -1, 1, -1}, {1, -1, 1, -1, 1, -1, 1, 1}, {1,
-1, 1, -1, 1, 1, -1, -1}, {1, -1, 1, -1, 1, 1, -1, 1}, {1, -1, 1, -1, 1,
1, 1, -1}, {1, -1, 1, -1, 1, 1, 1, 1}, {1, -1, 1, 1, -1, -1, -1, -1}, {1,
-1, 1, 1, -1, -1, -1, 1}, {1, -1, 1, 1, -1, -1, 1, -1}, {1, -1, 1, 1, -1,
-1, 1, 1}, {1, -1, 1, 1, -1, 1, -1, -1}, {1, -1, 1, 1, -1, 1, -1, 1}, {1,
-1, 1, 1, -1, 1, 1, -1}, {1, -1, 1, 1, -1, 1, 1, 1}, {1, -1, 1, 1, 1, -1,
-1, -1}, {1, -1, 1, 1, 1, -1, -1, 1}, {1, -1, 1, 1, 1, -1, 1, -1}, {1,
-1, 1, 1, 1, -1, 1, 1}, {1, -1, 1, 1, 1, 1, -1, -1}, {1, -1, 1, 1, 1, 1,
-1, 1}, {1, -1, 1, 1, 1, 1, 1, -1}, {1, -1, 1, 1, 1, 1, 1, 1}, {1, 1, -1,
-1, -1, -1, -1, -1}, {1, 1, -1, -1, -1, -1, -1, 1}, {1, 1, -1, -1, -1,
-1, 1, -1}, {1, 1, -1, -1, -1, -1, 1, 1}, {1, 1, -1, -1, -1, 1, -1, -1},
{1, 1, -1, -1, -1, 1, -1, 1}, {1, 1, -1, -1, -1, 1, 1, -1}, {1, 1, -1,
-1, -1, 1, 1, 1}, {1, 1, -1, -1, 1, -1, -1, -1}, {1, 1, -1, -1, 1, -1,
-1, 1}, {1, 1, -1, -1, 1, -1, 1, -1}, {1, 1, -1, -1, 1, -1, 1, 1}, {1, 1,
-1, -1, 1, 1, -1, -1}, {1, 1, -1, -1, 1, 1, -1, 1}, {1, 1, -1, -1, 1, 1,
1, -1}, {1, 1, -1, -1, 1, 1, 1, 1}, {1, 1, -1, 1, -1, -1, -1, -1}, {1, 1,
-1, 1, -1, -1, -1, 1}, {1, 1, -1, 1, -1, -1, 1, -1}, {1, 1, -1, 1, -1,
-1, 1, 1}, {1, 1, -1, 1, -1, 1, -1, -1}, {1, 1, -1, 1, -1, 1, -1, 1}, {1,
1, -1, 1, -1, 1, 1, -1}, {1, 1, -1, 1, -1, 1, 1, 1}, {1, 1, -1, 1, 1, -1,
-1, -1}, {1, 1, -1, 1, 1, -1, -1, 1}, {1, 1, -1, 1, 1, -1, 1, -1}, {1, 1,
-1, 1, 1, -1, 1, 1}, {1, 1, -1, 1, 1, 1, -1, -1}, {1, 1, -1, 1, 1, 1, -1,
1}, {1, 1, -1, 1, 1, 1, 1, -1}, {1, 1, -1, 1, 1, 1, 1, 1}, {1, 1, 1, -1,
-1, -1, -1, -1}, {1, 1, 1, -1, -1, -1, -1, 1}, {1, 1, 1, -1, -1, -1, 1,
-1}, {1, 1, 1, -1, -1, -1, 1, 1}, {1, 1, 1, -1, -1, 1, -1, -1}, {1, 1, 1,
-1, -1, 1, -1, 1}, {1, 1, 1, -1, -1, 1, 1, -1}, {1, 1, 1, -1, -1, 1, 1,
1}, {1, 1, 1, -1, 1, -1, -1, -1}, {1, 1, 1, -1, 1, -1, -1, 1}, {1, 1, 1,
-1, 1, -1, 1, -1}, {1, 1, 1, -1, 1, -1, 1, 1}, {1, 1, 1, -1, 1, 1, -1,
-1}, {1, 1, 1, -1, 1, 1, -1, 1}, {1, 1, 1, -1, 1, 1, 1, -1}, {1, 1, 1,
-1, 1, 1, 1, 1}, {1, 1, 1, 1, -1, -1, -1, -1}, {1, 1, 1, 1, -1, -1, -1,
1}, {1, 1, 1, 1, -1, -1, 1, -1}, {1, 1, 1, 1, -1, -1, 1, 1}, {1, 1, 1, 1,
-1, 1, -1, -1}, {1, 1, 1, 1, -1, 1, -1, 1}, {1, 1, 1, 1, -1, 1, 1, -1},
{1, 1, 1, 1, -1, 1, 1, 1}, {1, 1, 1, 1, 1, -1, -1, -1}, {1, 1, 1, 1, 1,
-1, -1, 1}, {1, 1, 1, 1, 1, -1, 1, -1}, {1, 1, 1, 1, 1, -1, 1, 1}, {1, 1,
1, 1, 1, 1, -1, -1}, {1, 1, 1, 1, 1, 1, -1, 1}, {1, 1, 1, 1, 1, 1, 1,
-1}, {1, 1, 1, 1, 1, 1, 1, 1}};
// Denominators: spins, colors and identical particles
const int denominators[nprocesses] = {96};
ntry = ntry + 1;
// Reset the matrix elements
for(int i = 0; i < nprocesses; i++ )
{
matrix_element[i] = 0.;
}
// Define permutation
int perm[nexternal];
for(int i = 0; i < nexternal; i++ )
{
perm[i] = i;
}
if (sum_hel == 0 || ntry < 10)
{
// Calculate the matrix element for all helicities
for(int ihel = 0; ihel < ncomb; ihel++ )
{
if (goodhel[ihel] || ntry < 2)
{
calculate_wavefunctions(perm, helicities[ihel]);
t[0] = matrix_1_epem_uuxgggg();
double tsum = 0;
for(int iproc = 0; iproc < nprocesses; iproc++ )
{
matrix_element[iproc] += t[iproc];
tsum += t[iproc];
}
// Store which helicities give non-zero result
if (tsum != 0. && !goodhel[ihel])
{
goodhel[ihel] = true;
ngood++;
igood[ngood] = ihel;
}
}
}
jhel = 0;
sum_hel = min(sum_hel, ngood);
}
else
{
// Only use the "good" helicities
for(int j = 0; j < sum_hel; j++ )
{
jhel++;
if (jhel >= ngood)
jhel = 0;
double hwgt = double(ngood)/double(sum_hel);
int ihel = igood[jhel];
calculate_wavefunctions(perm, helicities[ihel]);
t[0] = matrix_1_epem_uuxgggg();
for(int iproc = 0; iproc < nprocesses; iproc++ )
{
matrix_element[iproc] += t[iproc] * hwgt;
}
}
}
for (int i = 0; i < nprocesses; i++ )
matrix_element[i] /= denominators[i];
}
//--------------------------------------------------------------------------
// Evaluate |M|^2 for each subprocess
void eeuugggg::calculate_wavefunctions(const int perm[], const int hel[])
{
// Calculate all wavefunctions
oxxxxx(p[perm[0]], mME[0], hel[0], -1, w[0]);
ixxxxx(p[perm[1]], mME[1], hel[1], +1, w[1]);
oxxxxx(p[perm[2]], mME[2], hel[2], +1, w[2]);
ixxxxx(p[perm[3]], mME[3], hel[3], -1, w[3]);
vxxxxx(p[perm[4]], mME[4], hel[4], +1, w[4]);
vxxxxx(p[perm[5]], mME[5], hel[5], +1, w[5]);
vxxxxx(p[perm[6]], mME[6], hel[6], +1, w[6]);
vxxxxx(p[perm[7]], mME[7], hel[7], +1, w[7]);
FFV1P0_3(w[1], w[0], pars->GC_3, pars->ZERO, pars->ZERO, w[8]);
FFV1_1(w[2], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[9]);
FFV1_2(w[3], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[10]);
FFV1_1(w[9], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[11]);
FFV1_2(w[10], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[12]);
FFV1_2(w[10], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[13]);
FFV1_1(w[9], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[14]);
FFV1_2(w[10], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[15]);
FFV1_1(w[9], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[16]);
FFV2_4_3(w[1], w[0], pars->GC_50, pars->GC_59, pars->mdl_MZ, pars->mdl_WZ,
w[17]);
FFV2_5_2(w[3], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[18]);
FFV1_2(w[18], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[19]);
FFV1_2(w[18], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[20]);
FFV1_2(w[18], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[21]);
FFV1_2(w[3], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[22]);
FFV1_1(w[9], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[23]);
FFV1_2(w[22], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[24]);
FFV1_2(w[22], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[25]);
FFV1_2(w[22], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[26]);
FFV2_5_1(w[9], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[27]);
FFV2_5_2(w[22], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[28]);
VVV1P0_1(w[6], w[7], pars->GC_10, pars->ZERO, pars->ZERO, w[29]);
FFV1_2(w[3], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[30]);
FFV1_2(w[30], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[31]);
FFV1_2(w[30], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[32]);
FFV1_2(w[30], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[33]);
FFV2_5_2(w[30], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[34]);
VVV1P0_1(w[5], w[7], pars->GC_10, pars->ZERO, pars->ZERO, w[35]);
FFV1_2(w[3], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[36]);
FFV1_2(w[36], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[37]);
FFV1_2(w[36], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[38]);
FFV1_2(w[36], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[39]);
FFV2_5_2(w[36], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[40]);
VVV1P0_1(w[5], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[41]);
FFV1_2(w[3], w[41], pars->GC_11, pars->ZERO, pars->ZERO, w[42]);
VVV1P0_1(w[41], w[7], pars->GC_10, pars->ZERO, pars->ZERO, w[43]);
FFV1_1(w[9], w[41], pars->GC_11, pars->ZERO, pars->ZERO, w[44]);
FFV1_2(w[3], w[35], pars->GC_11, pars->ZERO, pars->ZERO, w[45]);
VVV1P0_1(w[35], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[46]);
FFV1_1(w[9], w[35], pars->GC_11, pars->ZERO, pars->ZERO, w[47]);
FFV1_2(w[3], w[29], pars->GC_11, pars->ZERO, pars->ZERO, w[48]);
VVV1P0_1(w[5], w[29], pars->GC_10, pars->ZERO, pars->ZERO, w[49]);
FFV1_1(w[9], w[29], pars->GC_11, pars->ZERO, pars->ZERO, w[50]);
VVVV1P0_1(w[5], w[6], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[51]);
VVVV3P0_1(w[5], w[6], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[52]);
VVVV4P0_1(w[5], w[6], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[53]);
FFV1_1(w[2], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[54]);
FFV1_1(w[54], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[55]);
FFV1_1(w[54], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[56]);
FFV1_2(w[10], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[57]);
FFV1_1(w[54], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[58]);
FFV1_2(w[18], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[59]);
FFV1_2(w[3], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[60]);
FFV1_1(w[54], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[61]);
FFV1_2(w[60], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[62]);
FFV1_2(w[60], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[63]);
FFV1_2(w[60], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[64]);
FFV2_5_1(w[54], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[65]);
FFV2_5_2(w[60], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[66]);
FFV1_2(w[30], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[67]);
VVV1P0_1(w[4], w[7], pars->GC_10, pars->ZERO, pars->ZERO, w[68]);
FFV1_2(w[36], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[69]);
VVV1P0_1(w[4], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[70]);
FFV1_2(w[3], w[70], pars->GC_11, pars->ZERO, pars->ZERO, w[71]);
VVV1P0_1(w[70], w[7], pars->GC_10, pars->ZERO, pars->ZERO, w[72]);
FFV1_1(w[54], w[70], pars->GC_11, pars->ZERO, pars->ZERO, w[73]);
FFV1_2(w[3], w[68], pars->GC_11, pars->ZERO, pars->ZERO, w[74]);
VVV1P0_1(w[68], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[75]);
FFV1_1(w[54], w[68], pars->GC_11, pars->ZERO, pars->ZERO, w[76]);
VVV1P0_1(w[4], w[29], pars->GC_10, pars->ZERO, pars->ZERO, w[77]);
FFV1_1(w[54], w[29], pars->GC_11, pars->ZERO, pars->ZERO, w[78]);
VVVV1P0_1(w[4], w[6], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[79]);
VVVV3P0_1(w[4], w[6], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[80]);
VVVV4P0_1(w[4], w[6], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[81]);
FFV1_1(w[2], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[82]);
FFV1_1(w[82], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[83]);
FFV1_1(w[82], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[84]);
FFV1_1(w[82], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[85]);
FFV1_1(w[82], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[86]);
FFV1_2(w[60], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[87]);
FFV2_5_1(w[82], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[88]);
FFV1_2(w[22], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[89]);
VVV1P0_1(w[4], w[5], pars->GC_10, pars->ZERO, pars->ZERO, w[90]);
FFV1_2(w[3], w[90], pars->GC_11, pars->ZERO, pars->ZERO, w[91]);
VVV1P0_1(w[90], w[7], pars->GC_10, pars->ZERO, pars->ZERO, w[92]);
FFV1_1(w[82], w[90], pars->GC_11, pars->ZERO, pars->ZERO, w[93]);
VVV1P0_1(w[68], w[5], pars->GC_10, pars->ZERO, pars->ZERO, w[94]);
FFV1_1(w[82], w[68], pars->GC_11, pars->ZERO, pars->ZERO, w[95]);
VVV1P0_1(w[4], w[35], pars->GC_10, pars->ZERO, pars->ZERO, w[96]);
FFV1_1(w[82], w[35], pars->GC_11, pars->ZERO, pars->ZERO, w[97]);
VVVV1P0_1(w[4], w[5], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[98]);
VVVV3P0_1(w[4], w[5], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[99]);
VVVV4P0_1(w[4], w[5], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[100]);
FFV1_1(w[2], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[101]);
FFV1_1(w[101], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[102]);
FFV1_1(w[101], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[103]);
FFV1_1(w[101], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[104]);
FFV1_1(w[101], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[105]);
FFV2_5_1(w[101], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[106]);
VVV1P0_1(w[90], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[107]);
FFV1_1(w[101], w[90], pars->GC_11, pars->ZERO, pars->ZERO, w[108]);
VVV1P0_1(w[70], w[5], pars->GC_10, pars->ZERO, pars->ZERO, w[109]);
FFV1_1(w[101], w[70], pars->GC_11, pars->ZERO, pars->ZERO, w[110]);
VVV1P0_1(w[4], w[41], pars->GC_10, pars->ZERO, pars->ZERO, w[111]);
FFV1_1(w[101], w[41], pars->GC_11, pars->ZERO, pars->ZERO, w[112]);
VVVV1P0_1(w[4], w[5], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[113]);
VVVV3P0_1(w[4], w[5], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[114]);
VVVV4P0_1(w[4], w[5], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[115]);
FFV1_1(w[2], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[116]);
FFV1_1(w[116], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[117]);
FFV1_1(w[116], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[118]);
FFV1_1(w[116], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[119]);
FFV2_5_1(w[2], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO,
w[120]);
FFV1_1(w[120], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[121]);
FFV1_1(w[120], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[122]);
FFV1_1(w[120], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[123]);
FFV1_2(w[60], w[41], pars->GC_11, pars->ZERO, pars->ZERO, w[124]);
FFV1_1(w[2], w[41], pars->GC_11, pars->ZERO, pars->ZERO, w[125]);
FFV1_2(w[60], w[35], pars->GC_11, pars->ZERO, pars->ZERO, w[126]);
FFV1_1(w[2], w[35], pars->GC_11, pars->ZERO, pars->ZERO, w[127]);
FFV1_2(w[60], w[29], pars->GC_11, pars->ZERO, pars->ZERO, w[128]);
FFV1_1(w[2], w[29], pars->GC_11, pars->ZERO, pars->ZERO, w[129]);
FFV1_1(w[116], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[130]);
FFV1_1(w[120], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[131]);
FFV1_2(w[22], w[70], pars->GC_11, pars->ZERO, pars->ZERO, w[132]);
FFV1_1(w[2], w[70], pars->GC_11, pars->ZERO, pars->ZERO, w[133]);
FFV1_2(w[22], w[68], pars->GC_11, pars->ZERO, pars->ZERO, w[134]);
FFV1_1(w[2], w[68], pars->GC_11, pars->ZERO, pars->ZERO, w[135]);
FFV1_2(w[22], w[29], pars->GC_11, pars->ZERO, pars->ZERO, w[136]);
FFV1_2(w[30], w[90], pars->GC_11, pars->ZERO, pars->ZERO, w[137]);
FFV1_1(w[2], w[90], pars->GC_11, pars->ZERO, pars->ZERO, w[138]);
FFV1_2(w[30], w[68], pars->GC_11, pars->ZERO, pars->ZERO, w[139]);
FFV1_2(w[30], w[35], pars->GC_11, pars->ZERO, pars->ZERO, w[140]);
FFV1_2(w[36], w[90], pars->GC_11, pars->ZERO, pars->ZERO, w[141]);
FFV1_2(w[36], w[70], pars->GC_11, pars->ZERO, pars->ZERO, w[142]);
FFV1_2(w[36], w[41], pars->GC_11, pars->ZERO, pars->ZERO, w[143]);
FFV1P0_3(w[3], w[116], pars->GC_11, pars->ZERO, pars->ZERO, w[144]);
VVVV1P0_1(w[90], w[6], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[145]);
VVVV3P0_1(w[90], w[6], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[146]);
VVVV4P0_1(w[90], w[6], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[147]);
FFV1P0_3(w[10], w[2], pars->GC_11, pars->ZERO, pars->ZERO, w[148]);
FFV1P0_3(w[3], w[120], pars->GC_11, pars->ZERO, pars->ZERO, w[149]);
FFV1P0_3(w[18], w[2], pars->GC_11, pars->ZERO, pars->ZERO, w[150]);
VVV1P0_1(w[90], w[29], pars->GC_10, pars->ZERO, pars->ZERO, w[151]);
VVVV1P0_1(w[70], w[5], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[152]);
VVVV3P0_1(w[70], w[5], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[153]);
VVVV4P0_1(w[70], w[5], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[154]);
VVV1P0_1(w[70], w[35], pars->GC_10, pars->ZERO, pars->ZERO, w[155]);
VVVV1P0_1(w[68], w[5], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[156]);
VVVV3P0_1(w[68], w[5], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[157]);
VVVV4P0_1(w[68], w[5], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[158]);
VVV1P0_1(w[68], w[41], pars->GC_10, pars->ZERO, pars->ZERO, w[159]);
VVVV1P0_1(w[4], w[41], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[160]);
VVVV3P0_1(w[4], w[41], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[161]);
VVVV4P0_1(w[4], w[41], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[162]);
VVVV1P0_1(w[4], w[35], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[163]);
VVVV3P0_1(w[4], w[35], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[164]);
VVVV4P0_1(w[4], w[35], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[165]);
VVVV1P0_1(w[4], w[5], w[29], pars->GC_12, pars->ZERO, pars->ZERO, w[166]);
VVVV3P0_1(w[4], w[5], w[29], pars->GC_12, pars->ZERO, pars->ZERO, w[167]);
VVVV4P0_1(w[4], w[5], w[29], pars->GC_12, pars->ZERO, pars->ZERO, w[168]);
FFV1_2(w[3], w[113], pars->GC_11, pars->ZERO, pars->ZERO, w[169]);
FFV1_2(w[3], w[114], pars->GC_11, pars->ZERO, pars->ZERO, w[170]);
FFV1_2(w[3], w[115], pars->GC_11, pars->ZERO, pars->ZERO, w[171]);
VVV1P0_1(w[113], w[7], pars->GC_10, pars->ZERO, pars->ZERO, w[172]);
VVV1P0_1(w[114], w[7], pars->GC_10, pars->ZERO, pars->ZERO, w[173]);
VVV1P0_1(w[115], w[7], pars->GC_10, pars->ZERO, pars->ZERO, w[174]);
FFV1_1(w[2], w[113], pars->GC_11, pars->ZERO, pars->ZERO, w[175]);
FFV1_1(w[2], w[114], pars->GC_11, pars->ZERO, pars->ZERO, w[176]);
FFV1_1(w[2], w[115], pars->GC_11, pars->ZERO, pars->ZERO, w[177]);
FFV1_2(w[3], w[98], pars->GC_11, pars->ZERO, pars->ZERO, w[178]);
FFV1_2(w[3], w[99], pars->GC_11, pars->ZERO, pars->ZERO, w[179]);
FFV1_2(w[3], w[100], pars->GC_11, pars->ZERO, pars->ZERO, w[180]);
VVV1P0_1(w[98], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[181]);
VVV1P0_1(w[99], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[182]);
VVV1P0_1(w[100], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[183]);
FFV1_1(w[2], w[98], pars->GC_11, pars->ZERO, pars->ZERO, w[184]);
FFV1_1(w[2], w[99], pars->GC_11, pars->ZERO, pars->ZERO, w[185]);
FFV1_1(w[2], w[100], pars->GC_11, pars->ZERO, pars->ZERO, w[186]);
FFV1_2(w[3], w[79], pars->GC_11, pars->ZERO, pars->ZERO, w[187]);
FFV1_2(w[3], w[80], pars->GC_11, pars->ZERO, pars->ZERO, w[188]);
FFV1_2(w[3], w[81], pars->GC_11, pars->ZERO, pars->ZERO, w[189]);
VVV1P0_1(w[79], w[5], pars->GC_10, pars->ZERO, pars->ZERO, w[190]);
VVV1P0_1(w[80], w[5], pars->GC_10, pars->ZERO, pars->ZERO, w[191]);
VVV1P0_1(w[81], w[5], pars->GC_10, pars->ZERO, pars->ZERO, w[192]);
FFV1_1(w[2], w[79], pars->GC_11, pars->ZERO, pars->ZERO, w[193]);
FFV1_1(w[2], w[80], pars->GC_11, pars->ZERO, pars->ZERO, w[194]);
FFV1_1(w[2], w[81], pars->GC_11, pars->ZERO, pars->ZERO, w[195]);
FFV1_2(w[3], w[51], pars->GC_11, pars->ZERO, pars->ZERO, w[196]);
FFV1_2(w[3], w[52], pars->GC_11, pars->ZERO, pars->ZERO, w[197]);
FFV1_2(w[3], w[53], pars->GC_11, pars->ZERO, pars->ZERO, w[198]);
VVV1P0_1(w[4], w[51], pars->GC_10, pars->ZERO, pars->ZERO, w[199]);
VVV1P0_1(w[4], w[52], pars->GC_10, pars->ZERO, pars->ZERO, w[200]);
VVV1P0_1(w[4], w[53], pars->GC_10, pars->ZERO, pars->ZERO, w[201]);
FFV1_1(w[2], w[51], pars->GC_11, pars->ZERO, pars->ZERO, w[202]);
FFV1_1(w[2], w[52], pars->GC_11, pars->ZERO, pars->ZERO, w[203]);
FFV1_1(w[2], w[53], pars->GC_11, pars->ZERO, pars->ZERO, w[204]);
// Calculate all amplitudes
// Amplitude(s) for diagram number 0
FFV1_0(w[12], w[11], w[7], pars->GC_11, amp[0]);
FFV1_0(w[13], w[11], w[6], pars->GC_11, amp[1]);
FFV1_0(w[15], w[14], w[7], pars->GC_11, amp[2]);
FFV1_0(w[13], w[14], w[5], pars->GC_11, amp[3]);
FFV1_0(w[15], w[16], w[6], pars->GC_11, amp[4]);
FFV1_0(w[12], w[16], w[5], pars->GC_11, amp[5]);
FFV1_0(w[19], w[11], w[7], pars->GC_11, amp[6]);
FFV1_0(w[20], w[11], w[6], pars->GC_11, amp[7]);
FFV1_0(w[21], w[14], w[7], pars->GC_11, amp[8]);
FFV1_0(w[20], w[14], w[5], pars->GC_11, amp[9]);
FFV1_0(w[21], w[16], w[6], pars->GC_11, amp[10]);
FFV1_0(w[19], w[16], w[5], pars->GC_11, amp[11]);
FFV1_0(w[24], w[23], w[7], pars->GC_11, amp[12]);
FFV1_0(w[25], w[23], w[6], pars->GC_11, amp[13]);
FFV1_0(w[26], w[14], w[7], pars->GC_11, amp[14]);
FFV1_0(w[26], w[16], w[6], pars->GC_11, amp[15]);
FFV1_0(w[25], w[14], w[8], pars->GC_2, amp[16]);
FFV1_0(w[24], w[16], w[8], pars->GC_2, amp[17]);
FFV1_0(w[24], w[27], w[7], pars->GC_11, amp[18]);
FFV1_0(w[25], w[27], w[6], pars->GC_11, amp[19]);
FFV1_0(w[28], w[14], w[7], pars->GC_11, amp[20]);
FFV1_0(w[28], w[16], w[6], pars->GC_11, amp[21]);
FFV2_5_0(w[25], w[14], w[17], pars->GC_51, pars->GC_58, amp[22]);
FFV2_5_0(w[24], w[16], w[17], pars->GC_51, pars->GC_58, amp[23]);
FFV1_0(w[22], w[23], w[29], pars->GC_11, amp[24]);
FFV1_0(w[26], w[9], w[29], pars->GC_11, amp[25]);
FFV1_0(w[22], w[27], w[29], pars->GC_11, amp[26]);
FFV1_0(w[28], w[9], w[29], pars->GC_11, amp[27]);
FFV1_0(w[31], w[23], w[7], pars->GC_11, amp[28]);
FFV1_0(w[32], w[23], w[5], pars->GC_11, amp[29]);
FFV1_0(w[33], w[11], w[7], pars->GC_11, amp[30]);
FFV1_0(w[33], w[16], w[5], pars->GC_11, amp[31]);
FFV1_0(w[32], w[11], w[8], pars->GC_2, amp[32]);
FFV1_0(w[31], w[16], w[8], pars->GC_2, amp[33]);
FFV1_0(w[31], w[27], w[7], pars->GC_11, amp[34]);
FFV1_0(w[32], w[27], w[5], pars->GC_11, amp[35]);
FFV1_0(w[34], w[11], w[7], pars->GC_11, amp[36]);
FFV1_0(w[34], w[16], w[5], pars->GC_11, amp[37]);
FFV2_5_0(w[32], w[11], w[17], pars->GC_51, pars->GC_58, amp[38]);
FFV2_5_0(w[31], w[16], w[17], pars->GC_51, pars->GC_58, amp[39]);
FFV1_0(w[30], w[23], w[35], pars->GC_11, amp[40]);
FFV1_0(w[33], w[9], w[35], pars->GC_11, amp[41]);
FFV1_0(w[30], w[27], w[35], pars->GC_11, amp[42]);
FFV1_0(w[34], w[9], w[35], pars->GC_11, amp[43]);
FFV1_0(w[37], w[23], w[6], pars->GC_11, amp[44]);
FFV1_0(w[38], w[23], w[5], pars->GC_11, amp[45]);
FFV1_0(w[39], w[11], w[6], pars->GC_11, amp[46]);
FFV1_0(w[39], w[14], w[5], pars->GC_11, amp[47]);
FFV1_0(w[38], w[11], w[8], pars->GC_2, amp[48]);
FFV1_0(w[37], w[14], w[8], pars->GC_2, amp[49]);
FFV1_0(w[37], w[27], w[6], pars->GC_11, amp[50]);
FFV1_0(w[38], w[27], w[5], pars->GC_11, amp[51]);
FFV1_0(w[40], w[11], w[6], pars->GC_11, amp[52]);
FFV1_0(w[40], w[14], w[5], pars->GC_11, amp[53]);
FFV2_5_0(w[38], w[11], w[17], pars->GC_51, pars->GC_58, amp[54]);
FFV2_5_0(w[37], w[14], w[17], pars->GC_51, pars->GC_58, amp[55]);
FFV1_0(w[36], w[23], w[41], pars->GC_11, amp[56]);
FFV1_0(w[39], w[9], w[41], pars->GC_11, amp[57]);
FFV1_0(w[36], w[27], w[41], pars->GC_11, amp[58]);
FFV1_0(w[40], w[9], w[41], pars->GC_11, amp[59]);
FFV1_0(w[42], w[23], w[7], pars->GC_11, amp[60]);
FFV1_0(w[3], w[23], w[43], pars->GC_11, amp[61]);
FFV1_0(w[10], w[44], w[7], pars->GC_11, amp[62]);
FFV1_0(w[10], w[16], w[41], pars->GC_11, amp[63]);
FFV1_0(w[10], w[9], w[43], pars->GC_11, amp[64]);
FFV1_0(w[42], w[16], w[8], pars->GC_2, amp[65]);
FFV1_0(w[42], w[27], w[7], pars->GC_11, amp[66]);
FFV1_0(w[3], w[27], w[43], pars->GC_11, amp[67]);
FFV1_0(w[18], w[44], w[7], pars->GC_11, amp[68]);
FFV1_0(w[18], w[16], w[41], pars->GC_11, amp[69]);
FFV1_0(w[18], w[9], w[43], pars->GC_11, amp[70]);
FFV2_5_0(w[42], w[16], w[17], pars->GC_51, pars->GC_58, amp[71]);
FFV1_0(w[45], w[23], w[6], pars->GC_11, amp[72]);
FFV1_0(w[3], w[23], w[46], pars->GC_11, amp[73]);
FFV1_0(w[10], w[47], w[6], pars->GC_11, amp[74]);
FFV1_0(w[10], w[14], w[35], pars->GC_11, amp[75]);
FFV1_0(w[10], w[9], w[46], pars->GC_11, amp[76]);
FFV1_0(w[45], w[14], w[8], pars->GC_2, amp[77]);
FFV1_0(w[45], w[27], w[6], pars->GC_11, amp[78]);
FFV1_0(w[3], w[27], w[46], pars->GC_11, amp[79]);
FFV1_0(w[18], w[47], w[6], pars->GC_11, amp[80]);
FFV1_0(w[18], w[14], w[35], pars->GC_11, amp[81]);
FFV1_0(w[18], w[9], w[46], pars->GC_11, amp[82]);
FFV2_5_0(w[45], w[14], w[17], pars->GC_51, pars->GC_58, amp[83]);
FFV1_0(w[48], w[23], w[5], pars->GC_11, amp[84]);
FFV1_0(w[3], w[23], w[49], pars->GC_11, amp[85]);
FFV1_0(w[10], w[11], w[29], pars->GC_11, amp[86]);
FFV1_0(w[10], w[50], w[5], pars->GC_11, amp[87]);
FFV1_0(w[10], w[9], w[49], pars->GC_11, amp[88]);
FFV1_0(w[48], w[11], w[8], pars->GC_2, amp[89]);
FFV1_0(w[48], w[27], w[5], pars->GC_11, amp[90]);
FFV1_0(w[3], w[27], w[49], pars->GC_11, amp[91]);
FFV1_0(w[18], w[11], w[29], pars->GC_11, amp[92]);
FFV1_0(w[18], w[50], w[5], pars->GC_11, amp[93]);
FFV1_0(w[18], w[9], w[49], pars->GC_11, amp[94]);
FFV2_5_0(w[48], w[11], w[17], pars->GC_51, pars->GC_58, amp[95]);
FFV1_0(w[3], w[23], w[51], pars->GC_11, amp[96]);
FFV1_0(w[3], w[23], w[52], pars->GC_11, amp[97]);
FFV1_0(w[3], w[23], w[53], pars->GC_11, amp[98]);
FFV1_0(w[10], w[9], w[51], pars->GC_11, amp[99]);
FFV1_0(w[10], w[9], w[52], pars->GC_11, amp[100]);
FFV1_0(w[10], w[9], w[53], pars->GC_11, amp[101]);
FFV1_0(w[3], w[27], w[51], pars->GC_11, amp[102]);
FFV1_0(w[3], w[27], w[52], pars->GC_11, amp[103]);
FFV1_0(w[3], w[27], w[53], pars->GC_11, amp[104]);
FFV1_0(w[18], w[9], w[51], pars->GC_11, amp[105]);
FFV1_0(w[18], w[9], w[52], pars->GC_11, amp[106]);
FFV1_0(w[18], w[9], w[53], pars->GC_11, amp[107]);
FFV1_0(w[12], w[55], w[7], pars->GC_11, amp[108]);
FFV1_0(w[13], w[55], w[6], pars->GC_11, amp[109]);
FFV1_0(w[57], w[56], w[7], pars->GC_11, amp[110]);
FFV1_0(w[13], w[56], w[4], pars->GC_11, amp[111]);
FFV1_0(w[57], w[58], w[6], pars->GC_11, amp[112]);
FFV1_0(w[12], w[58], w[4], pars->GC_11, amp[113]);
FFV1_0(w[19], w[55], w[7], pars->GC_11, amp[114]);
FFV1_0(w[20], w[55], w[6], pars->GC_11, amp[115]);
FFV1_0(w[59], w[56], w[7], pars->GC_11, amp[116]);
FFV1_0(w[20], w[56], w[4], pars->GC_11, amp[117]);
FFV1_0(w[59], w[58], w[6], pars->GC_11, amp[118]);
FFV1_0(w[19], w[58], w[4], pars->GC_11, amp[119]);
FFV1_0(w[62], w[61], w[7], pars->GC_11, amp[120]);
FFV1_0(w[63], w[61], w[6], pars->GC_11, amp[121]);
FFV1_0(w[64], w[56], w[7], pars->GC_11, amp[122]);
FFV1_0(w[64], w[58], w[6], pars->GC_11, amp[123]);
FFV1_0(w[63], w[56], w[8], pars->GC_2, amp[124]);
FFV1_0(w[62], w[58], w[8], pars->GC_2, amp[125]);
FFV1_0(w[62], w[65], w[7], pars->GC_11, amp[126]);
FFV1_0(w[63], w[65], w[6], pars->GC_11, amp[127]);
FFV1_0(w[66], w[56], w[7], pars->GC_11, amp[128]);
FFV1_0(w[66], w[58], w[6], pars->GC_11, amp[129]);
FFV2_5_0(w[63], w[56], w[17], pars->GC_51, pars->GC_58, amp[130]);
FFV2_5_0(w[62], w[58], w[17], pars->GC_51, pars->GC_58, amp[131]);
FFV1_0(w[60], w[61], w[29], pars->GC_11, amp[132]);
FFV1_0(w[64], w[54], w[29], pars->GC_11, amp[133]);
FFV1_0(w[60], w[65], w[29], pars->GC_11, amp[134]);
FFV1_0(w[66], w[54], w[29], pars->GC_11, amp[135]);
FFV1_0(w[67], w[61], w[7], pars->GC_11, amp[136]);
FFV1_0(w[32], w[61], w[4], pars->GC_11, amp[137]);
FFV1_0(w[33], w[55], w[7], pars->GC_11, amp[138]);
FFV1_0(w[33], w[58], w[4], pars->GC_11, amp[139]);
FFV1_0(w[32], w[55], w[8], pars->GC_2, amp[140]);
FFV1_0(w[67], w[58], w[8], pars->GC_2, amp[141]);
FFV1_0(w[67], w[65], w[7], pars->GC_11, amp[142]);
FFV1_0(w[32], w[65], w[4], pars->GC_11, amp[143]);
FFV1_0(w[34], w[55], w[7], pars->GC_11, amp[144]);
FFV1_0(w[34], w[58], w[4], pars->GC_11, amp[145]);
FFV2_5_0(w[32], w[55], w[17], pars->GC_51, pars->GC_58, amp[146]);
FFV2_5_0(w[67], w[58], w[17], pars->GC_51, pars->GC_58, amp[147]);
FFV1_0(w[30], w[61], w[68], pars->GC_11, amp[148]);
FFV1_0(w[33], w[54], w[68], pars->GC_11, amp[149]);
FFV1_0(w[30], w[65], w[68], pars->GC_11, amp[150]);
FFV1_0(w[34], w[54], w[68], pars->GC_11, amp[151]);
FFV1_0(w[69], w[61], w[6], pars->GC_11, amp[152]);
FFV1_0(w[38], w[61], w[4], pars->GC_11, amp[153]);
FFV1_0(w[39], w[55], w[6], pars->GC_11, amp[154]);
FFV1_0(w[39], w[56], w[4], pars->GC_11, amp[155]);
FFV1_0(w[38], w[55], w[8], pars->GC_2, amp[156]);
FFV1_0(w[69], w[56], w[8], pars->GC_2, amp[157]);
FFV1_0(w[69], w[65], w[6], pars->GC_11, amp[158]);
FFV1_0(w[38], w[65], w[4], pars->GC_11, amp[159]);
FFV1_0(w[40], w[55], w[6], pars->GC_11, amp[160]);
FFV1_0(w[40], w[56], w[4], pars->GC_11, amp[161]);
FFV2_5_0(w[38], w[55], w[17], pars->GC_51, pars->GC_58, amp[162]);
FFV2_5_0(w[69], w[56], w[17], pars->GC_51, pars->GC_58, amp[163]);
FFV1_0(w[36], w[61], w[70], pars->GC_11, amp[164]);
FFV1_0(w[39], w[54], w[70], pars->GC_11, amp[165]);
FFV1_0(w[36], w[65], w[70], pars->GC_11, amp[166]);
FFV1_0(w[40], w[54], w[70], pars->GC_11, amp[167]);
FFV1_0(w[71], w[61], w[7], pars->GC_11, amp[168]);
FFV1_0(w[3], w[61], w[72], pars->GC_11, amp[169]);
FFV1_0(w[10], w[73], w[7], pars->GC_11, amp[170]);
FFV1_0(w[10], w[58], w[70], pars->GC_11, amp[171]);
FFV1_0(w[10], w[54], w[72], pars->GC_11, amp[172]);
FFV1_0(w[71], w[58], w[8], pars->GC_2, amp[173]);
FFV1_0(w[71], w[65], w[7], pars->GC_11, amp[174]);
FFV1_0(w[3], w[65], w[72], pars->GC_11, amp[175]);
FFV1_0(w[18], w[73], w[7], pars->GC_11, amp[176]);
FFV1_0(w[18], w[58], w[70], pars->GC_11, amp[177]);
FFV1_0(w[18], w[54], w[72], pars->GC_11, amp[178]);
FFV2_5_0(w[71], w[58], w[17], pars->GC_51, pars->GC_58, amp[179]);
FFV1_0(w[74], w[61], w[6], pars->GC_11, amp[180]);
FFV1_0(w[3], w[61], w[75], pars->GC_11, amp[181]);
FFV1_0(w[10], w[76], w[6], pars->GC_11, amp[182]);
FFV1_0(w[10], w[56], w[68], pars->GC_11, amp[183]);
FFV1_0(w[10], w[54], w[75], pars->GC_11, amp[184]);
FFV1_0(w[74], w[56], w[8], pars->GC_2, amp[185]);
FFV1_0(w[74], w[65], w[6], pars->GC_11, amp[186]);
FFV1_0(w[3], w[65], w[75], pars->GC_11, amp[187]);
FFV1_0(w[18], w[76], w[6], pars->GC_11, amp[188]);
FFV1_0(w[18], w[56], w[68], pars->GC_11, amp[189]);
FFV1_0(w[18], w[54], w[75], pars->GC_11, amp[190]);
FFV2_5_0(w[74], w[56], w[17], pars->GC_51, pars->GC_58, amp[191]);
FFV1_0(w[48], w[61], w[4], pars->GC_11, amp[192]);
FFV1_0(w[3], w[61], w[77], pars->GC_11, amp[193]);
FFV1_0(w[10], w[55], w[29], pars->GC_11, amp[194]);
FFV1_0(w[10], w[78], w[4], pars->GC_11, amp[195]);
FFV1_0(w[10], w[54], w[77], pars->GC_11, amp[196]);
FFV1_0(w[48], w[55], w[8], pars->GC_2, amp[197]);
FFV1_0(w[48], w[65], w[4], pars->GC_11, amp[198]);
FFV1_0(w[3], w[65], w[77], pars->GC_11, amp[199]);
FFV1_0(w[18], w[55], w[29], pars->GC_11, amp[200]);
FFV1_0(w[18], w[78], w[4], pars->GC_11, amp[201]);
FFV1_0(w[18], w[54], w[77], pars->GC_11, amp[202]);
FFV2_5_0(w[48], w[55], w[17], pars->GC_51, pars->GC_58, amp[203]);
FFV1_0(w[3], w[61], w[79], pars->GC_11, amp[204]);
FFV1_0(w[3], w[61], w[80], pars->GC_11, amp[205]);
FFV1_0(w[3], w[61], w[81], pars->GC_11, amp[206]);
FFV1_0(w[10], w[54], w[79], pars->GC_11, amp[207]);
FFV1_0(w[10], w[54], w[80], pars->GC_11, amp[208]);
FFV1_0(w[10], w[54], w[81], pars->GC_11, amp[209]);
FFV1_0(w[3], w[65], w[79], pars->GC_11, amp[210]);
FFV1_0(w[3], w[65], w[80], pars->GC_11, amp[211]);
FFV1_0(w[3], w[65], w[81], pars->GC_11, amp[212]);
FFV1_0(w[18], w[54], w[79], pars->GC_11, amp[213]);
FFV1_0(w[18], w[54], w[80], pars->GC_11, amp[214]);
FFV1_0(w[18], w[54], w[81], pars->GC_11, amp[215]);
FFV1_0(w[15], w[83], w[7], pars->GC_11, amp[216]);
FFV1_0(w[13], w[83], w[5], pars->GC_11, amp[217]);
FFV1_0(w[57], w[84], w[7], pars->GC_11, amp[218]);
FFV1_0(w[13], w[84], w[4], pars->GC_11, amp[219]);
FFV1_0(w[57], w[85], w[5], pars->GC_11, amp[220]);
FFV1_0(w[15], w[85], w[4], pars->GC_11, amp[221]);
FFV1_0(w[21], w[83], w[7], pars->GC_11, amp[222]);
FFV1_0(w[20], w[83], w[5], pars->GC_11, amp[223]);
FFV1_0(w[59], w[84], w[7], pars->GC_11, amp[224]);
FFV1_0(w[20], w[84], w[4], pars->GC_11, amp[225]);
FFV1_0(w[59], w[85], w[5], pars->GC_11, amp[226]);
FFV1_0(w[21], w[85], w[4], pars->GC_11, amp[227]);
FFV1_0(w[87], w[86], w[7], pars->GC_11, amp[228]);
FFV1_0(w[63], w[86], w[5], pars->GC_11, amp[229]);
FFV1_0(w[64], w[84], w[7], pars->GC_11, amp[230]);
FFV1_0(w[64], w[85], w[5], pars->GC_11, amp[231]);
FFV1_0(w[63], w[84], w[8], pars->GC_2, amp[232]);
FFV1_0(w[87], w[85], w[8], pars->GC_2, amp[233]);
FFV1_0(w[87], w[88], w[7], pars->GC_11, amp[234]);
FFV1_0(w[63], w[88], w[5], pars->GC_11, amp[235]);
FFV1_0(w[66], w[84], w[7], pars->GC_11, amp[236]);
FFV1_0(w[66], w[85], w[5], pars->GC_11, amp[237]);
FFV2_5_0(w[63], w[84], w[17], pars->GC_51, pars->GC_58, amp[238]);
FFV2_5_0(w[87], w[85], w[17], pars->GC_51, pars->GC_58, amp[239]);
FFV1_0(w[60], w[86], w[35], pars->GC_11, amp[240]);
FFV1_0(w[64], w[82], w[35], pars->GC_11, amp[241]);
FFV1_0(w[60], w[88], w[35], pars->GC_11, amp[242]);
FFV1_0(w[66], w[82], w[35], pars->GC_11, amp[243]);
FFV1_0(w[89], w[86], w[7], pars->GC_11, amp[244]);
FFV1_0(w[25], w[86], w[4], pars->GC_11, amp[245]);
FFV1_0(w[26], w[83], w[7], pars->GC_11, amp[246]);
FFV1_0(w[26], w[85], w[4], pars->GC_11, amp[247]);
FFV1_0(w[25], w[83], w[8], pars->GC_2, amp[248]);
FFV1_0(w[89], w[85], w[8], pars->GC_2, amp[249]);
FFV1_0(w[89], w[88], w[7], pars->GC_11, amp[250]);
FFV1_0(w[25], w[88], w[4], pars->GC_11, amp[251]);
FFV1_0(w[28], w[83], w[7], pars->GC_11, amp[252]);
FFV1_0(w[28], w[85], w[4], pars->GC_11, amp[253]);
FFV2_5_0(w[25], w[83], w[17], pars->GC_51, pars->GC_58, amp[254]);
FFV2_5_0(w[89], w[85], w[17], pars->GC_51, pars->GC_58, amp[255]);
FFV1_0(w[22], w[86], w[68], pars->GC_11, amp[256]);
FFV1_0(w[26], w[82], w[68], pars->GC_11, amp[257]);
FFV1_0(w[22], w[88], w[68], pars->GC_11, amp[258]);
FFV1_0(w[28], w[82], w[68], pars->GC_11, amp[259]);
FFV1_0(w[69], w[86], w[5], pars->GC_11, amp[260]);
FFV1_0(w[37], w[86], w[4], pars->GC_11, amp[261]);
FFV1_0(w[39], w[83], w[5], pars->GC_11, amp[262]);
FFV1_0(w[39], w[84], w[4], pars->GC_11, amp[263]);
FFV1_0(w[37], w[83], w[8], pars->GC_2, amp[264]);
FFV1_0(w[69], w[84], w[8], pars->GC_2, amp[265]);
FFV1_0(w[69], w[88], w[5], pars->GC_11, amp[266]);
FFV1_0(w[37], w[88], w[4], pars->GC_11, amp[267]);
FFV1_0(w[40], w[83], w[5], pars->GC_11, amp[268]);
FFV1_0(w[40], w[84], w[4], pars->GC_11, amp[269]);
FFV2_5_0(w[37], w[83], w[17], pars->GC_51, pars->GC_58, amp[270]);
FFV2_5_0(w[69], w[84], w[17], pars->GC_51, pars->GC_58, amp[271]);
FFV1_0(w[36], w[86], w[90], pars->GC_11, amp[272]);
FFV1_0(w[39], w[82], w[90], pars->GC_11, amp[273]);
FFV1_0(w[36], w[88], w[90], pars->GC_11, amp[274]);
FFV1_0(w[40], w[82], w[90], pars->GC_11, amp[275]);
FFV1_0(w[91], w[86], w[7], pars->GC_11, amp[276]);
FFV1_0(w[3], w[86], w[92], pars->GC_11, amp[277]);
FFV1_0(w[10], w[93], w[7], pars->GC_11, amp[278]);
FFV1_0(w[10], w[85], w[90], pars->GC_11, amp[279]);
FFV1_0(w[10], w[82], w[92], pars->GC_11, amp[280]);
FFV1_0(w[91], w[85], w[8], pars->GC_2, amp[281]);
FFV1_0(w[91], w[88], w[7], pars->GC_11, amp[282]);
FFV1_0(w[3], w[88], w[92], pars->GC_11, amp[283]);
FFV1_0(w[18], w[93], w[7], pars->GC_11, amp[284]);
FFV1_0(w[18], w[85], w[90], pars->GC_11, amp[285]);
FFV1_0(w[18], w[82], w[92], pars->GC_11, amp[286]);
FFV2_5_0(w[91], w[85], w[17], pars->GC_51, pars->GC_58, amp[287]);
FFV1_0(w[74], w[86], w[5], pars->GC_11, amp[288]);
FFV1_0(w[3], w[86], w[94], pars->GC_11, amp[289]);
FFV1_0(w[10], w[95], w[5], pars->GC_11, amp[290]);
FFV1_0(w[10], w[84], w[68], pars->GC_11, amp[291]);
FFV1_0(w[10], w[82], w[94], pars->GC_11, amp[292]);
FFV1_0(w[74], w[84], w[8], pars->GC_2, amp[293]);
FFV1_0(w[74], w[88], w[5], pars->GC_11, amp[294]);
FFV1_0(w[3], w[88], w[94], pars->GC_11, amp[295]);
FFV1_0(w[18], w[95], w[5], pars->GC_11, amp[296]);
FFV1_0(w[18], w[84], w[68], pars->GC_11, amp[297]);
FFV1_0(w[18], w[82], w[94], pars->GC_11, amp[298]);
FFV2_5_0(w[74], w[84], w[17], pars->GC_51, pars->GC_58, amp[299]);
FFV1_0(w[45], w[86], w[4], pars->GC_11, amp[300]);
FFV1_0(w[3], w[86], w[96], pars->GC_11, amp[301]);
FFV1_0(w[10], w[83], w[35], pars->GC_11, amp[302]);
FFV1_0(w[10], w[97], w[4], pars->GC_11, amp[303]);
FFV1_0(w[10], w[82], w[96], pars->GC_11, amp[304]);
FFV1_0(w[45], w[83], w[8], pars->GC_2, amp[305]);
FFV1_0(w[45], w[88], w[4], pars->GC_11, amp[306]);
FFV1_0(w[3], w[88], w[96], pars->GC_11, amp[307]);
FFV1_0(w[18], w[83], w[35], pars->GC_11, amp[308]);
FFV1_0(w[18], w[97], w[4], pars->GC_11, amp[309]);
FFV1_0(w[18], w[82], w[96], pars->GC_11, amp[310]);
FFV2_5_0(w[45], w[83], w[17], pars->GC_51, pars->GC_58, amp[311]);
FFV1_0(w[3], w[86], w[98], pars->GC_11, amp[312]);
FFV1_0(w[3], w[86], w[99], pars->GC_11, amp[313]);
FFV1_0(w[3], w[86], w[100], pars->GC_11, amp[314]);
FFV1_0(w[10], w[82], w[98], pars->GC_11, amp[315]);
FFV1_0(w[10], w[82], w[99], pars->GC_11, amp[316]);
FFV1_0(w[10], w[82], w[100], pars->GC_11, amp[317]);
FFV1_0(w[3], w[88], w[98], pars->GC_11, amp[318]);
FFV1_0(w[3], w[88], w[99], pars->GC_11, amp[319]);
FFV1_0(w[3], w[88], w[100], pars->GC_11, amp[320]);
FFV1_0(w[18], w[82], w[98], pars->GC_11, amp[321]);
FFV1_0(w[18], w[82], w[99], pars->GC_11, amp[322]);
FFV1_0(w[18], w[82], w[100], pars->GC_11, amp[323]);
FFV1_0(w[15], w[102], w[6], pars->GC_11, amp[324]);
FFV1_0(w[12], w[102], w[5], pars->GC_11, amp[325]);
FFV1_0(w[57], w[103], w[6], pars->GC_11, amp[326]);
FFV1_0(w[12], w[103], w[4], pars->GC_11, amp[327]);
FFV1_0(w[57], w[104], w[5], pars->GC_11, amp[328]);
FFV1_0(w[15], w[104], w[4], pars->GC_11, amp[329]);
FFV1_0(w[21], w[102], w[6], pars->GC_11, amp[330]);
FFV1_0(w[19], w[102], w[5], pars->GC_11, amp[331]);
FFV1_0(w[59], w[103], w[6], pars->GC_11, amp[332]);
FFV1_0(w[19], w[103], w[4], pars->GC_11, amp[333]);
FFV1_0(w[59], w[104], w[5], pars->GC_11, amp[334]);
FFV1_0(w[21], w[104], w[4], pars->GC_11, amp[335]);
FFV1_0(w[87], w[105], w[6], pars->GC_11, amp[336]);
FFV1_0(w[62], w[105], w[5], pars->GC_11, amp[337]);
FFV1_0(w[64], w[103], w[6], pars->GC_11, amp[338]);
FFV1_0(w[64], w[104], w[5], pars->GC_11, amp[339]);
FFV1_0(w[62], w[103], w[8], pars->GC_2, amp[340]);
FFV1_0(w[87], w[104], w[8], pars->GC_2, amp[341]);
FFV1_0(w[87], w[106], w[6], pars->GC_11, amp[342]);
FFV1_0(w[62], w[106], w[5], pars->GC_11, amp[343]);
FFV1_0(w[66], w[103], w[6], pars->GC_11, amp[344]);
FFV1_0(w[66], w[104], w[5], pars->GC_11, amp[345]);
FFV2_5_0(w[62], w[103], w[17], pars->GC_51, pars->GC_58, amp[346]);
FFV2_5_0(w[87], w[104], w[17], pars->GC_51, pars->GC_58, amp[347]);
FFV1_0(w[60], w[105], w[41], pars->GC_11, amp[348]);
FFV1_0(w[64], w[101], w[41], pars->GC_11, amp[349]);
FFV1_0(w[60], w[106], w[41], pars->GC_11, amp[350]);
FFV1_0(w[66], w[101], w[41], pars->GC_11, amp[351]);
FFV1_0(w[89], w[105], w[6], pars->GC_11, amp[352]);
FFV1_0(w[24], w[105], w[4], pars->GC_11, amp[353]);
FFV1_0(w[26], w[102], w[6], pars->GC_11, amp[354]);
FFV1_0(w[26], w[104], w[4], pars->GC_11, amp[355]);
FFV1_0(w[24], w[102], w[8], pars->GC_2, amp[356]);
FFV1_0(w[89], w[104], w[8], pars->GC_2, amp[357]);
FFV1_0(w[89], w[106], w[6], pars->GC_11, amp[358]);
FFV1_0(w[24], w[106], w[4], pars->GC_11, amp[359]);
FFV1_0(w[28], w[102], w[6], pars->GC_11, amp[360]);
FFV1_0(w[28], w[104], w[4], pars->GC_11, amp[361]);
FFV2_5_0(w[24], w[102], w[17], pars->GC_51, pars->GC_58, amp[362]);
FFV2_5_0(w[89], w[104], w[17], pars->GC_51, pars->GC_58, amp[363]);
FFV1_0(w[22], w[105], w[70], pars->GC_11, amp[364]);
FFV1_0(w[26], w[101], w[70], pars->GC_11, amp[365]);
FFV1_0(w[22], w[106], w[70], pars->GC_11, amp[366]);
FFV1_0(w[28], w[101], w[70], pars->GC_11, amp[367]);
FFV1_0(w[67], w[105], w[5], pars->GC_11, amp[368]);
FFV1_0(w[31], w[105], w[4], pars->GC_11, amp[369]);
FFV1_0(w[33], w[102], w[5], pars->GC_11, amp[370]);
FFV1_0(w[33], w[103], w[4], pars->GC_11, amp[371]);
FFV1_0(w[31], w[102], w[8], pars->GC_2, amp[372]);
FFV1_0(w[67], w[103], w[8], pars->GC_2, amp[373]);
FFV1_0(w[67], w[106], w[5], pars->GC_11, amp[374]);
FFV1_0(w[31], w[106], w[4], pars->GC_11, amp[375]);
FFV1_0(w[34], w[102], w[5], pars->GC_11, amp[376]);
FFV1_0(w[34], w[103], w[4], pars->GC_11, amp[377]);
FFV2_5_0(w[31], w[102], w[17], pars->GC_51, pars->GC_58, amp[378]);
FFV2_5_0(w[67], w[103], w[17], pars->GC_51, pars->GC_58, amp[379]);
FFV1_0(w[30], w[105], w[90], pars->GC_11, amp[380]);
FFV1_0(w[33], w[101], w[90], pars->GC_11, amp[381]);
FFV1_0(w[30], w[106], w[90], pars->GC_11, amp[382]);
FFV1_0(w[34], w[101], w[90], pars->GC_11, amp[383]);
FFV1_0(w[91], w[105], w[6], pars->GC_11, amp[384]);
FFV1_0(w[3], w[105], w[107], pars->GC_11, amp[385]);
FFV1_0(w[10], w[108], w[6], pars->GC_11, amp[386]);
FFV1_0(w[10], w[104], w[90], pars->GC_11, amp[387]);
FFV1_0(w[10], w[101], w[107], pars->GC_11, amp[388]);
FFV1_0(w[91], w[104], w[8], pars->GC_2, amp[389]);
FFV1_0(w[91], w[106], w[6], pars->GC_11, amp[390]);
FFV1_0(w[3], w[106], w[107], pars->GC_11, amp[391]);
FFV1_0(w[18], w[108], w[6], pars->GC_11, amp[392]);
FFV1_0(w[18], w[104], w[90], pars->GC_11, amp[393]);
FFV1_0(w[18], w[101], w[107], pars->GC_11, amp[394]);
FFV2_5_0(w[91], w[104], w[17], pars->GC_51, pars->GC_58, amp[395]);
FFV1_0(w[71], w[105], w[5], pars->GC_11, amp[396]);
FFV1_0(w[3], w[105], w[109], pars->GC_11, amp[397]);
FFV1_0(w[10], w[110], w[5], pars->GC_11, amp[398]);
FFV1_0(w[10], w[103], w[70], pars->GC_11, amp[399]);
FFV1_0(w[10], w[101], w[109], pars->GC_11, amp[400]);
FFV1_0(w[71], w[103], w[8], pars->GC_2, amp[401]);
FFV1_0(w[71], w[106], w[5], pars->GC_11, amp[402]);
FFV1_0(w[3], w[106], w[109], pars->GC_11, amp[403]);
FFV1_0(w[18], w[110], w[5], pars->GC_11, amp[404]);
FFV1_0(w[18], w[103], w[70], pars->GC_11, amp[405]);
FFV1_0(w[18], w[101], w[109], pars->GC_11, amp[406]);
FFV2_5_0(w[71], w[103], w[17], pars->GC_51, pars->GC_58, amp[407]);
FFV1_0(w[42], w[105], w[4], pars->GC_11, amp[408]);
FFV1_0(w[3], w[105], w[111], pars->GC_11, amp[409]);
FFV1_0(w[10], w[102], w[41], pars->GC_11, amp[410]);
FFV1_0(w[10], w[112], w[4], pars->GC_11, amp[411]);
FFV1_0(w[10], w[101], w[111], pars->GC_11, amp[412]);
FFV1_0(w[42], w[102], w[8], pars->GC_2, amp[413]);
FFV1_0(w[42], w[106], w[4], pars->GC_11, amp[414]);
FFV1_0(w[3], w[106], w[111], pars->GC_11, amp[415]);
FFV1_0(w[18], w[102], w[41], pars->GC_11, amp[416]);
FFV1_0(w[18], w[112], w[4], pars->GC_11, amp[417]);
FFV1_0(w[18], w[101], w[111], pars->GC_11, amp[418]);
FFV2_5_0(w[42], w[102], w[17], pars->GC_51, pars->GC_58, amp[419]);
FFV1_0(w[3], w[105], w[113], pars->GC_11, amp[420]);
FFV1_0(w[3], w[105], w[114], pars->GC_11, amp[421]);
FFV1_0(w[3], w[105], w[115], pars->GC_11, amp[422]);
FFV1_0(w[10], w[101], w[113], pars->GC_11, amp[423]);
FFV1_0(w[10], w[101], w[114], pars->GC_11, amp[424]);
FFV1_0(w[10], w[101], w[115], pars->GC_11, amp[425]);
FFV1_0(w[3], w[106], w[113], pars->GC_11, amp[426]);
FFV1_0(w[3], w[106], w[114], pars->GC_11, amp[427]);
FFV1_0(w[3], w[106], w[115], pars->GC_11, amp[428]);
FFV1_0(w[18], w[101], w[113], pars->GC_11, amp[429]);
FFV1_0(w[18], w[101], w[114], pars->GC_11, amp[430]);
FFV1_0(w[18], w[101], w[115], pars->GC_11, amp[431]);
FFV1_0(w[87], w[117], w[7], pars->GC_11, amp[432]);
FFV1_0(w[87], w[118], w[6], pars->GC_11, amp[433]);
FFV1_0(w[62], w[119], w[7], pars->GC_11, amp[434]);
FFV1_0(w[62], w[118], w[5], pars->GC_11, amp[435]);
FFV1_0(w[63], w[119], w[6], pars->GC_11, amp[436]);
FFV1_0(w[63], w[117], w[5], pars->GC_11, amp[437]);
FFV1_0(w[87], w[121], w[7], pars->GC_11, amp[438]);
FFV1_0(w[87], w[122], w[6], pars->GC_11, amp[439]);
FFV1_0(w[62], w[123], w[7], pars->GC_11, amp[440]);
FFV1_0(w[62], w[122], w[5], pars->GC_11, amp[441]);
FFV1_0(w[63], w[123], w[6], pars->GC_11, amp[442]);
FFV1_0(w[63], w[121], w[5], pars->GC_11, amp[443]);
FFV1_0(w[124], w[116], w[7], pars->GC_11, amp[444]);
FFV1_0(w[63], w[116], w[41], pars->GC_11, amp[445]);
FFV1_0(w[60], w[116], w[43], pars->GC_11, amp[446]);
FFV1_0(w[64], w[125], w[7], pars->GC_11, amp[447]);
FFV1_0(w[64], w[2], w[43], pars->GC_11, amp[448]);
FFV1_0(w[63], w[125], w[8], pars->GC_2, amp[449]);
FFV1_0(w[124], w[120], w[7], pars->GC_11, amp[450]);
FFV1_0(w[63], w[120], w[41], pars->GC_11, amp[451]);
FFV1_0(w[60], w[120], w[43], pars->GC_11, amp[452]);
FFV1_0(w[66], w[125], w[7], pars->GC_11, amp[453]);
FFV1_0(w[66], w[2], w[43], pars->GC_11, amp[454]);
FFV2_5_0(w[63], w[125], w[17], pars->GC_51, pars->GC_58, amp[455]);
FFV1_0(w[126], w[116], w[6], pars->GC_11, amp[456]);
FFV1_0(w[62], w[116], w[35], pars->GC_11, amp[457]);
FFV1_0(w[60], w[116], w[46], pars->GC_11, amp[458]);
FFV1_0(w[64], w[127], w[6], pars->GC_11, amp[459]);
FFV1_0(w[64], w[2], w[46], pars->GC_11, amp[460]);
FFV1_0(w[62], w[127], w[8], pars->GC_2, amp[461]);
FFV1_0(w[126], w[120], w[6], pars->GC_11, amp[462]);
FFV1_0(w[62], w[120], w[35], pars->GC_11, amp[463]);
FFV1_0(w[60], w[120], w[46], pars->GC_11, amp[464]);
FFV1_0(w[66], w[127], w[6], pars->GC_11, amp[465]);
FFV1_0(w[66], w[2], w[46], pars->GC_11, amp[466]);
FFV2_5_0(w[62], w[127], w[17], pars->GC_51, pars->GC_58, amp[467]);
FFV1_0(w[87], w[116], w[29], pars->GC_11, amp[468]);
FFV1_0(w[128], w[116], w[5], pars->GC_11, amp[469]);
FFV1_0(w[60], w[116], w[49], pars->GC_11, amp[470]);
FFV1_0(w[64], w[129], w[5], pars->GC_11, amp[471]);
FFV1_0(w[64], w[2], w[49], pars->GC_11, amp[472]);
FFV1_0(w[87], w[129], w[8], pars->GC_2, amp[473]);
FFV1_0(w[87], w[120], w[29], pars->GC_11, amp[474]);
FFV1_0(w[128], w[120], w[5], pars->GC_11, amp[475]);
FFV1_0(w[60], w[120], w[49], pars->GC_11, amp[476]);
FFV1_0(w[66], w[129], w[5], pars->GC_11, amp[477]);
FFV1_0(w[66], w[2], w[49], pars->GC_11, amp[478]);
FFV2_5_0(w[87], w[129], w[17], pars->GC_51, pars->GC_58, amp[479]);
FFV1_0(w[60], w[116], w[51], pars->GC_11, amp[480]);
FFV1_0(w[60], w[116], w[52], pars->GC_11, amp[481]);
FFV1_0(w[60], w[116], w[53], pars->GC_11, amp[482]);
FFV1_0(w[64], w[2], w[51], pars->GC_11, amp[483]);
FFV1_0(w[64], w[2], w[52], pars->GC_11, amp[484]);
FFV1_0(w[64], w[2], w[53], pars->GC_11, amp[485]);
FFV1_0(w[60], w[120], w[51], pars->GC_11, amp[486]);
FFV1_0(w[60], w[120], w[52], pars->GC_11, amp[487]);
FFV1_0(w[60], w[120], w[53], pars->GC_11, amp[488]);
FFV1_0(w[66], w[2], w[51], pars->GC_11, amp[489]);
FFV1_0(w[66], w[2], w[52], pars->GC_11, amp[490]);
FFV1_0(w[66], w[2], w[53], pars->GC_11, amp[491]);
FFV1_0(w[89], w[117], w[7], pars->GC_11, amp[492]);
FFV1_0(w[89], w[118], w[6], pars->GC_11, amp[493]);
FFV1_0(w[24], w[130], w[7], pars->GC_11, amp[494]);
FFV1_0(w[24], w[118], w[4], pars->GC_11, amp[495]);
FFV1_0(w[25], w[130], w[6], pars->GC_11, amp[496]);
FFV1_0(w[25], w[117], w[4], pars->GC_11, amp[497]);
FFV1_0(w[89], w[121], w[7], pars->GC_11, amp[498]);
FFV1_0(w[89], w[122], w[6], pars->GC_11, amp[499]);
FFV1_0(w[24], w[131], w[7], pars->GC_11, amp[500]);
FFV1_0(w[24], w[122], w[4], pars->GC_11, amp[501]);
FFV1_0(w[25], w[131], w[6], pars->GC_11, amp[502]);
FFV1_0(w[25], w[121], w[4], pars->GC_11, amp[503]);
FFV1_0(w[132], w[116], w[7], pars->GC_11, amp[504]);
FFV1_0(w[25], w[116], w[70], pars->GC_11, amp[505]);
FFV1_0(w[22], w[116], w[72], pars->GC_11, amp[506]);
FFV1_0(w[26], w[133], w[7], pars->GC_11, amp[507]);
FFV1_0(w[26], w[2], w[72], pars->GC_11, amp[508]);
FFV1_0(w[25], w[133], w[8], pars->GC_2, amp[509]);
FFV1_0(w[132], w[120], w[7], pars->GC_11, amp[510]);
FFV1_0(w[25], w[120], w[70], pars->GC_11, amp[511]);
FFV1_0(w[22], w[120], w[72], pars->GC_11, amp[512]);
FFV1_0(w[28], w[133], w[7], pars->GC_11, amp[513]);
FFV1_0(w[28], w[2], w[72], pars->GC_11, amp[514]);
FFV2_5_0(w[25], w[133], w[17], pars->GC_51, pars->GC_58, amp[515]);
FFV1_0(w[134], w[116], w[6], pars->GC_11, amp[516]);
FFV1_0(w[24], w[116], w[68], pars->GC_11, amp[517]);
FFV1_0(w[22], w[116], w[75], pars->GC_11, amp[518]);
FFV1_0(w[26], w[135], w[6], pars->GC_11, amp[519]);
FFV1_0(w[26], w[2], w[75], pars->GC_11, amp[520]);
FFV1_0(w[24], w[135], w[8], pars->GC_2, amp[521]);
FFV1_0(w[134], w[120], w[6], pars->GC_11, amp[522]);
FFV1_0(w[24], w[120], w[68], pars->GC_11, amp[523]);
FFV1_0(w[22], w[120], w[75], pars->GC_11, amp[524]);
FFV1_0(w[28], w[135], w[6], pars->GC_11, amp[525]);
FFV1_0(w[28], w[2], w[75], pars->GC_11, amp[526]);
FFV2_5_0(w[24], w[135], w[17], pars->GC_51, pars->GC_58, amp[527]);
FFV1_0(w[89], w[116], w[29], pars->GC_11, amp[528]);
FFV1_0(w[136], w[116], w[4], pars->GC_11, amp[529]);
FFV1_0(w[22], w[116], w[77], pars->GC_11, amp[530]);
FFV1_0(w[26], w[129], w[4], pars->GC_11, amp[531]);
FFV1_0(w[26], w[2], w[77], pars->GC_11, amp[532]);
FFV1_0(w[89], w[129], w[8], pars->GC_2, amp[533]);
FFV1_0(w[89], w[120], w[29], pars->GC_11, amp[534]);
FFV1_0(w[136], w[120], w[4], pars->GC_11, amp[535]);
FFV1_0(w[22], w[120], w[77], pars->GC_11, amp[536]);
FFV1_0(w[28], w[129], w[4], pars->GC_11, amp[537]);
FFV1_0(w[28], w[2], w[77], pars->GC_11, amp[538]);
FFV2_5_0(w[89], w[129], w[17], pars->GC_51, pars->GC_58, amp[539]);
FFV1_0(w[22], w[116], w[79], pars->GC_11, amp[540]);
FFV1_0(w[22], w[116], w[80], pars->GC_11, amp[541]);
FFV1_0(w[22], w[116], w[81], pars->GC_11, amp[542]);
FFV1_0(w[26], w[2], w[79], pars->GC_11, amp[543]);
FFV1_0(w[26], w[2], w[80], pars->GC_11, amp[544]);
FFV1_0(w[26], w[2], w[81], pars->GC_11, amp[545]);
FFV1_0(w[22], w[120], w[79], pars->GC_11, amp[546]);
FFV1_0(w[22], w[120], w[80], pars->GC_11, amp[547]);
FFV1_0(w[22], w[120], w[81], pars->GC_11, amp[548]);
FFV1_0(w[28], w[2], w[79], pars->GC_11, amp[549]);
FFV1_0(w[28], w[2], w[80], pars->GC_11, amp[550]);
FFV1_0(w[28], w[2], w[81], pars->GC_11, amp[551]);
FFV1_0(w[67], w[119], w[7], pars->GC_11, amp[552]);
FFV1_0(w[67], w[118], w[5], pars->GC_11, amp[553]);
FFV1_0(w[31], w[130], w[7], pars->GC_11, amp[554]);
FFV1_0(w[31], w[118], w[4], pars->GC_11, amp[555]);
FFV1_0(w[32], w[130], w[5], pars->GC_11, amp[556]);
FFV1_0(w[32], w[119], w[4], pars->GC_11, amp[557]);
FFV1_0(w[67], w[123], w[7], pars->GC_11, amp[558]);
FFV1_0(w[67], w[122], w[5], pars->GC_11, amp[559]);
FFV1_0(w[31], w[131], w[7], pars->GC_11, amp[560]);
FFV1_0(w[31], w[122], w[4], pars->GC_11, amp[561]);
FFV1_0(w[32], w[131], w[5], pars->GC_11, amp[562]);
FFV1_0(w[32], w[123], w[4], pars->GC_11, amp[563]);
FFV1_0(w[137], w[116], w[7], pars->GC_11, amp[564]);
FFV1_0(w[32], w[116], w[90], pars->GC_11, amp[565]);
FFV1_0(w[30], w[116], w[92], pars->GC_11, amp[566]);
FFV1_0(w[33], w[138], w[7], pars->GC_11, amp[567]);
FFV1_0(w[33], w[2], w[92], pars->GC_11, amp[568]);
FFV1_0(w[32], w[138], w[8], pars->GC_2, amp[569]);
FFV1_0(w[137], w[120], w[7], pars->GC_11, amp[570]);
FFV1_0(w[32], w[120], w[90], pars->GC_11, amp[571]);
FFV1_0(w[30], w[120], w[92], pars->GC_11, amp[572]);
FFV1_0(w[34], w[138], w[7], pars->GC_11, amp[573]);
FFV1_0(w[34], w[2], w[92], pars->GC_11, amp[574]);
FFV2_5_0(w[32], w[138], w[17], pars->GC_51, pars->GC_58, amp[575]);
FFV1_0(w[139], w[116], w[5], pars->GC_11, amp[576]);
FFV1_0(w[31], w[116], w[68], pars->GC_11, amp[577]);
FFV1_0(w[30], w[116], w[94], pars->GC_11, amp[578]);
FFV1_0(w[33], w[135], w[5], pars->GC_11, amp[579]);
FFV1_0(w[33], w[2], w[94], pars->GC_11, amp[580]);
FFV1_0(w[31], w[135], w[8], pars->GC_2, amp[581]);
FFV1_0(w[139], w[120], w[5], pars->GC_11, amp[582]);
FFV1_0(w[31], w[120], w[68], pars->GC_11, amp[583]);
FFV1_0(w[30], w[120], w[94], pars->GC_11, amp[584]);
FFV1_0(w[34], w[135], w[5], pars->GC_11, amp[585]);
FFV1_0(w[34], w[2], w[94], pars->GC_11, amp[586]);
FFV2_5_0(w[31], w[135], w[17], pars->GC_51, pars->GC_58, amp[587]);
FFV1_0(w[67], w[116], w[35], pars->GC_11, amp[588]);
FFV1_0(w[140], w[116], w[4], pars->GC_11, amp[589]);
FFV1_0(w[30], w[116], w[96], pars->GC_11, amp[590]);
FFV1_0(w[33], w[127], w[4], pars->GC_11, amp[591]);
FFV1_0(w[33], w[2], w[96], pars->GC_11, amp[592]);
FFV1_0(w[67], w[127], w[8], pars->GC_2, amp[593]);
FFV1_0(w[67], w[120], w[35], pars->GC_11, amp[594]);
FFV1_0(w[140], w[120], w[4], pars->GC_11, amp[595]);
FFV1_0(w[30], w[120], w[96], pars->GC_11, amp[596]);
FFV1_0(w[34], w[127], w[4], pars->GC_11, amp[597]);
FFV1_0(w[34], w[2], w[96], pars->GC_11, amp[598]);
FFV2_5_0(w[67], w[127], w[17], pars->GC_51, pars->GC_58, amp[599]);
FFV1_0(w[30], w[116], w[98], pars->GC_11, amp[600]);
FFV1_0(w[30], w[116], w[99], pars->GC_11, amp[601]);
FFV1_0(w[30], w[116], w[100], pars->GC_11, amp[602]);
FFV1_0(w[33], w[2], w[98], pars->GC_11, amp[603]);
FFV1_0(w[33], w[2], w[99], pars->GC_11, amp[604]);
FFV1_0(w[33], w[2], w[100], pars->GC_11, amp[605]);
FFV1_0(w[30], w[120], w[98], pars->GC_11, amp[606]);
FFV1_0(w[30], w[120], w[99], pars->GC_11, amp[607]);
FFV1_0(w[30], w[120], w[100], pars->GC_11, amp[608]);
FFV1_0(w[34], w[2], w[98], pars->GC_11, amp[609]);
FFV1_0(w[34], w[2], w[99], pars->GC_11, amp[610]);
FFV1_0(w[34], w[2], w[100], pars->GC_11, amp[611]);
FFV1_0(w[69], w[119], w[6], pars->GC_11, amp[612]);
FFV1_0(w[69], w[117], w[5], pars->GC_11, amp[613]);
FFV1_0(w[37], w[130], w[6], pars->GC_11, amp[614]);
FFV1_0(w[37], w[117], w[4], pars->GC_11, amp[615]);
FFV1_0(w[38], w[130], w[5], pars->GC_11, amp[616]);
FFV1_0(w[38], w[119], w[4], pars->GC_11, amp[617]);
FFV1_0(w[69], w[123], w[6], pars->GC_11, amp[618]);
FFV1_0(w[69], w[121], w[5], pars->GC_11, amp[619]);
FFV1_0(w[37], w[131], w[6], pars->GC_11, amp[620]);
FFV1_0(w[37], w[121], w[4], pars->GC_11, amp[621]);
FFV1_0(w[38], w[131], w[5], pars->GC_11, amp[622]);
FFV1_0(w[38], w[123], w[4], pars->GC_11, amp[623]);
FFV1_0(w[141], w[116], w[6], pars->GC_11, amp[624]);
FFV1_0(w[38], w[116], w[90], pars->GC_11, amp[625]);
FFV1_0(w[36], w[116], w[107], pars->GC_11, amp[626]);
FFV1_0(w[39], w[138], w[6], pars->GC_11, amp[627]);
FFV1_0(w[39], w[2], w[107], pars->GC_11, amp[628]);
FFV1_0(w[38], w[138], w[8], pars->GC_2, amp[629]);
FFV1_0(w[141], w[120], w[6], pars->GC_11, amp[630]);
FFV1_0(w[38], w[120], w[90], pars->GC_11, amp[631]);
FFV1_0(w[36], w[120], w[107], pars->GC_11, amp[632]);
FFV1_0(w[40], w[138], w[6], pars->GC_11, amp[633]);
FFV1_0(w[40], w[2], w[107], pars->GC_11, amp[634]);
FFV2_5_0(w[38], w[138], w[17], pars->GC_51, pars->GC_58, amp[635]);
FFV1_0(w[142], w[116], w[5], pars->GC_11, amp[636]);
FFV1_0(w[37], w[116], w[70], pars->GC_11, amp[637]);
FFV1_0(w[36], w[116], w[109], pars->GC_11, amp[638]);
FFV1_0(w[39], w[133], w[5], pars->GC_11, amp[639]);
FFV1_0(w[39], w[2], w[109], pars->GC_11, amp[640]);
FFV1_0(w[37], w[133], w[8], pars->GC_2, amp[641]);
FFV1_0(w[142], w[120], w[5], pars->GC_11, amp[642]);
FFV1_0(w[37], w[120], w[70], pars->GC_11, amp[643]);
FFV1_0(w[36], w[120], w[109], pars->GC_11, amp[644]);
FFV1_0(w[40], w[133], w[5], pars->GC_11, amp[645]);
FFV1_0(w[40], w[2], w[109], pars->GC_11, amp[646]);
FFV2_5_0(w[37], w[133], w[17], pars->GC_51, pars->GC_58, amp[647]);
FFV1_0(w[69], w[116], w[41], pars->GC_11, amp[648]);
FFV1_0(w[143], w[116], w[4], pars->GC_11, amp[649]);
FFV1_0(w[36], w[116], w[111], pars->GC_11, amp[650]);
FFV1_0(w[39], w[125], w[4], pars->GC_11, amp[651]);
FFV1_0(w[39], w[2], w[111], pars->GC_11, amp[652]);
FFV1_0(w[69], w[125], w[8], pars->GC_2, amp[653]);
FFV1_0(w[69], w[120], w[41], pars->GC_11, amp[654]);
FFV1_0(w[143], w[120], w[4], pars->GC_11, amp[655]);
FFV1_0(w[36], w[120], w[111], pars->GC_11, amp[656]);
FFV1_0(w[40], w[125], w[4], pars->GC_11, amp[657]);
FFV1_0(w[40], w[2], w[111], pars->GC_11, amp[658]);
FFV2_5_0(w[69], w[125], w[17], pars->GC_51, pars->GC_58, amp[659]);
FFV1_0(w[36], w[116], w[113], pars->GC_11, amp[660]);
FFV1_0(w[36], w[116], w[114], pars->GC_11, amp[661]);
FFV1_0(w[36], w[116], w[115], pars->GC_11, amp[662]);
FFV1_0(w[39], w[2], w[113], pars->GC_11, amp[663]);
FFV1_0(w[39], w[2], w[114], pars->GC_11, amp[664]);
FFV1_0(w[39], w[2], w[115], pars->GC_11, amp[665]);
FFV1_0(w[36], w[120], w[113], pars->GC_11, amp[666]);
FFV1_0(w[36], w[120], w[114], pars->GC_11, amp[667]);
FFV1_0(w[36], w[120], w[115], pars->GC_11, amp[668]);
FFV1_0(w[40], w[2], w[113], pars->GC_11, amp[669]);
FFV1_0(w[40], w[2], w[114], pars->GC_11, amp[670]);
FFV1_0(w[40], w[2], w[115], pars->GC_11, amp[671]);
FFV1_0(w[91], w[117], w[7], pars->GC_11, amp[672]);
FFV1_0(w[91], w[118], w[6], pars->GC_11, amp[673]);
VVV1_0(w[107], w[7], w[144], pars->GC_10, amp[674]);
FFV1_0(w[3], w[118], w[107], pars->GC_11, amp[675]);
VVV1_0(w[92], w[6], w[144], pars->GC_10, amp[676]);
FFV1_0(w[3], w[117], w[92], pars->GC_11, amp[677]);
FFV1_0(w[3], w[116], w[145], pars->GC_11, amp[678]);
FFV1_0(w[3], w[116], w[146], pars->GC_11, amp[679]);
FFV1_0(w[3], w[116], w[147], pars->GC_11, amp[680]);
FFV1_0(w[12], w[138], w[7], pars->GC_11, amp[681]);
FFV1_0(w[13], w[138], w[6], pars->GC_11, amp[682]);
VVV1_0(w[107], w[7], w[148], pars->GC_10, amp[683]);
FFV1_0(w[13], w[2], w[107], pars->GC_11, amp[684]);
VVV1_0(w[92], w[6], w[148], pars->GC_10, amp[685]);
FFV1_0(w[12], w[2], w[92], pars->GC_11, amp[686]);
FFV1_0(w[10], w[2], w[145], pars->GC_11, amp[687]);
FFV1_0(w[10], w[2], w[146], pars->GC_11, amp[688]);
FFV1_0(w[10], w[2], w[147], pars->GC_11, amp[689]);
FFV1_0(w[91], w[121], w[7], pars->GC_11, amp[690]);
FFV1_0(w[91], w[122], w[6], pars->GC_11, amp[691]);
VVV1_0(w[107], w[7], w[149], pars->GC_10, amp[692]);
FFV1_0(w[3], w[122], w[107], pars->GC_11, amp[693]);
VVV1_0(w[92], w[6], w[149], pars->GC_10, amp[694]);
FFV1_0(w[3], w[121], w[92], pars->GC_11, amp[695]);
FFV1_0(w[3], w[120], w[145], pars->GC_11, amp[696]);
FFV1_0(w[3], w[120], w[146], pars->GC_11, amp[697]);
FFV1_0(w[3], w[120], w[147], pars->GC_11, amp[698]);
FFV1_0(w[19], w[138], w[7], pars->GC_11, amp[699]);
FFV1_0(w[20], w[138], w[6], pars->GC_11, amp[700]);
VVV1_0(w[107], w[7], w[150], pars->GC_10, amp[701]);
FFV1_0(w[20], w[2], w[107], pars->GC_11, amp[702]);
VVV1_0(w[92], w[6], w[150], pars->GC_10, amp[703]);
FFV1_0(w[19], w[2], w[92], pars->GC_11, amp[704]);
FFV1_0(w[18], w[2], w[145], pars->GC_11, amp[705]);
FFV1_0(w[18], w[2], w[146], pars->GC_11, amp[706]);
FFV1_0(w[18], w[2], w[147], pars->GC_11, amp[707]);
FFV1_0(w[91], w[116], w[29], pars->GC_11, amp[708]);
FFV1_0(w[48], w[116], w[90], pars->GC_11, amp[709]);
FFV1_0(w[3], w[116], w[151], pars->GC_11, amp[710]);
FFV1_0(w[10], w[138], w[29], pars->GC_11, amp[711]);
FFV1_0(w[10], w[129], w[90], pars->GC_11, amp[712]);
FFV1_0(w[10], w[2], w[151], pars->GC_11, amp[713]);
FFV1_0(w[48], w[138], w[8], pars->GC_2, amp[714]);
FFV1_0(w[91], w[129], w[8], pars->GC_2, amp[715]);
FFV1_0(w[91], w[120], w[29], pars->GC_11, amp[716]);
FFV1_0(w[48], w[120], w[90], pars->GC_11, amp[717]);
FFV1_0(w[3], w[120], w[151], pars->GC_11, amp[718]);
FFV1_0(w[18], w[138], w[29], pars->GC_11, amp[719]);
FFV1_0(w[18], w[129], w[90], pars->GC_11, amp[720]);
FFV1_0(w[18], w[2], w[151], pars->GC_11, amp[721]);
FFV2_5_0(w[48], w[138], w[17], pars->GC_51, pars->GC_58, amp[722]);
FFV2_5_0(w[91], w[129], w[17], pars->GC_51, pars->GC_58, amp[723]);
FFV1_0(w[71], w[119], w[7], pars->GC_11, amp[724]);
FFV1_0(w[71], w[118], w[5], pars->GC_11, amp[725]);
VVV1_0(w[109], w[7], w[144], pars->GC_10, amp[726]);
FFV1_0(w[3], w[118], w[109], pars->GC_11, amp[727]);
VVV1_0(w[72], w[5], w[144], pars->GC_10, amp[728]);
FFV1_0(w[3], w[119], w[72], pars->GC_11, amp[729]);
FFV1_0(w[3], w[116], w[152], pars->GC_11, amp[730]);
FFV1_0(w[3], w[116], w[153], pars->GC_11, amp[731]);
FFV1_0(w[3], w[116], w[154], pars->GC_11, amp[732]);
FFV1_0(w[15], w[133], w[7], pars->GC_11, amp[733]);
FFV1_0(w[13], w[133], w[5], pars->GC_11, amp[734]);
VVV1_0(w[109], w[7], w[148], pars->GC_10, amp[735]);
FFV1_0(w[13], w[2], w[109], pars->GC_11, amp[736]);
VVV1_0(w[72], w[5], w[148], pars->GC_10, amp[737]);
FFV1_0(w[15], w[2], w[72], pars->GC_11, amp[738]);
FFV1_0(w[10], w[2], w[152], pars->GC_11, amp[739]);
FFV1_0(w[10], w[2], w[153], pars->GC_11, amp[740]);
FFV1_0(w[10], w[2], w[154], pars->GC_11, amp[741]);
FFV1_0(w[71], w[123], w[7], pars->GC_11, amp[742]);
FFV1_0(w[71], w[122], w[5], pars->GC_11, amp[743]);
VVV1_0(w[109], w[7], w[149], pars->GC_10, amp[744]);
FFV1_0(w[3], w[122], w[109], pars->GC_11, amp[745]);
VVV1_0(w[72], w[5], w[149], pars->GC_10, amp[746]);
FFV1_0(w[3], w[123], w[72], pars->GC_11, amp[747]);
FFV1_0(w[3], w[120], w[152], pars->GC_11, amp[748]);
FFV1_0(w[3], w[120], w[153], pars->GC_11, amp[749]);
FFV1_0(w[3], w[120], w[154], pars->GC_11, amp[750]);
FFV1_0(w[21], w[133], w[7], pars->GC_11, amp[751]);
FFV1_0(w[20], w[133], w[5], pars->GC_11, amp[752]);
VVV1_0(w[109], w[7], w[150], pars->GC_10, amp[753]);
FFV1_0(w[20], w[2], w[109], pars->GC_11, amp[754]);
VVV1_0(w[72], w[5], w[150], pars->GC_10, amp[755]);
FFV1_0(w[21], w[2], w[72], pars->GC_11, amp[756]);
FFV1_0(w[18], w[2], w[152], pars->GC_11, amp[757]);
FFV1_0(w[18], w[2], w[153], pars->GC_11, amp[758]);
FFV1_0(w[18], w[2], w[154], pars->GC_11, amp[759]);
FFV1_0(w[71], w[116], w[35], pars->GC_11, amp[760]);
FFV1_0(w[45], w[116], w[70], pars->GC_11, amp[761]);
FFV1_0(w[3], w[116], w[155], pars->GC_11, amp[762]);
FFV1_0(w[10], w[133], w[35], pars->GC_11, amp[763]);
FFV1_0(w[10], w[127], w[70], pars->GC_11, amp[764]);
FFV1_0(w[10], w[2], w[155], pars->GC_11, amp[765]);
FFV1_0(w[45], w[133], w[8], pars->GC_2, amp[766]);
FFV1_0(w[71], w[127], w[8], pars->GC_2, amp[767]);
FFV1_0(w[71], w[120], w[35], pars->GC_11, amp[768]);
FFV1_0(w[45], w[120], w[70], pars->GC_11, amp[769]);
FFV1_0(w[3], w[120], w[155], pars->GC_11, amp[770]);
FFV1_0(w[18], w[133], w[35], pars->GC_11, amp[771]);
FFV1_0(w[18], w[127], w[70], pars->GC_11, amp[772]);
FFV1_0(w[18], w[2], w[155], pars->GC_11, amp[773]);
FFV2_5_0(w[45], w[133], w[17], pars->GC_51, pars->GC_58, amp[774]);
FFV2_5_0(w[71], w[127], w[17], pars->GC_51, pars->GC_58, amp[775]);
FFV1_0(w[74], w[119], w[6], pars->GC_11, amp[776]);
FFV1_0(w[74], w[117], w[5], pars->GC_11, amp[777]);
VVV1_0(w[94], w[6], w[144], pars->GC_10, amp[778]);
FFV1_0(w[3], w[117], w[94], pars->GC_11, amp[779]);
VVV1_0(w[75], w[5], w[144], pars->GC_10, amp[780]);
FFV1_0(w[3], w[119], w[75], pars->GC_11, amp[781]);
FFV1_0(w[3], w[116], w[156], pars->GC_11, amp[782]);
FFV1_0(w[3], w[116], w[157], pars->GC_11, amp[783]);
FFV1_0(w[3], w[116], w[158], pars->GC_11, amp[784]);
FFV1_0(w[15], w[135], w[6], pars->GC_11, amp[785]);
FFV1_0(w[12], w[135], w[5], pars->GC_11, amp[786]);
VVV1_0(w[94], w[6], w[148], pars->GC_10, amp[787]);
FFV1_0(w[12], w[2], w[94], pars->GC_11, amp[788]);
VVV1_0(w[75], w[5], w[148], pars->GC_10, amp[789]);
FFV1_0(w[15], w[2], w[75], pars->GC_11, amp[790]);
FFV1_0(w[10], w[2], w[156], pars->GC_11, amp[791]);
FFV1_0(w[10], w[2], w[157], pars->GC_11, amp[792]);
FFV1_0(w[10], w[2], w[158], pars->GC_11, amp[793]);
FFV1_0(w[74], w[123], w[6], pars->GC_11, amp[794]);
FFV1_0(w[74], w[121], w[5], pars->GC_11, amp[795]);
VVV1_0(w[94], w[6], w[149], pars->GC_10, amp[796]);
FFV1_0(w[3], w[121], w[94], pars->GC_11, amp[797]);
VVV1_0(w[75], w[5], w[149], pars->GC_10, amp[798]);
FFV1_0(w[3], w[123], w[75], pars->GC_11, amp[799]);
FFV1_0(w[3], w[120], w[156], pars->GC_11, amp[800]);
FFV1_0(w[3], w[120], w[157], pars->GC_11, amp[801]);
FFV1_0(w[3], w[120], w[158], pars->GC_11, amp[802]);
FFV1_0(w[21], w[135], w[6], pars->GC_11, amp[803]);
FFV1_0(w[19], w[135], w[5], pars->GC_11, amp[804]);
VVV1_0(w[94], w[6], w[150], pars->GC_10, amp[805]);
FFV1_0(w[19], w[2], w[94], pars->GC_11, amp[806]);
VVV1_0(w[75], w[5], w[150], pars->GC_10, amp[807]);
FFV1_0(w[21], w[2], w[75], pars->GC_11, amp[808]);
FFV1_0(w[18], w[2], w[156], pars->GC_11, amp[809]);
FFV1_0(w[18], w[2], w[157], pars->GC_11, amp[810]);
FFV1_0(w[18], w[2], w[158], pars->GC_11, amp[811]);
FFV1_0(w[74], w[116], w[41], pars->GC_11, amp[812]);
FFV1_0(w[42], w[116], w[68], pars->GC_11, amp[813]);
FFV1_0(w[3], w[116], w[159], pars->GC_11, amp[814]);
FFV1_0(w[10], w[135], w[41], pars->GC_11, amp[815]);
FFV1_0(w[10], w[125], w[68], pars->GC_11, amp[816]);
FFV1_0(w[10], w[2], w[159], pars->GC_11, amp[817]);
FFV1_0(w[42], w[135], w[8], pars->GC_2, amp[818]);
FFV1_0(w[74], w[125], w[8], pars->GC_2, amp[819]);
FFV1_0(w[74], w[120], w[41], pars->GC_11, amp[820]);
FFV1_0(w[42], w[120], w[68], pars->GC_11, amp[821]);
FFV1_0(w[3], w[120], w[159], pars->GC_11, amp[822]);
FFV1_0(w[18], w[135], w[41], pars->GC_11, amp[823]);
FFV1_0(w[18], w[125], w[68], pars->GC_11, amp[824]);
FFV1_0(w[18], w[2], w[159], pars->GC_11, amp[825]);
FFV2_5_0(w[42], w[135], w[17], pars->GC_51, pars->GC_58, amp[826]);
FFV2_5_0(w[74], w[125], w[17], pars->GC_51, pars->GC_58, amp[827]);
FFV1_0(w[42], w[130], w[7], pars->GC_11, amp[828]);
FFV1_0(w[42], w[118], w[4], pars->GC_11, amp[829]);
VVV1_0(w[111], w[7], w[144], pars->GC_10, amp[830]);
FFV1_0(w[3], w[118], w[111], pars->GC_11, amp[831]);
VVV1_0(w[4], w[43], w[144], pars->GC_10, amp[832]);
FFV1_0(w[3], w[130], w[43], pars->GC_11, amp[833]);
FFV1_0(w[3], w[116], w[160], pars->GC_11, amp[834]);
FFV1_0(w[3], w[116], w[161], pars->GC_11, amp[835]);
FFV1_0(w[3], w[116], w[162], pars->GC_11, amp[836]);
FFV1_0(w[57], w[125], w[7], pars->GC_11, amp[837]);
FFV1_0(w[13], w[125], w[4], pars->GC_11, amp[838]);
VVV1_0(w[111], w[7], w[148], pars->GC_10, amp[839]);
FFV1_0(w[13], w[2], w[111], pars->GC_11, amp[840]);
VVV1_0(w[4], w[43], w[148], pars->GC_10, amp[841]);
FFV1_0(w[57], w[2], w[43], pars->GC_11, amp[842]);
FFV1_0(w[10], w[2], w[160], pars->GC_11, amp[843]);
FFV1_0(w[10], w[2], w[161], pars->GC_11, amp[844]);
FFV1_0(w[10], w[2], w[162], pars->GC_11, amp[845]);
FFV1_0(w[42], w[131], w[7], pars->GC_11, amp[846]);
FFV1_0(w[42], w[122], w[4], pars->GC_11, amp[847]);
VVV1_0(w[111], w[7], w[149], pars->GC_10, amp[848]);
FFV1_0(w[3], w[122], w[111], pars->GC_11, amp[849]);
VVV1_0(w[4], w[43], w[149], pars->GC_10, amp[850]);
FFV1_0(w[3], w[131], w[43], pars->GC_11, amp[851]);
FFV1_0(w[3], w[120], w[160], pars->GC_11, amp[852]);
FFV1_0(w[3], w[120], w[161], pars->GC_11, amp[853]);
FFV1_0(w[3], w[120], w[162], pars->GC_11, amp[854]);
FFV1_0(w[59], w[125], w[7], pars->GC_11, amp[855]);
FFV1_0(w[20], w[125], w[4], pars->GC_11, amp[856]);
VVV1_0(w[111], w[7], w[150], pars->GC_10, amp[857]);
FFV1_0(w[20], w[2], w[111], pars->GC_11, amp[858]);
VVV1_0(w[4], w[43], w[150], pars->GC_10, amp[859]);
FFV1_0(w[59], w[2], w[43], pars->GC_11, amp[860]);
FFV1_0(w[18], w[2], w[160], pars->GC_11, amp[861]);
FFV1_0(w[18], w[2], w[161], pars->GC_11, amp[862]);
FFV1_0(w[18], w[2], w[162], pars->GC_11, amp[863]);
FFV1_0(w[45], w[130], w[6], pars->GC_11, amp[864]);
FFV1_0(w[45], w[117], w[4], pars->GC_11, amp[865]);
VVV1_0(w[96], w[6], w[144], pars->GC_10, amp[866]);
FFV1_0(w[3], w[117], w[96], pars->GC_11, amp[867]);
VVV1_0(w[4], w[46], w[144], pars->GC_10, amp[868]);
FFV1_0(w[3], w[130], w[46], pars->GC_11, amp[869]);
FFV1_0(w[3], w[116], w[163], pars->GC_11, amp[870]);
FFV1_0(w[3], w[116], w[164], pars->GC_11, amp[871]);
FFV1_0(w[3], w[116], w[165], pars->GC_11, amp[872]);
FFV1_0(w[57], w[127], w[6], pars->GC_11, amp[873]);
FFV1_0(w[12], w[127], w[4], pars->GC_11, amp[874]);
VVV1_0(w[96], w[6], w[148], pars->GC_10, amp[875]);
FFV1_0(w[12], w[2], w[96], pars->GC_11, amp[876]);
VVV1_0(w[4], w[46], w[148], pars->GC_10, amp[877]);
FFV1_0(w[57], w[2], w[46], pars->GC_11, amp[878]);
FFV1_0(w[10], w[2], w[163], pars->GC_11, amp[879]);
FFV1_0(w[10], w[2], w[164], pars->GC_11, amp[880]);
FFV1_0(w[10], w[2], w[165], pars->GC_11, amp[881]);
FFV1_0(w[45], w[131], w[6], pars->GC_11, amp[882]);
FFV1_0(w[45], w[121], w[4], pars->GC_11, amp[883]);
VVV1_0(w[96], w[6], w[149], pars->GC_10, amp[884]);
FFV1_0(w[3], w[121], w[96], pars->GC_11, amp[885]);
VVV1_0(w[4], w[46], w[149], pars->GC_10, amp[886]);
FFV1_0(w[3], w[131], w[46], pars->GC_11, amp[887]);
FFV1_0(w[3], w[120], w[163], pars->GC_11, amp[888]);
FFV1_0(w[3], w[120], w[164], pars->GC_11, amp[889]);
FFV1_0(w[3], w[120], w[165], pars->GC_11, amp[890]);
FFV1_0(w[59], w[127], w[6], pars->GC_11, amp[891]);
FFV1_0(w[19], w[127], w[4], pars->GC_11, amp[892]);
VVV1_0(w[96], w[6], w[150], pars->GC_10, amp[893]);
FFV1_0(w[19], w[2], w[96], pars->GC_11, amp[894]);
VVV1_0(w[4], w[46], w[150], pars->GC_10, amp[895]);
FFV1_0(w[59], w[2], w[46], pars->GC_11, amp[896]);
FFV1_0(w[18], w[2], w[163], pars->GC_11, amp[897]);
FFV1_0(w[18], w[2], w[164], pars->GC_11, amp[898]);
FFV1_0(w[18], w[2], w[165], pars->GC_11, amp[899]);
FFV1_0(w[48], w[130], w[5], pars->GC_11, amp[900]);
FFV1_0(w[48], w[119], w[4], pars->GC_11, amp[901]);
VVV1_0(w[77], w[5], w[144], pars->GC_10, amp[902]);
FFV1_0(w[3], w[119], w[77], pars->GC_11, amp[903]);
VVV1_0(w[4], w[49], w[144], pars->GC_10, amp[904]);
FFV1_0(w[3], w[130], w[49], pars->GC_11, amp[905]);
FFV1_0(w[3], w[116], w[166], pars->GC_11, amp[906]);
FFV1_0(w[3], w[116], w[167], pars->GC_11, amp[907]);
FFV1_0(w[3], w[116], w[168], pars->GC_11, amp[908]);
FFV1_0(w[57], w[129], w[5], pars->GC_11, amp[909]);
FFV1_0(w[15], w[129], w[4], pars->GC_11, amp[910]);
VVV1_0(w[77], w[5], w[148], pars->GC_10, amp[911]);
FFV1_0(w[15], w[2], w[77], pars->GC_11, amp[912]);
VVV1_0(w[4], w[49], w[148], pars->GC_10, amp[913]);
FFV1_0(w[57], w[2], w[49], pars->GC_11, amp[914]);
FFV1_0(w[10], w[2], w[166], pars->GC_11, amp[915]);
FFV1_0(w[10], w[2], w[167], pars->GC_11, amp[916]);
FFV1_0(w[10], w[2], w[168], pars->GC_11, amp[917]);
FFV1_0(w[48], w[131], w[5], pars->GC_11, amp[918]);
FFV1_0(w[48], w[123], w[4], pars->GC_11, amp[919]);
VVV1_0(w[77], w[5], w[149], pars->GC_10, amp[920]);
FFV1_0(w[3], w[123], w[77], pars->GC_11, amp[921]);
VVV1_0(w[4], w[49], w[149], pars->GC_10, amp[922]);
FFV1_0(w[3], w[131], w[49], pars->GC_11, amp[923]);
FFV1_0(w[3], w[120], w[166], pars->GC_11, amp[924]);
FFV1_0(w[3], w[120], w[167], pars->GC_11, amp[925]);
FFV1_0(w[3], w[120], w[168], pars->GC_11, amp[926]);
FFV1_0(w[59], w[129], w[5], pars->GC_11, amp[927]);
FFV1_0(w[21], w[129], w[4], pars->GC_11, amp[928]);
VVV1_0(w[77], w[5], w[150], pars->GC_10, amp[929]);
FFV1_0(w[21], w[2], w[77], pars->GC_11, amp[930]);
VVV1_0(w[4], w[49], w[150], pars->GC_10, amp[931]);
FFV1_0(w[59], w[2], w[49], pars->GC_11, amp[932]);
FFV1_0(w[18], w[2], w[166], pars->GC_11, amp[933]);
FFV1_0(w[18], w[2], w[167], pars->GC_11, amp[934]);
FFV1_0(w[18], w[2], w[168], pars->GC_11, amp[935]);
FFV1_0(w[169], w[116], w[7], pars->GC_11, amp[936]);
FFV1_0(w[170], w[116], w[7], pars->GC_11, amp[937]);
FFV1_0(w[171], w[116], w[7], pars->GC_11, amp[938]);
FFV1_0(w[3], w[116], w[172], pars->GC_11, amp[939]);
FFV1_0(w[3], w[116], w[173], pars->GC_11, amp[940]);
FFV1_0(w[3], w[116], w[174], pars->GC_11, amp[941]);
FFV1_0(w[10], w[175], w[7], pars->GC_11, amp[942]);
FFV1_0(w[10], w[176], w[7], pars->GC_11, amp[943]);
FFV1_0(w[10], w[177], w[7], pars->GC_11, amp[944]);
FFV1_0(w[10], w[2], w[172], pars->GC_11, amp[945]);
FFV1_0(w[10], w[2], w[173], pars->GC_11, amp[946]);
FFV1_0(w[10], w[2], w[174], pars->GC_11, amp[947]);
FFV1_0(w[169], w[120], w[7], pars->GC_11, amp[948]);
FFV1_0(w[170], w[120], w[7], pars->GC_11, amp[949]);
FFV1_0(w[171], w[120], w[7], pars->GC_11, amp[950]);
FFV1_0(w[3], w[120], w[172], pars->GC_11, amp[951]);
FFV1_0(w[3], w[120], w[173], pars->GC_11, amp[952]);
FFV1_0(w[3], w[120], w[174], pars->GC_11, amp[953]);
FFV1_0(w[18], w[175], w[7], pars->GC_11, amp[954]);
FFV1_0(w[18], w[176], w[7], pars->GC_11, amp[955]);
FFV1_0(w[18], w[177], w[7], pars->GC_11, amp[956]);
FFV1_0(w[18], w[2], w[172], pars->GC_11, amp[957]);
FFV1_0(w[18], w[2], w[173], pars->GC_11, amp[958]);
FFV1_0(w[18], w[2], w[174], pars->GC_11, amp[959]);
FFV1_0(w[178], w[116], w[6], pars->GC_11, amp[960]);
FFV1_0(w[179], w[116], w[6], pars->GC_11, amp[961]);
FFV1_0(w[180], w[116], w[6], pars->GC_11, amp[962]);
FFV1_0(w[3], w[116], w[181], pars->GC_11, amp[963]);
FFV1_0(w[3], w[116], w[182], pars->GC_11, amp[964]);
FFV1_0(w[3], w[116], w[183], pars->GC_11, amp[965]);
FFV1_0(w[10], w[184], w[6], pars->GC_11, amp[966]);
FFV1_0(w[10], w[185], w[6], pars->GC_11, amp[967]);
FFV1_0(w[10], w[186], w[6], pars->GC_11, amp[968]);
FFV1_0(w[10], w[2], w[181], pars->GC_11, amp[969]);
FFV1_0(w[10], w[2], w[182], pars->GC_11, amp[970]);
FFV1_0(w[10], w[2], w[183], pars->GC_11, amp[971]);
FFV1_0(w[178], w[120], w[6], pars->GC_11, amp[972]);
FFV1_0(w[179], w[120], w[6], pars->GC_11, amp[973]);
FFV1_0(w[180], w[120], w[6], pars->GC_11, amp[974]);
FFV1_0(w[3], w[120], w[181], pars->GC_11, amp[975]);
FFV1_0(w[3], w[120], w[182], pars->GC_11, amp[976]);
FFV1_0(w[3], w[120], w[183], pars->GC_11, amp[977]);
FFV1_0(w[18], w[184], w[6], pars->GC_11, amp[978]);
FFV1_0(w[18], w[185], w[6], pars->GC_11, amp[979]);
FFV1_0(w[18], w[186], w[6], pars->GC_11, amp[980]);
FFV1_0(w[18], w[2], w[181], pars->GC_11, amp[981]);
FFV1_0(w[18], w[2], w[182], pars->GC_11, amp[982]);
FFV1_0(w[18], w[2], w[183], pars->GC_11, amp[983]);
FFV1_0(w[187], w[116], w[5], pars->GC_11, amp[984]);
FFV1_0(w[188], w[116], w[5], pars->GC_11, amp[985]);
FFV1_0(w[189], w[116], w[5], pars->GC_11, amp[986]);
FFV1_0(w[3], w[116], w[190], pars->GC_11, amp[987]);
FFV1_0(w[3], w[116], w[191], pars->GC_11, amp[988]);
FFV1_0(w[3], w[116], w[192], pars->GC_11, amp[989]);
FFV1_0(w[10], w[193], w[5], pars->GC_11, amp[990]);
FFV1_0(w[10], w[194], w[5], pars->GC_11, amp[991]);
FFV1_0(w[10], w[195], w[5], pars->GC_11, amp[992]);
FFV1_0(w[10], w[2], w[190], pars->GC_11, amp[993]);
FFV1_0(w[10], w[2], w[191], pars->GC_11, amp[994]);
FFV1_0(w[10], w[2], w[192], pars->GC_11, amp[995]);
FFV1_0(w[187], w[120], w[5], pars->GC_11, amp[996]);
FFV1_0(w[188], w[120], w[5], pars->GC_11, amp[997]);
FFV1_0(w[189], w[120], w[5], pars->GC_11, amp[998]);
FFV1_0(w[3], w[120], w[190], pars->GC_11, amp[999]);
FFV1_0(w[3], w[120], w[191], pars->GC_11, amp[1000]);
FFV1_0(w[3], w[120], w[192], pars->GC_11, amp[1001]);
FFV1_0(w[18], w[193], w[5], pars->GC_11, amp[1002]);
FFV1_0(w[18], w[194], w[5], pars->GC_11, amp[1003]);
FFV1_0(w[18], w[195], w[5], pars->GC_11, amp[1004]);
FFV1_0(w[18], w[2], w[190], pars->GC_11, amp[1005]);
FFV1_0(w[18], w[2], w[191], pars->GC_11, amp[1006]);
FFV1_0(w[18], w[2], w[192], pars->GC_11, amp[1007]);
FFV1_0(w[196], w[116], w[4], pars->GC_11, amp[1008]);
FFV1_0(w[197], w[116], w[4], pars->GC_11, amp[1009]);
FFV1_0(w[198], w[116], w[4], pars->GC_11, amp[1010]);
FFV1_0(w[3], w[116], w[199], pars->GC_11, amp[1011]);
FFV1_0(w[3], w[116], w[200], pars->GC_11, amp[1012]);
FFV1_0(w[3], w[116], w[201], pars->GC_11, amp[1013]);
FFV1_0(w[10], w[202], w[4], pars->GC_11, amp[1014]);
FFV1_0(w[10], w[203], w[4], pars->GC_11, amp[1015]);
FFV1_0(w[10], w[204], w[4], pars->GC_11, amp[1016]);
FFV1_0(w[10], w[2], w[199], pars->GC_11, amp[1017]);
FFV1_0(w[10], w[2], w[200], pars->GC_11, amp[1018]);
FFV1_0(w[10], w[2], w[201], pars->GC_11, amp[1019]);
FFV1_0(w[196], w[120], w[4], pars->GC_11, amp[1020]);
FFV1_0(w[197], w[120], w[4], pars->GC_11, amp[1021]);
FFV1_0(w[198], w[120], w[4], pars->GC_11, amp[1022]);
FFV1_0(w[3], w[120], w[199], pars->GC_11, amp[1023]);
FFV1_0(w[3], w[120], w[200], pars->GC_11, amp[1024]);
FFV1_0(w[3], w[120], w[201], pars->GC_11, amp[1025]);
FFV1_0(w[18], w[202], w[4], pars->GC_11, amp[1026]);
FFV1_0(w[18], w[203], w[4], pars->GC_11, amp[1027]);
FFV1_0(w[18], w[204], w[4], pars->GC_11, amp[1028]);
FFV1_0(w[18], w[2], w[199], pars->GC_11, amp[1029]);
FFV1_0(w[18], w[2], w[200], pars->GC_11, amp[1030]);
FFV1_0(w[18], w[2], w[201], pars->GC_11, amp[1031]);
}
double eeuugggg::matrix_1_epem_uuxgggg()
{
// int i, j;
// Local variables
// const int ngraphs = 1032;
const int ncolor = 24;
- std::complex<double> ztemp;
std::complex<double> jamp[ncolor];
// The color matrix;
//static const double denom[ncolor] = {54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
// 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54};
/*static const double cf[ncolor][ncolor] = {{512, -64, -64, 8, 8, 80, -64, 8,
8, -1, -1, -10, 8, -1, 80, -10, 71, 62, -1, -10, -10, 62, 62, -28}, {-64,
512, 8, 80, -64, 8, 8, -64, -1, -10, 8, -1, -1, -10, -10, 62, 62, -28, 8,
-1, 80, -10, 71, 62}, {-64, 8, 512, -64, 80, 8, 8, -1, 80, -10, 71, 62,
-64, 8, 8, -1, -1, -10, -10, -1, 62, -28, -10, 62}, {8, 80, -64, 512, 8,
-64, -1, -10, -10, 62, 62, -28, 8, -64, -1, -10, 8, -1, -1, 8, 71, 62,
80, -10}, {8, -64, 80, 8, 512, -64, -1, 8, 71, 62, 80, -10, -10, -1, 62,
-28, -10, 62, -64, 8, 8, -1, -1, -10}, {80, 8, 8, -64, -64, 512, -10, -1,
62, -28, -10, 62, -1, 8, 71, 62, 80, -10, 8, -64, -1, -10, 8, -1}, {-64,
8, 8, -1, -1, -10, 512, -64, -64, 8, 8, 80, 80, -10, 8, -1, 62, 71, -10,
62, -1, -10, -28, 62}, {8, -64, -1, -10, 8, -1, -64, 512, 8, 80, -64, 8,
-10, 62, -1, -10, -28, 62, 80, -10, 8, -1, 62, 71}, {8, -1, 80, -10, 71,
62, -64, 8, 512, -64, 80, 8, 8, -1, -64, 8, -10, -1, 62, -28, -10, -1,
62, -10}, {-1, -10, -10, 62, 62, -28, 8, 80, -64, 512, 8, -64, -1, -10,
8, -64, -1, 8, 71, 62, -1, 8, -10, 80}, {-1, 8, 71, 62, 80, -10, 8, -64,
80, 8, 512, -64, 62, -28, -10, -1, 62, -10, 8, -1, -64, 8, -10, -1},
{-10, -1, 62, -28, -10, 62, 80, 8, 8, -64, -64, 512, 71, 62, -1, 8, -10,
80, -1, -10, 8, -64, -1, 8}, {8, -1, -64, 8, -10, -1, 80, -10, 8, -1, 62,
71, 512, -64, -64, 8, 8, 80, 62, -10, -28, 62, -1, -10}, {-1, -10, 8,
-64, -1, 8, -10, 62, -1, -10, -28, 62, -64, 512, 8, 80, -64, 8, -10, 80,
62, 71, 8, -1}, {80, -10, 8, -1, 62, 71, 8, -1, -64, 8, -10, -1, -64, 8,
512, -64, 80, 8, -28, 62, 62, -10, -10, -1}, {-10, 62, -1, -10, -28, 62,
-1, -10, 8, -64, -1, 8, 8, 80, -64, 512, 8, -64, 62, 71, -10, 80, -1, 8},
{71, 62, -1, 8, -10, 80, 62, -28, -10, -1, 62, -10, 8, -64, 80, 8, 512,
-64, -1, 8, -10, -1, -64, 8}, {62, -28, -10, -1, 62, -10, 71, 62, -1, 8,
-10, 80, 80, 8, 8, -64, -64, 512, -10, -1, -1, 8, 8, -64}, {-1, 8, -10,
-1, -64, 8, -10, 80, 62, 71, 8, -1, 62, -10, -28, 62, -1, -10, 512, -64,
-64, 8, 8, 80}, {-10, -1, -1, 8, 8, -64, 62, -10, -28, 62, -1, -10, -10,
80, 62, 71, 8, -1, -64, 512, 8, 80, -64, 8}, {-10, 80, 62, 71, 8, -1, -1,
8, -10, -1, -64, 8, -28, 62, 62, -10, -10, -1, -64, 8, 512, -64, 80, 8},
{62, -10, -28, 62, -1, -10, -10, -1, -1, 8, 8, -64, 62, 71, -10, 80, -1,
8, 8, 80, -64, 512, 8, -64}, {62, 71, -10, 80, -1, 8, -28, 62, 62, -10,
-10, -1, -1, 8, -10, -1, -64, 8, 8, -64, 80, 8, 512, -64}, {-28, 62, 62,
-10, -10, -1, 62, 71, -10, 80, -1, 8, -10, -1, -1, 8, 8, -64, 80, 8, 8,
-64, -64, 512}};
*/
// Calculate color flows
jamp[0] = +amp[1] + amp[7] + amp[45] + amp[46] + amp[48] + amp[51] + amp[52]
+ amp[54] - std::complex<double> (0, 1) * amp[56] - std::complex<double>
(0, 1) * amp[57] - std::complex<double> (0, 1) * amp[58] -
std::complex<double> (0, 1) * amp[59] - amp[61] - std::complex<double>
(0, 1) * amp[62] - amp[64] - amp[67] - std::complex<double> (0, 1) *
amp[68] - amp[70] - std::complex<double> (0, 1) * amp[84] - amp[85] -
std::complex<double> (0, 1) * amp[86] - amp[88] - std::complex<double>
(0, 1) * amp[89] - std::complex<double> (0, 1) * amp[90] - amp[91] -
std::complex<double> (0, 1) * amp[92] - amp[94] - std::complex<double>
(0, 1) * amp[95] + amp[98] - amp[96] + amp[101] - amp[99] + amp[104] -
amp[102] + amp[107] - amp[105] + amp[616] + amp[622] -
std::complex<double> (0, 1) * amp[625] - amp[626] - std::complex<double>
(0, 1) * amp[627] - amp[628] - std::complex<double> (0, 1) * amp[629] -
std::complex<double> (0, 1) * amp[631] - amp[632] - std::complex<double>
(0, 1) * amp[633] - amp[634] - std::complex<double> (0, 1) * amp[635] -
std::complex<double> (0, 1) * amp[649] - amp[650] - amp[652] -
std::complex<double> (0, 1) * amp[655] - amp[656] - amp[658] + amp[662] -
amp[660] + amp[665] - amp[663] + amp[668] - amp[666] + amp[671] -
amp[669] + std::complex<double> (0, 1) * amp[674] - std::complex<double>
(0, 1) * amp[680] + std::complex<double> (0, 1) * amp[678] -
std::complex<double> (0, 1) * amp[682] + std::complex<double> (0, 1) *
amp[683] - amp[684] - std::complex<double> (0, 1) * amp[689] +
std::complex<double> (0, 1) * amp[687] + std::complex<double> (0, 1) *
amp[692] - std::complex<double> (0, 1) * amp[698] + std::complex<double>
(0, 1) * amp[696] - std::complex<double> (0, 1) * amp[700] +
std::complex<double> (0, 1) * amp[701] - amp[702] - std::complex<double>
(0, 1) * amp[707] + std::complex<double> (0, 1) * amp[705] - amp[709] +
std::complex<double> (0, 1) * amp[710] - amp[711] + std::complex<double>
(0, 1) * amp[713] - amp[714] - amp[717] + std::complex<double> (0, 1) *
amp[718] - amp[719] + std::complex<double> (0, 1) * amp[721] - amp[722] +
std::complex<double> (0, 1) * amp[830] + std::complex<double> (0, 1) *
amp[832] - amp[833] - std::complex<double> (0, 1) * amp[836] +
std::complex<double> (0, 1) * amp[834] + std::complex<double> (0, 1) *
amp[839] - amp[840] + std::complex<double> (0, 1) * amp[841] -
std::complex<double> (0, 1) * amp[845] + std::complex<double> (0, 1) *
amp[843] + std::complex<double> (0, 1) * amp[848] + std::complex<double>
(0, 1) * amp[850] - amp[851] - std::complex<double> (0, 1) * amp[854] +
std::complex<double> (0, 1) * amp[852] + std::complex<double> (0, 1) *
amp[857] - amp[858] + std::complex<double> (0, 1) * amp[859] -
std::complex<double> (0, 1) * amp[863] + std::complex<double> (0, 1) *
amp[861] - std::complex<double> (0, 1) * amp[900] + std::complex<double>
(0, 1) * amp[904] - amp[905] - std::complex<double> (0, 1) * amp[908] +
std::complex<double> (0, 1) * amp[906] + std::complex<double> (0, 1) *
amp[913] - std::complex<double> (0, 1) * amp[917] + std::complex<double>
(0, 1) * amp[915] - std::complex<double> (0, 1) * amp[918] +
std::complex<double> (0, 1) * amp[922] - amp[923] - std::complex<double>
(0, 1) * amp[926] + std::complex<double> (0, 1) * amp[924] +
std::complex<double> (0, 1) * amp[931] - std::complex<double> (0, 1) *
amp[935] + std::complex<double> (0, 1) * amp[933] - std::complex<double>
(0, 1) * amp[941] + std::complex<double> (0, 1) * amp[939] + amp[944] -
amp[942] - std::complex<double> (0, 1) * amp[947] + std::complex<double>
(0, 1) * amp[945] - std::complex<double> (0, 1) * amp[953] +
std::complex<double> (0, 1) * amp[951] + amp[956] - amp[954] -
std::complex<double> (0, 1) * amp[959] + std::complex<double> (0, 1) *
amp[957] + amp[1010] - amp[1008] - std::complex<double> (0, 1) *
amp[1013] + std::complex<double> (0, 1) * amp[1011] -
std::complex<double> (0, 1) * amp[1019] + std::complex<double> (0, 1) *
amp[1017] + amp[1022] - amp[1020] - std::complex<double> (0, 1) *
amp[1025] + std::complex<double> (0, 1) * amp[1023] -
std::complex<double> (0, 1) * amp[1031] + std::complex<double> (0, 1) *
amp[1029];
jamp[1] = +amp[0] + amp[6] + amp[29] + amp[30] + amp[32] + amp[35] + amp[36]
+ amp[38] - std::complex<double> (0, 1) * amp[40] - std::complex<double>
(0, 1) * amp[41] - std::complex<double> (0, 1) * amp[42] -
std::complex<double> (0, 1) * amp[43] - amp[73] - std::complex<double>
(0, 1) * amp[74] - amp[76] - amp[79] - std::complex<double> (0, 1) *
amp[80] - amp[82] + std::complex<double> (0, 1) * amp[84] + amp[85] +
std::complex<double> (0, 1) * amp[86] + amp[88] + std::complex<double>
(0, 1) * amp[89] + std::complex<double> (0, 1) * amp[90] + amp[91] +
std::complex<double> (0, 1) * amp[92] + amp[94] + std::complex<double>
(0, 1) * amp[95] + amp[96] + amp[97] + amp[99] + amp[100] + amp[102] +
amp[103] + amp[105] + amp[106] + amp[556] + amp[562] -
std::complex<double> (0, 1) * amp[565] - amp[566] - std::complex<double>
(0, 1) * amp[567] - amp[568] - std::complex<double> (0, 1) * amp[569] -
std::complex<double> (0, 1) * amp[571] - amp[572] - std::complex<double>
(0, 1) * amp[573] - amp[574] - std::complex<double> (0, 1) * amp[575] -
std::complex<double> (0, 1) * amp[589] - amp[590] - amp[592] -
std::complex<double> (0, 1) * amp[595] - amp[596] - amp[598] + amp[602] -
amp[600] + amp[605] - amp[603] + amp[608] - amp[606] + amp[611] -
amp[609] + std::complex<double> (0, 1) * amp[676] - std::complex<double>
(0, 1) * amp[678] - std::complex<double> (0, 1) * amp[679] -
std::complex<double> (0, 1) * amp[681] + std::complex<double> (0, 1) *
amp[685] - amp[686] - std::complex<double> (0, 1) * amp[687] -
std::complex<double> (0, 1) * amp[688] + std::complex<double> (0, 1) *
amp[694] - std::complex<double> (0, 1) * amp[696] - std::complex<double>
(0, 1) * amp[697] - std::complex<double> (0, 1) * amp[699] +
std::complex<double> (0, 1) * amp[703] - amp[704] - std::complex<double>
(0, 1) * amp[705] - std::complex<double> (0, 1) * amp[706] + amp[709] -
std::complex<double> (0, 1) * amp[710] + amp[711] - std::complex<double>
(0, 1) * amp[713] + amp[714] + amp[717] - std::complex<double> (0, 1) *
amp[718] + amp[719] - std::complex<double> (0, 1) * amp[721] + amp[722] +
std::complex<double> (0, 1) * amp[866] + std::complex<double> (0, 1) *
amp[868] - amp[869] - std::complex<double> (0, 1) * amp[872] +
std::complex<double> (0, 1) * amp[870] + std::complex<double> (0, 1) *
amp[875] - amp[876] + std::complex<double> (0, 1) * amp[877] -
std::complex<double> (0, 1) * amp[881] + std::complex<double> (0, 1) *
amp[879] + std::complex<double> (0, 1) * amp[884] + std::complex<double>
(0, 1) * amp[886] - amp[887] - std::complex<double> (0, 1) * amp[890] +
std::complex<double> (0, 1) * amp[888] + std::complex<double> (0, 1) *
amp[893] - amp[894] + std::complex<double> (0, 1) * amp[895] -
std::complex<double> (0, 1) * amp[899] + std::complex<double> (0, 1) *
amp[897] + std::complex<double> (0, 1) * amp[900] - std::complex<double>
(0, 1) * amp[904] + amp[905] + std::complex<double> (0, 1) * amp[908] -
std::complex<double> (0, 1) * amp[906] - std::complex<double> (0, 1) *
amp[913] + std::complex<double> (0, 1) * amp[917] - std::complex<double>
(0, 1) * amp[915] + std::complex<double> (0, 1) * amp[918] -
std::complex<double> (0, 1) * amp[922] + amp[923] + std::complex<double>
(0, 1) * amp[926] - std::complex<double> (0, 1) * amp[924] -
std::complex<double> (0, 1) * amp[931] + std::complex<double> (0, 1) *
amp[935] - std::complex<double> (0, 1) * amp[933] - std::complex<double>
(0, 1) * amp[965] + std::complex<double> (0, 1) * amp[963] + amp[968] -
amp[966] - std::complex<double> (0, 1) * amp[971] + std::complex<double>
(0, 1) * amp[969] - std::complex<double> (0, 1) * amp[977] +
std::complex<double> (0, 1) * amp[975] + amp[980] - amp[978] -
std::complex<double> (0, 1) * amp[983] + std::complex<double> (0, 1) *
amp[981] + amp[1008] + amp[1009] - std::complex<double> (0, 1) *
amp[1011] - std::complex<double> (0, 1) * amp[1012] -
std::complex<double> (0, 1) * amp[1017] - std::complex<double> (0, 1) *
amp[1018] + amp[1020] + amp[1021] - std::complex<double> (0, 1) *
amp[1023] - std::complex<double> (0, 1) * amp[1024] -
std::complex<double> (0, 1) * amp[1029] - std::complex<double> (0, 1) *
amp[1030];
jamp[2] = +amp[3] + amp[9] + amp[44] + amp[47] + amp[49] + amp[50] + amp[53]
+ amp[55] + std::complex<double> (0, 1) * amp[56] + std::complex<double>
(0, 1) * amp[57] + std::complex<double> (0, 1) * amp[58] +
std::complex<double> (0, 1) * amp[59] + amp[61] + std::complex<double>
(0, 1) * amp[62] + amp[64] + amp[67] + std::complex<double> (0, 1) *
amp[68] + amp[70] - std::complex<double> (0, 1) * amp[72] + amp[73] -
std::complex<double> (0, 1) * amp[75] + amp[76] - std::complex<double>
(0, 1) * amp[77] - std::complex<double> (0, 1) * amp[78] + amp[79] -
std::complex<double> (0, 1) * amp[81] + amp[82] - std::complex<double>
(0, 1) * amp[83] - amp[98] - amp[97] - amp[101] - amp[100] - amp[104] -
amp[103] - amp[107] - amp[106] + amp[614] + amp[620] -
std::complex<double> (0, 1) * amp[637] - amp[638] - std::complex<double>
(0, 1) * amp[639] - amp[640] - std::complex<double> (0, 1) * amp[641] -
std::complex<double> (0, 1) * amp[643] - amp[644] - std::complex<double>
(0, 1) * amp[645] - amp[646] - std::complex<double> (0, 1) * amp[647] +
std::complex<double> (0, 1) * amp[649] + amp[650] + amp[652] +
std::complex<double> (0, 1) * amp[655] + amp[656] + amp[658] + amp[660] +
amp[661] + amp[663] + amp[664] + amp[666] + amp[667] + amp[669] +
amp[670] + std::complex<double> (0, 1) * amp[726] - std::complex<double>
(0, 1) * amp[732] + std::complex<double> (0, 1) * amp[730] -
std::complex<double> (0, 1) * amp[734] + std::complex<double> (0, 1) *
amp[735] - amp[736] - std::complex<double> (0, 1) * amp[741] +
std::complex<double> (0, 1) * amp[739] + std::complex<double> (0, 1) *
amp[744] - std::complex<double> (0, 1) * amp[750] + std::complex<double>
(0, 1) * amp[748] - std::complex<double> (0, 1) * amp[752] +
std::complex<double> (0, 1) * amp[753] - amp[754] - std::complex<double>
(0, 1) * amp[759] + std::complex<double> (0, 1) * amp[757] - amp[761] +
std::complex<double> (0, 1) * amp[762] - amp[763] + std::complex<double>
(0, 1) * amp[765] - amp[766] - amp[769] + std::complex<double> (0, 1) *
amp[770] - amp[771] + std::complex<double> (0, 1) * amp[773] - amp[774] -
std::complex<double> (0, 1) * amp[830] - std::complex<double> (0, 1) *
amp[832] + amp[833] + std::complex<double> (0, 1) * amp[836] -
std::complex<double> (0, 1) * amp[834] - std::complex<double> (0, 1) *
amp[839] + amp[840] - std::complex<double> (0, 1) * amp[841] +
std::complex<double> (0, 1) * amp[845] - std::complex<double> (0, 1) *
amp[843] - std::complex<double> (0, 1) * amp[848] - std::complex<double>
(0, 1) * amp[850] + amp[851] + std::complex<double> (0, 1) * amp[854] -
std::complex<double> (0, 1) * amp[852] - std::complex<double> (0, 1) *
amp[857] + amp[858] - std::complex<double> (0, 1) * amp[859] +
std::complex<double> (0, 1) * amp[863] - std::complex<double> (0, 1) *
amp[861] - std::complex<double> (0, 1) * amp[864] - std::complex<double>
(0, 1) * amp[868] + amp[869] - std::complex<double> (0, 1) * amp[870] -
std::complex<double> (0, 1) * amp[871] - std::complex<double> (0, 1) *
amp[877] - std::complex<double> (0, 1) * amp[879] - std::complex<double>
(0, 1) * amp[880] - std::complex<double> (0, 1) * amp[882] -
std::complex<double> (0, 1) * amp[886] + amp[887] - std::complex<double>
(0, 1) * amp[888] - std::complex<double> (0, 1) * amp[889] -
std::complex<double> (0, 1) * amp[895] - std::complex<double> (0, 1) *
amp[897] - std::complex<double> (0, 1) * amp[898] - std::complex<double>
(0, 1) * amp[939] - std::complex<double> (0, 1) * amp[940] + amp[942] +
amp[943] - std::complex<double> (0, 1) * amp[945] - std::complex<double>
(0, 1) * amp[946] - std::complex<double> (0, 1) * amp[951] -
std::complex<double> (0, 1) * amp[952] + amp[954] + amp[955] -
std::complex<double> (0, 1) * amp[957] - std::complex<double> (0, 1) *
amp[958] - amp[1010] - amp[1009] + std::complex<double> (0, 1) *
amp[1013] + std::complex<double> (0, 1) * amp[1012] +
std::complex<double> (0, 1) * amp[1019] + std::complex<double> (0, 1) *
amp[1018] - amp[1022] - amp[1021] + std::complex<double> (0, 1) *
amp[1025] + std::complex<double> (0, 1) * amp[1024] +
std::complex<double> (0, 1) * amp[1031] + std::complex<double> (0, 1) *
amp[1030];
jamp[3] = +amp[2] + amp[8] + amp[13] + amp[14] + amp[16] + amp[19] + amp[20]
+ amp[22] - std::complex<double> (0, 1) * amp[24] - std::complex<double>
(0, 1) * amp[25] - std::complex<double> (0, 1) * amp[26] -
std::complex<double> (0, 1) * amp[27] + std::complex<double> (0, 1) *
amp[72] - amp[73] + std::complex<double> (0, 1) * amp[75] - amp[76] +
std::complex<double> (0, 1) * amp[77] + std::complex<double> (0, 1) *
amp[78] - amp[79] + std::complex<double> (0, 1) * amp[81] - amp[82] +
std::complex<double> (0, 1) * amp[83] + amp[85] - std::complex<double>
(0, 1) * amp[87] + amp[88] + amp[91] - std::complex<double> (0, 1) *
amp[93] + amp[94] + amp[96] + amp[97] + amp[99] + amp[100] + amp[102] +
amp[103] + amp[105] + amp[106] + amp[496] + amp[502] -
std::complex<double> (0, 1) * amp[505] - amp[506] - std::complex<double>
(0, 1) * amp[507] - amp[508] - std::complex<double> (0, 1) * amp[509] -
std::complex<double> (0, 1) * amp[511] - amp[512] - std::complex<double>
(0, 1) * amp[513] - amp[514] - std::complex<double> (0, 1) * amp[515] -
std::complex<double> (0, 1) * amp[529] - amp[530] - amp[532] -
std::complex<double> (0, 1) * amp[535] - amp[536] - amp[538] + amp[542] -
amp[540] + amp[545] - amp[543] + amp[548] - amp[546] + amp[551] -
amp[549] + std::complex<double> (0, 1) * amp[728] - std::complex<double>
(0, 1) * amp[730] - std::complex<double> (0, 1) * amp[731] -
std::complex<double> (0, 1) * amp[733] + std::complex<double> (0, 1) *
amp[737] - amp[738] - std::complex<double> (0, 1) * amp[739] -
std::complex<double> (0, 1) * amp[740] + std::complex<double> (0, 1) *
amp[746] - std::complex<double> (0, 1) * amp[748] - std::complex<double>
(0, 1) * amp[749] - std::complex<double> (0, 1) * amp[751] +
std::complex<double> (0, 1) * amp[755] - amp[756] - std::complex<double>
(0, 1) * amp[757] - std::complex<double> (0, 1) * amp[758] + amp[761] -
std::complex<double> (0, 1) * amp[762] + amp[763] - std::complex<double>
(0, 1) * amp[765] + amp[766] + amp[769] - std::complex<double> (0, 1) *
amp[770] + amp[771] - std::complex<double> (0, 1) * amp[773] + amp[774] +
std::complex<double> (0, 1) * amp[864] + std::complex<double> (0, 1) *
amp[868] - amp[869] + std::complex<double> (0, 1) * amp[870] +
std::complex<double> (0, 1) * amp[871] + std::complex<double> (0, 1) *
amp[877] + std::complex<double> (0, 1) * amp[879] + std::complex<double>
(0, 1) * amp[880] + std::complex<double> (0, 1) * amp[882] +
std::complex<double> (0, 1) * amp[886] - amp[887] + std::complex<double>
(0, 1) * amp[888] + std::complex<double> (0, 1) * amp[889] +
std::complex<double> (0, 1) * amp[895] + std::complex<double> (0, 1) *
amp[897] + std::complex<double> (0, 1) * amp[898] + std::complex<double>
(0, 1) * amp[902] - std::complex<double> (0, 1) * amp[904] + amp[905] -
std::complex<double> (0, 1) * amp[906] - std::complex<double> (0, 1) *
amp[907] + std::complex<double> (0, 1) * amp[911] - amp[912] -
std::complex<double> (0, 1) * amp[913] - std::complex<double> (0, 1) *
amp[915] - std::complex<double> (0, 1) * amp[916] + std::complex<double>
(0, 1) * amp[920] - std::complex<double> (0, 1) * amp[922] + amp[923] -
std::complex<double> (0, 1) * amp[924] - std::complex<double> (0, 1) *
amp[925] + std::complex<double> (0, 1) * amp[929] - amp[930] -
std::complex<double> (0, 1) * amp[931] - std::complex<double> (0, 1) *
amp[933] - std::complex<double> (0, 1) * amp[934] - std::complex<double>
(0, 1) * amp[989] + std::complex<double> (0, 1) * amp[987] + amp[992] -
amp[990] - std::complex<double> (0, 1) * amp[995] + std::complex<double>
(0, 1) * amp[993] - std::complex<double> (0, 1) * amp[1001] +
std::complex<double> (0, 1) * amp[999] + amp[1004] - amp[1002] -
std::complex<double> (0, 1) * amp[1007] + std::complex<double> (0, 1) *
amp[1005] + amp[1008] + amp[1009] - std::complex<double> (0, 1) *
amp[1011] - std::complex<double> (0, 1) * amp[1012] -
std::complex<double> (0, 1) * amp[1017] - std::complex<double> (0, 1) *
amp[1018] + amp[1020] + amp[1021] - std::complex<double> (0, 1) *
amp[1023] - std::complex<double> (0, 1) * amp[1024] -
std::complex<double> (0, 1) * amp[1029] - std::complex<double> (0, 1) *
amp[1030];
jamp[4] = +amp[5] + amp[11] + amp[28] + amp[31] + amp[33] + amp[34] + amp[37]
+ amp[39] + std::complex<double> (0, 1) * amp[40] + std::complex<double>
(0, 1) * amp[41] + std::complex<double> (0, 1) * amp[42] +
std::complex<double> (0, 1) * amp[43] - std::complex<double> (0, 1) *
amp[60] + amp[61] - std::complex<double> (0, 1) * amp[63] + amp[64] -
std::complex<double> (0, 1) * amp[65] - std::complex<double> (0, 1) *
amp[66] + amp[67] - std::complex<double> (0, 1) * amp[69] + amp[70] -
std::complex<double> (0, 1) * amp[71] + amp[73] + std::complex<double>
(0, 1) * amp[74] + amp[76] + amp[79] + std::complex<double> (0, 1) *
amp[80] + amp[82] - amp[98] - amp[97] - amp[101] - amp[100] - amp[104] -
amp[103] - amp[107] - amp[106] + amp[554] + amp[560] -
std::complex<double> (0, 1) * amp[577] - amp[578] - std::complex<double>
(0, 1) * amp[579] - amp[580] - std::complex<double> (0, 1) * amp[581] -
std::complex<double> (0, 1) * amp[583] - amp[584] - std::complex<double>
(0, 1) * amp[585] - amp[586] - std::complex<double> (0, 1) * amp[587] +
std::complex<double> (0, 1) * amp[589] + amp[590] + amp[592] +
std::complex<double> (0, 1) * amp[595] + amp[596] + amp[598] + amp[600] +
amp[601] + amp[603] + amp[604] + amp[606] + amp[607] + amp[609] +
amp[610] + std::complex<double> (0, 1) * amp[778] - std::complex<double>
(0, 1) * amp[784] + std::complex<double> (0, 1) * amp[782] -
std::complex<double> (0, 1) * amp[786] + std::complex<double> (0, 1) *
amp[787] - amp[788] - std::complex<double> (0, 1) * amp[793] +
std::complex<double> (0, 1) * amp[791] + std::complex<double> (0, 1) *
amp[796] - std::complex<double> (0, 1) * amp[802] + std::complex<double>
(0, 1) * amp[800] - std::complex<double> (0, 1) * amp[804] +
std::complex<double> (0, 1) * amp[805] - amp[806] - std::complex<double>
(0, 1) * amp[811] + std::complex<double> (0, 1) * amp[809] - amp[813] +
std::complex<double> (0, 1) * amp[814] - amp[815] + std::complex<double>
(0, 1) * amp[817] - amp[818] - amp[821] + std::complex<double> (0, 1) *
amp[822] - amp[823] + std::complex<double> (0, 1) * amp[825] - amp[826] -
std::complex<double> (0, 1) * amp[828] - std::complex<double> (0, 1) *
amp[832] + amp[833] - std::complex<double> (0, 1) * amp[834] -
std::complex<double> (0, 1) * amp[835] - std::complex<double> (0, 1) *
amp[841] - std::complex<double> (0, 1) * amp[843] - std::complex<double>
(0, 1) * amp[844] - std::complex<double> (0, 1) * amp[846] -
std::complex<double> (0, 1) * amp[850] + amp[851] - std::complex<double>
(0, 1) * amp[852] - std::complex<double> (0, 1) * amp[853] -
std::complex<double> (0, 1) * amp[859] - std::complex<double> (0, 1) *
amp[861] - std::complex<double> (0, 1) * amp[862] - std::complex<double>
(0, 1) * amp[866] - std::complex<double> (0, 1) * amp[868] + amp[869] +
std::complex<double> (0, 1) * amp[872] - std::complex<double> (0, 1) *
amp[870] - std::complex<double> (0, 1) * amp[875] + amp[876] -
std::complex<double> (0, 1) * amp[877] + std::complex<double> (0, 1) *
amp[881] - std::complex<double> (0, 1) * amp[879] - std::complex<double>
(0, 1) * amp[884] - std::complex<double> (0, 1) * amp[886] + amp[887] +
std::complex<double> (0, 1) * amp[890] - std::complex<double> (0, 1) *
amp[888] - std::complex<double> (0, 1) * amp[893] + amp[894] -
std::complex<double> (0, 1) * amp[895] + std::complex<double> (0, 1) *
amp[899] - std::complex<double> (0, 1) * amp[897] - std::complex<double>
(0, 1) * amp[963] - std::complex<double> (0, 1) * amp[964] + amp[966] +
amp[967] - std::complex<double> (0, 1) * amp[969] - std::complex<double>
(0, 1) * amp[970] - std::complex<double> (0, 1) * amp[975] -
std::complex<double> (0, 1) * amp[976] + amp[978] + amp[979] -
std::complex<double> (0, 1) * amp[981] - std::complex<double> (0, 1) *
amp[982] - amp[1010] - amp[1009] + std::complex<double> (0, 1) *
amp[1013] + std::complex<double> (0, 1) * amp[1012] +
std::complex<double> (0, 1) * amp[1019] + std::complex<double> (0, 1) *
amp[1018] - amp[1022] - amp[1021] + std::complex<double> (0, 1) *
amp[1025] + std::complex<double> (0, 1) * amp[1024] +
std::complex<double> (0, 1) * amp[1031] + std::complex<double> (0, 1) *
amp[1030];
jamp[5] = +amp[4] + amp[10] + amp[12] + amp[15] + amp[17] + amp[18] + amp[21]
+ amp[23] + std::complex<double> (0, 1) * amp[24] + std::complex<double>
(0, 1) * amp[25] + std::complex<double> (0, 1) * amp[26] +
std::complex<double> (0, 1) * amp[27] + std::complex<double> (0, 1) *
amp[60] - amp[61] + std::complex<double> (0, 1) * amp[63] - amp[64] +
std::complex<double> (0, 1) * amp[65] + std::complex<double> (0, 1) *
amp[66] - amp[67] + std::complex<double> (0, 1) * amp[69] - amp[70] +
std::complex<double> (0, 1) * amp[71] - amp[85] + std::complex<double>
(0, 1) * amp[87] - amp[88] - amp[91] + std::complex<double> (0, 1) *
amp[93] - amp[94] + amp[98] - amp[96] + amp[101] - amp[99] + amp[104] -
amp[102] + amp[107] - amp[105] + amp[494] + amp[500] -
std::complex<double> (0, 1) * amp[517] - amp[518] - std::complex<double>
(0, 1) * amp[519] - amp[520] - std::complex<double> (0, 1) * amp[521] -
std::complex<double> (0, 1) * amp[523] - amp[524] - std::complex<double>
(0, 1) * amp[525] - amp[526] - std::complex<double> (0, 1) * amp[527] +
std::complex<double> (0, 1) * amp[529] + amp[530] + amp[532] +
std::complex<double> (0, 1) * amp[535] + amp[536] + amp[538] + amp[540] +
amp[541] + amp[543] + amp[544] + amp[546] + amp[547] + amp[549] +
amp[550] + std::complex<double> (0, 1) * amp[780] - std::complex<double>
(0, 1) * amp[782] - std::complex<double> (0, 1) * amp[783] -
std::complex<double> (0, 1) * amp[785] + std::complex<double> (0, 1) *
amp[789] - amp[790] - std::complex<double> (0, 1) * amp[791] -
std::complex<double> (0, 1) * amp[792] + std::complex<double> (0, 1) *
amp[798] - std::complex<double> (0, 1) * amp[800] - std::complex<double>
(0, 1) * amp[801] - std::complex<double> (0, 1) * amp[803] +
std::complex<double> (0, 1) * amp[807] - amp[808] - std::complex<double>
(0, 1) * amp[809] - std::complex<double> (0, 1) * amp[810] + amp[813] -
std::complex<double> (0, 1) * amp[814] + amp[815] - std::complex<double>
(0, 1) * amp[817] + amp[818] + amp[821] - std::complex<double> (0, 1) *
amp[822] + amp[823] - std::complex<double> (0, 1) * amp[825] + amp[826] +
std::complex<double> (0, 1) * amp[828] + std::complex<double> (0, 1) *
amp[832] - amp[833] + std::complex<double> (0, 1) * amp[834] +
std::complex<double> (0, 1) * amp[835] + std::complex<double> (0, 1) *
amp[841] + std::complex<double> (0, 1) * amp[843] + std::complex<double>
(0, 1) * amp[844] + std::complex<double> (0, 1) * amp[846] +
std::complex<double> (0, 1) * amp[850] - amp[851] + std::complex<double>
(0, 1) * amp[852] + std::complex<double> (0, 1) * amp[853] +
std::complex<double> (0, 1) * amp[859] + std::complex<double> (0, 1) *
amp[861] + std::complex<double> (0, 1) * amp[862] - std::complex<double>
(0, 1) * amp[902] + std::complex<double> (0, 1) * amp[904] - amp[905] +
std::complex<double> (0, 1) * amp[906] + std::complex<double> (0, 1) *
amp[907] - std::complex<double> (0, 1) * amp[911] + amp[912] +
std::complex<double> (0, 1) * amp[913] + std::complex<double> (0, 1) *
amp[915] + std::complex<double> (0, 1) * amp[916] - std::complex<double>
(0, 1) * amp[920] + std::complex<double> (0, 1) * amp[922] - amp[923] +
std::complex<double> (0, 1) * amp[924] + std::complex<double> (0, 1) *
amp[925] - std::complex<double> (0, 1) * amp[929] + amp[930] +
std::complex<double> (0, 1) * amp[931] + std::complex<double> (0, 1) *
amp[933] + std::complex<double> (0, 1) * amp[934] - std::complex<double>
(0, 1) * amp[987] - std::complex<double> (0, 1) * amp[988] + amp[990] +
amp[991] - std::complex<double> (0, 1) * amp[993] - std::complex<double>
(0, 1) * amp[994] - std::complex<double> (0, 1) * amp[999] -
std::complex<double> (0, 1) * amp[1000] + amp[1002] + amp[1003] -
std::complex<double> (0, 1) * amp[1005] - std::complex<double> (0, 1) *
amp[1006] + amp[1010] - amp[1008] - std::complex<double> (0, 1) *
amp[1013] + std::complex<double> (0, 1) * amp[1011] -
std::complex<double> (0, 1) * amp[1019] + std::complex<double> (0, 1) *
amp[1017] + amp[1022] - amp[1020] - std::complex<double> (0, 1) *
amp[1025] + std::complex<double> (0, 1) * amp[1023] -
std::complex<double> (0, 1) * amp[1031] + std::complex<double> (0, 1) *
amp[1029];
jamp[6] = +amp[109] + amp[115] + amp[153] + amp[154] + amp[156] + amp[159] +
amp[160] + amp[162] - std::complex<double> (0, 1) * amp[164] -
std::complex<double> (0, 1) * amp[165] - std::complex<double> (0, 1) *
amp[166] - std::complex<double> (0, 1) * amp[167] - amp[169] -
std::complex<double> (0, 1) * amp[170] - amp[172] - amp[175] -
std::complex<double> (0, 1) * amp[176] - amp[178] - std::complex<double>
(0, 1) * amp[192] - amp[193] - std::complex<double> (0, 1) * amp[194] -
amp[196] - std::complex<double> (0, 1) * amp[197] - std::complex<double>
(0, 1) * amp[198] - amp[199] - std::complex<double> (0, 1) * amp[200] -
amp[202] - std::complex<double> (0, 1) * amp[203] + amp[206] - amp[204] +
amp[209] - amp[207] + amp[212] - amp[210] + amp[215] - amp[213] +
amp[617] + amp[623] + std::complex<double> (0, 1) * amp[625] + amp[626] +
std::complex<double> (0, 1) * amp[627] + amp[628] + std::complex<double>
(0, 1) * amp[629] + std::complex<double> (0, 1) * amp[631] + amp[632] +
std::complex<double> (0, 1) * amp[633] + amp[634] + std::complex<double>
(0, 1) * amp[635] - std::complex<double> (0, 1) * amp[636] + amp[638] +
amp[640] - std::complex<double> (0, 1) * amp[642] + amp[644] + amp[646] -
amp[662] - amp[661] - amp[665] - amp[664] - amp[668] - amp[667] -
amp[671] - amp[670] - std::complex<double> (0, 1) * amp[674] +
std::complex<double> (0, 1) * amp[680] - std::complex<double> (0, 1) *
amp[678] + std::complex<double> (0, 1) * amp[682] - std::complex<double>
(0, 1) * amp[683] + amp[684] + std::complex<double> (0, 1) * amp[689] -
std::complex<double> (0, 1) * amp[687] - std::complex<double> (0, 1) *
amp[692] + std::complex<double> (0, 1) * amp[698] - std::complex<double>
(0, 1) * amp[696] + std::complex<double> (0, 1) * amp[700] -
std::complex<double> (0, 1) * amp[701] + amp[702] + std::complex<double>
(0, 1) * amp[707] - std::complex<double> (0, 1) * amp[705] + amp[709] -
std::complex<double> (0, 1) * amp[710] + amp[711] - std::complex<double>
(0, 1) * amp[713] + amp[714] + amp[717] - std::complex<double> (0, 1) *
amp[718] + amp[719] - std::complex<double> (0, 1) * amp[721] + amp[722] -
std::complex<double> (0, 1) * amp[726] - std::complex<double> (0, 1) *
amp[728] - amp[729] + std::complex<double> (0, 1) * amp[732] +
std::complex<double> (0, 1) * amp[731] - std::complex<double> (0, 1) *
amp[735] + amp[736] - std::complex<double> (0, 1) * amp[737] +
std::complex<double> (0, 1) * amp[741] + std::complex<double> (0, 1) *
amp[740] - std::complex<double> (0, 1) * amp[744] - std::complex<double>
(0, 1) * amp[746] - amp[747] + std::complex<double> (0, 1) * amp[750] +
std::complex<double> (0, 1) * amp[749] - std::complex<double> (0, 1) *
amp[753] + amp[754] - std::complex<double> (0, 1) * amp[755] +
std::complex<double> (0, 1) * amp[759] + std::complex<double> (0, 1) *
amp[758] - std::complex<double> (0, 1) * amp[901] - std::complex<double>
(0, 1) * amp[902] - amp[903] + std::complex<double> (0, 1) * amp[908] +
std::complex<double> (0, 1) * amp[907] - std::complex<double> (0, 1) *
amp[911] + std::complex<double> (0, 1) * amp[917] + std::complex<double>
(0, 1) * amp[916] - std::complex<double> (0, 1) * amp[919] -
std::complex<double> (0, 1) * amp[920] - amp[921] + std::complex<double>
(0, 1) * amp[926] + std::complex<double> (0, 1) * amp[925] -
std::complex<double> (0, 1) * amp[929] + std::complex<double> (0, 1) *
amp[935] + std::complex<double> (0, 1) * amp[934] + std::complex<double>
(0, 1) * amp[941] + std::complex<double> (0, 1) * amp[940] - amp[944] -
amp[943] + std::complex<double> (0, 1) * amp[947] + std::complex<double>
(0, 1) * amp[946] + std::complex<double> (0, 1) * amp[953] +
std::complex<double> (0, 1) * amp[952] - amp[956] - amp[955] +
std::complex<double> (0, 1) * amp[959] + std::complex<double> (0, 1) *
amp[958] + amp[986] - amp[984] + std::complex<double> (0, 1) * amp[989] -
std::complex<double> (0, 1) * amp[987] + std::complex<double> (0, 1) *
amp[995] - std::complex<double> (0, 1) * amp[993] + amp[998] - amp[996] +
std::complex<double> (0, 1) * amp[1001] - std::complex<double> (0, 1) *
amp[999] + std::complex<double> (0, 1) * amp[1007] - std::complex<double>
(0, 1) * amp[1005];
jamp[7] = +amp[108] + amp[114] + amp[137] + amp[138] + amp[140] + amp[143] +
amp[144] + amp[146] - std::complex<double> (0, 1) * amp[148] -
std::complex<double> (0, 1) * amp[149] - std::complex<double> (0, 1) *
amp[150] - std::complex<double> (0, 1) * amp[151] - amp[181] -
std::complex<double> (0, 1) * amp[182] - amp[184] - amp[187] -
std::complex<double> (0, 1) * amp[188] - amp[190] + std::complex<double>
(0, 1) * amp[192] + amp[193] + std::complex<double> (0, 1) * amp[194] +
amp[196] + std::complex<double> (0, 1) * amp[197] + std::complex<double>
(0, 1) * amp[198] + amp[199] + std::complex<double> (0, 1) * amp[200] +
amp[202] + std::complex<double> (0, 1) * amp[203] + amp[204] + amp[205] +
amp[207] + amp[208] + amp[210] + amp[211] + amp[213] + amp[214] +
amp[557] + amp[563] + std::complex<double> (0, 1) * amp[565] + amp[566] +
std::complex<double> (0, 1) * amp[567] + amp[568] + std::complex<double>
(0, 1) * amp[569] + std::complex<double> (0, 1) * amp[571] + amp[572] +
std::complex<double> (0, 1) * amp[573] + amp[574] + std::complex<double>
(0, 1) * amp[575] - std::complex<double> (0, 1) * amp[576] + amp[578] +
amp[580] - std::complex<double> (0, 1) * amp[582] + amp[584] + amp[586] -
amp[602] - amp[601] - amp[605] - amp[604] - amp[608] - amp[607] -
amp[611] - amp[610] - std::complex<double> (0, 1) * amp[676] +
std::complex<double> (0, 1) * amp[678] + std::complex<double> (0, 1) *
amp[679] + std::complex<double> (0, 1) * amp[681] - std::complex<double>
(0, 1) * amp[685] + amp[686] + std::complex<double> (0, 1) * amp[687] +
std::complex<double> (0, 1) * amp[688] - std::complex<double> (0, 1) *
amp[694] + std::complex<double> (0, 1) * amp[696] + std::complex<double>
(0, 1) * amp[697] + std::complex<double> (0, 1) * amp[699] -
std::complex<double> (0, 1) * amp[703] + amp[704] + std::complex<double>
(0, 1) * amp[705] + std::complex<double> (0, 1) * amp[706] - amp[709] +
std::complex<double> (0, 1) * amp[710] - amp[711] + std::complex<double>
(0, 1) * amp[713] - amp[714] - amp[717] + std::complex<double> (0, 1) *
amp[718] - amp[719] + std::complex<double> (0, 1) * amp[721] - amp[722] -
std::complex<double> (0, 1) * amp[778] - std::complex<double> (0, 1) *
amp[780] - amp[781] + std::complex<double> (0, 1) * amp[784] +
std::complex<double> (0, 1) * amp[783] - std::complex<double> (0, 1) *
amp[787] + amp[788] - std::complex<double> (0, 1) * amp[789] +
std::complex<double> (0, 1) * amp[793] + std::complex<double> (0, 1) *
amp[792] - std::complex<double> (0, 1) * amp[796] - std::complex<double>
(0, 1) * amp[798] - amp[799] + std::complex<double> (0, 1) * amp[802] +
std::complex<double> (0, 1) * amp[801] - std::complex<double> (0, 1) *
amp[805] + amp[806] - std::complex<double> (0, 1) * amp[807] +
std::complex<double> (0, 1) * amp[811] + std::complex<double> (0, 1) *
amp[810] + std::complex<double> (0, 1) * amp[901] + std::complex<double>
(0, 1) * amp[902] + amp[903] - std::complex<double> (0, 1) * amp[908] -
std::complex<double> (0, 1) * amp[907] + std::complex<double> (0, 1) *
amp[911] - std::complex<double> (0, 1) * amp[917] - std::complex<double>
(0, 1) * amp[916] + std::complex<double> (0, 1) * amp[919] +
std::complex<double> (0, 1) * amp[920] + amp[921] - std::complex<double>
(0, 1) * amp[926] - std::complex<double> (0, 1) * amp[925] +
std::complex<double> (0, 1) * amp[929] - std::complex<double> (0, 1) *
amp[935] - std::complex<double> (0, 1) * amp[934] + std::complex<double>
(0, 1) * amp[965] + std::complex<double> (0, 1) * amp[964] - amp[968] -
amp[967] + std::complex<double> (0, 1) * amp[971] + std::complex<double>
(0, 1) * amp[970] + std::complex<double> (0, 1) * amp[977] +
std::complex<double> (0, 1) * amp[976] - amp[980] - amp[979] +
std::complex<double> (0, 1) * amp[983] + std::complex<double> (0, 1) *
amp[982] + amp[984] + amp[985] + std::complex<double> (0, 1) * amp[987] +
std::complex<double> (0, 1) * amp[988] + std::complex<double> (0, 1) *
amp[993] + std::complex<double> (0, 1) * amp[994] + amp[996] + amp[997] +
std::complex<double> (0, 1) * amp[999] + std::complex<double> (0, 1) *
amp[1000] + std::complex<double> (0, 1) * amp[1005] +
std::complex<double> (0, 1) * amp[1006];
jamp[8] = +amp[111] + amp[117] + amp[152] + amp[155] + amp[157] + amp[158] +
amp[161] + amp[163] + std::complex<double> (0, 1) * amp[164] +
std::complex<double> (0, 1) * amp[165] + std::complex<double> (0, 1) *
amp[166] + std::complex<double> (0, 1) * amp[167] + amp[169] +
std::complex<double> (0, 1) * amp[170] + amp[172] + amp[175] +
std::complex<double> (0, 1) * amp[176] + amp[178] - std::complex<double>
(0, 1) * amp[180] + amp[181] - std::complex<double> (0, 1) * amp[183] +
amp[184] - std::complex<double> (0, 1) * amp[185] - std::complex<double>
(0, 1) * amp[186] + amp[187] - std::complex<double> (0, 1) * amp[189] +
amp[190] - std::complex<double> (0, 1) * amp[191] - amp[206] - amp[205] -
amp[209] - amp[208] - amp[212] - amp[211] - amp[215] - amp[214] +
amp[612] + amp[618] + std::complex<double> (0, 1) * amp[636] - amp[638] -
amp[640] + std::complex<double> (0, 1) * amp[642] - amp[644] - amp[646] -
std::complex<double> (0, 1) * amp[648] + amp[650] - std::complex<double>
(0, 1) * amp[651] + amp[652] - std::complex<double> (0, 1) * amp[653] -
std::complex<double> (0, 1) * amp[654] + amp[656] - std::complex<double>
(0, 1) * amp[657] + amp[658] - std::complex<double> (0, 1) * amp[659] +
amp[660] + amp[661] + amp[663] + amp[664] + amp[666] + amp[667] +
amp[669] + amp[670] + std::complex<double> (0, 1) * amp[726] +
std::complex<double> (0, 1) * amp[728] + amp[729] - std::complex<double>
(0, 1) * amp[732] - std::complex<double> (0, 1) * amp[731] +
std::complex<double> (0, 1) * amp[735] - amp[736] + std::complex<double>
(0, 1) * amp[737] - std::complex<double> (0, 1) * amp[741] -
std::complex<double> (0, 1) * amp[740] + std::complex<double> (0, 1) *
amp[744] + std::complex<double> (0, 1) * amp[746] + amp[747] -
std::complex<double> (0, 1) * amp[750] - std::complex<double> (0, 1) *
amp[749] + std::complex<double> (0, 1) * amp[753] - amp[754] +
std::complex<double> (0, 1) * amp[755] - std::complex<double> (0, 1) *
amp[759] - std::complex<double> (0, 1) * amp[758] - std::complex<double>
(0, 1) * amp[776] + std::complex<double> (0, 1) * amp[780] + amp[781] -
std::complex<double> (0, 1) * amp[782] - std::complex<double> (0, 1) *
amp[783] + std::complex<double> (0, 1) * amp[789] - std::complex<double>
(0, 1) * amp[791] - std::complex<double> (0, 1) * amp[792] -
std::complex<double> (0, 1) * amp[794] + std::complex<double> (0, 1) *
amp[798] + amp[799] - std::complex<double> (0, 1) * amp[800] -
std::complex<double> (0, 1) * amp[801] + std::complex<double> (0, 1) *
amp[807] - std::complex<double> (0, 1) * amp[809] - std::complex<double>
(0, 1) * amp[810] - amp[812] - std::complex<double> (0, 1) * amp[814] -
amp[816] - std::complex<double> (0, 1) * amp[817] - amp[819] - amp[820] -
std::complex<double> (0, 1) * amp[822] - amp[824] - std::complex<double>
(0, 1) * amp[825] - amp[827] - std::complex<double> (0, 1) * amp[830] +
std::complex<double> (0, 1) * amp[836] + std::complex<double> (0, 1) *
amp[835] - std::complex<double> (0, 1) * amp[838] - std::complex<double>
(0, 1) * amp[839] + amp[840] + std::complex<double> (0, 1) * amp[845] +
std::complex<double> (0, 1) * amp[844] - std::complex<double> (0, 1) *
amp[848] + std::complex<double> (0, 1) * amp[854] + std::complex<double>
(0, 1) * amp[853] - std::complex<double> (0, 1) * amp[856] -
std::complex<double> (0, 1) * amp[857] + amp[858] + std::complex<double>
(0, 1) * amp[863] + std::complex<double> (0, 1) * amp[862] -
std::complex<double> (0, 1) * amp[939] - std::complex<double> (0, 1) *
amp[940] + amp[942] + amp[943] - std::complex<double> (0, 1) * amp[945] -
std::complex<double> (0, 1) * amp[946] - std::complex<double> (0, 1) *
amp[951] - std::complex<double> (0, 1) * amp[952] + amp[954] + amp[955] -
std::complex<double> (0, 1) * amp[957] - std::complex<double> (0, 1) *
amp[958] - amp[986] - amp[985] - std::complex<double> (0, 1) * amp[989] -
std::complex<double> (0, 1) * amp[988] - std::complex<double> (0, 1) *
amp[995] - std::complex<double> (0, 1) * amp[994] - amp[998] - amp[997] -
std::complex<double> (0, 1) * amp[1001] - std::complex<double> (0, 1) *
amp[1000] - std::complex<double> (0, 1) * amp[1007] -
std::complex<double> (0, 1) * amp[1006];
jamp[9] = +amp[110] + amp[116] + amp[121] + amp[122] + amp[124] + amp[127] +
amp[128] + amp[130] - std::complex<double> (0, 1) * amp[132] -
std::complex<double> (0, 1) * amp[133] - std::complex<double> (0, 1) *
amp[134] - std::complex<double> (0, 1) * amp[135] + std::complex<double>
(0, 1) * amp[180] - amp[181] + std::complex<double> (0, 1) * amp[183] -
amp[184] + std::complex<double> (0, 1) * amp[185] + std::complex<double>
(0, 1) * amp[186] - amp[187] + std::complex<double> (0, 1) * amp[189] -
amp[190] + std::complex<double> (0, 1) * amp[191] + amp[193] -
std::complex<double> (0, 1) * amp[195] + amp[196] + amp[199] -
std::complex<double> (0, 1) * amp[201] + amp[202] + amp[204] + amp[205] +
amp[207] + amp[208] + amp[210] + amp[211] + amp[213] + amp[214] +
amp[436] + amp[442] - std::complex<double> (0, 1) * amp[445] - amp[446] -
std::complex<double> (0, 1) * amp[447] - amp[448] - std::complex<double>
(0, 1) * amp[449] - std::complex<double> (0, 1) * amp[451] - amp[452] -
std::complex<double> (0, 1) * amp[453] - amp[454] - std::complex<double>
(0, 1) * amp[455] - std::complex<double> (0, 1) * amp[469] - amp[470] -
amp[472] - std::complex<double> (0, 1) * amp[475] - amp[476] - amp[478] +
amp[482] - amp[480] + amp[485] - amp[483] + amp[488] - amp[486] +
amp[491] - amp[489] + std::complex<double> (0, 1) * amp[776] -
std::complex<double> (0, 1) * amp[780] - amp[781] + std::complex<double>
(0, 1) * amp[782] + std::complex<double> (0, 1) * amp[783] -
std::complex<double> (0, 1) * amp[789] + std::complex<double> (0, 1) *
amp[791] + std::complex<double> (0, 1) * amp[792] + std::complex<double>
(0, 1) * amp[794] - std::complex<double> (0, 1) * amp[798] - amp[799] +
std::complex<double> (0, 1) * amp[800] + std::complex<double> (0, 1) *
amp[801] - std::complex<double> (0, 1) * amp[807] + std::complex<double>
(0, 1) * amp[809] + std::complex<double> (0, 1) * amp[810] + amp[812] +
std::complex<double> (0, 1) * amp[814] + amp[816] + std::complex<double>
(0, 1) * amp[817] + amp[819] + amp[820] + std::complex<double> (0, 1) *
amp[822] + amp[824] + std::complex<double> (0, 1) * amp[825] + amp[827] -
std::complex<double> (0, 1) * amp[832] - std::complex<double> (0, 1) *
amp[834] - std::complex<double> (0, 1) * amp[835] - std::complex<double>
(0, 1) * amp[837] - std::complex<double> (0, 1) * amp[841] - amp[842] -
std::complex<double> (0, 1) * amp[843] - std::complex<double> (0, 1) *
amp[844] - std::complex<double> (0, 1) * amp[850] - std::complex<double>
(0, 1) * amp[852] - std::complex<double> (0, 1) * amp[853] -
std::complex<double> (0, 1) * amp[855] - std::complex<double> (0, 1) *
amp[859] - amp[860] - std::complex<double> (0, 1) * amp[861] -
std::complex<double> (0, 1) * amp[862] + std::complex<double> (0, 1) *
amp[902] + amp[903] - std::complex<double> (0, 1) * amp[904] -
std::complex<double> (0, 1) * amp[906] - std::complex<double> (0, 1) *
amp[907] + std::complex<double> (0, 1) * amp[911] - std::complex<double>
(0, 1) * amp[913] - amp[914] - std::complex<double> (0, 1) * amp[915] -
std::complex<double> (0, 1) * amp[916] + std::complex<double> (0, 1) *
amp[920] + amp[921] - std::complex<double> (0, 1) * amp[922] -
std::complex<double> (0, 1) * amp[924] - std::complex<double> (0, 1) *
amp[925] + std::complex<double> (0, 1) * amp[929] - std::complex<double>
(0, 1) * amp[931] - amp[932] - std::complex<double> (0, 1) * amp[933] -
std::complex<double> (0, 1) * amp[934] + amp[984] + amp[985] +
std::complex<double> (0, 1) * amp[987] + std::complex<double> (0, 1) *
amp[988] + std::complex<double> (0, 1) * amp[993] + std::complex<double>
(0, 1) * amp[994] + amp[996] + amp[997] + std::complex<double> (0, 1) *
amp[999] + std::complex<double> (0, 1) * amp[1000] + std::complex<double>
(0, 1) * amp[1005] + std::complex<double> (0, 1) * amp[1006] +
std::complex<double> (0, 1) * amp[1013] - std::complex<double> (0, 1) *
amp[1011] + amp[1016] - amp[1014] + std::complex<double> (0, 1) *
amp[1019] - std::complex<double> (0, 1) * amp[1017] +
std::complex<double> (0, 1) * amp[1025] - std::complex<double> (0, 1) *
amp[1023] + amp[1028] - amp[1026] + std::complex<double> (0, 1) *
amp[1031] - std::complex<double> (0, 1) * amp[1029];
jamp[10] = +amp[113] + amp[119] + amp[136] + amp[139] + amp[141] + amp[142] +
amp[145] + amp[147] + std::complex<double> (0, 1) * amp[148] +
std::complex<double> (0, 1) * amp[149] + std::complex<double> (0, 1) *
amp[150] + std::complex<double> (0, 1) * amp[151] - std::complex<double>
(0, 1) * amp[168] + amp[169] - std::complex<double> (0, 1) * amp[171] +
amp[172] - std::complex<double> (0, 1) * amp[173] - std::complex<double>
(0, 1) * amp[174] + amp[175] - std::complex<double> (0, 1) * amp[177] +
amp[178] - std::complex<double> (0, 1) * amp[179] + amp[181] +
std::complex<double> (0, 1) * amp[182] + amp[184] + amp[187] +
std::complex<double> (0, 1) * amp[188] + amp[190] - amp[206] - amp[205] -
amp[209] - amp[208] - amp[212] - amp[211] - amp[215] - amp[214] +
amp[552] + amp[558] + std::complex<double> (0, 1) * amp[576] - amp[578] -
amp[580] + std::complex<double> (0, 1) * amp[582] - amp[584] - amp[586] -
std::complex<double> (0, 1) * amp[588] + amp[590] - std::complex<double>
(0, 1) * amp[591] + amp[592] - std::complex<double> (0, 1) * amp[593] -
std::complex<double> (0, 1) * amp[594] + amp[596] - std::complex<double>
(0, 1) * amp[597] + amp[598] - std::complex<double> (0, 1) * amp[599] +
amp[600] + amp[601] + amp[603] + amp[604] + amp[606] + amp[607] +
amp[609] + amp[610] - std::complex<double> (0, 1) * amp[724] +
std::complex<double> (0, 1) * amp[728] + amp[729] - std::complex<double>
(0, 1) * amp[730] - std::complex<double> (0, 1) * amp[731] +
std::complex<double> (0, 1) * amp[737] - std::complex<double> (0, 1) *
amp[739] - std::complex<double> (0, 1) * amp[740] - std::complex<double>
(0, 1) * amp[742] + std::complex<double> (0, 1) * amp[746] + amp[747] -
std::complex<double> (0, 1) * amp[748] - std::complex<double> (0, 1) *
amp[749] + std::complex<double> (0, 1) * amp[755] - std::complex<double>
(0, 1) * amp[757] - std::complex<double> (0, 1) * amp[758] - amp[760] -
std::complex<double> (0, 1) * amp[762] - amp[764] - std::complex<double>
(0, 1) * amp[765] - amp[767] - amp[768] - std::complex<double> (0, 1) *
amp[770] - amp[772] - std::complex<double> (0, 1) * amp[773] - amp[775] +
std::complex<double> (0, 1) * amp[778] + std::complex<double> (0, 1) *
amp[780] + amp[781] - std::complex<double> (0, 1) * amp[784] -
std::complex<double> (0, 1) * amp[783] + std::complex<double> (0, 1) *
amp[787] - amp[788] + std::complex<double> (0, 1) * amp[789] -
std::complex<double> (0, 1) * amp[793] - std::complex<double> (0, 1) *
amp[792] + std::complex<double> (0, 1) * amp[796] + std::complex<double>
(0, 1) * amp[798] + amp[799] - std::complex<double> (0, 1) * amp[802] -
std::complex<double> (0, 1) * amp[801] + std::complex<double> (0, 1) *
amp[805] - amp[806] + std::complex<double> (0, 1) * amp[807] -
std::complex<double> (0, 1) * amp[811] - std::complex<double> (0, 1) *
amp[810] - std::complex<double> (0, 1) * amp[866] + std::complex<double>
(0, 1) * amp[872] + std::complex<double> (0, 1) * amp[871] -
std::complex<double> (0, 1) * amp[874] - std::complex<double> (0, 1) *
amp[875] + amp[876] + std::complex<double> (0, 1) * amp[881] +
std::complex<double> (0, 1) * amp[880] - std::complex<double> (0, 1) *
amp[884] + std::complex<double> (0, 1) * amp[890] + std::complex<double>
(0, 1) * amp[889] - std::complex<double> (0, 1) * amp[892] -
std::complex<double> (0, 1) * amp[893] + amp[894] + std::complex<double>
(0, 1) * amp[899] + std::complex<double> (0, 1) * amp[898] -
std::complex<double> (0, 1) * amp[963] - std::complex<double> (0, 1) *
amp[964] + amp[966] + amp[967] - std::complex<double> (0, 1) * amp[969] -
std::complex<double> (0, 1) * amp[970] - std::complex<double> (0, 1) *
amp[975] - std::complex<double> (0, 1) * amp[976] + amp[978] + amp[979] -
std::complex<double> (0, 1) * amp[981] - std::complex<double> (0, 1) *
amp[982] - amp[986] - amp[985] - std::complex<double> (0, 1) * amp[989] -
std::complex<double> (0, 1) * amp[988] - std::complex<double> (0, 1) *
amp[995] - std::complex<double> (0, 1) * amp[994] - amp[998] - amp[997] -
std::complex<double> (0, 1) * amp[1001] - std::complex<double> (0, 1) *
amp[1000] - std::complex<double> (0, 1) * amp[1007] -
std::complex<double> (0, 1) * amp[1006];
jamp[11] = +amp[112] + amp[118] + amp[120] + amp[123] + amp[125] + amp[126] +
amp[129] + amp[131] + std::complex<double> (0, 1) * amp[132] +
std::complex<double> (0, 1) * amp[133] + std::complex<double> (0, 1) *
amp[134] + std::complex<double> (0, 1) * amp[135] + std::complex<double>
(0, 1) * amp[168] - amp[169] + std::complex<double> (0, 1) * amp[171] -
amp[172] + std::complex<double> (0, 1) * amp[173] + std::complex<double>
(0, 1) * amp[174] - amp[175] + std::complex<double> (0, 1) * amp[177] -
amp[178] + std::complex<double> (0, 1) * amp[179] - amp[193] +
std::complex<double> (0, 1) * amp[195] - amp[196] - amp[199] +
std::complex<double> (0, 1) * amp[201] - amp[202] + amp[206] - amp[204] +
amp[209] - amp[207] + amp[212] - amp[210] + amp[215] - amp[213] +
amp[434] + amp[440] - std::complex<double> (0, 1) * amp[457] - amp[458] -
std::complex<double> (0, 1) * amp[459] - amp[460] - std::complex<double>
(0, 1) * amp[461] - std::complex<double> (0, 1) * amp[463] - amp[464] -
std::complex<double> (0, 1) * amp[465] - amp[466] - std::complex<double>
(0, 1) * amp[467] + std::complex<double> (0, 1) * amp[469] + amp[470] +
amp[472] + std::complex<double> (0, 1) * amp[475] + amp[476] + amp[478] +
amp[480] + amp[481] + amp[483] + amp[484] + amp[486] + amp[487] +
amp[489] + amp[490] + std::complex<double> (0, 1) * amp[724] -
std::complex<double> (0, 1) * amp[728] - amp[729] + std::complex<double>
(0, 1) * amp[730] + std::complex<double> (0, 1) * amp[731] -
std::complex<double> (0, 1) * amp[737] + std::complex<double> (0, 1) *
amp[739] + std::complex<double> (0, 1) * amp[740] + std::complex<double>
(0, 1) * amp[742] - std::complex<double> (0, 1) * amp[746] - amp[747] +
std::complex<double> (0, 1) * amp[748] + std::complex<double> (0, 1) *
amp[749] - std::complex<double> (0, 1) * amp[755] + std::complex<double>
(0, 1) * amp[757] + std::complex<double> (0, 1) * amp[758] + amp[760] +
std::complex<double> (0, 1) * amp[762] + amp[764] + std::complex<double>
(0, 1) * amp[765] + amp[767] + amp[768] + std::complex<double> (0, 1) *
amp[770] + amp[772] + std::complex<double> (0, 1) * amp[773] + amp[775] -
std::complex<double> (0, 1) * amp[868] - std::complex<double> (0, 1) *
amp[870] - std::complex<double> (0, 1) * amp[871] - std::complex<double>
(0, 1) * amp[873] - std::complex<double> (0, 1) * amp[877] - amp[878] -
std::complex<double> (0, 1) * amp[879] - std::complex<double> (0, 1) *
amp[880] - std::complex<double> (0, 1) * amp[886] - std::complex<double>
(0, 1) * amp[888] - std::complex<double> (0, 1) * amp[889] -
std::complex<double> (0, 1) * amp[891] - std::complex<double> (0, 1) *
amp[895] - amp[896] - std::complex<double> (0, 1) * amp[897] -
std::complex<double> (0, 1) * amp[898] - std::complex<double> (0, 1) *
amp[902] - amp[903] + std::complex<double> (0, 1) * amp[904] +
std::complex<double> (0, 1) * amp[906] + std::complex<double> (0, 1) *
amp[907] - std::complex<double> (0, 1) * amp[911] + std::complex<double>
(0, 1) * amp[913] + amp[914] + std::complex<double> (0, 1) * amp[915] +
std::complex<double> (0, 1) * amp[916] - std::complex<double> (0, 1) *
amp[920] - amp[921] + std::complex<double> (0, 1) * amp[922] +
std::complex<double> (0, 1) * amp[924] + std::complex<double> (0, 1) *
amp[925] - std::complex<double> (0, 1) * amp[929] + std::complex<double>
(0, 1) * amp[931] + amp[932] + std::complex<double> (0, 1) * amp[933] +
std::complex<double> (0, 1) * amp[934] + amp[986] - amp[984] +
std::complex<double> (0, 1) * amp[989] - std::complex<double> (0, 1) *
amp[987] + std::complex<double> (0, 1) * amp[995] - std::complex<double>
(0, 1) * amp[993] + amp[998] - amp[996] + std::complex<double> (0, 1) *
amp[1001] - std::complex<double> (0, 1) * amp[999] + std::complex<double>
(0, 1) * amp[1007] - std::complex<double> (0, 1) * amp[1005] +
std::complex<double> (0, 1) * amp[1011] + std::complex<double> (0, 1) *
amp[1012] + amp[1014] + amp[1015] + std::complex<double> (0, 1) *
amp[1017] + std::complex<double> (0, 1) * amp[1018] +
std::complex<double> (0, 1) * amp[1023] + std::complex<double> (0, 1) *
amp[1024] + amp[1026] + amp[1027] + std::complex<double> (0, 1) *
amp[1029] + std::complex<double> (0, 1) * amp[1030];
jamp[12] = +amp[217] + amp[223] + amp[261] + amp[262] + amp[264] + amp[267] +
amp[268] + amp[270] - std::complex<double> (0, 1) * amp[272] -
std::complex<double> (0, 1) * amp[273] - std::complex<double> (0, 1) *
amp[274] - std::complex<double> (0, 1) * amp[275] - amp[277] -
std::complex<double> (0, 1) * amp[278] - amp[280] - amp[283] -
std::complex<double> (0, 1) * amp[284] - amp[286] - std::complex<double>
(0, 1) * amp[300] - amp[301] - std::complex<double> (0, 1) * amp[302] -
amp[304] - std::complex<double> (0, 1) * amp[305] - std::complex<double>
(0, 1) * amp[306] - amp[307] - std::complex<double> (0, 1) * amp[308] -
amp[310] - std::complex<double> (0, 1) * amp[311] + amp[314] - amp[312] +
amp[317] - amp[315] + amp[320] - amp[318] + amp[323] - amp[321] +
amp[615] + amp[621] - std::complex<double> (0, 1) * amp[624] + amp[626] +
amp[628] - std::complex<double> (0, 1) * amp[630] + amp[632] + amp[634] +
std::complex<double> (0, 1) * amp[637] + amp[638] + std::complex<double>
(0, 1) * amp[639] + amp[640] + std::complex<double> (0, 1) * amp[641] +
std::complex<double> (0, 1) * amp[643] + amp[644] + std::complex<double>
(0, 1) * amp[645] + amp[646] + std::complex<double> (0, 1) * amp[647] -
amp[662] - amp[661] - amp[665] - amp[664] - amp[668] - amp[667] -
amp[671] - amp[670] - std::complex<double> (0, 1) * amp[674] -
std::complex<double> (0, 1) * amp[676] - amp[677] + std::complex<double>
(0, 1) * amp[680] + std::complex<double> (0, 1) * amp[679] -
std::complex<double> (0, 1) * amp[683] + amp[684] - std::complex<double>
(0, 1) * amp[685] + std::complex<double> (0, 1) * amp[689] +
std::complex<double> (0, 1) * amp[688] - std::complex<double> (0, 1) *
amp[692] - std::complex<double> (0, 1) * amp[694] - amp[695] +
std::complex<double> (0, 1) * amp[698] + std::complex<double> (0, 1) *
amp[697] - std::complex<double> (0, 1) * amp[701] + amp[702] -
std::complex<double> (0, 1) * amp[703] + std::complex<double> (0, 1) *
amp[707] + std::complex<double> (0, 1) * amp[706] - std::complex<double>
(0, 1) * amp[726] + std::complex<double> (0, 1) * amp[732] -
std::complex<double> (0, 1) * amp[730] + std::complex<double> (0, 1) *
amp[734] - std::complex<double> (0, 1) * amp[735] + amp[736] +
std::complex<double> (0, 1) * amp[741] - std::complex<double> (0, 1) *
amp[739] - std::complex<double> (0, 1) * amp[744] + std::complex<double>
(0, 1) * amp[750] - std::complex<double> (0, 1) * amp[748] +
std::complex<double> (0, 1) * amp[752] - std::complex<double> (0, 1) *
amp[753] + amp[754] + std::complex<double> (0, 1) * amp[759] -
std::complex<double> (0, 1) * amp[757] + amp[761] - std::complex<double>
(0, 1) * amp[762] + amp[763] - std::complex<double> (0, 1) * amp[765] +
amp[766] + amp[769] - std::complex<double> (0, 1) * amp[770] + amp[771] -
std::complex<double> (0, 1) * amp[773] + amp[774] - std::complex<double>
(0, 1) * amp[865] - std::complex<double> (0, 1) * amp[866] - amp[867] +
std::complex<double> (0, 1) * amp[872] + std::complex<double> (0, 1) *
amp[871] - std::complex<double> (0, 1) * amp[875] + std::complex<double>
(0, 1) * amp[881] + std::complex<double> (0, 1) * amp[880] -
std::complex<double> (0, 1) * amp[883] - std::complex<double> (0, 1) *
amp[884] - amp[885] + std::complex<double> (0, 1) * amp[890] +
std::complex<double> (0, 1) * amp[889] - std::complex<double> (0, 1) *
amp[893] + std::complex<double> (0, 1) * amp[899] + std::complex<double>
(0, 1) * amp[898] + std::complex<double> (0, 1) * amp[941] +
std::complex<double> (0, 1) * amp[940] - amp[944] - amp[943] +
std::complex<double> (0, 1) * amp[947] + std::complex<double> (0, 1) *
amp[946] + std::complex<double> (0, 1) * amp[953] + std::complex<double>
(0, 1) * amp[952] - amp[956] - amp[955] + std::complex<double> (0, 1) *
amp[959] + std::complex<double> (0, 1) * amp[958] + amp[962] - amp[960] +
std::complex<double> (0, 1) * amp[965] - std::complex<double> (0, 1) *
amp[963] + std::complex<double> (0, 1) * amp[971] - std::complex<double>
(0, 1) * amp[969] + amp[974] - amp[972] + std::complex<double> (0, 1) *
amp[977] - std::complex<double> (0, 1) * amp[975] + std::complex<double>
(0, 1) * amp[983] - std::complex<double> (0, 1) * amp[981];
jamp[13] = +amp[216] + amp[222] + amp[245] + amp[246] + amp[248] + amp[251] +
amp[252] + amp[254] - std::complex<double> (0, 1) * amp[256] -
std::complex<double> (0, 1) * amp[257] - std::complex<double> (0, 1) *
amp[258] - std::complex<double> (0, 1) * amp[259] - amp[289] -
std::complex<double> (0, 1) * amp[290] - amp[292] - amp[295] -
std::complex<double> (0, 1) * amp[296] - amp[298] + std::complex<double>
(0, 1) * amp[300] + amp[301] + std::complex<double> (0, 1) * amp[302] +
amp[304] + std::complex<double> (0, 1) * amp[305] + std::complex<double>
(0, 1) * amp[306] + amp[307] + std::complex<double> (0, 1) * amp[308] +
amp[310] + std::complex<double> (0, 1) * amp[311] + amp[312] + amp[313] +
amp[315] + amp[316] + amp[318] + amp[319] + amp[321] + amp[322] +
amp[497] + amp[503] + std::complex<double> (0, 1) * amp[505] + amp[506] +
std::complex<double> (0, 1) * amp[507] + amp[508] + std::complex<double>
(0, 1) * amp[509] + std::complex<double> (0, 1) * amp[511] + amp[512] +
std::complex<double> (0, 1) * amp[513] + amp[514] + std::complex<double>
(0, 1) * amp[515] - std::complex<double> (0, 1) * amp[516] + amp[518] +
amp[520] - std::complex<double> (0, 1) * amp[522] + amp[524] + amp[526] -
amp[542] - amp[541] - amp[545] - amp[544] - amp[548] - amp[547] -
amp[551] - amp[550] - std::complex<double> (0, 1) * amp[728] +
std::complex<double> (0, 1) * amp[730] + std::complex<double> (0, 1) *
amp[731] + std::complex<double> (0, 1) * amp[733] - std::complex<double>
(0, 1) * amp[737] + amp[738] + std::complex<double> (0, 1) * amp[739] +
std::complex<double> (0, 1) * amp[740] - std::complex<double> (0, 1) *
amp[746] + std::complex<double> (0, 1) * amp[748] + std::complex<double>
(0, 1) * amp[749] + std::complex<double> (0, 1) * amp[751] -
std::complex<double> (0, 1) * amp[755] + amp[756] + std::complex<double>
(0, 1) * amp[757] + std::complex<double> (0, 1) * amp[758] - amp[761] +
std::complex<double> (0, 1) * amp[762] - amp[763] + std::complex<double>
(0, 1) * amp[765] - amp[766] - amp[769] + std::complex<double> (0, 1) *
amp[770] - amp[771] + std::complex<double> (0, 1) * amp[773] - amp[774] -
std::complex<double> (0, 1) * amp[778] - amp[779] - std::complex<double>
(0, 1) * amp[780] + std::complex<double> (0, 1) * amp[784] +
std::complex<double> (0, 1) * amp[783] - std::complex<double> (0, 1) *
amp[787] - std::complex<double> (0, 1) * amp[789] + amp[790] +
std::complex<double> (0, 1) * amp[793] + std::complex<double> (0, 1) *
amp[792] - std::complex<double> (0, 1) * amp[796] - amp[797] -
std::complex<double> (0, 1) * amp[798] + std::complex<double> (0, 1) *
amp[802] + std::complex<double> (0, 1) * amp[801] - std::complex<double>
(0, 1) * amp[805] - std::complex<double> (0, 1) * amp[807] + amp[808] +
std::complex<double> (0, 1) * amp[811] + std::complex<double> (0, 1) *
amp[810] + std::complex<double> (0, 1) * amp[865] + std::complex<double>
(0, 1) * amp[866] + amp[867] - std::complex<double> (0, 1) * amp[872] -
std::complex<double> (0, 1) * amp[871] + std::complex<double> (0, 1) *
amp[875] - std::complex<double> (0, 1) * amp[881] - std::complex<double>
(0, 1) * amp[880] + std::complex<double> (0, 1) * amp[883] +
std::complex<double> (0, 1) * amp[884] + amp[885] - std::complex<double>
(0, 1) * amp[890] - std::complex<double> (0, 1) * amp[889] +
std::complex<double> (0, 1) * amp[893] - std::complex<double> (0, 1) *
amp[899] - std::complex<double> (0, 1) * amp[898] + amp[960] + amp[961] +
std::complex<double> (0, 1) * amp[963] + std::complex<double> (0, 1) *
amp[964] + std::complex<double> (0, 1) * amp[969] + std::complex<double>
(0, 1) * amp[970] + amp[972] + amp[973] + std::complex<double> (0, 1) *
amp[975] + std::complex<double> (0, 1) * amp[976] + std::complex<double>
(0, 1) * amp[981] + std::complex<double> (0, 1) * amp[982] +
std::complex<double> (0, 1) * amp[989] + std::complex<double> (0, 1) *
amp[988] - amp[992] - amp[991] + std::complex<double> (0, 1) * amp[995] +
std::complex<double> (0, 1) * amp[994] + std::complex<double> (0, 1) *
amp[1001] + std::complex<double> (0, 1) * amp[1000] - amp[1004] -
amp[1003] + std::complex<double> (0, 1) * amp[1007] +
std::complex<double> (0, 1) * amp[1006];
jamp[14] = +amp[219] + amp[225] + amp[260] + amp[263] + amp[265] + amp[266] +
amp[269] + amp[271] + std::complex<double> (0, 1) * amp[272] +
std::complex<double> (0, 1) * amp[273] + std::complex<double> (0, 1) *
amp[274] + std::complex<double> (0, 1) * amp[275] + amp[277] +
std::complex<double> (0, 1) * amp[278] + amp[280] + amp[283] +
std::complex<double> (0, 1) * amp[284] + amp[286] - std::complex<double>
(0, 1) * amp[288] + amp[289] - std::complex<double> (0, 1) * amp[291] +
amp[292] - std::complex<double> (0, 1) * amp[293] - std::complex<double>
(0, 1) * amp[294] + amp[295] - std::complex<double> (0, 1) * amp[297] +
amp[298] - std::complex<double> (0, 1) * amp[299] - amp[314] - amp[313] -
amp[317] - amp[316] - amp[320] - amp[319] - amp[323] - amp[322] +
amp[613] + amp[619] + std::complex<double> (0, 1) * amp[624] - amp[626] -
amp[628] + std::complex<double> (0, 1) * amp[630] - amp[632] - amp[634] +
std::complex<double> (0, 1) * amp[648] - amp[650] + std::complex<double>
(0, 1) * amp[651] - amp[652] + std::complex<double> (0, 1) * amp[653] +
std::complex<double> (0, 1) * amp[654] - amp[656] + std::complex<double>
(0, 1) * amp[657] - amp[658] + std::complex<double> (0, 1) * amp[659] +
amp[662] - amp[660] + amp[665] - amp[663] + amp[668] - amp[666] +
amp[671] - amp[669] + std::complex<double> (0, 1) * amp[674] +
std::complex<double> (0, 1) * amp[676] + amp[677] - std::complex<double>
(0, 1) * amp[680] - std::complex<double> (0, 1) * amp[679] +
std::complex<double> (0, 1) * amp[683] - amp[684] + std::complex<double>
(0, 1) * amp[685] - std::complex<double> (0, 1) * amp[689] -
std::complex<double> (0, 1) * amp[688] + std::complex<double> (0, 1) *
amp[692] + std::complex<double> (0, 1) * amp[694] + amp[695] -
std::complex<double> (0, 1) * amp[698] - std::complex<double> (0, 1) *
amp[697] + std::complex<double> (0, 1) * amp[701] - amp[702] +
std::complex<double> (0, 1) * amp[703] - std::complex<double> (0, 1) *
amp[707] - std::complex<double> (0, 1) * amp[706] - std::complex<double>
(0, 1) * amp[777] + std::complex<double> (0, 1) * amp[778] + amp[779] -
std::complex<double> (0, 1) * amp[784] + std::complex<double> (0, 1) *
amp[782] + std::complex<double> (0, 1) * amp[787] - std::complex<double>
(0, 1) * amp[793] + std::complex<double> (0, 1) * amp[791] -
std::complex<double> (0, 1) * amp[795] + std::complex<double> (0, 1) *
amp[796] + amp[797] - std::complex<double> (0, 1) * amp[802] +
std::complex<double> (0, 1) * amp[800] + std::complex<double> (0, 1) *
amp[805] - std::complex<double> (0, 1) * amp[811] + std::complex<double>
(0, 1) * amp[809] + amp[812] + std::complex<double> (0, 1) * amp[814] +
amp[816] + std::complex<double> (0, 1) * amp[817] + amp[819] + amp[820] +
std::complex<double> (0, 1) * amp[822] + amp[824] + std::complex<double>
(0, 1) * amp[825] + amp[827] + std::complex<double> (0, 1) * amp[830] -
std::complex<double> (0, 1) * amp[836] - std::complex<double> (0, 1) *
amp[835] + std::complex<double> (0, 1) * amp[838] + std::complex<double>
(0, 1) * amp[839] - amp[840] - std::complex<double> (0, 1) * amp[845] -
std::complex<double> (0, 1) * amp[844] + std::complex<double> (0, 1) *
amp[848] - std::complex<double> (0, 1) * amp[854] - std::complex<double>
(0, 1) * amp[853] + std::complex<double> (0, 1) * amp[856] +
std::complex<double> (0, 1) * amp[857] - amp[858] - std::complex<double>
(0, 1) * amp[863] - std::complex<double> (0, 1) * amp[862] -
std::complex<double> (0, 1) * amp[941] + std::complex<double> (0, 1) *
amp[939] + amp[944] - amp[942] - std::complex<double> (0, 1) * amp[947] +
std::complex<double> (0, 1) * amp[945] - std::complex<double> (0, 1) *
amp[953] + std::complex<double> (0, 1) * amp[951] + amp[956] - amp[954] -
std::complex<double> (0, 1) * amp[959] + std::complex<double> (0, 1) *
amp[957] - amp[962] - amp[961] - std::complex<double> (0, 1) * amp[965] -
std::complex<double> (0, 1) * amp[964] - std::complex<double> (0, 1) *
amp[971] - std::complex<double> (0, 1) * amp[970] - amp[974] - amp[973] -
std::complex<double> (0, 1) * amp[977] - std::complex<double> (0, 1) *
amp[976] - std::complex<double> (0, 1) * amp[983] - std::complex<double>
(0, 1) * amp[982];
jamp[15] = +amp[218] + amp[224] + amp[229] + amp[230] + amp[232] + amp[235] +
amp[236] + amp[238] - std::complex<double> (0, 1) * amp[240] -
std::complex<double> (0, 1) * amp[241] - std::complex<double> (0, 1) *
amp[242] - std::complex<double> (0, 1) * amp[243] + std::complex<double>
(0, 1) * amp[288] - amp[289] + std::complex<double> (0, 1) * amp[291] -
amp[292] + std::complex<double> (0, 1) * amp[293] + std::complex<double>
(0, 1) * amp[294] - amp[295] + std::complex<double> (0, 1) * amp[297] -
amp[298] + std::complex<double> (0, 1) * amp[299] + amp[301] -
std::complex<double> (0, 1) * amp[303] + amp[304] + amp[307] -
std::complex<double> (0, 1) * amp[309] + amp[310] + amp[312] + amp[313] +
amp[315] + amp[316] + amp[318] + amp[319] + amp[321] + amp[322] +
amp[437] + amp[443] + std::complex<double> (0, 1) * amp[445] + amp[446] +
std::complex<double> (0, 1) * amp[447] + amp[448] + std::complex<double>
(0, 1) * amp[449] + std::complex<double> (0, 1) * amp[451] + amp[452] +
std::complex<double> (0, 1) * amp[453] + amp[454] + std::complex<double>
(0, 1) * amp[455] - std::complex<double> (0, 1) * amp[456] + amp[458] +
amp[460] - std::complex<double> (0, 1) * amp[462] + amp[464] + amp[466] -
amp[482] - amp[481] - amp[485] - amp[484] - amp[488] - amp[487] -
amp[491] - amp[490] + std::complex<double> (0, 1) * amp[777] -
std::complex<double> (0, 1) * amp[778] - amp[779] + std::complex<double>
(0, 1) * amp[784] - std::complex<double> (0, 1) * amp[782] -
std::complex<double> (0, 1) * amp[787] + std::complex<double> (0, 1) *
amp[793] - std::complex<double> (0, 1) * amp[791] + std::complex<double>
(0, 1) * amp[795] - std::complex<double> (0, 1) * amp[796] - amp[797] +
std::complex<double> (0, 1) * amp[802] - std::complex<double> (0, 1) *
amp[800] - std::complex<double> (0, 1) * amp[805] + std::complex<double>
(0, 1) * amp[811] - std::complex<double> (0, 1) * amp[809] - amp[812] -
std::complex<double> (0, 1) * amp[814] - amp[816] - std::complex<double>
(0, 1) * amp[817] - amp[819] - amp[820] - std::complex<double> (0, 1) *
amp[822] - amp[824] - std::complex<double> (0, 1) * amp[825] - amp[827] +
std::complex<double> (0, 1) * amp[832] + std::complex<double> (0, 1) *
amp[834] + std::complex<double> (0, 1) * amp[835] + std::complex<double>
(0, 1) * amp[837] + std::complex<double> (0, 1) * amp[841] + amp[842] +
std::complex<double> (0, 1) * amp[843] + std::complex<double> (0, 1) *
amp[844] + std::complex<double> (0, 1) * amp[850] + std::complex<double>
(0, 1) * amp[852] + std::complex<double> (0, 1) * amp[853] +
std::complex<double> (0, 1) * amp[855] + std::complex<double> (0, 1) *
amp[859] + amp[860] + std::complex<double> (0, 1) * amp[861] +
std::complex<double> (0, 1) * amp[862] + std::complex<double> (0, 1) *
amp[866] + amp[867] + std::complex<double> (0, 1) * amp[868] -
std::complex<double> (0, 1) * amp[872] + std::complex<double> (0, 1) *
amp[870] + std::complex<double> (0, 1) * amp[875] + std::complex<double>
(0, 1) * amp[877] + amp[878] - std::complex<double> (0, 1) * amp[881] +
std::complex<double> (0, 1) * amp[879] + std::complex<double> (0, 1) *
amp[884] + amp[885] + std::complex<double> (0, 1) * amp[886] -
std::complex<double> (0, 1) * amp[890] + std::complex<double> (0, 1) *
amp[888] + std::complex<double> (0, 1) * amp[893] + std::complex<double>
(0, 1) * amp[895] + amp[896] - std::complex<double> (0, 1) * amp[899] +
std::complex<double> (0, 1) * amp[897] + amp[960] + amp[961] +
std::complex<double> (0, 1) * amp[963] + std::complex<double> (0, 1) *
amp[964] + std::complex<double> (0, 1) * amp[969] + std::complex<double>
(0, 1) * amp[970] + amp[972] + amp[973] + std::complex<double> (0, 1) *
amp[975] + std::complex<double> (0, 1) * amp[976] + std::complex<double>
(0, 1) * amp[981] + std::complex<double> (0, 1) * amp[982] -
std::complex<double> (0, 1) * amp[1013] - std::complex<double> (0, 1) *
amp[1012] - amp[1016] - amp[1015] - std::complex<double> (0, 1) *
amp[1019] - std::complex<double> (0, 1) * amp[1018] -
std::complex<double> (0, 1) * amp[1025] - std::complex<double> (0, 1) *
amp[1024] - amp[1028] - amp[1027] - std::complex<double> (0, 1) *
amp[1031] - std::complex<double> (0, 1) * amp[1030];
jamp[16] = +amp[221] + amp[227] + amp[244] + amp[247] + amp[249] + amp[250] +
amp[253] + amp[255] + std::complex<double> (0, 1) * amp[256] +
std::complex<double> (0, 1) * amp[257] + std::complex<double> (0, 1) *
amp[258] + std::complex<double> (0, 1) * amp[259] - std::complex<double>
(0, 1) * amp[276] + amp[277] - std::complex<double> (0, 1) * amp[279] +
amp[280] - std::complex<double> (0, 1) * amp[281] - std::complex<double>
(0, 1) * amp[282] + amp[283] - std::complex<double> (0, 1) * amp[285] +
amp[286] - std::complex<double> (0, 1) * amp[287] + amp[289] +
std::complex<double> (0, 1) * amp[290] + amp[292] + amp[295] +
std::complex<double> (0, 1) * amp[296] + amp[298] - amp[314] - amp[313] -
amp[317] - amp[316] - amp[320] - amp[319] - amp[323] - amp[322] +
amp[492] + amp[498] + std::complex<double> (0, 1) * amp[516] - amp[518] -
amp[520] + std::complex<double> (0, 1) * amp[522] - amp[524] - amp[526] -
std::complex<double> (0, 1) * amp[528] + amp[530] - std::complex<double>
(0, 1) * amp[531] + amp[532] - std::complex<double> (0, 1) * amp[533] -
std::complex<double> (0, 1) * amp[534] + amp[536] - std::complex<double>
(0, 1) * amp[537] + amp[538] - std::complex<double> (0, 1) * amp[539] +
amp[540] + amp[541] + amp[543] + amp[544] + amp[546] + amp[547] +
amp[549] + amp[550] - std::complex<double> (0, 1) * amp[672] +
std::complex<double> (0, 1) * amp[676] + amp[677] - std::complex<double>
(0, 1) * amp[678] - std::complex<double> (0, 1) * amp[679] +
std::complex<double> (0, 1) * amp[685] - std::complex<double> (0, 1) *
amp[687] - std::complex<double> (0, 1) * amp[688] - std::complex<double>
(0, 1) * amp[690] + std::complex<double> (0, 1) * amp[694] + amp[695] -
std::complex<double> (0, 1) * amp[696] - std::complex<double> (0, 1) *
amp[697] + std::complex<double> (0, 1) * amp[703] - std::complex<double>
(0, 1) * amp[705] - std::complex<double> (0, 1) * amp[706] - amp[708] -
std::complex<double> (0, 1) * amp[710] - amp[712] - std::complex<double>
(0, 1) * amp[713] - amp[715] - amp[716] - std::complex<double> (0, 1) *
amp[718] - amp[720] - std::complex<double> (0, 1) * amp[721] - amp[723] +
std::complex<double> (0, 1) * amp[778] + amp[779] + std::complex<double>
(0, 1) * amp[780] - std::complex<double> (0, 1) * amp[784] -
std::complex<double> (0, 1) * amp[783] + std::complex<double> (0, 1) *
amp[787] + std::complex<double> (0, 1) * amp[789] - amp[790] -
std::complex<double> (0, 1) * amp[793] - std::complex<double> (0, 1) *
amp[792] + std::complex<double> (0, 1) * amp[796] + amp[797] +
std::complex<double> (0, 1) * amp[798] - std::complex<double> (0, 1) *
amp[802] - std::complex<double> (0, 1) * amp[801] + std::complex<double>
(0, 1) * amp[805] + std::complex<double> (0, 1) * amp[807] - amp[808] -
std::complex<double> (0, 1) * amp[811] - std::complex<double> (0, 1) *
amp[810] - std::complex<double> (0, 1) * amp[902] + std::complex<double>
(0, 1) * amp[908] + std::complex<double> (0, 1) * amp[907] -
std::complex<double> (0, 1) * amp[910] - std::complex<double> (0, 1) *
amp[911] + amp[912] + std::complex<double> (0, 1) * amp[917] +
std::complex<double> (0, 1) * amp[916] - std::complex<double> (0, 1) *
amp[920] + std::complex<double> (0, 1) * amp[926] + std::complex<double>
(0, 1) * amp[925] - std::complex<double> (0, 1) * amp[928] -
std::complex<double> (0, 1) * amp[929] + amp[930] + std::complex<double>
(0, 1) * amp[935] + std::complex<double> (0, 1) * amp[934] - amp[962] -
amp[961] - std::complex<double> (0, 1) * amp[965] - std::complex<double>
(0, 1) * amp[964] - std::complex<double> (0, 1) * amp[971] -
std::complex<double> (0, 1) * amp[970] - amp[974] - amp[973] -
std::complex<double> (0, 1) * amp[977] - std::complex<double> (0, 1) *
amp[976] - std::complex<double> (0, 1) * amp[983] - std::complex<double>
(0, 1) * amp[982] - std::complex<double> (0, 1) * amp[987] -
std::complex<double> (0, 1) * amp[988] + amp[990] + amp[991] -
std::complex<double> (0, 1) * amp[993] - std::complex<double> (0, 1) *
amp[994] - std::complex<double> (0, 1) * amp[999] - std::complex<double>
(0, 1) * amp[1000] + amp[1002] + amp[1003] - std::complex<double> (0, 1)
* amp[1005] - std::complex<double> (0, 1) * amp[1006];
jamp[17] = +amp[220] + amp[226] + amp[228] + amp[231] + amp[233] + amp[234] +
amp[237] + amp[239] + std::complex<double> (0, 1) * amp[240] +
std::complex<double> (0, 1) * amp[241] + std::complex<double> (0, 1) *
amp[242] + std::complex<double> (0, 1) * amp[243] + std::complex<double>
(0, 1) * amp[276] - amp[277] + std::complex<double> (0, 1) * amp[279] -
amp[280] + std::complex<double> (0, 1) * amp[281] + std::complex<double>
(0, 1) * amp[282] - amp[283] + std::complex<double> (0, 1) * amp[285] -
amp[286] + std::complex<double> (0, 1) * amp[287] - amp[301] +
std::complex<double> (0, 1) * amp[303] - amp[304] - amp[307] +
std::complex<double> (0, 1) * amp[309] - amp[310] + amp[314] - amp[312] +
amp[317] - amp[315] + amp[320] - amp[318] + amp[323] - amp[321] +
amp[432] + amp[438] + std::complex<double> (0, 1) * amp[456] - amp[458] -
amp[460] + std::complex<double> (0, 1) * amp[462] - amp[464] - amp[466] -
std::complex<double> (0, 1) * amp[468] + amp[470] - std::complex<double>
(0, 1) * amp[471] + amp[472] - std::complex<double> (0, 1) * amp[473] -
std::complex<double> (0, 1) * amp[474] + amp[476] - std::complex<double>
(0, 1) * amp[477] + amp[478] - std::complex<double> (0, 1) * amp[479] +
amp[480] + amp[481] + amp[483] + amp[484] + amp[486] + amp[487] +
amp[489] + amp[490] + std::complex<double> (0, 1) * amp[672] -
std::complex<double> (0, 1) * amp[676] - amp[677] + std::complex<double>
(0, 1) * amp[678] + std::complex<double> (0, 1) * amp[679] -
std::complex<double> (0, 1) * amp[685] + std::complex<double> (0, 1) *
amp[687] + std::complex<double> (0, 1) * amp[688] + std::complex<double>
(0, 1) * amp[690] - std::complex<double> (0, 1) * amp[694] - amp[695] +
std::complex<double> (0, 1) * amp[696] + std::complex<double> (0, 1) *
amp[697] - std::complex<double> (0, 1) * amp[703] + std::complex<double>
(0, 1) * amp[705] + std::complex<double> (0, 1) * amp[706] + amp[708] +
std::complex<double> (0, 1) * amp[710] + amp[712] + std::complex<double>
(0, 1) * amp[713] + amp[715] + amp[716] + std::complex<double> (0, 1) *
amp[718] + amp[720] + std::complex<double> (0, 1) * amp[721] + amp[723] -
std::complex<double> (0, 1) * amp[866] - amp[867] - std::complex<double>
(0, 1) * amp[868] + std::complex<double> (0, 1) * amp[872] -
std::complex<double> (0, 1) * amp[870] - std::complex<double> (0, 1) *
amp[875] - std::complex<double> (0, 1) * amp[877] - amp[878] +
std::complex<double> (0, 1) * amp[881] - std::complex<double> (0, 1) *
amp[879] - std::complex<double> (0, 1) * amp[884] - amp[885] -
std::complex<double> (0, 1) * amp[886] + std::complex<double> (0, 1) *
amp[890] - std::complex<double> (0, 1) * amp[888] - std::complex<double>
(0, 1) * amp[893] - std::complex<double> (0, 1) * amp[895] - amp[896] +
std::complex<double> (0, 1) * amp[899] - std::complex<double> (0, 1) *
amp[897] + std::complex<double> (0, 1) * amp[904] - std::complex<double>
(0, 1) * amp[908] + std::complex<double> (0, 1) * amp[906] -
std::complex<double> (0, 1) * amp[909] + std::complex<double> (0, 1) *
amp[913] + amp[914] - std::complex<double> (0, 1) * amp[917] +
std::complex<double> (0, 1) * amp[915] + std::complex<double> (0, 1) *
amp[922] - std::complex<double> (0, 1) * amp[926] + std::complex<double>
(0, 1) * amp[924] - std::complex<double> (0, 1) * amp[927] +
std::complex<double> (0, 1) * amp[931] + amp[932] - std::complex<double>
(0, 1) * amp[935] + std::complex<double> (0, 1) * amp[933] + amp[962] -
amp[960] + std::complex<double> (0, 1) * amp[965] - std::complex<double>
(0, 1) * amp[963] + std::complex<double> (0, 1) * amp[971] -
std::complex<double> (0, 1) * amp[969] + amp[974] - amp[972] +
std::complex<double> (0, 1) * amp[977] - std::complex<double> (0, 1) *
amp[975] + std::complex<double> (0, 1) * amp[983] - std::complex<double>
(0, 1) * amp[981] + std::complex<double> (0, 1) * amp[1011] +
std::complex<double> (0, 1) * amp[1012] + amp[1014] + amp[1015] +
std::complex<double> (0, 1) * amp[1017] + std::complex<double> (0, 1) *
amp[1018] + std::complex<double> (0, 1) * amp[1023] +
std::complex<double> (0, 1) * amp[1024] + amp[1026] + amp[1027] +
std::complex<double> (0, 1) * amp[1029] + std::complex<double> (0, 1) *
amp[1030];
jamp[18] = +amp[325] + amp[331] + amp[369] + amp[370] + amp[372] + amp[375] +
amp[376] + amp[378] - std::complex<double> (0, 1) * amp[380] -
std::complex<double> (0, 1) * amp[381] - std::complex<double> (0, 1) *
amp[382] - std::complex<double> (0, 1) * amp[383] - amp[385] -
std::complex<double> (0, 1) * amp[386] - amp[388] - amp[391] -
std::complex<double> (0, 1) * amp[392] - amp[394] - std::complex<double>
(0, 1) * amp[408] - amp[409] - std::complex<double> (0, 1) * amp[410] -
amp[412] - std::complex<double> (0, 1) * amp[413] - std::complex<double>
(0, 1) * amp[414] - amp[415] - std::complex<double> (0, 1) * amp[416] -
amp[418] - std::complex<double> (0, 1) * amp[419] + amp[422] - amp[420] +
amp[425] - amp[423] + amp[428] - amp[426] + amp[431] - amp[429] +
amp[555] + amp[561] - std::complex<double> (0, 1) * amp[564] + amp[566] +
amp[568] - std::complex<double> (0, 1) * amp[570] + amp[572] + amp[574] +
std::complex<double> (0, 1) * amp[577] + amp[578] + std::complex<double>
(0, 1) * amp[579] + amp[580] + std::complex<double> (0, 1) * amp[581] +
std::complex<double> (0, 1) * amp[583] + amp[584] + std::complex<double>
(0, 1) * amp[585] + amp[586] + std::complex<double> (0, 1) * amp[587] -
amp[602] - amp[601] - amp[605] - amp[604] - amp[608] - amp[607] -
amp[611] - amp[610] - std::complex<double> (0, 1) * amp[674] - amp[675] -
std::complex<double> (0, 1) * amp[676] + std::complex<double> (0, 1) *
amp[680] + std::complex<double> (0, 1) * amp[679] - std::complex<double>
(0, 1) * amp[683] - std::complex<double> (0, 1) * amp[685] + amp[686] +
std::complex<double> (0, 1) * amp[689] + std::complex<double> (0, 1) *
amp[688] - std::complex<double> (0, 1) * amp[692] - amp[693] -
std::complex<double> (0, 1) * amp[694] + std::complex<double> (0, 1) *
amp[698] + std::complex<double> (0, 1) * amp[697] - std::complex<double>
(0, 1) * amp[701] - std::complex<double> (0, 1) * amp[703] + amp[704] +
std::complex<double> (0, 1) * amp[707] + std::complex<double> (0, 1) *
amp[706] - std::complex<double> (0, 1) * amp[778] + std::complex<double>
(0, 1) * amp[784] - std::complex<double> (0, 1) * amp[782] +
std::complex<double> (0, 1) * amp[786] - std::complex<double> (0, 1) *
amp[787] + amp[788] + std::complex<double> (0, 1) * amp[793] -
std::complex<double> (0, 1) * amp[791] - std::complex<double> (0, 1) *
amp[796] + std::complex<double> (0, 1) * amp[802] - std::complex<double>
(0, 1) * amp[800] + std::complex<double> (0, 1) * amp[804] -
std::complex<double> (0, 1) * amp[805] + amp[806] + std::complex<double>
(0, 1) * amp[811] - std::complex<double> (0, 1) * amp[809] + amp[813] -
std::complex<double> (0, 1) * amp[814] + amp[815] - std::complex<double>
(0, 1) * amp[817] + amp[818] + amp[821] - std::complex<double> (0, 1) *
amp[822] + amp[823] - std::complex<double> (0, 1) * amp[825] + amp[826] -
std::complex<double> (0, 1) * amp[829] - std::complex<double> (0, 1) *
amp[830] - amp[831] + std::complex<double> (0, 1) * amp[836] +
std::complex<double> (0, 1) * amp[835] - std::complex<double> (0, 1) *
amp[839] + std::complex<double> (0, 1) * amp[845] + std::complex<double>
(0, 1) * amp[844] - std::complex<double> (0, 1) * amp[847] -
std::complex<double> (0, 1) * amp[848] - amp[849] + std::complex<double>
(0, 1) * amp[854] + std::complex<double> (0, 1) * amp[853] -
std::complex<double> (0, 1) * amp[857] + std::complex<double> (0, 1) *
amp[863] + std::complex<double> (0, 1) * amp[862] + amp[938] - amp[936] +
std::complex<double> (0, 1) * amp[941] - std::complex<double> (0, 1) *
amp[939] + std::complex<double> (0, 1) * amp[947] - std::complex<double>
(0, 1) * amp[945] + amp[950] - amp[948] + std::complex<double> (0, 1) *
amp[953] - std::complex<double> (0, 1) * amp[951] + std::complex<double>
(0, 1) * amp[959] - std::complex<double> (0, 1) * amp[957] +
std::complex<double> (0, 1) * amp[965] + std::complex<double> (0, 1) *
amp[964] - amp[968] - amp[967] + std::complex<double> (0, 1) * amp[971] +
std::complex<double> (0, 1) * amp[970] + std::complex<double> (0, 1) *
amp[977] + std::complex<double> (0, 1) * amp[976] - amp[980] - amp[979] +
std::complex<double> (0, 1) * amp[983] + std::complex<double> (0, 1) *
amp[982];
jamp[19] = +amp[324] + amp[330] + amp[353] + amp[354] + amp[356] + amp[359] +
amp[360] + amp[362] - std::complex<double> (0, 1) * amp[364] -
std::complex<double> (0, 1) * amp[365] - std::complex<double> (0, 1) *
amp[366] - std::complex<double> (0, 1) * amp[367] - amp[397] -
std::complex<double> (0, 1) * amp[398] - amp[400] - amp[403] -
std::complex<double> (0, 1) * amp[404] - amp[406] + std::complex<double>
(0, 1) * amp[408] + amp[409] + std::complex<double> (0, 1) * amp[410] +
amp[412] + std::complex<double> (0, 1) * amp[413] + std::complex<double>
(0, 1) * amp[414] + amp[415] + std::complex<double> (0, 1) * amp[416] +
amp[418] + std::complex<double> (0, 1) * amp[419] + amp[420] + amp[421] +
amp[423] + amp[424] + amp[426] + amp[427] + amp[429] + amp[430] +
amp[495] + amp[501] - std::complex<double> (0, 1) * amp[504] + amp[506] +
amp[508] - std::complex<double> (0, 1) * amp[510] + amp[512] + amp[514] +
std::complex<double> (0, 1) * amp[517] + amp[518] + std::complex<double>
(0, 1) * amp[519] + amp[520] + std::complex<double> (0, 1) * amp[521] +
std::complex<double> (0, 1) * amp[523] + amp[524] + std::complex<double>
(0, 1) * amp[525] + amp[526] + std::complex<double> (0, 1) * amp[527] -
amp[542] - amp[541] - amp[545] - amp[544] - amp[548] - amp[547] -
amp[551] - amp[550] - std::complex<double> (0, 1) * amp[726] - amp[727] -
std::complex<double> (0, 1) * amp[728] + std::complex<double> (0, 1) *
amp[732] + std::complex<double> (0, 1) * amp[731] - std::complex<double>
(0, 1) * amp[735] - std::complex<double> (0, 1) * amp[737] + amp[738] +
std::complex<double> (0, 1) * amp[741] + std::complex<double> (0, 1) *
amp[740] - std::complex<double> (0, 1) * amp[744] - amp[745] -
std::complex<double> (0, 1) * amp[746] + std::complex<double> (0, 1) *
amp[750] + std::complex<double> (0, 1) * amp[749] - std::complex<double>
(0, 1) * amp[753] - std::complex<double> (0, 1) * amp[755] + amp[756] +
std::complex<double> (0, 1) * amp[759] + std::complex<double> (0, 1) *
amp[758] - std::complex<double> (0, 1) * amp[780] + std::complex<double>
(0, 1) * amp[782] + std::complex<double> (0, 1) * amp[783] +
std::complex<double> (0, 1) * amp[785] - std::complex<double> (0, 1) *
amp[789] + amp[790] + std::complex<double> (0, 1) * amp[791] +
std::complex<double> (0, 1) * amp[792] - std::complex<double> (0, 1) *
amp[798] + std::complex<double> (0, 1) * amp[800] + std::complex<double>
(0, 1) * amp[801] + std::complex<double> (0, 1) * amp[803] -
std::complex<double> (0, 1) * amp[807] + amp[808] + std::complex<double>
(0, 1) * amp[809] + std::complex<double> (0, 1) * amp[810] - amp[813] +
std::complex<double> (0, 1) * amp[814] - amp[815] + std::complex<double>
(0, 1) * amp[817] - amp[818] - amp[821] + std::complex<double> (0, 1) *
amp[822] - amp[823] + std::complex<double> (0, 1) * amp[825] - amp[826] +
std::complex<double> (0, 1) * amp[829] + std::complex<double> (0, 1) *
amp[830] + amp[831] - std::complex<double> (0, 1) * amp[836] -
std::complex<double> (0, 1) * amp[835] + std::complex<double> (0, 1) *
amp[839] - std::complex<double> (0, 1) * amp[845] - std::complex<double>
(0, 1) * amp[844] + std::complex<double> (0, 1) * amp[847] +
std::complex<double> (0, 1) * amp[848] + amp[849] - std::complex<double>
(0, 1) * amp[854] - std::complex<double> (0, 1) * amp[853] +
std::complex<double> (0, 1) * amp[857] - std::complex<double> (0, 1) *
amp[863] - std::complex<double> (0, 1) * amp[862] + amp[936] + amp[937] +
std::complex<double> (0, 1) * amp[939] + std::complex<double> (0, 1) *
amp[940] + std::complex<double> (0, 1) * amp[945] + std::complex<double>
(0, 1) * amp[946] + amp[948] + amp[949] + std::complex<double> (0, 1) *
amp[951] + std::complex<double> (0, 1) * amp[952] + std::complex<double>
(0, 1) * amp[957] + std::complex<double> (0, 1) * amp[958] +
std::complex<double> (0, 1) * amp[989] + std::complex<double> (0, 1) *
amp[988] - amp[992] - amp[991] + std::complex<double> (0, 1) * amp[995] +
std::complex<double> (0, 1) * amp[994] + std::complex<double> (0, 1) *
amp[1001] + std::complex<double> (0, 1) * amp[1000] - amp[1004] -
amp[1003] + std::complex<double> (0, 1) * amp[1007] +
std::complex<double> (0, 1) * amp[1006];
jamp[20] = +amp[327] + amp[333] + amp[368] + amp[371] + amp[373] + amp[374] +
amp[377] + amp[379] + std::complex<double> (0, 1) * amp[380] +
std::complex<double> (0, 1) * amp[381] + std::complex<double> (0, 1) *
amp[382] + std::complex<double> (0, 1) * amp[383] + amp[385] +
std::complex<double> (0, 1) * amp[386] + amp[388] + amp[391] +
std::complex<double> (0, 1) * amp[392] + amp[394] - std::complex<double>
(0, 1) * amp[396] + amp[397] - std::complex<double> (0, 1) * amp[399] +
amp[400] - std::complex<double> (0, 1) * amp[401] - std::complex<double>
(0, 1) * amp[402] + amp[403] - std::complex<double> (0, 1) * amp[405] +
amp[406] - std::complex<double> (0, 1) * amp[407] - amp[422] - amp[421] -
amp[425] - amp[424] - amp[428] - amp[427] - amp[431] - amp[430] +
amp[553] + amp[559] + std::complex<double> (0, 1) * amp[564] - amp[566] -
amp[568] + std::complex<double> (0, 1) * amp[570] - amp[572] - amp[574] +
std::complex<double> (0, 1) * amp[588] - amp[590] + std::complex<double>
(0, 1) * amp[591] - amp[592] + std::complex<double> (0, 1) * amp[593] +
std::complex<double> (0, 1) * amp[594] - amp[596] + std::complex<double>
(0, 1) * amp[597] - amp[598] + std::complex<double> (0, 1) * amp[599] +
amp[602] - amp[600] + amp[605] - amp[603] + amp[608] - amp[606] +
amp[611] - amp[609] + std::complex<double> (0, 1) * amp[674] + amp[675] +
std::complex<double> (0, 1) * amp[676] - std::complex<double> (0, 1) *
amp[680] - std::complex<double> (0, 1) * amp[679] + std::complex<double>
(0, 1) * amp[683] + std::complex<double> (0, 1) * amp[685] - amp[686] -
std::complex<double> (0, 1) * amp[689] - std::complex<double> (0, 1) *
amp[688] + std::complex<double> (0, 1) * amp[692] + amp[693] +
std::complex<double> (0, 1) * amp[694] - std::complex<double> (0, 1) *
amp[698] - std::complex<double> (0, 1) * amp[697] + std::complex<double>
(0, 1) * amp[701] + std::complex<double> (0, 1) * amp[703] - amp[704] -
std::complex<double> (0, 1) * amp[707] - std::complex<double> (0, 1) *
amp[706] - std::complex<double> (0, 1) * amp[725] + std::complex<double>
(0, 1) * amp[726] + amp[727] - std::complex<double> (0, 1) * amp[732] +
std::complex<double> (0, 1) * amp[730] + std::complex<double> (0, 1) *
amp[735] - std::complex<double> (0, 1) * amp[741] + std::complex<double>
(0, 1) * amp[739] - std::complex<double> (0, 1) * amp[743] +
std::complex<double> (0, 1) * amp[744] + amp[745] - std::complex<double>
(0, 1) * amp[750] + std::complex<double> (0, 1) * amp[748] +
std::complex<double> (0, 1) * amp[753] - std::complex<double> (0, 1) *
amp[759] + std::complex<double> (0, 1) * amp[757] + amp[760] +
std::complex<double> (0, 1) * amp[762] + amp[764] + std::complex<double>
(0, 1) * amp[765] + amp[767] + amp[768] + std::complex<double> (0, 1) *
amp[770] + amp[772] + std::complex<double> (0, 1) * amp[773] + amp[775] +
std::complex<double> (0, 1) * amp[866] - std::complex<double> (0, 1) *
amp[872] - std::complex<double> (0, 1) * amp[871] + std::complex<double>
(0, 1) * amp[874] + std::complex<double> (0, 1) * amp[875] - amp[876] -
std::complex<double> (0, 1) * amp[881] - std::complex<double> (0, 1) *
amp[880] + std::complex<double> (0, 1) * amp[884] - std::complex<double>
(0, 1) * amp[890] - std::complex<double> (0, 1) * amp[889] +
std::complex<double> (0, 1) * amp[892] + std::complex<double> (0, 1) *
amp[893] - amp[894] - std::complex<double> (0, 1) * amp[899] -
std::complex<double> (0, 1) * amp[898] - amp[938] - amp[937] -
std::complex<double> (0, 1) * amp[941] - std::complex<double> (0, 1) *
amp[940] - std::complex<double> (0, 1) * amp[947] - std::complex<double>
(0, 1) * amp[946] - amp[950] - amp[949] - std::complex<double> (0, 1) *
amp[953] - std::complex<double> (0, 1) * amp[952] - std::complex<double>
(0, 1) * amp[959] - std::complex<double> (0, 1) * amp[958] -
std::complex<double> (0, 1) * amp[965] + std::complex<double> (0, 1) *
amp[963] + amp[968] - amp[966] - std::complex<double> (0, 1) * amp[971] +
std::complex<double> (0, 1) * amp[969] - std::complex<double> (0, 1) *
amp[977] + std::complex<double> (0, 1) * amp[975] + amp[980] - amp[978] -
std::complex<double> (0, 1) * amp[983] + std::complex<double> (0, 1) *
amp[981];
jamp[21] = +amp[326] + amp[332] + amp[337] + amp[338] + amp[340] + amp[343] +
amp[344] + amp[346] - std::complex<double> (0, 1) * amp[348] -
std::complex<double> (0, 1) * amp[349] - std::complex<double> (0, 1) *
amp[350] - std::complex<double> (0, 1) * amp[351] + std::complex<double>
(0, 1) * amp[396] - amp[397] + std::complex<double> (0, 1) * amp[399] -
amp[400] + std::complex<double> (0, 1) * amp[401] + std::complex<double>
(0, 1) * amp[402] - amp[403] + std::complex<double> (0, 1) * amp[405] -
amp[406] + std::complex<double> (0, 1) * amp[407] + amp[409] -
std::complex<double> (0, 1) * amp[411] + amp[412] + amp[415] -
std::complex<double> (0, 1) * amp[417] + amp[418] + amp[420] + amp[421] +
amp[423] + amp[424] + amp[426] + amp[427] + amp[429] + amp[430] +
amp[435] + amp[441] - std::complex<double> (0, 1) * amp[444] + amp[446] +
amp[448] - std::complex<double> (0, 1) * amp[450] + amp[452] + amp[454] +
std::complex<double> (0, 1) * amp[457] + amp[458] + std::complex<double>
(0, 1) * amp[459] + amp[460] + std::complex<double> (0, 1) * amp[461] +
std::complex<double> (0, 1) * amp[463] + amp[464] + std::complex<double>
(0, 1) * amp[465] + amp[466] + std::complex<double> (0, 1) * amp[467] -
amp[482] - amp[481] - amp[485] - amp[484] - amp[488] - amp[487] -
amp[491] - amp[490] + std::complex<double> (0, 1) * amp[725] -
std::complex<double> (0, 1) * amp[726] - amp[727] + std::complex<double>
(0, 1) * amp[732] - std::complex<double> (0, 1) * amp[730] -
std::complex<double> (0, 1) * amp[735] + std::complex<double> (0, 1) *
amp[741] - std::complex<double> (0, 1) * amp[739] + std::complex<double>
(0, 1) * amp[743] - std::complex<double> (0, 1) * amp[744] - amp[745] +
std::complex<double> (0, 1) * amp[750] - std::complex<double> (0, 1) *
amp[748] - std::complex<double> (0, 1) * amp[753] + std::complex<double>
(0, 1) * amp[759] - std::complex<double> (0, 1) * amp[757] - amp[760] -
std::complex<double> (0, 1) * amp[762] - amp[764] - std::complex<double>
(0, 1) * amp[765] - amp[767] - amp[768] - std::complex<double> (0, 1) *
amp[770] - amp[772] - std::complex<double> (0, 1) * amp[773] - amp[775] +
std::complex<double> (0, 1) * amp[830] + amp[831] + std::complex<double>
(0, 1) * amp[832] - std::complex<double> (0, 1) * amp[836] +
std::complex<double> (0, 1) * amp[834] + std::complex<double> (0, 1) *
amp[839] + std::complex<double> (0, 1) * amp[841] + amp[842] -
std::complex<double> (0, 1) * amp[845] + std::complex<double> (0, 1) *
amp[843] + std::complex<double> (0, 1) * amp[848] + amp[849] +
std::complex<double> (0, 1) * amp[850] - std::complex<double> (0, 1) *
amp[854] + std::complex<double> (0, 1) * amp[852] + std::complex<double>
(0, 1) * amp[857] + std::complex<double> (0, 1) * amp[859] + amp[860] -
std::complex<double> (0, 1) * amp[863] + std::complex<double> (0, 1) *
amp[861] + std::complex<double> (0, 1) * amp[868] + std::complex<double>
(0, 1) * amp[870] + std::complex<double> (0, 1) * amp[871] +
std::complex<double> (0, 1) * amp[873] + std::complex<double> (0, 1) *
amp[877] + amp[878] + std::complex<double> (0, 1) * amp[879] +
std::complex<double> (0, 1) * amp[880] + std::complex<double> (0, 1) *
amp[886] + std::complex<double> (0, 1) * amp[888] + std::complex<double>
(0, 1) * amp[889] + std::complex<double> (0, 1) * amp[891] +
std::complex<double> (0, 1) * amp[895] + amp[896] + std::complex<double>
(0, 1) * amp[897] + std::complex<double> (0, 1) * amp[898] + amp[936] +
amp[937] + std::complex<double> (0, 1) * amp[939] + std::complex<double>
(0, 1) * amp[940] + std::complex<double> (0, 1) * amp[945] +
std::complex<double> (0, 1) * amp[946] + amp[948] + amp[949] +
std::complex<double> (0, 1) * amp[951] + std::complex<double> (0, 1) *
amp[952] + std::complex<double> (0, 1) * amp[957] + std::complex<double>
(0, 1) * amp[958] - std::complex<double> (0, 1) * amp[1013] -
std::complex<double> (0, 1) * amp[1012] - amp[1016] - amp[1015] -
std::complex<double> (0, 1) * amp[1019] - std::complex<double> (0, 1) *
amp[1018] - std::complex<double> (0, 1) * amp[1025] -
std::complex<double> (0, 1) * amp[1024] - amp[1028] - amp[1027] -
std::complex<double> (0, 1) * amp[1031] - std::complex<double> (0, 1) *
amp[1030];
jamp[22] = +amp[329] + amp[335] + amp[352] + amp[355] + amp[357] + amp[358] +
amp[361] + amp[363] + std::complex<double> (0, 1) * amp[364] +
std::complex<double> (0, 1) * amp[365] + std::complex<double> (0, 1) *
amp[366] + std::complex<double> (0, 1) * amp[367] - std::complex<double>
(0, 1) * amp[384] + amp[385] - std::complex<double> (0, 1) * amp[387] +
amp[388] - std::complex<double> (0, 1) * amp[389] - std::complex<double>
(0, 1) * amp[390] + amp[391] - std::complex<double> (0, 1) * amp[393] +
amp[394] - std::complex<double> (0, 1) * amp[395] + amp[397] +
std::complex<double> (0, 1) * amp[398] + amp[400] + amp[403] +
std::complex<double> (0, 1) * amp[404] + amp[406] - amp[422] - amp[421] -
amp[425] - amp[424] - amp[428] - amp[427] - amp[431] - amp[430] +
amp[493] + amp[499] + std::complex<double> (0, 1) * amp[504] - amp[506] -
amp[508] + std::complex<double> (0, 1) * amp[510] - amp[512] - amp[514] +
std::complex<double> (0, 1) * amp[528] - amp[530] + std::complex<double>
(0, 1) * amp[531] - amp[532] + std::complex<double> (0, 1) * amp[533] +
std::complex<double> (0, 1) * amp[534] - amp[536] + std::complex<double>
(0, 1) * amp[537] - amp[538] + std::complex<double> (0, 1) * amp[539] +
amp[542] - amp[540] + amp[545] - amp[543] + amp[548] - amp[546] +
amp[551] - amp[549] - std::complex<double> (0, 1) * amp[673] +
std::complex<double> (0, 1) * amp[674] + amp[675] - std::complex<double>
(0, 1) * amp[680] + std::complex<double> (0, 1) * amp[678] +
std::complex<double> (0, 1) * amp[683] - std::complex<double> (0, 1) *
amp[689] + std::complex<double> (0, 1) * amp[687] - std::complex<double>
(0, 1) * amp[691] + std::complex<double> (0, 1) * amp[692] + amp[693] -
std::complex<double> (0, 1) * amp[698] + std::complex<double> (0, 1) *
amp[696] + std::complex<double> (0, 1) * amp[701] - std::complex<double>
(0, 1) * amp[707] + std::complex<double> (0, 1) * amp[705] + amp[708] +
std::complex<double> (0, 1) * amp[710] + amp[712] + std::complex<double>
(0, 1) * amp[713] + amp[715] + amp[716] + std::complex<double> (0, 1) *
amp[718] + amp[720] + std::complex<double> (0, 1) * amp[721] + amp[723] +
std::complex<double> (0, 1) * amp[726] + amp[727] + std::complex<double>
(0, 1) * amp[728] - std::complex<double> (0, 1) * amp[732] -
std::complex<double> (0, 1) * amp[731] + std::complex<double> (0, 1) *
amp[735] + std::complex<double> (0, 1) * amp[737] - amp[738] -
std::complex<double> (0, 1) * amp[741] - std::complex<double> (0, 1) *
amp[740] + std::complex<double> (0, 1) * amp[744] + amp[745] +
std::complex<double> (0, 1) * amp[746] - std::complex<double> (0, 1) *
amp[750] - std::complex<double> (0, 1) * amp[749] + std::complex<double>
(0, 1) * amp[753] + std::complex<double> (0, 1) * amp[755] - amp[756] -
std::complex<double> (0, 1) * amp[759] - std::complex<double> (0, 1) *
amp[758] + std::complex<double> (0, 1) * amp[902] - std::complex<double>
(0, 1) * amp[908] - std::complex<double> (0, 1) * amp[907] +
std::complex<double> (0, 1) * amp[910] + std::complex<double> (0, 1) *
amp[911] - amp[912] - std::complex<double> (0, 1) * amp[917] -
std::complex<double> (0, 1) * amp[916] + std::complex<double> (0, 1) *
amp[920] - std::complex<double> (0, 1) * amp[926] - std::complex<double>
(0, 1) * amp[925] + std::complex<double> (0, 1) * amp[928] +
std::complex<double> (0, 1) * amp[929] - amp[930] - std::complex<double>
(0, 1) * amp[935] - std::complex<double> (0, 1) * amp[934] - amp[938] -
amp[937] - std::complex<double> (0, 1) * amp[941] - std::complex<double>
(0, 1) * amp[940] - std::complex<double> (0, 1) * amp[947] -
std::complex<double> (0, 1) * amp[946] - amp[950] - amp[949] -
std::complex<double> (0, 1) * amp[953] - std::complex<double> (0, 1) *
amp[952] - std::complex<double> (0, 1) * amp[959] - std::complex<double>
(0, 1) * amp[958] - std::complex<double> (0, 1) * amp[989] +
std::complex<double> (0, 1) * amp[987] + amp[992] - amp[990] -
std::complex<double> (0, 1) * amp[995] + std::complex<double> (0, 1) *
amp[993] - std::complex<double> (0, 1) * amp[1001] + std::complex<double>
(0, 1) * amp[999] + amp[1004] - amp[1002] - std::complex<double> (0, 1) *
amp[1007] + std::complex<double> (0, 1) * amp[1005];
jamp[23] = +amp[328] + amp[334] + amp[336] + amp[339] + amp[341] + amp[342] +
amp[345] + amp[347] + std::complex<double> (0, 1) * amp[348] +
std::complex<double> (0, 1) * amp[349] + std::complex<double> (0, 1) *
amp[350] + std::complex<double> (0, 1) * amp[351] + std::complex<double>
(0, 1) * amp[384] - amp[385] + std::complex<double> (0, 1) * amp[387] -
amp[388] + std::complex<double> (0, 1) * amp[389] + std::complex<double>
(0, 1) * amp[390] - amp[391] + std::complex<double> (0, 1) * amp[393] -
amp[394] + std::complex<double> (0, 1) * amp[395] - amp[409] +
std::complex<double> (0, 1) * amp[411] - amp[412] - amp[415] +
std::complex<double> (0, 1) * amp[417] - amp[418] + amp[422] - amp[420] +
amp[425] - amp[423] + amp[428] - amp[426] + amp[431] - amp[429] +
amp[433] + amp[439] + std::complex<double> (0, 1) * amp[444] - amp[446] -
amp[448] + std::complex<double> (0, 1) * amp[450] - amp[452] - amp[454] +
std::complex<double> (0, 1) * amp[468] - amp[470] + std::complex<double>
(0, 1) * amp[471] - amp[472] + std::complex<double> (0, 1) * amp[473] +
std::complex<double> (0, 1) * amp[474] - amp[476] + std::complex<double>
(0, 1) * amp[477] - amp[478] + std::complex<double> (0, 1) * amp[479] +
amp[482] - amp[480] + amp[485] - amp[483] + amp[488] - amp[486] +
amp[491] - amp[489] + std::complex<double> (0, 1) * amp[673] -
std::complex<double> (0, 1) * amp[674] - amp[675] + std::complex<double>
(0, 1) * amp[680] - std::complex<double> (0, 1) * amp[678] -
std::complex<double> (0, 1) * amp[683] + std::complex<double> (0, 1) *
amp[689] - std::complex<double> (0, 1) * amp[687] + std::complex<double>
(0, 1) * amp[691] - std::complex<double> (0, 1) * amp[692] - amp[693] +
std::complex<double> (0, 1) * amp[698] - std::complex<double> (0, 1) *
amp[696] - std::complex<double> (0, 1) * amp[701] + std::complex<double>
(0, 1) * amp[707] - std::complex<double> (0, 1) * amp[705] - amp[708] -
std::complex<double> (0, 1) * amp[710] - amp[712] - std::complex<double>
(0, 1) * amp[713] - amp[715] - amp[716] - std::complex<double> (0, 1) *
amp[718] - amp[720] - std::complex<double> (0, 1) * amp[721] - amp[723] -
std::complex<double> (0, 1) * amp[830] - amp[831] - std::complex<double>
(0, 1) * amp[832] + std::complex<double> (0, 1) * amp[836] -
std::complex<double> (0, 1) * amp[834] - std::complex<double> (0, 1) *
amp[839] - std::complex<double> (0, 1) * amp[841] - amp[842] +
std::complex<double> (0, 1) * amp[845] - std::complex<double> (0, 1) *
amp[843] - std::complex<double> (0, 1) * amp[848] - amp[849] -
std::complex<double> (0, 1) * amp[850] + std::complex<double> (0, 1) *
amp[854] - std::complex<double> (0, 1) * amp[852] - std::complex<double>
(0, 1) * amp[857] - std::complex<double> (0, 1) * amp[859] - amp[860] +
std::complex<double> (0, 1) * amp[863] - std::complex<double> (0, 1) *
amp[861] - std::complex<double> (0, 1) * amp[904] + std::complex<double>
(0, 1) * amp[908] - std::complex<double> (0, 1) * amp[906] +
std::complex<double> (0, 1) * amp[909] - std::complex<double> (0, 1) *
amp[913] - amp[914] + std::complex<double> (0, 1) * amp[917] -
std::complex<double> (0, 1) * amp[915] - std::complex<double> (0, 1) *
amp[922] + std::complex<double> (0, 1) * amp[926] - std::complex<double>
(0, 1) * amp[924] + std::complex<double> (0, 1) * amp[927] -
std::complex<double> (0, 1) * amp[931] - amp[932] + std::complex<double>
(0, 1) * amp[935] - std::complex<double> (0, 1) * amp[933] + amp[938] -
amp[936] + std::complex<double> (0, 1) * amp[941] - std::complex<double>
(0, 1) * amp[939] + std::complex<double> (0, 1) * amp[947] -
std::complex<double> (0, 1) * amp[945] + amp[950] - amp[948] +
std::complex<double> (0, 1) * amp[953] - std::complex<double> (0, 1) *
amp[951] + std::complex<double> (0, 1) * amp[959] - std::complex<double>
(0, 1) * amp[957] + std::complex<double> (0, 1) * amp[1013] -
std::complex<double> (0, 1) * amp[1011] + amp[1016] - amp[1014] +
std::complex<double> (0, 1) * amp[1019] - std::complex<double> (0, 1) *
amp[1017] + std::complex<double> (0, 1) * amp[1025] -
std::complex<double> (0, 1) * amp[1023] + amp[1028] - amp[1026] +
std::complex<double> (0, 1) * amp[1031] - std::complex<double> (0, 1) *
amp[1029];
// Store the leading color flows for choice of color
for(int i = 0; i < ncolor; i++ )
jamp2[0][i] += real(jamp[i] * conj(jamp[i]));
return -1.;
}
double eeuugggg::get_jamp2(int i)
{
return jamp2[0][i];
}
int eeuugggg::colorstring(int i, int j)
{
static const int res[24][8] = {
{5, 6, 7, 8, 3, 4, 0, 0},
{5, 6, 8, 7, 3, 4, 0, 0},
{5, 7, 6, 8, 3, 4, 0, 0},
{5, 7, 8, 6, 3, 4, 0, 0},
{5, 8, 6, 7, 3, 4, 0, 0},
{5, 8, 7, 6, 3, 4, 0, 0},
{6, 5, 7, 8, 3, 4, 0, 0},
{6, 5, 8, 7, 3, 4, 0, 0},
{6, 7, 5, 8, 3, 4, 0, 0},
{6, 7, 8, 5, 3, 4, 0, 0},
{6, 8, 5, 7, 3, 4, 0, 0},
{6, 8, 7, 5, 3, 4, 0, 0},
{7, 5, 6, 8, 3, 4, 0, 0},
{7, 5, 8, 6, 3, 4, 0, 0},
{7, 6, 5, 8, 3, 4, 0, 0},
{7, 6, 8, 5, 3, 4, 0, 0},
{7, 8, 5, 6, 3, 4, 0, 0},
{7, 8, 6, 5, 3, 4, 0, 0},
{8, 5, 6, 7, 3, 4, 0, 0},
{8, 5, 7, 6, 3, 4, 0, 0},
{8, 6, 5, 7, 3, 4, 0, 0},
{8, 6, 7, 5, 3, 4, 0, 0},
{8, 7, 5, 6, 3, 4, 0, 0},
{8, 7, 6, 5, 3, 4, 0, 0}};
return res[i][j];
}
int eeuugggg::NCol()
{
static const int ncolor = 24;
return ncolor;
}
diff --git a/Shower/Dipole/Kinematics/FFMassiveKinematics.h b/Shower/Dipole/Kinematics/FFMassiveKinematics.h
--- a/Shower/Dipole/Kinematics/FFMassiveKinematics.h
+++ b/Shower/Dipole/Kinematics/FFMassiveKinematics.h
@@ -1,305 +1,299 @@
// -*- C++ -*-
//
// FFMassiveKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FFMassiveKinematics_H
#define HERWIG_FFMassiveKinematics_H
//
// This is the declaration of the FFMassiveKinematics class.
//
#include "DipoleSplittingKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer, Stephen Webster
*
* \brief FFMassiveKinematics implements massive splittings
* off a final-final dipole.
*
*/
class FFMassiveKinematics: public DipoleSplittingKinematics {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
FFMassiveKinematics();
/**
* The destructor.
*/
virtual ~FFMassiveKinematics();
//@}
public:
/**
* Return the boundaries in between the evolution
* variable random number is to be sampled; the lower
* cuoff is assumed to correspond to the infrared cutoff.
*/
virtual pair<double,double> kappaSupport(const DipoleSplittingInfo& dIndex) const;
/**
* Return the boundaries in between the momentum
* fraction random number is to be sampled.
*/
virtual pair<double,double> xiSupport(const DipoleSplittingInfo& dIndex) const;
/**
* Return the boundaries on the momentum fraction
*/
virtual pair<double,double> zBoundaries(Energy,
const DipoleSplittingInfo&,
const DipoleSplittingKernel&) const {
return {0.0,1.0};
}
/**
* Return the dipole scale associated to the
* given pair of emitter and spectator. This
* should be the invariant mass or absolute value
* final/final or initial/initial and the absolute
* value of the momentum transfer for intial/final or
* final/initial dipoles.
*/
virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double, double,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split,
tPPtr emitter, tPPtr spectator) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
// Only the DipoleSplittingInfo version should be used for massive
// dipoles, for now anyway.
assert(false);
return ZERO;
}
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
// Only the DipoleSplittingInfo version should be used for massive
// dipoles, for now anyway.
assert(false);
return ZERO;
}
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the random number associated to
* the given pt.
*/
virtual double ptToRandom(Energy pt, Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
DipoleSplittingInfo& dIndex,
const DipoleSplittingKernel& split);
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo);
public:
/**
* Triangular / Kallen function
*/
template <class T>
inline T rootOfKallen (T a, T b, T c) const {
if ( a*a + b*b + c*c - 2.*(a*b + a*c + b*c) > ZERO )
return sqrt(a*a + b*b + c*c - 2.*(a*b + a*c + b*c) ) ;
else
return ZERO; }
/**
* Perform a rotation on both momenta such that the first one will
* point along the (positive) z axis. Rotate back to the original
* reference frame by applying rotateUz(returnedVector) to each momentum.
*/
ThreeVector<double> rotateToZ (Lorentz5Momentum& pTarget, Lorentz5Momentum& p1){
ThreeVector<double> oldAxis = pTarget.vect().unit();
double ct = oldAxis.z(); double st = sqrt( 1.-sqr(ct) ); // cos,sin(theta)
double cp = oldAxis.x()/st; double sp = oldAxis.y()/st; // cos,sin(phi)
pTarget.setZ( pTarget.vect().mag() ); pTarget.setX( 0.*GeV ); pTarget.setY( 0.*GeV );
Lorentz5Momentum p1old = p1;
p1.setX( sp*p1old.x() - cp*p1old.y() );
p1.setY( ct*cp*p1old.x() + ct*sp*p1old.y() - st*p1old.z() );
p1.setZ( st*cp*p1old.x() + st*sp*p1old.y() + ct*p1old.z() );
return oldAxis;
}
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;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FFMassiveKinematics> initFFMassiveKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FFMassiveKinematics & operator=(const FFMassiveKinematics &) = delete;
-
- /**
- * Option to use the full jacobian, including the z->zprime jacobian.
- **/
- bool theFullJacobian;
-
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FFMassiveKinematics. */
template <>
struct BaseClassTrait<Herwig::FFMassiveKinematics,1> {
/** Typedef of the first base class of FFMassiveKinematics. */
typedef Herwig::DipoleSplittingKinematics NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FFMassiveKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FFMassiveKinematics>
: public ClassTraitsBase<Herwig::FFMassiveKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FFMassiveKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* FFMassiveKinematics is implemented. It may also include several, space-separated,
* libraries if the class FFMassiveKinematics depends on other classes (base classes
* excepted). In this case the listed libraries will be dynamically
* linked in the order they are specified.
*/
static string library() { return "HwDipoleShower.so"; }
};
/** @endcond */
}
#endif /* HERWIG_FFMassiveKinematics_H */
diff --git a/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.h b/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.h
--- a/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.h
+++ b/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.h
@@ -1,331 +1,327 @@
// -*- C++ -*-
//
// FIMassiveDecayKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FIMassiveDecayKinematics_H
#define HERWIG_FIMassiveDecayKinematics_H
//
// This is the declaration of the FIMassiveDecayKinematics class.
//
#include "DipoleSplittingKinematics.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Utilities/UtilityBase.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Stephen Webster
*
* \brief FIMassiveDecayKinematics implements massive splittings
* off a final-initial decay dipole.
*
*/
class FIMassiveDecayKinematics: public DipoleSplittingKinematics {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
FIMassiveDecayKinematics();
/**
* The destructor.
*/
virtual ~FIMassiveDecayKinematics();
//@}
public:
/**
* Return the boundaries in between the evolution
* variable random number is to be sampled; the lower
* cuoff is assumed to correspond to the infrared cutoff.
*/
virtual pair<double,double> kappaSupport(const DipoleSplittingInfo& dIndex) const;
/**
* Return the boundaries in between the momentum
* fraction random number is to be sampled.
*/
virtual pair<double,double> xiSupport(const DipoleSplittingInfo& dIndex) const;
/**
* Return the boundaries on the momentum fraction
*/
virtual pair<double,double> zBoundaries(Energy,
const DipoleSplittingInfo&,
const DipoleSplittingKernel&) const {
return {0.0,1.0};
}
/**
* Return the dipole scale associated to the
* given pair of emitter and spectator. This
* should be the invariant mass or absolute value
* final/final or initial/initial and the absolute
* value of the momentum transfer for intial/final or
* final/initial dipoles.
*/
virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const;
/**
* Return the mass of the system absorbing
* the recoil in the dipole splitting.
* This is only used in decay dipoles.
*/
virtual Energy recoilMassKin(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double, double,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split,
tPPtr emitter, tPPtr spectator) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
// Only the DipoleSplittingInfo version should be used for the decays.
assert(false);
return ZERO;
}
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
// Only the DipoleSplittingInfo version should be used for the decays.
assert(false);
return ZERO;
}
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the random number associated to
* the given pt.
*/
virtual double ptToRandom(Energy pt, Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
DipoleSplittingInfo& info,
const DipoleSplittingKernel& split);
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo);
/**
* Return the nVector as required for spin correlations.
*/
virtual Lorentz5Momentum nVector(const Lorentz5Momentum& pEmitter, const Lorentz5Momentum& pSpectator, const DipoleSplittingInfo& dInfo) const;
/*
* Return true if this splitting is of a dipole which contains
* a decayed parton and requires the remnant to absorb the recoil.
*/
virtual bool isDecay() const { return true; }
/**
* Perform the recoil in the case of a decayed parton
*/
virtual void decayRecoil ( PList& recoilSystem ) {
PList::iterator beginRecoil = recoilSystem.begin();
PList::iterator endRecoil = recoilSystem.end();
// This is the final momentum that we must transform the system to
const Momentum3 transformMom = splitRecoilMomentum().vect();
// Calculate required Lorentz rotation
Lorentz5Momentum sum = ThePEG::UtilityBase::sumMomentum(beginRecoil, endRecoil);
LorentzRotation rot = ThePEG::UtilityBase::transformToCMS(sum);
rot = ThePEG::UtilityBase::transformFromCMS
(Lorentz5Momentum(transformMom, sqrt(transformMom.mag2() + sum.m2()))) * rot;
// Transform the particle spinInfo if required
for ( const auto& p : recoilSystem ) {
if ( p->spinInfo() )
p->spinInfo()->transform(p->momentum(),rot);
}
ThePEG::UtilityBase::transform(beginRecoil, endRecoil, rot );
}
public:
/**
* Triangular / Kallen function
*/
template <class T>
inline T rootOfKallen (T a, T b, T c) const {
if ( a*a + b*b + c*c - 2.*(a*b + a*c + b*c) > ZERO )
return sqrt(a*a + b*b + c*c - 2.*(a*b + a*c + b*c) ) ;
else
return ZERO; }
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;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FIMassiveDecayKinematics> initFIMassiveDecayKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FIMassiveDecayKinematics & operator=(const FIMassiveDecayKinematics &) = delete;
-
- /**
- * Option to use the full jacobian, including the z->zprime jacobian.
- **/
- bool theFullJacobian;
+
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FIMassiveDecayKinematics. */
template <>
struct BaseClassTrait<Herwig::FIMassiveDecayKinematics,1> {
/** Typedef of the first base class of FIMassiveDecayKinematics. */
typedef Herwig::DipoleSplittingKinematics NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FIMassiveDecayKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FIMassiveDecayKinematics>
: public ClassTraitsBase<Herwig::FIMassiveDecayKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FIMassiveDecayKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* FIMassiveDecayKinematics is implemented. It may also include several, space-separated,
* libraries if the class FIMassiveDecayKinematics depends on other classes (base classes
* excepted). In this case the listed libraries will be dynamically
* linked in the order they are specified.
*/
static string library() { return "HwDipoleShower.so"; }
};
/** @endcond */
}
#endif /* HERWIG_FIMassiveDecayKinematics_H */
diff --git a/Shower/Dipole/Merging/Node.cc b/Shower/Dipole/Merging/Node.cc
--- a/Shower/Dipole/Merging/Node.cc
+++ b/Shower/Dipole/Merging/Node.cc
@@ -1,489 +1,489 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the Node class.
//
#include "Node.h"
#include "MergingFactory.h"
#include "Merger.h"
using namespace Herwig;
Node::Node(MatchboxMEBasePtr nodeME, int cutstage, MergerPtr mh)
:Interfaced(),
thenodeMEPtr(nodeME),
thedipol(),
theparent(),
theCutStage(cutstage),
- isOrdered(true),
+ //isOrdered(true),
theSubtractedReal(false),
theVirtualContribution(false),
theMergingHelper(mh)
{
nodeME->maxMultCKKW(1);
nodeME->minMultCKKW(0);
}
Node::Node(NodePtr deephead,
NodePtr head,
SubtractionDipolePtr dipol,
MatchboxMEBasePtr nodeME,
int cutstage)
:Interfaced(), thenodeMEPtr(nodeME),
thedipol(dipol),
theparent(head),
theDeepHead(deephead),
theCutStage(cutstage),
-isOrdered(true),
+//isOrdered(true),
theSubtractedReal(false),
theVirtualContribution(false),
theMergingHelper() //The subnodes have no merging helper
{
}
Node::~Node() { }
SubtractionDipolePtr Node::dipole() const {
return thedipol;
}
/** returns the matrix element pointer */
const MatchboxMEBasePtr Node::nodeME() const {
return thenodeMEPtr;
}
/** access the matrix element pointer */
MatchboxMEBasePtr Node::nodeME() {
return thenodeMEPtr;
}
pair<PVector , PVector> Node::getInOut( ){
PVector in;
const auto me= nodeME();
const auto pd=me->mePartonData();
for( auto i : {0 , 1} )
in.push_back(pd[i]->produceParticle( me->lastMEMomenta()[i] ) );
PVector out;
for ( size_t i = 2;i< pd.size();i++ ){
PPtr p = pd[i]->produceParticle( me->lastMEMomenta()[i] );
out.push_back( p );
}
return { in , out };
}
int Node::legsize() const {return nodeME()->legsize();}
NodePtr Node::randomChild() {
return thechildren[UseRandom::irnd(thechildren.size())];
}
bool Node::allAbove(Energy pt) {
for (NodePtr child : thechildren)
if ( child->pT() < pt )
return false;
return true;
}
Energy Node::maxChildPt(){
Energy maxi=-1*GeV;
for (NodePtr child : thechildren)maxi=max(child->pT(),maxi);
return maxi;
}
bool Node::isInHistoryOf(NodePtr other) {
while (other->parent()) {
if (other == this)
return true;
other = other->parent();
}
return false;
}
void Node::flushCaches() {
if (didflush) return;
didflush=true;
for ( auto const & ch: thechildren) {
ch->xcomb()->clean();
ch->nodeME()->flushCaches();
ch->flushCaches();
}
}
void Node::setKinematics() {
for (auto const & ch: thechildren) {
ch->dipole()->setXComb(ch->xcomb());
ch->dipole()->setKinematics();
ch->nodeME()->setKinematics();
ch->setKinematics();
}
}
void Node::clearKinematics() {
for (auto const & ch: thechildren) {
ch->dipole()->setXComb(ch->xcomb());
ch->nodeME()->clearKinematics();
ch->dipole()->clearKinematics();
ch->clearKinematics();
}
}
bool Node::generateKinematics(const double *r, bool directCut) {
didflush=false;
// If there are no children to the child process we are done.
if(children().empty()) return true;
assert(parent());
if ( ! directCut && pT() < deepHead()->MH()->mergePt()) {
// Real emission:
// If there are children to the child process,
// we now require that all subsequent children
// with pt < merging scale are in their ME region.
// Since the possible children of the real emission
// contribution are now in their ME region,
// it is clear that a second clustering is possible
// -- modulo phase space restrictions.
// Therefore the real emission contribution
// are unitarised and the cross section is
// hardly modified.
auto inOutPair = getInOut();
NodePtr rc = randomChild();
rc->dipole()->setXComb(rc->xcomb());
if(!rc->dipole()->generateKinematics(r))assert(false);
// If not in ME -> return false
if(!deepHead()->MH()->matrixElementRegion( inOutPair.first ,
inOutPair.second ,
rc->pT() ,
deepHead()->MH()->mergePt() ) )return false;
}
for (auto & ch : children() ) {
ch->dipole()->setXComb(ch->xcomb());
if ( !ch->dipole()->generateKinematics(r) ) { assert(false); }
ch->generateKinematics( r, true);
}
return true;
}
bool Node::firstgenerateKinematics(const double *r, bool directCut) {
didflush=false;
// This is called form the merging helper for the first node. So:
assert(!parent());
assert(xcomb());
if(MH()->treefactory()->nonQCDCuts()){
tcPDVector outdata(xcomb()->mePartonData().begin()+2,
xcomb()->mePartonData().end());
vector<LorentzMomentum> outmomenta(xcomb()->meMomenta().begin()+2,
xcomb()->meMomenta().end());
if ( !MH()->treefactory()->nonQCDCuts()->passCuts(outdata,outmomenta,
xcomb()->mePartonData()[0],
xcomb()->mePartonData()[1]) )
return false;
}
///// This should not be needed!!!
///// ( Warning inMerger::matrixElementRegion gets triggered.)
flushCaches();
//Set here the new merge Pt for the next phase space point.( Smearing!!!)
MH()->smearMergePt();
// If there are no children to this node, we are done here:
if (children().empty())
return true;
// directCut is for born and for virtual contributions.
// if directCut is true, then cut on the first ME region.
// call recursiv generate kinematics for subsequent nodes.
if ( directCut ){
auto inOutPair = getInOut();
NodePtr rc = randomChild();
rc->dipole()->setXComb(rc->xcomb());
if ( !rc->dipole()->generateKinematics(r) ) { return false; }
rc->nodeME()->setXComb(rc->xcomb());
if(MH()->gamma() == 1.){
if(!MH()->matrixElementRegion( inOutPair.first ,
inOutPair.second ,
rc->pT() ,
MH()->mergePt() ) ){
return false;
}
}else{
// Different treatment if gamma is not 1.
// Since the dipoles need to be calculated always
// their alpha region is touched.
// AlphaRegion != MERegion !!!
bool inAlphaPS = false;
for (auto const & ch: thechildren) {
ch->dipole()->setXComb(ch->xcomb());
if ( !ch->dipole()->generateKinematics(r) )
return false;
MH()->treefactory()->setAlphaParameter( MH()->gamma() );
inAlphaPS |= ch->dipole()->aboveAlpha();
MH()->treefactory()->setAlphaParameter( 1. );
}
NodePtr rc = randomChild();
if(!inAlphaPS&&
!MH()->matrixElementRegion( inOutPair.first ,
inOutPair.second ,
rc->pT() ,
MH()->mergePt() ) )
return false;
}
}
for (auto const & ch: thechildren) {
ch->dipole()->setXComb(ch->xcomb());
if ( !ch->dipole()->generateKinematics(r) ) { cout<<"\nCould not generate dipole kinematics";;return false; }
if( ! ch->generateKinematics(r,directCut) )return false;
}
return true;
}
StdXCombPtr Node::xcomb() const {
assert(thexcomb);
return thexcomb;
}
StdXCombPtr Node::xcomb(){
if(thexcomb)return thexcomb;
assert(parent());
thexcomb=dipole()->makeBornXComb(parent()->xcomb());
xcomb()->head(parent()->xcomb());
dipole()->setXComb(thexcomb);
return thexcomb;
}
void Node::setXComb(tStdXCombPtr xc) {
assert ( !parent() );
thexcomb=xc;
assert(thexcomb->lastParticles().first);
}
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
void Node::birth(const vector<MatchboxMEBasePtr> & vec) {
// produce the children
vector<SubtractionDipolePtr> dipoles =
nodeME()->getDipoles(DipoleRepository::dipoles(
nodeME()->factory()->dipoleSet()), vec, true);
for ( auto const & dip : dipoles ) {
dip->doSubtraction();
NodePtr node = new_ptr(Node(theDeepHead,
this,
dip,
dip->underlyingBornME(),
theDeepHead->cutStage()));
thechildren.push_back(node);
}
}
vector<NodePtr> Node::getNextOrderedNodes(bool normal, double hardScaleFactor) const {
vector<NodePtr> temp = children();
vector<NodePtr> res;
for (NodePtr const & child : children()) {
if(deepHead()->MH()->mergePt()>child->pT()) {
res.clear();
return res;
}
}
for (NodePtr const & child: children()) {
if (parent()&& normal) {
if ( child->pT() < pT() ) {
continue;
}
}
if ( child->children().size() != 0 ) {
for (NodePtr itChild: child->children()) {
if( itChild->pT() > child->pT()&&child->inShowerPS(itChild->pT()) ) {
res.push_back(child);
break;
}
}
}
else {
const auto sc=child->nodeME()->factory()->scaleChoice();
sc->setXComb(child->xcomb());
if ( sqr(hardScaleFactor)*
sc->renormalizationScale() >= sqr(child->pT()) &&
child->inShowerPS(hardScaleFactor*sqrt(sc->renormalizationScale()))) {
res.push_back(child);
}
}
}
return res;
}
bool Node::inShowerPS(Energy hardpT)const {
// Here we decide if the current phase space
// point can be reached from the underlying Node.
// Full phase space available -> Tilde Kinematic is always fine.
if(deepHead()->MH()->openZBoundaries()==1)
return true;
double z_ = dipole()->lastZ();
// restrict according to hard scale
if(deepHead()->MH()->openZBoundaries()==0){
pair<double, double> zbounds =
dipole()->tildeKinematics()->zBounds(pT(), hardpT);
return (zbounds.first<z_&&z_<zbounds.second);
}
assert(false);
}
NodePtr Node::getHistory(bool normal, double hardScaleFactor) {
NodePtr res = this;
vector<NodePtr> temp = getNextOrderedNodes(normal, hardScaleFactor);
Energy minpt = Constants::MaxEnergy;
Selector<NodePtr> subprosel;
while (temp.size() != 0) {
minpt = Constants::MaxEnergy;
subprosel.clear();
for (NodePtr const & child : temp) {
assert(deepHead()->MH()->largeNBasis());
if( child->dipole()->underlyingBornME()->largeNColourCorrelatedME2(
{child->dipole()->bornEmitter(),
child->dipole()->bornSpectator()},
deepHead()->MH()->largeNBasis()) != 0.
) {
double weight = 1.;
if ( deepHead()->MH()->chooseHistory() == 0 )
weight = abs(child->dipole()->dSigHatDR()/nanobarn);
else if ( deepHead()->MH()->chooseHistory() == 1 )
weight = abs(child->dipole()->dSigHatDR()/child->nodeME()->dSigHatDRB());
else if ( deepHead()->MH()->chooseHistory() == 2 )
weight = 1.;
else if ( deepHead()->MH()->chooseHistory() == 3 )
weight = 1_GeV/child->pT();
else
assert(false);
if(weight != 0.) {
subprosel.insert(weight , child);
minpt = min(minpt, child->pT());
}
}
}
if (subprosel.empty())
return res;
res = subprosel.select(UseRandom::rnd());
temp = res->getNextOrderedNodes(true, hardScaleFactor);
}
return res;
}
pair<CrossSection, CrossSection> Node::calcDipandPS(Energy scale)const {
return dipole()->dipandPs(sqr(scale), deepHead()->MH()->largeNBasis());
}
CrossSection Node::calcPs(Energy scale)const {
return dipole()->ps(sqr(scale), deepHead()->MH()->largeNBasis());
}
CrossSection Node::calcDip(Energy scale)const {
return dipole()->dip(sqr(scale));
}
IBPtr Node::clone() const {
return new_ptr(*this);
}
IBPtr Node::fullclone() const {
return new_ptr(*this);
}
#include "ThePEG/Persistency/PersistentOStream.h"
void Node::persistentOutput(PersistentOStream & os) const {
os <<
thexcomb<<
thenodeMEPtr<<
thedipol<<
thechildren<<
theparent<<
theProjector<<
theDeepHead<<
theCutStage<<
ounit(theRunningPt, GeV)<<
theSubtractedReal<<
theVirtualContribution<<
theMergingHelper;
}
#include "ThePEG/Persistency/PersistentIStream.h"
void Node::persistentInput(PersistentIStream & is, int) {
is >>
thexcomb>>
thenodeMEPtr>>
thedipol>>
thechildren>>
theparent>>
theProjector>>
theDeepHead>>
theCutStage>>
iunit(theRunningPt, GeV)>>
theSubtractedReal>>
theVirtualContribution>>
theMergingHelper;
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
#include "ThePEG/Utilities/DescribeClass.h"
DescribeClass<Node, Interfaced>
describeHerwigNode("Herwig::Node", "HwDipoleShower.so");
void Node::Init() {
static ClassDocumentation<Node>
documentation("There is no documentation for the Node class");
}
diff --git a/Shower/Dipole/Merging/Node.h b/Shower/Dipole/Merging/Node.h
--- a/Shower/Dipole/Merging/Node.h
+++ b/Shower/Dipole/Merging/Node.h
@@ -1,237 +1,237 @@
// -*- C++ -*-
#ifndef Herwig_Node_H
#define Herwig_Node_H
//
// This is the declaration of the Node class.
//
#include "Node.fh"
#include "MergingFactory.fh"
#include "Merger.h"
#include "ThePEG/Config/ThePEG.h"
#include "ThePEG/Config/std.h"
#include "ThePEG/Interface/Interfaced.h"
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxMEBase.fh"
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.fh"
#include "Herwig/Shower/Dipole/Base/DipoleEventRecord.h"
#include "ThePEG/MatrixElement/MEBase.h"
#include <vector>
namespace Herwig {
using namespace ThePEG;
/**
* Here is the documentation of the Node class.
*
* @see \ref NodeInterfaces "The interfaces"
* defined for Node.
*/
class Node : public Interfaced {
public:
/** @name Standard constructors and destructors. */
//@{
Node (){};
// constructor for first nodes
Node(MatchboxMEBasePtr nodeME , int cutstage , MergerPtr mh );
// another constructor for underlying nodes
Node(NodePtr deephead,
NodePtr head,
SubtractionDipolePtr dipol,
MatchboxMEBasePtr nodeME,
int cutstage);
/// The destructor.
virtual ~Node();
//@}
public:
// get children from vector<MatchboxMEBasePtr>
void birth(const vector<MatchboxMEBasePtr> & vec);
/// recursive setXComb. proStage is the number of clusterings
/// before the projectors get filled.
void setXComb(tStdXCombPtr xc);
/// calculate the dipole and ps approximation
pair<CrossSection, CrossSection> calcDipandPS(Energy scale)const;
/// calculate the ps approximation
CrossSection calcPs(Energy scale)const;
/// calculate the dipole
CrossSection calcDip(Energy scale)const;
/// recursive flush caches and clean up XCombs.
void flushCaches();
/// recursive clearKinematics
void clearKinematics();
/// recursive setKinematics
void setKinematics();
/// recursive generateKinematics using tilde kinematics of the dipoles
bool generateKinematics(const double *r, bool directCut);
/// generate the kinamatics of the first node
bool firstgenerateKinematics(const double *r, bool directCut);
//return the ME
const MatchboxMEBasePtr nodeME() const;
//return the node ME
MatchboxMEBasePtr nodeME();
//return the parent Node
NodePtr parent() const {return theparent;}
/// vector of children nodes created in birth
vector< NodePtr > children() const {return thechildren;}
//pick a random child (flat)
NodePtr randomChild();
/// true if all children show scales above pt
bool allAbove(Energy pt);
/// return maximum of all child pts.
Energy maxChildPt();
/// true if the node is in the history of other.
bool isInHistoryOf(NodePtr other);
/// legsize of the node ME
int legsize() const;
/// set the first node (first men). only use in factory
void deepHead(NodePtr deephead) {theDeepHead = deephead;}
/// return the first node
NodePtr deepHead() const {return theDeepHead;}
/// returns the dipol of the node.
SubtractionDipolePtr dipole() const;
/// return the xcomb
StdXCombPtr xcomb() const;
/// return the xcomb (if not created, create one from head)
StdXCombPtr xcomb() ;
/// return the current running pt
Energy runningPt() const { return theRunningPt; }
/// set the current running pt
void runningPt(Energy x) { theRunningPt=x; }
/// return the cut stage to cut on merging pt in generate kinematics
int cutStage() const { return theCutStage; }
/// get a vector of the next nodes, ordered in pt (and in parton shower phace space)
vector<NodePtr> getNextOrderedNodes(bool normal=true, double hardscalefactor=1.) const;
//true if the node is in shower history for a given pt
bool inShowerPS(Energy hardpt)const;
//get the history
NodePtr getHistory(bool normal=true, double hardscalefactor=1.);
//true if node correspond to a subtracted real.
bool subtractedReal() const {return theSubtractedReal;}
/// set if node correspont to a subtracted real.
void subtractedReal(bool x) { theSubtractedReal = x;}
//true if node correspond to a virtual contribution.
bool virtualContribution() const { return theVirtualContribution ;}
/// set if node correspont to a virtual contribution.
void virtualContribution(bool x) {theVirtualContribution = x;}
//pointer to the merging helper
MergerPtr MH()const{return theMergingHelper;}
/// set the merging helper
void MH(MergerPtr a){theMergingHelper=a;}
/// pT of the dipole
Energy pT()const{return dipole()->lastPt();}
/// get incoming and outgoing particles (TODO: expensive)
pair<PVector , PVector> getInOut();
private:
/// the Matrixelement representing this node.
MatchboxMEBasePtr thenodeMEPtr;
/// the dipol used to substract
/// and generate kinematics using tilde kinematics
SubtractionDipolePtr thedipol;
/// the parent node
NodePtr theparent;
/// The godfather node of whole tree.(Firstnode)
NodePtr theDeepHead;
/**
* The CutStage is number of clusterings which are possible without
* introducing a merging scale to cut away singularities.
* -> subtracted MEs have the CutStage 1.
* -> virtual and normal tree level ME get 0.
*/
int theCutStage;
/// tell if node belongs to an ordered history
- bool isOrdered;
+ // bool isOrdered;
/// flag to tell if node is subtracted real
bool theSubtractedReal;
/// flag to tell if node is virtual contribution
bool theVirtualContribution;
/// the merging helper
MergerPtr theMergingHelper;
//the xcomb of the node
StdXCombPtr thexcomb;
/// vector of the children node
vector< NodePtr > thechildren;
/// the current running pt
Energy theRunningPt;
/// The nodes of the projection stage.
NodePtr theProjector;
/// flag not to enter infinite loop. (There should be a better solution...)
bool didflush=false;
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;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
Node & operator=(const Node &) = delete;
};
}
#endif /* Herwig_Node_H */
diff --git a/Shower/QTilde/QTildeShowerHandler.h b/Shower/QTilde/QTildeShowerHandler.h
--- a/Shower/QTilde/QTildeShowerHandler.h
+++ b/Shower/QTilde/QTildeShowerHandler.h
@@ -1,846 +1,841 @@
// -*- C++ -*-
#ifndef Herwig_QTildeShowerHandler_H
#define Herwig_QTildeShowerHandler_H
//
// This is the declaration of the QTildeShowerHandler class.
//
#include "QTildeShowerHandler.fh"
#include "Herwig/Shower/ShowerHandler.h"
#include "Herwig/Shower/QTilde/SplittingFunctions/SplittingGenerator.h"
#include "Herwig/Shower/QTilde/Base/ShowerTree.h"
#include "Herwig/Shower/QTilde/Base/ShowerProgenitor.fh"
#include "Herwig/Shower/QTilde/Base/HardTree.h"
#include "Herwig/Shower/QTilde/Base/Branching.h"
#include "Herwig/Shower/QTilde/Base/ShowerVeto.h"
#include "Herwig/Shower/QTilde/Base/FullShowerVeto.h"
#include "Herwig/Shower/QTilde/Kinematics/KinematicsReconstructor.fh"
#include "Herwig/Shower/QTilde/Base/PartnerFinder.fh"
#include "Herwig/Shower/QTilde/SplittingFunctions/SudakovFormFactor.fh"
#include "Herwig/MatrixElement/HwMEBase.h"
#include "Herwig/Decay/HwDecayerBase.h"
#include "Herwig/MatrixElement/Matchbox/Matching/ShowerApproximation.h"
#include "Herwig/Shower/RealEmissionProcess.h"
#include "Herwig/Utilities/Statistic.h"
namespace Herwig {
using namespace ThePEG;
/**
* The QTildeShowerHandler class.
*
* @see \ref QTildeShowerHandlerInterfaces "The interfaces"
* defined for QTildeShowerHandler.
*/
class QTildeShowerHandler: public ShowerHandler {
public:
/**
* Pointer to an XComb object
*/
typedef Ptr<XComb>::pointer XCPtr;
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
QTildeShowerHandler();
/**
* The destructor.
*/
virtual ~QTildeShowerHandler();
//@}
public:
/**
* At the end of the Showering, transform ShowerParticle objects
* into ThePEG particles and fill the event record with them.
* Notice that the parent/child relationships and the
* transformation from ShowerColourLine objects into ThePEG
* ColourLine ones must be properly handled.
*/
void fillEventRecord();
/**
* Return the relevant hard scale to be used in the profile scales
*/
virtual Energy hardScale() const {
return muPt;
}
/**
* Hook to allow vetoing of event after showering hard sub-process
* as in e.g. MLM merging.
*/
virtual bool showerHardProcessVeto() const { return false; }
/**
* Generate hard emissions for CKKW etc
*/
virtual HardTreePtr generateCKKW(ShowerTreePtr tree) const;
/**
* Members to perform the shower
*/
//@{
/**
* Perform the shower of the hard process
*/
virtual void showerHardProcess(ShowerTreePtr,XCPtr);
/**
* Perform the shower of a decay
*/
virtual void showerDecay(ShowerTreePtr);
//@}
/**
* Access to the flags and shower variables
*/
//@{
/**
* Get the SplittingGenerator
*/
tSplittingGeneratorPtr splittingGenerator() const { return _splittingGenerator; }
/**
* Mode for hard emissions
*/
int hardEmission() const {return _hardEmission;}
//@}
/**
* Connect the Hard and Shower trees
*/
virtual void connectTrees(ShowerTreePtr showerTree, HardTreePtr hardTree, bool hard );
/**
* Access to switches for spin correlations
*/
//@{
/**
* Soft correlations
*/
unsigned int softCorrelations() const {
return _softOpt;
}
/**
* Any correlations
*/
virtual bool correlations() const {
return spinCorrelations()!=0||_softOpt!=0;
}
//@}
public:
/**
* Access methods to access the objects
*/
//@{
/**
* Access to the KinematicsReconstructor object
*/
tKinematicsReconstructorPtr kinematicsReconstructor() const { return _reconstructor; }
/**
* Access to the PartnerFinder object
*/
tPartnerFinderPtr partnerFinder() const { return _partnerfinder; }
//@}
protected:
/**
* Perform the shower
*/
void doShowering(bool hard,XCPtr);
/**
* Generate the hard matrix element correction
*/
virtual RealEmissionProcessPtr hardMatrixElementCorrection(bool);
/**
* Generate the hardest emission
*/
virtual void hardestEmission(bool hard);
/**
* Set up for applying a matrix element correction
*/
void setupMECorrection(RealEmissionProcessPtr real);
/**
* Extract the particles to be showered, set the evolution scales
* and apply the hard matrix element correction
* @param hard Whether this is a hard process or decay
* @return The particles to be showered
*/
virtual vector<ShowerProgenitorPtr> setupShower(bool hard);
/**
* set the colour partners
*/
virtual void setEvolutionPartners(bool hard,ShowerInteraction,
bool clear);
/**
* Methods to perform the evolution of an individual particle, including
* recursive calling on the products
*/
//@{
/**
* It does the forward evolution of the time-like input particle
* (and recursively for all its radiation products).
* accepting only emissions which conforms to the showerVariables
* and soft matrix element correction.
* If at least one emission has occurred then the method returns true.
* @param particle The particle to be showered
*/
virtual bool timeLikeShower(tShowerParticlePtr particle, ShowerInteraction,
Branching fb, bool first);
/**
* It does the backward evolution of the space-like input particle
* (and recursively for all its time-like radiation products).
* accepting only emissions which conforms to the showerVariables.
* If at least one emission has occurred then the method returns true
* @param particle The particle to be showered
* @param beam The beam particle
*/
virtual bool spaceLikeShower(tShowerParticlePtr particle,PPtr beam,
ShowerInteraction);
/**
* If does the forward evolution of the input on-shell particle
* involved in a decay
* (and recursively for all its time-like radiation products).
* accepting only emissions which conforms to the showerVariables.
* @param particle The particle to be showered
* @param maxscale The maximum scale for the shower.
* @param minimumMass The minimum mass of the final-state system
*/
virtual bool
spaceLikeDecayShower(tShowerParticlePtr particle,
const ShowerParticle::EvolutionScales & maxScales,
Energy minimumMass,ShowerInteraction,
Branching fb);
/**
* Truncated shower from a time-like particle
*/
virtual bool truncatedTimeLikeShower(tShowerParticlePtr particle,
HardBranchingPtr branch,
ShowerInteraction type,
Branching fb, bool first);
/**
* Truncated shower from a space-like particle
*/
virtual bool truncatedSpaceLikeShower(tShowerParticlePtr particle,PPtr beam,
HardBranchingPtr branch,
ShowerInteraction type);
/**
* Truncated shower from a time-like particle
*/
virtual bool truncatedSpaceLikeDecayShower(tShowerParticlePtr particle,
const ShowerParticle::EvolutionScales & maxScales,
Energy minimumMass, HardBranchingPtr branch,
ShowerInteraction type, Branching fb);
//@}
/**
* Switches for matrix element corrections
*/
//@{
/**
* Any ME correction?
*/
bool MECOn() const {
return _hardEmission == 1;
}
/**
* Any hard ME correction?
*/
bool hardMEC() const {
return _hardEmission == 1 && (_meCorrMode == 1 || _meCorrMode == 2);
}
/**
* Any soft ME correction?
*/
bool softMEC() const {
return _hardEmission == 1 && (_meCorrMode == 1 || _meCorrMode > 2);
}
//@}
/**
* Is the truncated shower on?
*/
bool isTruncatedShowerON() const {return _trunc_Mode;}
/**
* Switch for intrinsic pT
*/
//@{
/**
* Any intrinsic pT?
*/
bool ipTon() const {
return _iptrms != ZERO || ( _beta == 1.0 && _gamma != ZERO && _iptmax !=ZERO );
}
//@}
/**@name Additional shower vetoes */
//@{
/**
* Insert a veto.
*/
void addVeto (ShowerVetoPtr v) { _vetoes.push_back(v); }
/**
* Remove a veto.
*/
void removeVeto (ShowerVetoPtr v) {
vector<ShowerVetoPtr>::iterator vit = find(_vetoes.begin(),_vetoes.end(),v);
if (vit != _vetoes.end())
_vetoes.erase(vit);
}
//@}
/**
* Switches for vetoing hard emissions
*/
//@{
/**
* Returns true if the hard veto read-in is to be applied to only
* the primary collision and false otherwise.
*/
bool hardVetoReadOption() const {return _hardVetoReadOption;}
//@}
/**
* Enhancement factors for radiation needed to generate the soft matrix
* element correction.
*/
//@{
/**
* Access the enhancement factor for initial-state radiation
*/
double initialStateRadiationEnhancementFactor() const { return _initialenhance; }
/**
* Access the enhancement factor for final-state radiation
*/
double finalStateRadiationEnhancementFactor() const { return _finalenhance; }
/**
* Set the enhancement factor for initial-state radiation
*/
void initialStateRadiationEnhancementFactor(double in) { _initialenhance=in; }
/**
* Set the enhancement factor for final-state radiation
*/
void finalStateRadiationEnhancementFactor(double in) { _finalenhance=in; }
//@}
/**
* Access to set/get the HardTree currently beinging showered
*/
//@{
/**
* The HardTree currently being showered
*/
tHardTreePtr hardTree() {return _hardtree;}
/**
* The HardTree currently being showered
*/
void hardTree(tHardTreePtr in) {_hardtree = in;}
//@}
/**
* Access/set the beam particle for the current initial-state shower
*/
//@{
/**
* Get the beam particle data
*/
Ptr<BeamParticleData>::const_pointer beamParticle() const { return _beam; }
/**
* Set the beam particle data
*/
void setBeamParticle(Ptr<BeamParticleData>::const_pointer in) { _beam=in; }
//@}
/**
* Set/Get the current tree being evolver for inheriting classes
*/
//@{
/**
* Get the tree
*/
tShowerTreePtr currentTree() { return _currenttree; }
/**
* Set the tree
*/
void currentTree(tShowerTreePtr tree) { _currenttree=tree; }
//@}
/**
* Access the maximum number of attempts to generate the shower
*/
unsigned int maximumTries() const { return _maxtry; }
/**
* Set/Get the ShowerProgenitor for the current shower
*/
//@{
/**
* Access the progenitor
*/
ShowerProgenitorPtr progenitor() { return _progenitor; }
/**
* Set the progenitor
*/
void progenitor(ShowerProgenitorPtr in) { _progenitor=in; }
//@}
/**
* Calculate the intrinsic \f$p_T\f$.
*/
virtual void generateIntrinsicpT(vector<ShowerProgenitorPtr>);
/**
* Access to the intrinsic \f$p_T\f$ for inheriting classes
*/
map<tShowerProgenitorPtr,pair<Energy,double> > & intrinsicpT() { return _intrinsic; }
/**
* find the maximally allowed pt acc to the hard process.
*/
void setupMaximumScales(const vector<ShowerProgenitorPtr> &,XCPtr);
/**
* find the relevant hard scales for profile scales.
*/
void setupHardScales(const vector<ShowerProgenitorPtr> &,XCPtr);
/**
* Convert the HardTree into an extra shower emission
*/
void convertHardTree(bool hard,ShowerInteraction type);
protected:
/**
* Find the parton extracted from the incoming particle after ISR
*/
PPtr findFirstParton(tPPtr seed) const;
/**
* Fix Remnant connections after ISR
*/
tPPair remakeRemnant(tPPair oldp);
protected:
/**
* Start the shower of a timelike particle
*/
virtual bool startTimeLikeShower(ShowerInteraction);
/**
* Update of the time-like stuff
*/
void updateHistory(tShowerParticlePtr particle);
/**
* Start the shower of a spacelike particle
*/
virtual bool startSpaceLikeShower(PPtr,ShowerInteraction);
/**
* Start the shower of a spacelike particle
*/
virtual bool
startSpaceLikeDecayShower(const ShowerParticle::EvolutionScales & maxScales,
Energy minimumMass,ShowerInteraction);
/**
* Select the branching for the next time-like emission
*/
Branching selectTimeLikeBranching(tShowerParticlePtr particle,
ShowerInteraction type,
HardBranchingPtr branch);
/**
* Select the branching for the next space-like emission in a decay
*/
Branching selectSpaceLikeDecayBranching(tShowerParticlePtr particle,
const ShowerParticle::EvolutionScales & maxScales,
Energy minmass,ShowerInteraction type,
HardBranchingPtr branch);
/**
* Create the timelike child of a branching
*/
ShowerParticleVector createTimeLikeChildren(tShowerParticlePtr particle,
IdList ids);
/**
* Vetos for the timelike shower
*/
virtual bool timeLikeVetoed(const Branching &,ShowerParticlePtr);
/**
* Vetos for the spacelike shower
*/
virtual bool spaceLikeVetoed(const Branching &,ShowerParticlePtr);
/**
* Vetos for the spacelike shower
*/
virtual bool spaceLikeDecayVetoed(const Branching &,ShowerParticlePtr);
/**
* Only generate the hard emission, for testing only.
*/
bool hardOnly() const {return _limitEmissions==3;}
/**
* Check the flags
*/
void checkFlags();
/**
*
*/
void addFSRUsingDecayPOWHEG(HardTreePtr ISRTree);
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:
/**
* The main method which manages the showering of a subprocess.
*/
virtual tPPair cascade(tSubProPtr sub, XCPtr xcomb);
/**
* Decay a ShowerTree
*/
void decay(ShowerTreePtr tree, ShowerDecayMap & decay);
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:
/**
* 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();
/**
* Initialize this object. Called in the run phase just before
* a run begins.
*/
virtual void doinitrun();
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
QTildeShowerHandler & operator=(const QTildeShowerHandler &) = delete;
private:
/**
* Stuff from the ShowerHandler
*/
//@{
/**
* The ShowerTree for the hard process
*/
ShowerTreePtr hard_;
/**
* The ShowerTree for the decays
*/
ShowerDecayMap decay_;
/**
* The ShowerTrees for which the initial shower
*/
vector<ShowerTreePtr> done_;
//@}
private :
/**
* Pointer to the splitting generator
*/
SplittingGeneratorPtr _splittingGenerator;
/**
* Maximum number of tries to generate the shower of a particular tree
*/
unsigned int _maxtry;
/**
* Matrix element correction switch
*/
unsigned int _meCorrMode;
/**
* Control of the reconstruction option
*/
unsigned int _evolutionScheme;
/**
* If hard veto pT scale is being read-in this determines
* whether the read-in value is applied to primary and
* secondary (MPI) scatters or just the primary one, with
* the usual computation of the veto being performed for
* the secondary (MPI) scatters.
*/
bool _hardVetoReadOption;
/**
* rms intrinsic pT of Gaussian distribution
*/
Energy _iptrms;
/**
* Proportion of inverse quadratic intrinsic pT distribution
*/
double _beta;
/**
* Parameter for inverse quadratic: 2*Beta*Gamma/(sqr(Gamma)+sqr(intrinsicpT))
*/
Energy _gamma;
/**
* Upper bound on intrinsic pT for inverse quadratic
*/
Energy _iptmax;
/**
* Limit the number of emissions for testing
*/
unsigned int _limitEmissions;
/**
* The progenitor of the current shower
*/
ShowerProgenitorPtr _progenitor;
/**
* Matrix element
*/
HwMEBasePtr _hardme;
/**
* Decayer
*/
HwDecayerBasePtr _decayme;
/**
* The ShowerTree currently being showered
*/
ShowerTreePtr _currenttree;
/**
* The HardTree currently being showered
*/
HardTreePtr _hardtree;
/**
* Radiation enhancement factors for use with the veto algorithm
* if needed by the soft matrix element correction
*/
//@{
/**
* Enhancement factor for initial-state radiation
*/
double _initialenhance;
/**
* Enhancement factor for final-state radiation
*/
double _finalenhance;
//@}
/**
* The beam particle data for the current initial-state shower
*/
Ptr<BeamParticleData>::const_pointer _beam;
/**
* Storage of the intrinsic \f$p_t\f$ of the particles
*/
map<tShowerProgenitorPtr,pair<Energy,double> > _intrinsic;
/**
* Vetoes
*/
vector<ShowerVetoPtr> _vetoes;
/**
* Full Shower Vetoes
*/
vector<FullShowerVetoPtr> _fullShowerVetoes;
/**
* Number of iterations for reweighting
*/
unsigned int _nReWeight;
/**
* Whether or not we are reweighting
*/
bool _reWeight;
/**
* number of IS emissions
*/
unsigned int _nis;
/**
* Number of FS emissions
*/
unsigned int _nfs;
/**
* The option for wqhich interactions to use
*/
ShowerInteraction interaction_;
/**
* Truncated shower switch
*/
bool _trunc_Mode;
-
- /**
- * Count of the number of truncated emissions
- */
- unsigned int _truncEmissions;
/**
* Mode for the hard emissions
*/
int _hardEmission;
/**
* Option for the kernal for soft correlations
*/
unsigned int _softOpt;
/**
* Option for hard radiation in POWHEG events
*/
bool _hardPOWHEG;
/**
* True if no warnings about incorrect hard emission
* mode setting have been issued yet
*/
static bool _hardEmissionWarn;
/**
* True if no warnings about missing truncated shower
* have been issued yet
*/
static bool _missingTruncWarn;
/**
* The relevant hard scale to be used in the profile scales
*/
Energy muPt;
private:
/**
* Pointer to the various objects
*/
//@{
/**
* Pointer to the KinematicsReconstructor object
*/
KinematicsReconstructorPtr _reconstructor;
/**
* Pointer to the PartnerFinder object
*/
PartnerFinderPtr _partnerfinder;
//@}
};
}
#endif /* HERWIG_QTildeShowerHandler_H */
diff --git a/Utilities/GaussianIntegrator.h b/Utilities/GaussianIntegrator.h
--- a/Utilities/GaussianIntegrator.h
+++ b/Utilities/GaussianIntegrator.h
@@ -1,132 +1,125 @@
// -*- C++ -*-
//
// GaussianIntegrator.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_GaussianIntegrator_H
#define HERWIG_GaussianIntegrator_H
//
// This is the declaration of the GaussianIntegrator class.
//
#include "ThePEG/Pointer/ReferenceCounted.h"
#include "ThePEG/Repository/CurrentGenerator.h"
#include <vector>
namespace Herwig {
using namespace ThePEG;
/** \ingroup Utilities
* \author Peter Richardson
* This class is designed to perform the integral of a function
* using Gaussian quadrature.The method is adaptive based on using 6th,12th,
* 24th,48th, or 96th order Gaussian quadrature combined with
* subdivision of the integral if this is insufficient.
*
* The class is templated on a simple class which should provide a
* T::operator () (double) const which provides the integrand for the function.
*/
class GaussianIntegrator : public Pointer::ReferenceCounted {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* Default Constructor
*/
GaussianIntegrator()
- : _abserr(1.E-35), _relerr(5.E-5), _binwidth(1.E-5),
- _maxint(100), _maxeval(100000) {
+ : _abserr(1.E-35), _relerr(5.E-5), _binwidth(1.E-5), _maxeval(100000) {
// setup the weights and abscissae
Init();
}
/**
* Specify all the parameters.
* @param abserr Absolute error.
* @param relerr Relative error.
* @param binwidth Width of the bin as a fraction of the integration region.
- * @param maxint Maximum number of intervals
* @param maxeval Maximum number of function evaluations
*/
GaussianIntegrator(double abserr, double relerr, double binwidth,
- int maxint, int maxeval)
+ int maxeval)
: _abserr(abserr), _relerr(relerr),
- _binwidth(binwidth), _maxint(maxint),
+ _binwidth(binwidth),
_maxeval(maxeval) {
// setup the weights and abscissae
Init();
}
/// helper type for the integration result
template <class T>
using ValT = decltype(std::declval<typename T::ValType>()
* std::declval<typename T::ArgType>());
/**
* The value of the integral
* @param lower The lower limit of integration.
* @param upper The upper limit of integration.
*/
template <class T>
inline ValT<T> value(const T &,
const typename T::ArgType lower,
const typename T::ArgType upper) const;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
GaussianIntegrator & operator=(const GaussianIntegrator &) = delete;
/**
* Initialise the weights and abscissae.
*/
void Init();
private:
/**
* The weights for the gaussian quadrature.
*/
std::vector< std::vector<double> > _weights;
/**
* The abscissae.
*/
std::vector< std::vector <double> > _abscissae;
/**
* The parameters controlling the error.
*/
double _abserr,_relerr;
/**
* The minimum width of a bin as a fraction of the integration region.
*/
double _binwidth;
/**
- * Maximum number of bins.
- */
- int _maxint;
-
- /**
* Maximum number of function evaluations.
*/
int _maxeval;
};
}
#include "GaussianIntegrator.tcc"
#endif /* HERWIG_GaussianIntegrator_H */

File Metadata

Mime Type
text/x-diff
Expires
Tue, Nov 19, 4:27 PM (1 d, 13 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3805167
Default Alt Text
(732 KB)

Event Timeline