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 describeHerwigBaryon1MesonDecayerBase("Herwig::Baryon1MesonDecayerBase", "HwBaryonDecay.so"); void Baryon1MesonDecayerBase::Init() { static ClassDocumentation 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(&inpart), incoming); else SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,_rho, const_ptr_cast(&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(&inpart),incoming,true); SpinorBarWaveFunction::constructSpinInfo(_inHalfBar,decay[0],outgoing,true); } else { SpinorBarWaveFunction:: constructSpinInfo(_inHalfBar,const_ptr_cast(&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 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(&inpart), incoming); else SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,_rho, const_ptr_cast(&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(&inpart),incoming,true); SpinorBarWaveFunction::constructSpinInfo(_inHalfBar,decay[0],outgoing,true); } else { SpinorBarWaveFunction:: constructSpinInfo(_inHalfBar,const_ptr_cast(&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 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 ispin(3); LorentzVector > 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(&inpart), incoming); else SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,_rho, const_ptr_cast(&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(&inpart),incoming,true); RSSpinorBarWaveFunction::constructSpinInfo(_inThreeHalfBar, decay[0],outgoing,true); } else { SpinorBarWaveFunction:: constructSpinInfo(_inHalfBar,const_ptr_cast(&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 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 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 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(&inpart), incoming); else SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,_rho, const_ptr_cast(&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(&inpart),incoming,true); RSSpinorBarWaveFunction::constructSpinInfo(_inThreeHalfBar, decay[0],outgoing,true); } else { SpinorBarWaveFunction:: constructSpinInfo(_inHalfBar,const_ptr_cast(&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 ispin(3); LorentzVector > svec; Complex prod; complex scalar; LorentzSpinor stemp; LorentzSpinorBar 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 h1(-2.*Qp*A1),h2(2.*Qm*B1); // complex h3(-2./r3*Qp*(A1-Qm*Qm/m2*A2/msum)); // complex h4( 2./r3*Qm*(B1-Qp*Qp/m2*B2/msum)); // complex 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 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(&inpart), incoming); } else { RSSpinorBarWaveFunction::calculateWaveFunctions(_inThreeHalfBar,_rho, const_ptr_cast(&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(&inpart),incoming,true); SpinorBarWaveFunction::constructSpinInfo(_inHalfBar,decay[0],outgoing,true); } else { RSSpinorBarWaveFunction:: constructSpinInfo(_inThreeHalfBar,const_ptr_cast(&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 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 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(&inpart), incoming); } else { RSSpinorBarWaveFunction::calculateWaveFunctions(_inThreeHalfBar,_rho, const_ptr_cast(&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(&inpart),incoming,true); RSSpinorBarWaveFunction::constructSpinInfo(_inThreeHalfBar, decay[0],outgoing,true); } else { RSSpinorBarWaveFunction:: constructSpinInfo(_inThreeHalfBar,const_ptr_cast(&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 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(&inpart), incoming); } else { RSSpinorBarWaveFunction::calculateWaveFunctions(_inThreeHalfBar,_rho, const_ptr_cast(&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(&inpart),incoming,true); SpinorBarWaveFunction::constructSpinInfo(_inHalfBar,decay[0],outgoing,true); } else { RSSpinorBarWaveFunction:: constructSpinInfo(_inThreeHalfBar,const_ptr_cast(&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 ispin(3); LorentzVector > svec; LorentzSpinor stemp; LorentzSpinorBar sbtemp; complex 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 h1(-2.*Qp*A1),h2(2.*Qm*B1); // complex h3(-2./r3*Qp*(A1-Qm*Qm/m1*A2/msum)); // complex h4( 2./r3*Qm*(B1-Qp*Qp/m1*B2/msum)); // complex 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 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;ixmass(); 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;ixmass(); 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 describeHerwigChengHeavyBaryonFormFactor("Herwig::ChengHeavyBaryonFormFactor", "HwFormFactors.so"); void ChengHeavyBaryonFormFactor::Init() { static ClassDocumentation 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 interfaceUpMass ("DownMass", "The consituent mass of the down quark", &ChengHeavyBaryonFormFactor::_md, GeV, 0.322*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter interfaceDownMass ("UpMass", "The consituent mass of the up quark", &ChengHeavyBaryonFormFactor::_mu, GeV, 0.338*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter interfacStrangeMass ("StrangeMass", "The consituent mass of the strange quark", &ChengHeavyBaryonFormFactor::_ms, GeV, 0.510*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter interfaceCharmMass ("CharmMass", "The consituent mass of the charm quark", &ChengHeavyBaryonFormFactor::_mc, GeV, 1.6*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter interfaceBottomMass ("BottomMass", "The consituent mass of the bottom quark", &ChengHeavyBaryonFormFactor::_mb, GeV, 5.0*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter 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 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 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 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 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 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 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 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 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 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 interfaceNfi ("Nfi", "The prefactor for a given form factor", &ChengHeavyBaryonFormFactor::_Nfi, -1, 1.0, -10.0, 10.0, false, false, true); static ParVector 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 & 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 _wquarkwgt; /** * Weight \f$W\to \ell \nu\f$ */ vector _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 _inHalf; /** * 2nd spinor for the decay */ mutable vector _outHalf; /** * 1st barred spinor for the decay */ mutable vector _inHalfBar; /** * 2nd barred spinor for the decay */ mutable vector _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 SMWDecayer 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 & 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 hardProcess, double phi, double muj, double muk, int iemit, bool subtract) const; /** * Calculate the ratio between NLO & LO ME */ double meRatio(vector partons, vector 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 & partons, const vector & momenta) const; /** * Calculate the NLO real emission piece of ME */ InvEnergy2 realME(const vector & partons, const vector & 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 quarkWeight_; /** * Weights for the W to leptons decays. */ vector leptonWeight_; //@} /** * Spin density matrix for the decay */ mutable RhoDMatrix rho_; /** * Polarization vectors for the decay */ mutable vector vectors_; /** * Spinors for the decay */ mutable vector wave_; /** * Barred spinors for the decay */ mutable vector 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 partons_; /** * The fermion momenta */ vector 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 _map; /** * Masses of the particles involved */ vector _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 _qprf; /** * Momenta of the charged particles in the parent's rest frame after radiation */ vector _qnewprf; /** * Momenta of the photons in the parent rest frame */ vector _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 _qlab; /** * Momenta of the charged particles in the lab frame after radiation */ vector _qnewlab; /** * Momenta of the photons in the lab frame */ vector _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 _cosphot; /** * Sine of the photon angles */ vector _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 #include #include #include #include #include #include #include "Herwig/Utilities/Kinematics.h" #include "CheckId.h" #include "Cluster.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include using namespace Herwig; DescribeClass 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 documentation ("Class responsibles for chopping up the clusters"); static Reference 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 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 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 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 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 interfaceClPowLight ("ClPowLight","cluster mass exponent for light quarks", &ClusterFissioner::_clPowLight, 0, 2.0, 0.0, 10.0,false,false,false); static Parameter interfaceClPowBottom ("ClPowBottom","cluster mass exponent for b quarks", &ClusterFissioner::_clPowBottom, 0, 2.0, 0.0, 10.0,false,false,false); static Parameter interfaceClPowCharm ("ClPowCharm","cluster mass exponent for c quarks", &ClusterFissioner::_clPowCharm, 0, 2.0, 0.0, 10.0,false,false,false); static Parameter 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 interfacePSplitLight ("PSplitLight","cluster mass splitting param for light quarks", &ClusterFissioner::_pSplitLight, 0, 1.0, 0.0, 10.0,false,false,false); static Parameter interfacePSplitBottom ("PSplitBottom","cluster mass splitting param for b quarks", &ClusterFissioner::_pSplitBottom, 0, 1.0, 0.0, 10.0,false,false,false); static Parameter interfacePSplitCharm ("PSplitCharm","cluster mass splitting param for c quarks", &ClusterFissioner::_pSplitCharm, 0, 1.0, 0.0, 10.0,false,false,false); static Parameter interfacePSplitExotic ("PSplitExotic","cluster mass splitting param for exotic quarks", &ClusterFissioner::_pSplitExotic, 0, 1.0, 0.0, 10.0,false,false,false); static Switch 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 interfaceFissionPwtUquark ("FissionPwtUquark", "Weight for fission in U quarks", &ClusterFissioner::_fissionPwtUquark, 1, 0.0, 1.0, false, false, Interface::limited); static Parameter interfaceFissionPwtDquark ("FissionPwtDquark", "Weight for fission in D quarks", &ClusterFissioner::_fissionPwtDquark, 1, 0.0, 1.0, false, false, Interface::limited); static Parameter interfaceFissionPwtSquark ("FissionPwtSquark", "Weight for fission in S quarks", &ClusterFissioner::_fissionPwtSquark, 0.5, 0.0, 1.0, false, false, Interface::limited); static Switch 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 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 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 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 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 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 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 & 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(ct.first.first); ClusterPtr two = dynamic_ptr_cast(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;ixnumComponents(),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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Herwig/Utilities/EnumParticles.h" #include "CluHadConfig.h" #include "Cluster.h" #include using namespace Herwig; ClusterHadronizationHandler * ClusterHadronizationHandler::currentHandler_ = 0; DescribeClass 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 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 interfacePartonSplitter("PartonSplitter", "A reference to the PartonSplitter object", &Herwig::ClusterHadronizationHandler::_partonSplitter, false, false, true, false); static Reference interfaceClusterFinder("ClusterFinder", "A reference to the ClusterFinder object", &Herwig::ClusterHadronizationHandler::_clusterFinder, false, false, true, false); static Reference interfaceColourReconnector("ColourReconnector", "A reference to the ColourReconnector object", &Herwig::ClusterHadronizationHandler::_colourReconnector, false, false, true, false); static Reference interfaceClusterFissioner("ClusterFissioner", "A reference to the ClusterFissioner object", &Herwig::ClusterHadronizationHandler::_clusterFissioner, false, false, true, false); static Reference interfaceLightClusterDecayer("LightClusterDecayer", "A reference to the LightClusterDecayer object", &Herwig::ClusterHadronizationHandler::_lightClusterDecayer, false, false, true, false); static Reference interfaceClusterDecayer("ClusterDecayer", "A reference to the ClusterDecayer object", &Herwig::ClusterHadronizationHandler::_clusterDecayer, false, false, true, false); static Parameter 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 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 interfaceUnderlyingEventHandler ("UnderlyingEventHandler", "Pointer to the handler for the Underlying Event. " "Set to NULL to disable.", &ClusterHadronizationHandler::_underlyingEventHandler, false, false, true, true, false); static Switch 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 & 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;ixscale()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 allDecendants; for (tPVector::const_iterator it = tagged.begin(); it != tagged.end(); ++it) { extractChildren(*it, allDecendants); } for(set::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::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 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 "<::tptr eh = dynamic_ptr_cast::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::tptr eh = dynamic_ptr_cast::tptr>(generator()->eventHandler()); // All diffractive processes make use of this ME. // The static map can be used to collect all the sumOfWeights. static map 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(countUpdateWeightsampler()->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 MEMinBias::diagrams(const DiagramVector & diags) const { Selector sel; for ( DiagramIndex i = 0; i < diags.size(); ++i ) sel.insert(1.0, i); return sel; } Selector 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 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 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 documentation ("There is no documentation for the MEMinBias class"); static Parameter interfacecsNorm ("csNorm", "Normalization of the min-bias cross section.", &MEMinBias::csNorm_, 1.0, 0.0, 100.0, false, false, Interface::limited); static Parameter 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 interfaceMPIHandler ("MPIHandler", "The object that administers all additional scatterings.", &MEMinBias::MPIHandler_, false, false, true, true); static Switch 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 MEPP2Higgs::epsi_ = complex(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 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 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 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 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 interfaceCoupling ("Coupling", "Pointer to the object to calculate the coupling for the correction", &MEPP2Higgs::alpha_, false, false, true, false, false); static Switch 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 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 interfaceMinimumInLoop ("MinimumInLoop", "The minimum flavour of the quarks to include in the loops", &MEPP2Higgs::minLoop_, 6, 5, 6, false, false, Interface::limited); static Parameter interfaceMaximumInLoop ("MaximumInLoop", "The maximum flavour of the quarks to include in the loops", &MEPP2Higgs::maxLoop_, 6, 5, 6, false, false, Interface::limited); static Switch 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 interfaceMinimumFlavour ("MinimumFlavour", "The minimum flavour of the incoming quarks in the hard process", &MEPP2Higgs::minFlavour_, 4, 3, 5, false, false, Interface::limited); static Parameter interfaceMaximumFlavour ("MaximumFlavour", "The maximum flavour of the incoming quarks in the hard process", &MEPP2Higgs::maxFlavour_, 5, 3, 5, false, false, Interface::limited); static Parameter 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 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 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 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 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 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 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 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 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 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 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 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 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(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(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 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 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 fin; vector 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 MEPP2Higgs::diagrams(const DiagramVector & diags) const { Selector sel; for (DiagramIndex i = 0; i < diags.size(); ++i) sel.insert(1.0, i); return sel; } Selector 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 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 g1,g2; vector q; vector 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 q1; vector 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 g1, vector 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 & fin, vector & 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 beams; for(unsigned int ix=0;ixbornIncoming().size();++ix) { incoming.push_back(born->bornIncoming()[ix]); beams.push_back(dynamic_ptr_cast(born->hadrons()[ix]->dataPtr())); } pair xnew=born->x(); if(incoming[0]->momentum().z()bornOutgoing()[0]; // calculate the momenta unsigned int iemit,itype; vector 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()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()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()x(xnew); born->interaction(ShowerInteraction::QCD); return born; } bool MEPP2Higgs::softMatrixElementVeto(PPtr parent, PPtr progenitor, const bool & fs, const Energy & highestpT, const vector & 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(pTid()==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;ixbornIncoming().size();++ix) { incoming.push_back( born->bornIncoming()[ix] ); beams_.push_back( dynamic_ptr_cast(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 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 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 beams,PPtr higgs, unsigned int & iemit, unsigned int & itype, vector & pnew, pair & 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(smaxpdf(); 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=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=1.||xnew[1]<=0.||xnew[1]>=1.) return false; if(rn 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 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 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 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 weights; vector 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=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 MEPP2Higgs::C(Energy2 s,Energy2 mf2) const { complex output; - Complex pii(0.,Constants::pi); + const Complex pii(0.,Constants::pi); double rat=s/(4.*mf2); 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 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 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 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 & 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(pt1.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_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*ypdf()->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 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 MEee2VectorMeson::colourGeometries(tcDiagPtr) const { static ColourLines neutral ( " " ); Selector 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 describeHerwigMEee2VectorMeson("Herwig::MEee2VectorMeson", "HwMELepton.so"); void MEee2VectorMeson::Init() { static ClassDocumentation 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 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 interfaceVectorMeson ("VectorMeson", "The vector meson produced", &MEee2VectorMeson::vector_, false, false, true, false, false); static Parameter interfaceCoupling ("Coupling", "The leptonic coupling of the vector meson", &MEee2VectorMeson::coupling_, 0., 0.0, 100.0, false, false, Interface::limited); } Selector MEee2VectorMeson::diagrams(const DiagramVector &) const { Selector 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(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 fin; vector ain; vector 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 fin, vector ain, vector 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()id()) swap(hard[0],hard[1]); vector fin; vector ain; vector 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(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 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 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 & partons, const vector & 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 & fin, vector & ain, vector & fout, vector & 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 partons, vector 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 & partons, const vector & momenta) const; /** * Generate the momenta for a hard configuration */ Energy generateHard(RealEmissionProcessPtr tree, vector & 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 partons_; /** * Momenta of the leading-order partons */ vector 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 zBounds(Energy pt, Energy hardPt = ZERO) const; /** * For generated pt and z, check if this point is * kinematically allowed */ /*virtual*/ bool ptzAllowed(pair ptz, vector* values ) const; /** * Generate pt and z */ virtual pair generatePtZ(double& jac, const double * r, vector* values) const; public: /** * Triangular / Kallen function */ template 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 rotateToZ (Lorentz5Momentum& pTarget, Lorentz5Momentum& p1) { ThreeVector 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 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 (dim,dim))); } } // Fill the density matrix for the first time void DensityOperator::fill(const Ptr::ptr MBXCombPtr, const cPDVector& partons, const vector& momenta){ // Map from helicity structure to amplitude vector in the color basis const map,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 mePartonDataColoured = theColourBasis->normalOrderMap(mePartonData); // Get the colour basis to colour basis map for this hard subprocess map >::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& 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& 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 cb2cbMap; // Get the momenta for comparison const vector& 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 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 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,matrix >::iterator dOit = theDensityOperatorMap.find(mePartonDataColoured); assert(dOit != theDensityOperatorMap.end()); // Initialize the density operator matrix& 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,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,Complex>& Vijk, const cPDVector& before, const cPDVector& after, const map,map >& emissionsMap, const bool splitAGluon, const bool initialGluonSplitting) { size_t dimBefore = theColourBasis->prepare( before, false ); size_t dimAfter = theColourBasis->prepare( after, false ); vector beforeColoured = theColourBasis->normalOrderMap(before); vector afterColoured = theColourBasis->normalOrderMap(after); const map,matrix >::iterator dOit = theDensityOperatorMap.find(beforeColoured); assert(dOit != theDensityOperatorMap.end()); const matrix& densOpBefore = dOit->second; prepare(after); matrix& 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 Tij; matrix TijMn (dimAfter,dimBefore); compressed_matrix Tk; matrix 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,map > 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& 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 particlesColoured = theColourBasis->normalOrderMap(particles); // ... and find corresponding density operator const map,matrix >::iterator particlesit = theDensityOperatorMap.find(particlesColoured); assert(particlesit != theDensityOperatorMap.end()); const matrix& densOp = particlesit->second; double Ti2 = colourNorm(particles[i]); // Emitter-spectator pair const pair ik = make_pair(i,k); // Create key for color matrix element correction map pair,pair > 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 >,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 ikemission; // Normal order particles as defined in ColourBasis const vector particlesColoured = theColourBasis->normalOrderMap(particles); vector 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 DensityOperator::prodSparseDense(const compressed_matrix& Tij, const matrix& 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 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::const_iterator1 it1 = Tij.begin1(); it1 != Tij.end1(); it1++ ) { for ( compressed_matrix::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 DensityOperator::prodDenseSparse(const matrix& TijMn, const compressed_matrix& 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 TijMnTkdagger (dimAfter,dimAfter,0); size_t jj; size_t kk; for ( compressed_matrix::const_iterator1 it1 = Tk.begin1(); it1 != Tk.end1(); it1++ ) { for ( compressed_matrix::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 DensityOperator::boostToRestFrame(const vector& momenta) { // We need 2 initial particles assert(momenta.size() >= 2); // The boosted vectors vector 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 describeHerwigDensityOperator("Herwig::DensityOperator", "DensityOperator.so"); void DensityOperator::Init() { static ClassDocumentation 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> Tree2toNGenerator:: generate(const PDVector& legs, unsigned int orderInGs, unsigned int orderInGem) { vector::ptr> res; list > 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 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 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 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 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 > Tree2toNGenerator:: cluster(const vector& children, unsigned int orderInGs, unsigned int orderInGem) const { list > 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(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::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 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::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 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 > Tree2toNGenerator:: clusterAll(const list >& current, unsigned int orderInGs, unsigned int orderInGem) const { list > res; for ( list >::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 > next = cluster(*c,gs,gem); if ( next.empty() ) continue; list > cled = clusterAll(next,orderInGs-gs,orderInGem-gem); copy(cled.begin(),cled.end(),back_inserter(res)); } } return res; } list > 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 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 > 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 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 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 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 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 describeHerwigTree2toNGenerator("Herwig::Tree2toNGenerator", "Herwig.so"); void Tree2toNGenerator::Init() { static ClassDocumentation documentation ("Generate Tree2toNDiagrams for a given process."); static RefVector interfaceVertices ("Vertices", "All vertices to consider.", &Tree2toNGenerator::theVertices, -1, false, false, true, false, false); static RefVector interfaceExcludeVertices ("ExcludeVertices", "The vertices to exclude.", &Tree2toNGenerator::theExcludeVertices, -1, false, false, true, false, false); static RefVector interfaceExcludeInternal ("ExcludeInternal", "Particles to be exluded from becoming internal lines.", &Tree2toNGenerator::theExcludeInternal, -1, false, false, true, false, false); static RefVector interfaceRestrictLines ("RestrictLines", "Particles to be exluded from becoming internal lines.", &Tree2toNGenerator::theRestrictLines, -1, false, false, true, false, false); static Command interfaceSpaceLikeRange ("SpaceLikeRange", "Limit the number of spacelike occurences of the specified particle.", &Tree2toNGenerator::doSpaceLikeRange, false); static Command interfaceTimeLikeRange ("TimeLikeRange", "Limit the number of timelike occurences of the specified particle.", &Tree2toNGenerator::doTimeLikeRange, false); static Command 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 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 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 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 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 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 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 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 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 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 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::transient_const_pointer> (lastParticles().first->dataPtr()); _hadron_B=dynamic_ptr_cast::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=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::transient_const_pointer _hadron_A; /** * The BeamParticleData object for the second hadron */ mutable Ptr::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 describeHerwigMEPP2ZHPowheg("Herwig::MEPP2ZHPowheg", "HwMEHadron.so HwPowhegMEHadron.so"); void MEPP2ZHPowheg::Init() { static ClassDocumentation 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 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 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 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 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 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 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 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 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::transient_const_pointer> (lastParticles().first->dataPtr()); _hadron_B=dynamic_ptr_cast::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=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::transient_const_pointer _hadron_A; /** * The BeamParticleData object for the second hadron */ mutable Ptr::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(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 describeHerwigADDModelFFGGRVertex("Herwig::ADDModelFFGGRVertex", "HwADDModel.so"); void ADDModelFFGGRVertex::Init() { static ClassDocumentation 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 describeHerwigVVSLoopVertex("Herwig::VVSLoopVertex", "Herwig.so"); void VVSLoopVertex::Init() { static ClassDocumentation 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 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 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 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::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 partons, pair pdfs, bool first) { if(theRems.first) { ParticleVector children=theRems.first->children(); for(unsigned int ix=0;ixdataPtr()==theRems.first->dataPtr()) theRems.first = dynamic_ptr_cast(children[ix]); } } if(theRems.second) { ParticleVector children=theRems.second->children(); for(unsigned int ix=0;ixdataPtr()==theRems.second->dataPtr()) theRems.second = dynamic_ptr_cast(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; iychildren().size(); ++iy) pnew[0] += theRems.first->children()[iy]->momentum(); for(unsigned int iy=0; iychildren().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 ids; if(child==21||child==22) { ids=content.flav; for(unsigned int ix=0;ix > > partonprob; double ptotal(0.); for(unsigned int iflav=0;iflav prob; for(unsigned int iz=0;izvalue(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 > >::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(;izsecond.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 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 progenitors; for(unsigned int ix=0;ixchildren().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 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;ixchildren().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 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 psystem.mass() + diquark->mass()) --iloc; if(iloc==progenitors.size()) { // try touching the lepton in dis as a last restort for(unsigned int ix=0;ixmomentum(); ptotal = psystem + deltap; ptotal.rescaleMass(); psystem.rescaleMass(); ++iloc; } --iloc; if(ptotal.mass() > psystem.mass() + diquark->mass()) { if(DISRemnantOpt_==0||DISRemnantOpt_==2) Throw() << "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;iychildren().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;iychildren().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 <<" "<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 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 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& 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::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;jmaximumCMEnergy()); + //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 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 remnants; rem1->set5Momentum(r1); rem2->set5Momentum(r2); remnants.push_back(rem1); remnants.push_back(rem2); vector 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 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 partons; vector 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; iaddColoured(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; iaddAntiColoured(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 &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 mom(ncl); // Sets the slopes depending on the constituent quarks of the cluster for(unsigned int ix=0;ix xi(ncl); vector 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; ipT2...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 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=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 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; iDiquark 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 & particles) const { if(part->children().empty()) particles.push_back(part); else { for(unsigned int ix=0;ixchildren().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 describeHerwigHwRemDecayer("Herwig::HwRemDecayer", "HwShower.so"); void HwRemDecayer::Init() { static ClassDocumentation documentation ("The HwRemDecayer class decays the remnant for Herwig"); static Parameter 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 interfaceMaxBin ("MaxBin", "Maximum number of z bins", &HwRemDecayer::_nbinmax, 100, 10, 1000, false, false, Interface::limited); static Reference interfaceAlphaS ("AlphaS", "Pointer to object to calculate the strong coupling", &HwRemDecayer::_alphaS, false, false, true, false, false); static Reference interfaceAlphaEM ("AlphaEM", "Pointer to object to calculate the electromagnetic coupling", &HwRemDecayer::_alphaEM, false, false, true, false, false); static Parameter 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 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 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 interfaceMaxTrySoft ("MaxTrySoft", "The maximum number of regeneration attempts for an additional soft scattering", &HwRemDecayer::maxtrySoft_, 10, 0, 100, false, false, Interface::limited); static Parameter 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 interaceladderPower ("ladderPower", "The power factor in the ladder parameterization.", &HwRemDecayer::ladderPower_, 1.0, -5.0, 10.0, false, false, Interface::limited); static Parameter interfaceladderNorm ("ladderNorm", "The normalization factor in the ladder parameterization", &HwRemDecayer::ladderNorm_, 1.0, 0.0, 10.0, false, false, Interface::limited); static Parameter interfaceladderMult ("ladderMult", "The ladder multiplicity factor ", &HwRemDecayer::ladderMult_, 1.0, 0.0, 10.0, false, false, Interface::limited); static Parameter interfaceladderbFactor ("ladderbFactor", "The additive factor in the multiperipheral ladder multiplicity.", &HwRemDecayer::ladderbFactor_, 1.0, 0.0, 10.0, false, false, Interface::limited); static Parameter 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 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 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 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 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;ixchildren().size();++ix) { if(dynamic_ptr_cast(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& newParticles, const pair& newPDFs, pair newFractions, pair 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& newParticles, const pair& newPDFs, pair newFractions, pair decaying, pair offShell, pair 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::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 left_particles; pair right_particles; pair left_pdfs; pair right_pdfs; pair left_fractions; pair right_fractions; // Pairs containing indicators for decayed particles pair left_decays = {false,false}; pair right_decays = {false,false}; // Pairs containing indicators for off-shell particles pair left_off_shells = {false,false}; pair 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 #include #include #include using namespace std; namespace MG5_sm_COLOREA { void ixxxxx(double p[4], double fmass, int nhel, int nsf, complex fi[6]) { complex chi[2]; double sf[2], sfomega[2], omega[2], pp, pp3, sqp0p3, sqm[2]; int ip, im, nh; fi[0] = complex (-p[0] * nsf, -p[3] * nsf); fi[1] = complex (-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 (sqrt(pp3 * 0.5/pp), 0); if (pp3 == 0.0) { chi[1] = complex (-nh, 0); } else { chi[1] = complex (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 (sqp0p3, 0.0); if (sqp0p3 == 0.0) { chi[1] = complex (-nhel * sqrt(2.0 * p[0]), 0.0); } else { chi[1] = complex (nh * p[1], p[2])/sqp0p3; } if (nh == 1) { fi[2] = complex (0.0, 0.0); fi[3] = complex (0.0, 0.0); fi[4] = chi[0]; fi[5] = chi[1]; } else { fi[2] = chi[1]; fi[3] = chi[0]; fi[4] = complex (0.0, 0.0); fi[5] = complex (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 tc[18]) { complex 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 (p[0] * nst, p[3] * nst); ft[5][0] = complex (p[1] * nst, p[2] * nst); // construct eps+ if(nhel >= 0) { if(pp == 0) { ep[0] = complex (0, 0); ep[1] = complex (-sqh, 0); ep[2] = complex (0, nst * sqh); ep[3] = complex (0, 0); } else { ep[0] = complex (0, 0); ep[3] = complex (pt/pp * sqh, 0); if(pt != 0) { pzpt = p[3]/(pp * pt) * sqh; ep[1] = complex (-p[1] * pzpt, -nst * p[2]/pt * sqh); ep[2] = complex (-p[2] * pzpt, nst * p[1]/pt * sqh); } else { ep[1] = complex (-sqh, 0); ep[2] = complex (0, nst * Sgn(sqh, p[3])); } } } // construct eps- if(nhel <= 0) { if(pp == 0) { em[0] = complex (0, 0); em[1] = complex (sqh, 0); em[2] = complex (0, nst * sqh); em[3] = complex (0, 0); } else { em[0] = complex (0, 0); em[3] = complex (-pt/pp * sqh, 0); if(pt != 0) { pzpt = -p[3]/(pp * pt) * sqh; em[1] = complex (-p[1] * pzpt, -nst * p[2]/pt * sqh); em[2] = complex (-p[2] * pzpt, nst * p[1]/pt * sqh); } else { em[1] = complex (sqh, 0); em[2] = complex (0, nst * Sgn(sqh, p[3])); } } } // construct eps0 if(std::labs(nhel) <= 1) { if(pp == 0) { e0[0] = complex (0, 0); e0[1] = complex (0, 0); e0[2] = complex (0, 0); e0[3] = complex (1, 0); } else { emp = p[0]/(tmass * pp); e0[0] = complex (pp/tmass, 0); e0[3] = complex (p[3] * emp, 0); if(pt != 0) { e0[1] = complex (p[1] * emp, 0); e0[2] = complex (p[2] * emp, 0); } else { e0[1] = complex (0, 0); e0[2] = complex (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 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 (p[0] * nsv, p[3] * nsv); vc[1] = complex (p[1] * nsv, p[2] * nsv); if (vmass != 0.0) { hel0 = 1.0 - std::abs(hel); if(pp == 0.0) { vc[2] = complex (0.0, 0.0); vc[3] = complex (-hel * sqh, 0.0); vc[4] = complex (0.0, nsvahl * sqh); vc[5] = complex (hel0, 0.0); } else { emp = p[0]/(vmass * pp); vc[2] = complex (hel0 * pp/vmass, 0.0); vc[5] = complex (hel0 * p[3] * emp + hel * pt/pp * sqh, 0.0); if (pt != 0.0) { pzpt = p[3]/(pp * pt) * sqh * hel; vc[3] = complex (hel0 * p[1] * emp - p[1] * pzpt, -nsvahl * p[2]/pt * sqh); vc[4] = complex (hel0 * p[2] * emp - p[2] * pzpt, nsvahl * p[1]/pt * sqh); } else { vc[3] = complex (-hel * sqh, 0.0); vc[4] = complex (0.0, nsvahl * Sgn(sqh, p[3])); } } } else { pp = p[0]; pt = sqrt((p[1] * p[1]) + (p[2] * p[2])); vc[2] = complex (0.0, 0.0); vc[5] = complex (hel * pt/pp * sqh, 0.0); if (pt != 0.0) { pzpt = p[3]/(pp * pt) * sqh * hel; vc[3] = complex (-p[1] * pzpt, -nsv * p[2]/pt * sqh); vc[4] = complex (-p[2] * pzpt, nsv * p[1]/pt * sqh); } else { vc[3] = complex (-hel * sqh, 0.0); vc[4] = complex (0.0, nsv * Sgn(sqh, p[3])); } } return; } void sxxxxx(double p[4], int nss, complex sc[3]) { sc[2] = complex (1.00, 0.00); sc[0] = complex (p[0] * nss, p[3] * nss); sc[1] = complex (p[1] * nss, p[2] * nss); return; } void oxxxxx(double p[4], double fmass, int nhel, int nsf, complex fo[6]) { complex chi[2]; double sf[2], sfomeg[2], omega[2], pp, pp3, sqp0p3, sqm[2]; int nh, ip, im; fo[0] = complex (p[0] * nsf, p[3] * nsf); fo[1] = complex (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 (sqrt(pp3 * 0.5/pp), 0.00); if (pp3 == 0.00) { chi[1] = complex (-nh, 0.00); } else { chi[1] = complex (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 (sqp0p3, 0.00); if(sqp0p3 == 0.000) { chi[1] = complex (-nhel, 0.00) * sqrt(2.0 * p[0]); } else { chi[1] = complex (nh * p[1], -p[2])/sqp0p3; } if(nh == 1) { fo[2] = chi[0]; fo[3] = chi[1]; fo[4] = complex (0.00, 0.00); fo[5] = complex (0.00, 0.00); } else { fo[2] = complex (0.00, 0.00); fo[3] = complex (0.00, 0.00); fo[4] = chi[1]; fo[5] = chi[0]; } } return; } void FFV1P0_3(std::complex F1[], std::complex F2[], std::complex COUP, double M3, double W3, std::complex V3[]) { static std::complex cI = std::complex (0., 1.); double P3[4]; std::complex 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 F1[], std::complex V3[], std::complex COUP, double M2, double W2, std::complex F2[]) { static std::complex cI = std::complex (0., 1.); double P2[4]; std::complex 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 F1[], std::complex V3[], std::complex COUP1, std::complex COUP2, double M2, double W2, std::complex F2[]) { std::complex Ftmp[6]; - std::complex 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 F1[], std::complex V3[], std::complex COUP, double M2, double W2, std::complex F2[]) { static std::complex cI = std::complex (0., 1.); double P2[4]; std::complex 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 F1[], std::complex F2[], std::complex V3[], std::complex COUP, std::complex & vertex) { static std::complex cI = std::complex (0., 1.); std::complex 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 F1[], std::complex F2[], std::complex V3[], std::complex COUP1, std::complex COUP2, std::complex & vertex) { std::complex tmp; FFV2_0(F1, F2, V3, COUP1, vertex); FFV5_0(F1, F2, V3, COUP2, tmp); vertex = vertex + tmp; } void FFV5_1(std::complex F2[], std::complex V3[], std::complex COUP, double M1, double W1, std::complex F1[]) { static std::complex cI = std::complex (0., 1.); double P1[4]; std::complex 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 F1[], std::complex F2[], std::complex V3[], std::complex COUP, std::complex & vertex) { static std::complex cI = std::complex (0., 1.); std::complex 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 V2[], std::complex V3[], std::complex V4[], std::complex COUP, double M1, double W1, std::complex V1[]) { static std::complex cI = std::complex (0., 1.); std::complex TMP12; std::complex TMP11; double P1[4]; std::complex 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 V2[], std::complex V3[], std::complex V4[], std::complex COUP, double M1, double W1, std::complex V1[]) { static std::complex cI = std::complex (0., 1.); std::complex TMP12; double P1[4]; std::complex TMP6; std::complex 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 V1[], std::complex V2[], std::complex V3[], std::complex COUP, std::complex & vertex) { static std::complex cI = std::complex (0., 1.); std::complex TMP2; std::complex TMP1; double P1[4]; std::complex TMP0; double P2[4]; std::complex TMP7; double P3[4]; std::complex TMP6; std::complex TMP5; std::complex TMP4; std::complex TMP3; std::complex 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 F1[], std::complex F2[], std::complex COUP, double M3, double W3, std::complex V3[]) { static std::complex cI = std::complex (0., 1.); std::complex denom; std::complex 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 F1[], std::complex F2[], std::complex COUP1, std::complex COUP2, double M3, double W3, std::complex V3[]) { - std::complex denom; - int i; + int i; std::complex 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 F1[], std::complex V3[], std::complex COUP, double M2, double W2, std::complex F2[]) { static std::complex cI = std::complex (0., 1.); double P2[4]; std::complex 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 F2[], std::complex V3[], std::complex COUP, double M1, double W1, std::complex F1[]) { static std::complex cI = std::complex (0., 1.); double P1[4]; std::complex 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 F2[], std::complex V3[], std::complex COUP1, std::complex COUP2, double M1, double W1, std::complex F1[]) { - std::complex denom; - int i; + int i; std::complex 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 F1[], std::complex F2[], std::complex V3[], std::complex COUP, std::complex & vertex) { static std::complex cI = std::complex (0., 1.); std::complex TMP15; std::complex 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 F2[], std::complex V3[], std::complex COUP, double M1, double W1, std::complex F1[]) { static std::complex cI = std::complex (0., 1.); double P1[4]; std::complex 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 F1[], std::complex F2[], std::complex COUP, double M3, double W3, std::complex V3[]) { static std::complex cI = std::complex (0., 1.); std::complex denom; std::complex TMP10; double P3[4]; double OM3; std::complex 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 V2[], std::complex V3[], std::complex V4[], std::complex COUP, double M1, double W1, std::complex V1[]) { static std::complex cI = std::complex (0., 1.); std::complex TMP11; double P1[4]; std::complex TMP6; std::complex 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 V2[], std::complex V3[], std::complex COUP, double M1, double W1, std::complex V1[]) { static std::complex cI = std::complex (0., 1.); std::complex TMP2; double P1[4]; std::complex TMP0; double P2[4]; double P3[4]; std::complex TMP6; std::complex TMP5; std::complex TMP4; std::complex 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 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 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 "< r )return std::vector(res[i], res[i] + sizeof res[i] / sizeof res[i][0]); } std::cerr<<"\nproducePermutation: Upps.. Something went wrong!!\n"<(); } 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 ztemp; std::complex 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 (0, 1) * amp[12] - std::complex (0, 1) * amp[13] - std::complex (0, 1) * amp[14] - std::complex (0, 1) * amp[15]; jamp[1] = +amp[4] + amp[5] + amp[6] + amp[7] + amp[8] + amp[9] + std::complex (0, 1) * amp[12] + std::complex (0, 1) * amp[13] + std::complex (0, 1) * amp[14] + std::complex (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 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 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(res[i], res[i] + sizeof res[i] / sizeof res[i][0]); } //std::cout<<"producePermutation: Upps.. Something went wrong!!"; return std::vector(); } 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 * * 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 ztemp; std::complex 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 (0, 1) * amp[12] - std::complex (0, 1) * amp[13] - std::complex (0, 1) * amp[14] - std::complex (0, 1) * amp[15] + amp[65] + amp[67] - std::complex (0, 1) * amp[68] - std::complex (0, 1) * amp[69] - std::complex (0, 1) * amp[70] - std::complex (0, 1) * amp[71] - amp[73] - std::complex (0, 1) * amp[74] - amp[75] - amp[77] - std::complex (0, 1) * amp[78] - amp[79] - std::complex (0, 1) * amp[88] - amp[89] - amp[91] - std::complex (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 (0, 1) * amp[12] + std::complex (0, 1) * amp[13] + std::complex (0, 1) * amp[14] + std::complex (0, 1) * amp[15] + amp[57] + amp[59] - std::complex (0, 1) * amp[60] - std::complex (0, 1) * amp[61] - std::complex (0, 1) * amp[62] - std::complex (0, 1) * amp[63] - amp[81] - std::complex (0, 1) * amp[82] - amp[83] - amp[85] - std::complex (0, 1) * amp[86] - amp[87] + std::complex (0, 1) * amp[88] + amp[89] + amp[91] + std::complex (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 (0, 1) * amp[28] - std::complex (0, 1) * amp[29] - std::complex (0, 1) * amp[30] - std::complex (0, 1) * amp[31] + amp[64] + amp[66] + std::complex (0, 1) * amp[68] + std::complex (0, 1) * amp[69] + std::complex (0, 1) * amp[70] + std::complex (0, 1) * amp[71] + amp[73] + std::complex (0, 1) * amp[74] + amp[75] + amp[77] + std::complex (0, 1) * amp[78] + amp[79] - std::complex (0, 1) * amp[80] + amp[81] + amp[83] - std::complex (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 (0, 1) * amp[28] + std::complex (0, 1) * amp[29] + std::complex (0, 1) * amp[30] + std::complex (0, 1) * amp[31] + amp[49] + amp[51] - std::complex (0, 1) * amp[52] - std::complex (0, 1) * amp[53] - std::complex (0, 1) * amp[54] - std::complex (0, 1) * amp[55] + std::complex (0, 1) * amp[80] - amp[81] - amp[83] + std::complex (0, 1) * amp[84] - amp[85] - amp[87] + amp[89] - std::complex (0, 1) * amp[90] + amp[91] + amp[93] - std::complex (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 (0, 1) * amp[44] - std::complex (0, 1) * amp[45] - std::complex (0, 1) * amp[46] - std::complex (0, 1) * amp[47] + amp[56] + amp[58] + std::complex (0, 1) * amp[60] + std::complex (0, 1) * amp[61] + std::complex (0, 1) * amp[62] + std::complex (0, 1) * amp[63] - std::complex (0, 1) * amp[72] + amp[73] + amp[75] - std::complex (0, 1) * amp[76] + amp[77] + amp[79] + amp[81] + std::complex (0, 1) * amp[82] + amp[83] + amp[85] + std::complex (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 (0, 1) * amp[44] + std::complex (0, 1) * amp[45] + std::complex (0, 1) * amp[46] + std::complex (0, 1) * amp[47] + amp[48] + amp[50] + std::complex (0, 1) * amp[52] + std::complex (0, 1) * amp[53] + std::complex (0, 1) * amp[54] + std::complex (0, 1) * amp[55] + std::complex (0, 1) * amp[72] - amp[73] - amp[75] + std::complex (0, 1) * amp[76] - amp[77] - amp[79] - amp[89] + std::complex (0, 1) * amp[90] - amp[91] - amp[93] + std::complex (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 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 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(res[i], res[i] + sizeof res[i] / sizeof res[i][0]); } //std::cout<<"producePermutation: Upps.. Something went wrong!!"; return std::vector(); } 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 * * 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 ztemp; std::complex 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 (0, 1) * amp[56] - std::complex (0, 1) * amp[57] - std::complex (0, 1) * amp[58] - std::complex (0, 1) * amp[59] - amp[61] - std::complex (0, 1) * amp[62] - amp[64] - amp[67] - std::complex (0, 1) * amp[68] - amp[70] - std::complex (0, 1) * amp[84] - amp[85] - std::complex (0, 1) * amp[86] - amp[88] - std::complex (0, 1) * amp[89] - std::complex (0, 1) * amp[90] - amp[91] - std::complex (0, 1) * amp[92] - amp[94] - std::complex (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 (0, 1) * amp[625] - amp[626] - std::complex (0, 1) * amp[627] - amp[628] - std::complex (0, 1) * amp[629] - std::complex (0, 1) * amp[631] - amp[632] - std::complex (0, 1) * amp[633] - amp[634] - std::complex (0, 1) * amp[635] - std::complex (0, 1) * amp[649] - amp[650] - amp[652] - std::complex (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 (0, 1) * amp[674] - std::complex (0, 1) * amp[680] + std::complex (0, 1) * amp[678] - std::complex (0, 1) * amp[682] + std::complex (0, 1) * amp[683] - amp[684] - std::complex (0, 1) * amp[689] + std::complex (0, 1) * amp[687] + std::complex (0, 1) * amp[692] - std::complex (0, 1) * amp[698] + std::complex (0, 1) * amp[696] - std::complex (0, 1) * amp[700] + std::complex (0, 1) * amp[701] - amp[702] - std::complex (0, 1) * amp[707] + std::complex (0, 1) * amp[705] - amp[709] + std::complex (0, 1) * amp[710] - amp[711] + std::complex (0, 1) * amp[713] - amp[714] - amp[717] + std::complex (0, 1) * amp[718] - amp[719] + std::complex (0, 1) * amp[721] - amp[722] + std::complex (0, 1) * amp[830] + std::complex (0, 1) * amp[832] - amp[833] - std::complex (0, 1) * amp[836] + std::complex (0, 1) * amp[834] + std::complex (0, 1) * amp[839] - amp[840] + std::complex (0, 1) * amp[841] - std::complex (0, 1) * amp[845] + std::complex (0, 1) * amp[843] + std::complex (0, 1) * amp[848] + std::complex (0, 1) * amp[850] - amp[851] - std::complex (0, 1) * amp[854] + std::complex (0, 1) * amp[852] + std::complex (0, 1) * amp[857] - amp[858] + std::complex (0, 1) * amp[859] - std::complex (0, 1) * amp[863] + std::complex (0, 1) * amp[861] - std::complex (0, 1) * amp[900] + std::complex (0, 1) * amp[904] - amp[905] - std::complex (0, 1) * amp[908] + std::complex (0, 1) * amp[906] + std::complex (0, 1) * amp[913] - std::complex (0, 1) * amp[917] + std::complex (0, 1) * amp[915] - std::complex (0, 1) * amp[918] + std::complex (0, 1) * amp[922] - amp[923] - std::complex (0, 1) * amp[926] + std::complex (0, 1) * amp[924] + std::complex (0, 1) * amp[931] - std::complex (0, 1) * amp[935] + std::complex (0, 1) * amp[933] - std::complex (0, 1) * amp[941] + std::complex (0, 1) * amp[939] + amp[944] - amp[942] - std::complex (0, 1) * amp[947] + std::complex (0, 1) * amp[945] - std::complex (0, 1) * amp[953] + std::complex (0, 1) * amp[951] + amp[956] - amp[954] - std::complex (0, 1) * amp[959] + std::complex (0, 1) * amp[957] + amp[1010] - amp[1008] - std::complex (0, 1) * amp[1013] + std::complex (0, 1) * amp[1011] - std::complex (0, 1) * amp[1019] + std::complex (0, 1) * amp[1017] + amp[1022] - amp[1020] - std::complex (0, 1) * amp[1025] + std::complex (0, 1) * amp[1023] - std::complex (0, 1) * amp[1031] + std::complex (0, 1) * amp[1029]; jamp[1] = +amp[0] + amp[6] + amp[29] + amp[30] + amp[32] + amp[35] + amp[36] + amp[38] - std::complex (0, 1) * amp[40] - std::complex (0, 1) * amp[41] - std::complex (0, 1) * amp[42] - std::complex (0, 1) * amp[43] - amp[73] - std::complex (0, 1) * amp[74] - amp[76] - amp[79] - std::complex (0, 1) * amp[80] - amp[82] + std::complex (0, 1) * amp[84] + amp[85] + std::complex (0, 1) * amp[86] + amp[88] + std::complex (0, 1) * amp[89] + std::complex (0, 1) * amp[90] + amp[91] + std::complex (0, 1) * amp[92] + amp[94] + std::complex (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 (0, 1) * amp[565] - amp[566] - std::complex (0, 1) * amp[567] - amp[568] - std::complex (0, 1) * amp[569] - std::complex (0, 1) * amp[571] - amp[572] - std::complex (0, 1) * amp[573] - amp[574] - std::complex (0, 1) * amp[575] - std::complex (0, 1) * amp[589] - amp[590] - amp[592] - std::complex (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 (0, 1) * amp[676] - std::complex (0, 1) * amp[678] - std::complex (0, 1) * amp[679] - std::complex (0, 1) * amp[681] + std::complex (0, 1) * amp[685] - amp[686] - std::complex (0, 1) * amp[687] - std::complex (0, 1) * amp[688] + std::complex (0, 1) * amp[694] - std::complex (0, 1) * amp[696] - std::complex (0, 1) * amp[697] - std::complex (0, 1) * amp[699] + std::complex (0, 1) * amp[703] - amp[704] - std::complex (0, 1) * amp[705] - std::complex (0, 1) * amp[706] + amp[709] - std::complex (0, 1) * amp[710] + amp[711] - std::complex (0, 1) * amp[713] + amp[714] + amp[717] - std::complex (0, 1) * amp[718] + amp[719] - std::complex (0, 1) * amp[721] + amp[722] + std::complex (0, 1) * amp[866] + std::complex (0, 1) * amp[868] - amp[869] - std::complex (0, 1) * amp[872] + std::complex (0, 1) * amp[870] + std::complex (0, 1) * amp[875] - amp[876] + std::complex (0, 1) * amp[877] - std::complex (0, 1) * amp[881] + std::complex (0, 1) * amp[879] + std::complex (0, 1) * amp[884] + std::complex (0, 1) * amp[886] - amp[887] - std::complex (0, 1) * amp[890] + std::complex (0, 1) * amp[888] + std::complex (0, 1) * amp[893] - amp[894] + std::complex (0, 1) * amp[895] - std::complex (0, 1) * amp[899] + std::complex (0, 1) * amp[897] + std::complex (0, 1) * amp[900] - std::complex (0, 1) * amp[904] + amp[905] + std::complex (0, 1) * amp[908] - std::complex (0, 1) * amp[906] - std::complex (0, 1) * amp[913] + std::complex (0, 1) * amp[917] - std::complex (0, 1) * amp[915] + std::complex (0, 1) * amp[918] - std::complex (0, 1) * amp[922] + amp[923] + std::complex (0, 1) * amp[926] - std::complex (0, 1) * amp[924] - std::complex (0, 1) * amp[931] + std::complex (0, 1) * amp[935] - std::complex (0, 1) * amp[933] - std::complex (0, 1) * amp[965] + std::complex (0, 1) * amp[963] + amp[968] - amp[966] - std::complex (0, 1) * amp[971] + std::complex (0, 1) * amp[969] - std::complex (0, 1) * amp[977] + std::complex (0, 1) * amp[975] + amp[980] - amp[978] - std::complex (0, 1) * amp[983] + std::complex (0, 1) * amp[981] + amp[1008] + amp[1009] - std::complex (0, 1) * amp[1011] - std::complex (0, 1) * amp[1012] - std::complex (0, 1) * amp[1017] - std::complex (0, 1) * amp[1018] + amp[1020] + amp[1021] - std::complex (0, 1) * amp[1023] - std::complex (0, 1) * amp[1024] - std::complex (0, 1) * amp[1029] - std::complex (0, 1) * amp[1030]; jamp[2] = +amp[3] + amp[9] + amp[44] + amp[47] + amp[49] + amp[50] + amp[53] + amp[55] + std::complex (0, 1) * amp[56] + std::complex (0, 1) * amp[57] + std::complex (0, 1) * amp[58] + std::complex (0, 1) * amp[59] + amp[61] + std::complex (0, 1) * amp[62] + amp[64] + amp[67] + std::complex (0, 1) * amp[68] + amp[70] - std::complex (0, 1) * amp[72] + amp[73] - std::complex (0, 1) * amp[75] + amp[76] - std::complex (0, 1) * amp[77] - std::complex (0, 1) * amp[78] + amp[79] - std::complex (0, 1) * amp[81] + amp[82] - std::complex (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 (0, 1) * amp[637] - amp[638] - std::complex (0, 1) * amp[639] - amp[640] - std::complex (0, 1) * amp[641] - std::complex (0, 1) * amp[643] - amp[644] - std::complex (0, 1) * amp[645] - amp[646] - std::complex (0, 1) * amp[647] + std::complex (0, 1) * amp[649] + amp[650] + amp[652] + std::complex (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 (0, 1) * amp[726] - std::complex (0, 1) * amp[732] + std::complex (0, 1) * amp[730] - std::complex (0, 1) * amp[734] + std::complex (0, 1) * amp[735] - amp[736] - std::complex (0, 1) * amp[741] + std::complex (0, 1) * amp[739] + std::complex (0, 1) * amp[744] - std::complex (0, 1) * amp[750] + std::complex (0, 1) * amp[748] - std::complex (0, 1) * amp[752] + std::complex (0, 1) * amp[753] - amp[754] - std::complex (0, 1) * amp[759] + std::complex (0, 1) * amp[757] - amp[761] + std::complex (0, 1) * amp[762] - amp[763] + std::complex (0, 1) * amp[765] - amp[766] - amp[769] + std::complex (0, 1) * amp[770] - amp[771] + std::complex (0, 1) * amp[773] - amp[774] - std::complex (0, 1) * amp[830] - std::complex (0, 1) * amp[832] + amp[833] + std::complex (0, 1) * amp[836] - std::complex (0, 1) * amp[834] - std::complex (0, 1) * amp[839] + amp[840] - std::complex (0, 1) * amp[841] + std::complex (0, 1) * amp[845] - std::complex (0, 1) * amp[843] - std::complex (0, 1) * amp[848] - std::complex (0, 1) * amp[850] + amp[851] + std::complex (0, 1) * amp[854] - std::complex (0, 1) * amp[852] - std::complex (0, 1) * amp[857] + amp[858] - std::complex (0, 1) * amp[859] + std::complex (0, 1) * amp[863] - std::complex (0, 1) * amp[861] - std::complex (0, 1) * amp[864] - std::complex (0, 1) * amp[868] + amp[869] - std::complex (0, 1) * amp[870] - std::complex (0, 1) * amp[871] - std::complex (0, 1) * amp[877] - std::complex (0, 1) * amp[879] - std::complex (0, 1) * amp[880] - std::complex (0, 1) * amp[882] - std::complex (0, 1) * amp[886] + amp[887] - std::complex (0, 1) * amp[888] - std::complex (0, 1) * amp[889] - std::complex (0, 1) * amp[895] - std::complex (0, 1) * amp[897] - std::complex (0, 1) * amp[898] - std::complex (0, 1) * amp[939] - std::complex (0, 1) * amp[940] + amp[942] + amp[943] - std::complex (0, 1) * amp[945] - std::complex (0, 1) * amp[946] - std::complex (0, 1) * amp[951] - std::complex (0, 1) * amp[952] + amp[954] + amp[955] - std::complex (0, 1) * amp[957] - std::complex (0, 1) * amp[958] - amp[1010] - amp[1009] + std::complex (0, 1) * amp[1013] + std::complex (0, 1) * amp[1012] + std::complex (0, 1) * amp[1019] + std::complex (0, 1) * amp[1018] - amp[1022] - amp[1021] + std::complex (0, 1) * amp[1025] + std::complex (0, 1) * amp[1024] + std::complex (0, 1) * amp[1031] + std::complex (0, 1) * amp[1030]; jamp[3] = +amp[2] + amp[8] + amp[13] + amp[14] + amp[16] + amp[19] + amp[20] + amp[22] - std::complex (0, 1) * amp[24] - std::complex (0, 1) * amp[25] - std::complex (0, 1) * amp[26] - std::complex (0, 1) * amp[27] + std::complex (0, 1) * amp[72] - amp[73] + std::complex (0, 1) * amp[75] - amp[76] + std::complex (0, 1) * amp[77] + std::complex (0, 1) * amp[78] - amp[79] + std::complex (0, 1) * amp[81] - amp[82] + std::complex (0, 1) * amp[83] + amp[85] - std::complex (0, 1) * amp[87] + amp[88] + amp[91] - std::complex (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 (0, 1) * amp[505] - amp[506] - std::complex (0, 1) * amp[507] - amp[508] - std::complex (0, 1) * amp[509] - std::complex (0, 1) * amp[511] - amp[512] - std::complex (0, 1) * amp[513] - amp[514] - std::complex (0, 1) * amp[515] - std::complex (0, 1) * amp[529] - amp[530] - amp[532] - std::complex (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 (0, 1) * amp[728] - std::complex (0, 1) * amp[730] - std::complex (0, 1) * amp[731] - std::complex (0, 1) * amp[733] + std::complex (0, 1) * amp[737] - amp[738] - std::complex (0, 1) * amp[739] - std::complex (0, 1) * amp[740] + std::complex (0, 1) * amp[746] - std::complex (0, 1) * amp[748] - std::complex (0, 1) * amp[749] - std::complex (0, 1) * amp[751] + std::complex (0, 1) * amp[755] - amp[756] - std::complex (0, 1) * amp[757] - std::complex (0, 1) * amp[758] + amp[761] - std::complex (0, 1) * amp[762] + amp[763] - std::complex (0, 1) * amp[765] + amp[766] + amp[769] - std::complex (0, 1) * amp[770] + amp[771] - std::complex (0, 1) * amp[773] + amp[774] + std::complex (0, 1) * amp[864] + std::complex (0, 1) * amp[868] - amp[869] + std::complex (0, 1) * amp[870] + std::complex (0, 1) * amp[871] + std::complex (0, 1) * amp[877] + std::complex (0, 1) * amp[879] + std::complex (0, 1) * amp[880] + std::complex (0, 1) * amp[882] + std::complex (0, 1) * amp[886] - amp[887] + std::complex (0, 1) * amp[888] + std::complex (0, 1) * amp[889] + std::complex (0, 1) * amp[895] + std::complex (0, 1) * amp[897] + std::complex (0, 1) * amp[898] + std::complex (0, 1) * amp[902] - std::complex (0, 1) * amp[904] + amp[905] - std::complex (0, 1) * amp[906] - std::complex (0, 1) * amp[907] + std::complex (0, 1) * amp[911] - amp[912] - std::complex (0, 1) * amp[913] - std::complex (0, 1) * amp[915] - std::complex (0, 1) * amp[916] + std::complex (0, 1) * amp[920] - std::complex (0, 1) * amp[922] + amp[923] - std::complex (0, 1) * amp[924] - std::complex (0, 1) * amp[925] + std::complex (0, 1) * amp[929] - amp[930] - std::complex (0, 1) * amp[931] - std::complex (0, 1) * amp[933] - std::complex (0, 1) * amp[934] - std::complex (0, 1) * amp[989] + std::complex (0, 1) * amp[987] + amp[992] - amp[990] - std::complex (0, 1) * amp[995] + std::complex (0, 1) * amp[993] - std::complex (0, 1) * amp[1001] + std::complex (0, 1) * amp[999] + amp[1004] - amp[1002] - std::complex (0, 1) * amp[1007] + std::complex (0, 1) * amp[1005] + amp[1008] + amp[1009] - std::complex (0, 1) * amp[1011] - std::complex (0, 1) * amp[1012] - std::complex (0, 1) * amp[1017] - std::complex (0, 1) * amp[1018] + amp[1020] + amp[1021] - std::complex (0, 1) * amp[1023] - std::complex (0, 1) * amp[1024] - std::complex (0, 1) * amp[1029] - std::complex (0, 1) * amp[1030]; jamp[4] = +amp[5] + amp[11] + amp[28] + amp[31] + amp[33] + amp[34] + amp[37] + amp[39] + std::complex (0, 1) * amp[40] + std::complex (0, 1) * amp[41] + std::complex (0, 1) * amp[42] + std::complex (0, 1) * amp[43] - std::complex (0, 1) * amp[60] + amp[61] - std::complex (0, 1) * amp[63] + amp[64] - std::complex (0, 1) * amp[65] - std::complex (0, 1) * amp[66] + amp[67] - std::complex (0, 1) * amp[69] + amp[70] - std::complex (0, 1) * amp[71] + amp[73] + std::complex (0, 1) * amp[74] + amp[76] + amp[79] + std::complex (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 (0, 1) * amp[577] - amp[578] - std::complex (0, 1) * amp[579] - amp[580] - std::complex (0, 1) * amp[581] - std::complex (0, 1) * amp[583] - amp[584] - std::complex (0, 1) * amp[585] - amp[586] - std::complex (0, 1) * amp[587] + std::complex (0, 1) * amp[589] + amp[590] + amp[592] + std::complex (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 (0, 1) * amp[778] - std::complex (0, 1) * amp[784] + std::complex (0, 1) * amp[782] - std::complex (0, 1) * amp[786] + std::complex (0, 1) * amp[787] - amp[788] - std::complex (0, 1) * amp[793] + std::complex (0, 1) * amp[791] + std::complex (0, 1) * amp[796] - std::complex (0, 1) * amp[802] + std::complex (0, 1) * amp[800] - std::complex (0, 1) * amp[804] + std::complex (0, 1) * amp[805] - amp[806] - std::complex (0, 1) * amp[811] + std::complex (0, 1) * amp[809] - amp[813] + std::complex (0, 1) * amp[814] - amp[815] + std::complex (0, 1) * amp[817] - amp[818] - amp[821] + std::complex (0, 1) * amp[822] - amp[823] + std::complex (0, 1) * amp[825] - amp[826] - std::complex (0, 1) * amp[828] - std::complex (0, 1) * amp[832] + amp[833] - std::complex (0, 1) * amp[834] - std::complex (0, 1) * amp[835] - std::complex (0, 1) * amp[841] - std::complex (0, 1) * amp[843] - std::complex (0, 1) * amp[844] - std::complex (0, 1) * amp[846] - std::complex (0, 1) * amp[850] + amp[851] - std::complex (0, 1) * amp[852] - std::complex (0, 1) * amp[853] - std::complex (0, 1) * amp[859] - std::complex (0, 1) * amp[861] - std::complex (0, 1) * amp[862] - std::complex (0, 1) * amp[866] - std::complex (0, 1) * amp[868] + amp[869] + std::complex (0, 1) * amp[872] - std::complex (0, 1) * amp[870] - std::complex (0, 1) * amp[875] + amp[876] - std::complex (0, 1) * amp[877] + std::complex (0, 1) * amp[881] - std::complex (0, 1) * amp[879] - std::complex (0, 1) * amp[884] - std::complex (0, 1) * amp[886] + amp[887] + std::complex (0, 1) * amp[890] - std::complex (0, 1) * amp[888] - std::complex (0, 1) * amp[893] + amp[894] - std::complex (0, 1) * amp[895] + std::complex (0, 1) * amp[899] - std::complex (0, 1) * amp[897] - std::complex (0, 1) * amp[963] - std::complex (0, 1) * amp[964] + amp[966] + amp[967] - std::complex (0, 1) * amp[969] - std::complex (0, 1) * amp[970] - std::complex (0, 1) * amp[975] - std::complex (0, 1) * amp[976] + amp[978] + amp[979] - std::complex (0, 1) * amp[981] - std::complex (0, 1) * amp[982] - amp[1010] - amp[1009] + std::complex (0, 1) * amp[1013] + std::complex (0, 1) * amp[1012] + std::complex (0, 1) * amp[1019] + std::complex (0, 1) * amp[1018] - amp[1022] - amp[1021] + std::complex (0, 1) * amp[1025] + std::complex (0, 1) * amp[1024] + std::complex (0, 1) * amp[1031] + std::complex (0, 1) * amp[1030]; jamp[5] = +amp[4] + amp[10] + amp[12] + amp[15] + amp[17] + amp[18] + amp[21] + amp[23] + std::complex (0, 1) * amp[24] + std::complex (0, 1) * amp[25] + std::complex (0, 1) * amp[26] + std::complex (0, 1) * amp[27] + std::complex (0, 1) * amp[60] - amp[61] + std::complex (0, 1) * amp[63] - amp[64] + std::complex (0, 1) * amp[65] + std::complex (0, 1) * amp[66] - amp[67] + std::complex (0, 1) * amp[69] - amp[70] + std::complex (0, 1) * amp[71] - amp[85] + std::complex (0, 1) * amp[87] - amp[88] - amp[91] + std::complex (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 (0, 1) * amp[517] - amp[518] - std::complex (0, 1) * amp[519] - amp[520] - std::complex (0, 1) * amp[521] - std::complex (0, 1) * amp[523] - amp[524] - std::complex (0, 1) * amp[525] - amp[526] - std::complex (0, 1) * amp[527] + std::complex (0, 1) * amp[529] + amp[530] + amp[532] + std::complex (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 (0, 1) * amp[780] - std::complex (0, 1) * amp[782] - std::complex (0, 1) * amp[783] - std::complex (0, 1) * amp[785] + std::complex (0, 1) * amp[789] - amp[790] - std::complex (0, 1) * amp[791] - std::complex (0, 1) * amp[792] + std::complex (0, 1) * amp[798] - std::complex (0, 1) * amp[800] - std::complex (0, 1) * amp[801] - std::complex (0, 1) * amp[803] + std::complex (0, 1) * amp[807] - amp[808] - std::complex (0, 1) * amp[809] - std::complex (0, 1) * amp[810] + amp[813] - std::complex (0, 1) * amp[814] + amp[815] - std::complex (0, 1) * amp[817] + amp[818] + amp[821] - std::complex (0, 1) * amp[822] + amp[823] - std::complex (0, 1) * amp[825] + amp[826] + std::complex (0, 1) * amp[828] + std::complex (0, 1) * amp[832] - amp[833] + std::complex (0, 1) * amp[834] + std::complex (0, 1) * amp[835] + std::complex (0, 1) * amp[841] + std::complex (0, 1) * amp[843] + std::complex (0, 1) * amp[844] + std::complex (0, 1) * amp[846] + std::complex (0, 1) * amp[850] - amp[851] + std::complex (0, 1) * amp[852] + std::complex (0, 1) * amp[853] + std::complex (0, 1) * amp[859] + std::complex (0, 1) * amp[861] + std::complex (0, 1) * amp[862] - std::complex (0, 1) * amp[902] + std::complex (0, 1) * amp[904] - amp[905] + std::complex (0, 1) * amp[906] + std::complex (0, 1) * amp[907] - std::complex (0, 1) * amp[911] + amp[912] + std::complex (0, 1) * amp[913] + std::complex (0, 1) * amp[915] + std::complex (0, 1) * amp[916] - std::complex (0, 1) * amp[920] + std::complex (0, 1) * amp[922] - amp[923] + std::complex (0, 1) * amp[924] + std::complex (0, 1) * amp[925] - std::complex (0, 1) * amp[929] + amp[930] + std::complex (0, 1) * amp[931] + std::complex (0, 1) * amp[933] + std::complex (0, 1) * amp[934] - std::complex (0, 1) * amp[987] - std::complex (0, 1) * amp[988] + amp[990] + amp[991] - std::complex (0, 1) * amp[993] - std::complex (0, 1) * amp[994] - std::complex (0, 1) * amp[999] - std::complex (0, 1) * amp[1000] + amp[1002] + amp[1003] - std::complex (0, 1) * amp[1005] - std::complex (0, 1) * amp[1006] + amp[1010] - amp[1008] - std::complex (0, 1) * amp[1013] + std::complex (0, 1) * amp[1011] - std::complex (0, 1) * amp[1019] + std::complex (0, 1) * amp[1017] + amp[1022] - amp[1020] - std::complex (0, 1) * amp[1025] + std::complex (0, 1) * amp[1023] - std::complex (0, 1) * amp[1031] + std::complex (0, 1) * amp[1029]; jamp[6] = +amp[109] + amp[115] + amp[153] + amp[154] + amp[156] + amp[159] + amp[160] + amp[162] - std::complex (0, 1) * amp[164] - std::complex (0, 1) * amp[165] - std::complex (0, 1) * amp[166] - std::complex (0, 1) * amp[167] - amp[169] - std::complex (0, 1) * amp[170] - amp[172] - amp[175] - std::complex (0, 1) * amp[176] - amp[178] - std::complex (0, 1) * amp[192] - amp[193] - std::complex (0, 1) * amp[194] - amp[196] - std::complex (0, 1) * amp[197] - std::complex (0, 1) * amp[198] - amp[199] - std::complex (0, 1) * amp[200] - amp[202] - std::complex (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 (0, 1) * amp[625] + amp[626] + std::complex (0, 1) * amp[627] + amp[628] + std::complex (0, 1) * amp[629] + std::complex (0, 1) * amp[631] + amp[632] + std::complex (0, 1) * amp[633] + amp[634] + std::complex (0, 1) * amp[635] - std::complex (0, 1) * amp[636] + amp[638] + amp[640] - std::complex (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 (0, 1) * amp[674] + std::complex (0, 1) * amp[680] - std::complex (0, 1) * amp[678] + std::complex (0, 1) * amp[682] - std::complex (0, 1) * amp[683] + amp[684] + std::complex (0, 1) * amp[689] - std::complex (0, 1) * amp[687] - std::complex (0, 1) * amp[692] + std::complex (0, 1) * amp[698] - std::complex (0, 1) * amp[696] + std::complex (0, 1) * amp[700] - std::complex (0, 1) * amp[701] + amp[702] + std::complex (0, 1) * amp[707] - std::complex (0, 1) * amp[705] + amp[709] - std::complex (0, 1) * amp[710] + amp[711] - std::complex (0, 1) * amp[713] + amp[714] + amp[717] - std::complex (0, 1) * amp[718] + amp[719] - std::complex (0, 1) * amp[721] + amp[722] - std::complex (0, 1) * amp[726] - std::complex (0, 1) * amp[728] - amp[729] + std::complex (0, 1) * amp[732] + std::complex (0, 1) * amp[731] - std::complex (0, 1) * amp[735] + amp[736] - std::complex (0, 1) * amp[737] + std::complex (0, 1) * amp[741] + std::complex (0, 1) * amp[740] - std::complex (0, 1) * amp[744] - std::complex (0, 1) * amp[746] - amp[747] + std::complex (0, 1) * amp[750] + std::complex (0, 1) * amp[749] - std::complex (0, 1) * amp[753] + amp[754] - std::complex (0, 1) * amp[755] + std::complex (0, 1) * amp[759] + std::complex (0, 1) * amp[758] - std::complex (0, 1) * amp[901] - std::complex (0, 1) * amp[902] - amp[903] + std::complex (0, 1) * amp[908] + std::complex (0, 1) * amp[907] - std::complex (0, 1) * amp[911] + std::complex (0, 1) * amp[917] + std::complex (0, 1) * amp[916] - std::complex (0, 1) * amp[919] - std::complex (0, 1) * amp[920] - amp[921] + std::complex (0, 1) * amp[926] + std::complex (0, 1) * amp[925] - std::complex (0, 1) * amp[929] + std::complex (0, 1) * amp[935] + std::complex (0, 1) * amp[934] + std::complex (0, 1) * amp[941] + std::complex (0, 1) * amp[940] - amp[944] - amp[943] + std::complex (0, 1) * amp[947] + std::complex (0, 1) * amp[946] + std::complex (0, 1) * amp[953] + std::complex (0, 1) * amp[952] - amp[956] - amp[955] + std::complex (0, 1) * amp[959] + std::complex (0, 1) * amp[958] + amp[986] - amp[984] + std::complex (0, 1) * amp[989] - std::complex (0, 1) * amp[987] + std::complex (0, 1) * amp[995] - std::complex (0, 1) * amp[993] + amp[998] - amp[996] + std::complex (0, 1) * amp[1001] - std::complex (0, 1) * amp[999] + std::complex (0, 1) * amp[1007] - std::complex (0, 1) * amp[1005]; jamp[7] = +amp[108] + amp[114] + amp[137] + amp[138] + amp[140] + amp[143] + amp[144] + amp[146] - std::complex (0, 1) * amp[148] - std::complex (0, 1) * amp[149] - std::complex (0, 1) * amp[150] - std::complex (0, 1) * amp[151] - amp[181] - std::complex (0, 1) * amp[182] - amp[184] - amp[187] - std::complex (0, 1) * amp[188] - amp[190] + std::complex (0, 1) * amp[192] + amp[193] + std::complex (0, 1) * amp[194] + amp[196] + std::complex (0, 1) * amp[197] + std::complex (0, 1) * amp[198] + amp[199] + std::complex (0, 1) * amp[200] + amp[202] + std::complex (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 (0, 1) * amp[565] + amp[566] + std::complex (0, 1) * amp[567] + amp[568] + std::complex (0, 1) * amp[569] + std::complex (0, 1) * amp[571] + amp[572] + std::complex (0, 1) * amp[573] + amp[574] + std::complex (0, 1) * amp[575] - std::complex (0, 1) * amp[576] + amp[578] + amp[580] - std::complex (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 (0, 1) * amp[676] + std::complex (0, 1) * amp[678] + std::complex (0, 1) * amp[679] + std::complex (0, 1) * amp[681] - std::complex (0, 1) * amp[685] + amp[686] + std::complex (0, 1) * amp[687] + std::complex (0, 1) * amp[688] - std::complex (0, 1) * amp[694] + std::complex (0, 1) * amp[696] + std::complex (0, 1) * amp[697] + std::complex (0, 1) * amp[699] - std::complex (0, 1) * amp[703] + amp[704] + std::complex (0, 1) * amp[705] + std::complex (0, 1) * amp[706] - amp[709] + std::complex (0, 1) * amp[710] - amp[711] + std::complex (0, 1) * amp[713] - amp[714] - amp[717] + std::complex (0, 1) * amp[718] - amp[719] + std::complex (0, 1) * amp[721] - amp[722] - std::complex (0, 1) * amp[778] - std::complex (0, 1) * amp[780] - amp[781] + std::complex (0, 1) * amp[784] + std::complex (0, 1) * amp[783] - std::complex (0, 1) * amp[787] + amp[788] - std::complex (0, 1) * amp[789] + std::complex (0, 1) * amp[793] + std::complex (0, 1) * amp[792] - std::complex (0, 1) * amp[796] - std::complex (0, 1) * amp[798] - amp[799] + std::complex (0, 1) * amp[802] + std::complex (0, 1) * amp[801] - std::complex (0, 1) * amp[805] + amp[806] - std::complex (0, 1) * amp[807] + std::complex (0, 1) * amp[811] + std::complex (0, 1) * amp[810] + std::complex (0, 1) * amp[901] + std::complex (0, 1) * amp[902] + amp[903] - std::complex (0, 1) * amp[908] - std::complex (0, 1) * amp[907] + std::complex (0, 1) * amp[911] - std::complex (0, 1) * amp[917] - std::complex (0, 1) * amp[916] + std::complex (0, 1) * amp[919] + std::complex (0, 1) * amp[920] + amp[921] - std::complex (0, 1) * amp[926] - std::complex (0, 1) * amp[925] + std::complex (0, 1) * amp[929] - std::complex (0, 1) * amp[935] - std::complex (0, 1) * amp[934] + std::complex (0, 1) * amp[965] + std::complex (0, 1) * amp[964] - amp[968] - amp[967] + std::complex (0, 1) * amp[971] + std::complex (0, 1) * amp[970] + std::complex (0, 1) * amp[977] + std::complex (0, 1) * amp[976] - amp[980] - amp[979] + std::complex (0, 1) * amp[983] + std::complex (0, 1) * amp[982] + amp[984] + amp[985] + std::complex (0, 1) * amp[987] + std::complex (0, 1) * amp[988] + std::complex (0, 1) * amp[993] + std::complex (0, 1) * amp[994] + amp[996] + amp[997] + std::complex (0, 1) * amp[999] + std::complex (0, 1) * amp[1000] + std::complex (0, 1) * amp[1005] + std::complex (0, 1) * amp[1006]; jamp[8] = +amp[111] + amp[117] + amp[152] + amp[155] + amp[157] + amp[158] + amp[161] + amp[163] + std::complex (0, 1) * amp[164] + std::complex (0, 1) * amp[165] + std::complex (0, 1) * amp[166] + std::complex (0, 1) * amp[167] + amp[169] + std::complex (0, 1) * amp[170] + amp[172] + amp[175] + std::complex (0, 1) * amp[176] + amp[178] - std::complex (0, 1) * amp[180] + amp[181] - std::complex (0, 1) * amp[183] + amp[184] - std::complex (0, 1) * amp[185] - std::complex (0, 1) * amp[186] + amp[187] - std::complex (0, 1) * amp[189] + amp[190] - std::complex (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 (0, 1) * amp[636] - amp[638] - amp[640] + std::complex (0, 1) * amp[642] - amp[644] - amp[646] - std::complex (0, 1) * amp[648] + amp[650] - std::complex (0, 1) * amp[651] + amp[652] - std::complex (0, 1) * amp[653] - std::complex (0, 1) * amp[654] + amp[656] - std::complex (0, 1) * amp[657] + amp[658] - std::complex (0, 1) * amp[659] + amp[660] + amp[661] + amp[663] + amp[664] + amp[666] + amp[667] + amp[669] + amp[670] + std::complex (0, 1) * amp[726] + std::complex (0, 1) * amp[728] + amp[729] - std::complex (0, 1) * amp[732] - std::complex (0, 1) * amp[731] + std::complex (0, 1) * amp[735] - amp[736] + std::complex (0, 1) * amp[737] - std::complex (0, 1) * amp[741] - std::complex (0, 1) * amp[740] + std::complex (0, 1) * amp[744] + std::complex (0, 1) * amp[746] + amp[747] - std::complex (0, 1) * amp[750] - std::complex (0, 1) * amp[749] + std::complex (0, 1) * amp[753] - amp[754] + std::complex (0, 1) * amp[755] - std::complex (0, 1) * amp[759] - std::complex (0, 1) * amp[758] - std::complex (0, 1) * amp[776] + std::complex (0, 1) * amp[780] + amp[781] - std::complex (0, 1) * amp[782] - std::complex (0, 1) * amp[783] + std::complex (0, 1) * amp[789] - std::complex (0, 1) * amp[791] - std::complex (0, 1) * amp[792] - std::complex (0, 1) * amp[794] + std::complex (0, 1) * amp[798] + amp[799] - std::complex (0, 1) * amp[800] - std::complex (0, 1) * amp[801] + std::complex (0, 1) * amp[807] - std::complex (0, 1) * amp[809] - std::complex (0, 1) * amp[810] - amp[812] - std::complex (0, 1) * amp[814] - amp[816] - std::complex (0, 1) * amp[817] - amp[819] - amp[820] - std::complex (0, 1) * amp[822] - amp[824] - std::complex (0, 1) * amp[825] - amp[827] - std::complex (0, 1) * amp[830] + std::complex (0, 1) * amp[836] + std::complex (0, 1) * amp[835] - std::complex (0, 1) * amp[838] - std::complex (0, 1) * amp[839] + amp[840] + std::complex (0, 1) * amp[845] + std::complex (0, 1) * amp[844] - std::complex (0, 1) * amp[848] + std::complex (0, 1) * amp[854] + std::complex (0, 1) * amp[853] - std::complex (0, 1) * amp[856] - std::complex (0, 1) * amp[857] + amp[858] + std::complex (0, 1) * amp[863] + std::complex (0, 1) * amp[862] - std::complex (0, 1) * amp[939] - std::complex (0, 1) * amp[940] + amp[942] + amp[943] - std::complex (0, 1) * amp[945] - std::complex (0, 1) * amp[946] - std::complex (0, 1) * amp[951] - std::complex (0, 1) * amp[952] + amp[954] + amp[955] - std::complex (0, 1) * amp[957] - std::complex (0, 1) * amp[958] - amp[986] - amp[985] - std::complex (0, 1) * amp[989] - std::complex (0, 1) * amp[988] - std::complex (0, 1) * amp[995] - std::complex (0, 1) * amp[994] - amp[998] - amp[997] - std::complex (0, 1) * amp[1001] - std::complex (0, 1) * amp[1000] - std::complex (0, 1) * amp[1007] - std::complex (0, 1) * amp[1006]; jamp[9] = +amp[110] + amp[116] + amp[121] + amp[122] + amp[124] + amp[127] + amp[128] + amp[130] - std::complex (0, 1) * amp[132] - std::complex (0, 1) * amp[133] - std::complex (0, 1) * amp[134] - std::complex (0, 1) * amp[135] + std::complex (0, 1) * amp[180] - amp[181] + std::complex (0, 1) * amp[183] - amp[184] + std::complex (0, 1) * amp[185] + std::complex (0, 1) * amp[186] - amp[187] + std::complex (0, 1) * amp[189] - amp[190] + std::complex (0, 1) * amp[191] + amp[193] - std::complex (0, 1) * amp[195] + amp[196] + amp[199] - std::complex (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 (0, 1) * amp[445] - amp[446] - std::complex (0, 1) * amp[447] - amp[448] - std::complex (0, 1) * amp[449] - std::complex (0, 1) * amp[451] - amp[452] - std::complex (0, 1) * amp[453] - amp[454] - std::complex (0, 1) * amp[455] - std::complex (0, 1) * amp[469] - amp[470] - amp[472] - std::complex (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 (0, 1) * amp[776] - std::complex (0, 1) * amp[780] - amp[781] + std::complex (0, 1) * amp[782] + std::complex (0, 1) * amp[783] - std::complex (0, 1) * amp[789] + std::complex (0, 1) * amp[791] + std::complex (0, 1) * amp[792] + std::complex (0, 1) * amp[794] - std::complex (0, 1) * amp[798] - amp[799] + std::complex (0, 1) * amp[800] + std::complex (0, 1) * amp[801] - std::complex (0, 1) * amp[807] + std::complex (0, 1) * amp[809] + std::complex (0, 1) * amp[810] + amp[812] + std::complex (0, 1) * amp[814] + amp[816] + std::complex (0, 1) * amp[817] + amp[819] + amp[820] + std::complex (0, 1) * amp[822] + amp[824] + std::complex (0, 1) * amp[825] + amp[827] - std::complex (0, 1) * amp[832] - std::complex (0, 1) * amp[834] - std::complex (0, 1) * amp[835] - std::complex (0, 1) * amp[837] - std::complex (0, 1) * amp[841] - amp[842] - std::complex (0, 1) * amp[843] - std::complex (0, 1) * amp[844] - std::complex (0, 1) * amp[850] - std::complex (0, 1) * amp[852] - std::complex (0, 1) * amp[853] - std::complex (0, 1) * amp[855] - std::complex (0, 1) * amp[859] - amp[860] - std::complex (0, 1) * amp[861] - std::complex (0, 1) * amp[862] + std::complex (0, 1) * amp[902] + amp[903] - std::complex (0, 1) * amp[904] - std::complex (0, 1) * amp[906] - std::complex (0, 1) * amp[907] + std::complex (0, 1) * amp[911] - std::complex (0, 1) * amp[913] - amp[914] - std::complex (0, 1) * amp[915] - std::complex (0, 1) * amp[916] + std::complex (0, 1) * amp[920] + amp[921] - std::complex (0, 1) * amp[922] - std::complex (0, 1) * amp[924] - std::complex (0, 1) * amp[925] + std::complex (0, 1) * amp[929] - std::complex (0, 1) * amp[931] - amp[932] - std::complex (0, 1) * amp[933] - std::complex (0, 1) * amp[934] + amp[984] + amp[985] + std::complex (0, 1) * amp[987] + std::complex (0, 1) * amp[988] + std::complex (0, 1) * amp[993] + std::complex (0, 1) * amp[994] + amp[996] + amp[997] + std::complex (0, 1) * amp[999] + std::complex (0, 1) * amp[1000] + std::complex (0, 1) * amp[1005] + std::complex (0, 1) * amp[1006] + std::complex (0, 1) * amp[1013] - std::complex (0, 1) * amp[1011] + amp[1016] - amp[1014] + std::complex (0, 1) * amp[1019] - std::complex (0, 1) * amp[1017] + std::complex (0, 1) * amp[1025] - std::complex (0, 1) * amp[1023] + amp[1028] - amp[1026] + std::complex (0, 1) * amp[1031] - std::complex (0, 1) * amp[1029]; jamp[10] = +amp[113] + amp[119] + amp[136] + amp[139] + amp[141] + amp[142] + amp[145] + amp[147] + std::complex (0, 1) * amp[148] + std::complex (0, 1) * amp[149] + std::complex (0, 1) * amp[150] + std::complex (0, 1) * amp[151] - std::complex (0, 1) * amp[168] + amp[169] - std::complex (0, 1) * amp[171] + amp[172] - std::complex (0, 1) * amp[173] - std::complex (0, 1) * amp[174] + amp[175] - std::complex (0, 1) * amp[177] + amp[178] - std::complex (0, 1) * amp[179] + amp[181] + std::complex (0, 1) * amp[182] + amp[184] + amp[187] + std::complex (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 (0, 1) * amp[576] - amp[578] - amp[580] + std::complex (0, 1) * amp[582] - amp[584] - amp[586] - std::complex (0, 1) * amp[588] + amp[590] - std::complex (0, 1) * amp[591] + amp[592] - std::complex (0, 1) * amp[593] - std::complex (0, 1) * amp[594] + amp[596] - std::complex (0, 1) * amp[597] + amp[598] - std::complex (0, 1) * amp[599] + amp[600] + amp[601] + amp[603] + amp[604] + amp[606] + amp[607] + amp[609] + amp[610] - std::complex (0, 1) * amp[724] + std::complex (0, 1) * amp[728] + amp[729] - std::complex (0, 1) * amp[730] - std::complex (0, 1) * amp[731] + std::complex (0, 1) * amp[737] - std::complex (0, 1) * amp[739] - std::complex (0, 1) * amp[740] - std::complex (0, 1) * amp[742] + std::complex (0, 1) * amp[746] + amp[747] - std::complex (0, 1) * amp[748] - std::complex (0, 1) * amp[749] + std::complex (0, 1) * amp[755] - std::complex (0, 1) * amp[757] - std::complex (0, 1) * amp[758] - amp[760] - std::complex (0, 1) * amp[762] - amp[764] - std::complex (0, 1) * amp[765] - amp[767] - amp[768] - std::complex (0, 1) * amp[770] - amp[772] - std::complex (0, 1) * amp[773] - amp[775] + std::complex (0, 1) * amp[778] + std::complex (0, 1) * amp[780] + amp[781] - std::complex (0, 1) * amp[784] - std::complex (0, 1) * amp[783] + std::complex (0, 1) * amp[787] - amp[788] + std::complex (0, 1) * amp[789] - std::complex (0, 1) * amp[793] - std::complex (0, 1) * amp[792] + std::complex (0, 1) * amp[796] + std::complex (0, 1) * amp[798] + amp[799] - std::complex (0, 1) * amp[802] - std::complex (0, 1) * amp[801] + std::complex (0, 1) * amp[805] - amp[806] + std::complex (0, 1) * amp[807] - std::complex (0, 1) * amp[811] - std::complex (0, 1) * amp[810] - std::complex (0, 1) * amp[866] + std::complex (0, 1) * amp[872] + std::complex (0, 1) * amp[871] - std::complex (0, 1) * amp[874] - std::complex (0, 1) * amp[875] + amp[876] + std::complex (0, 1) * amp[881] + std::complex (0, 1) * amp[880] - std::complex (0, 1) * amp[884] + std::complex (0, 1) * amp[890] + std::complex (0, 1) * amp[889] - std::complex (0, 1) * amp[892] - std::complex (0, 1) * amp[893] + amp[894] + std::complex (0, 1) * amp[899] + std::complex (0, 1) * amp[898] - std::complex (0, 1) * amp[963] - std::complex (0, 1) * amp[964] + amp[966] + amp[967] - std::complex (0, 1) * amp[969] - std::complex (0, 1) * amp[970] - std::complex (0, 1) * amp[975] - std::complex (0, 1) * amp[976] + amp[978] + amp[979] - std::complex (0, 1) * amp[981] - std::complex (0, 1) * amp[982] - amp[986] - amp[985] - std::complex (0, 1) * amp[989] - std::complex (0, 1) * amp[988] - std::complex (0, 1) * amp[995] - std::complex (0, 1) * amp[994] - amp[998] - amp[997] - std::complex (0, 1) * amp[1001] - std::complex (0, 1) * amp[1000] - std::complex (0, 1) * amp[1007] - std::complex (0, 1) * amp[1006]; jamp[11] = +amp[112] + amp[118] + amp[120] + amp[123] + amp[125] + amp[126] + amp[129] + amp[131] + std::complex (0, 1) * amp[132] + std::complex (0, 1) * amp[133] + std::complex (0, 1) * amp[134] + std::complex (0, 1) * amp[135] + std::complex (0, 1) * amp[168] - amp[169] + std::complex (0, 1) * amp[171] - amp[172] + std::complex (0, 1) * amp[173] + std::complex (0, 1) * amp[174] - amp[175] + std::complex (0, 1) * amp[177] - amp[178] + std::complex (0, 1) * amp[179] - amp[193] + std::complex (0, 1) * amp[195] - amp[196] - amp[199] + std::complex (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 (0, 1) * amp[457] - amp[458] - std::complex (0, 1) * amp[459] - amp[460] - std::complex (0, 1) * amp[461] - std::complex (0, 1) * amp[463] - amp[464] - std::complex (0, 1) * amp[465] - amp[466] - std::complex (0, 1) * amp[467] + std::complex (0, 1) * amp[469] + amp[470] + amp[472] + std::complex (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 (0, 1) * amp[724] - std::complex (0, 1) * amp[728] - amp[729] + std::complex (0, 1) * amp[730] + std::complex (0, 1) * amp[731] - std::complex (0, 1) * amp[737] + std::complex (0, 1) * amp[739] + std::complex (0, 1) * amp[740] + std::complex (0, 1) * amp[742] - std::complex (0, 1) * amp[746] - amp[747] + std::complex (0, 1) * amp[748] + std::complex (0, 1) * amp[749] - std::complex (0, 1) * amp[755] + std::complex (0, 1) * amp[757] + std::complex (0, 1) * amp[758] + amp[760] + std::complex (0, 1) * amp[762] + amp[764] + std::complex (0, 1) * amp[765] + amp[767] + amp[768] + std::complex (0, 1) * amp[770] + amp[772] + std::complex (0, 1) * amp[773] + amp[775] - std::complex (0, 1) * amp[868] - std::complex (0, 1) * amp[870] - std::complex (0, 1) * amp[871] - std::complex (0, 1) * amp[873] - std::complex (0, 1) * amp[877] - amp[878] - std::complex (0, 1) * amp[879] - std::complex (0, 1) * amp[880] - std::complex (0, 1) * amp[886] - std::complex (0, 1) * amp[888] - std::complex (0, 1) * amp[889] - std::complex (0, 1) * amp[891] - std::complex (0, 1) * amp[895] - amp[896] - std::complex (0, 1) * amp[897] - std::complex (0, 1) * amp[898] - std::complex (0, 1) * amp[902] - amp[903] + std::complex (0, 1) * amp[904] + std::complex (0, 1) * amp[906] + std::complex (0, 1) * amp[907] - std::complex (0, 1) * amp[911] + std::complex (0, 1) * amp[913] + amp[914] + std::complex (0, 1) * amp[915] + std::complex (0, 1) * amp[916] - std::complex (0, 1) * amp[920] - amp[921] + std::complex (0, 1) * amp[922] + std::complex (0, 1) * amp[924] + std::complex (0, 1) * amp[925] - std::complex (0, 1) * amp[929] + std::complex (0, 1) * amp[931] + amp[932] + std::complex (0, 1) * amp[933] + std::complex (0, 1) * amp[934] + amp[986] - amp[984] + std::complex (0, 1) * amp[989] - std::complex (0, 1) * amp[987] + std::complex (0, 1) * amp[995] - std::complex (0, 1) * amp[993] + amp[998] - amp[996] + std::complex (0, 1) * amp[1001] - std::complex (0, 1) * amp[999] + std::complex (0, 1) * amp[1007] - std::complex (0, 1) * amp[1005] + std::complex (0, 1) * amp[1011] + std::complex (0, 1) * amp[1012] + amp[1014] + amp[1015] + std::complex (0, 1) * amp[1017] + std::complex (0, 1) * amp[1018] + std::complex (0, 1) * amp[1023] + std::complex (0, 1) * amp[1024] + amp[1026] + amp[1027] + std::complex (0, 1) * amp[1029] + std::complex (0, 1) * amp[1030]; jamp[12] = +amp[217] + amp[223] + amp[261] + amp[262] + amp[264] + amp[267] + amp[268] + amp[270] - std::complex (0, 1) * amp[272] - std::complex (0, 1) * amp[273] - std::complex (0, 1) * amp[274] - std::complex (0, 1) * amp[275] - amp[277] - std::complex (0, 1) * amp[278] - amp[280] - amp[283] - std::complex (0, 1) * amp[284] - amp[286] - std::complex (0, 1) * amp[300] - amp[301] - std::complex (0, 1) * amp[302] - amp[304] - std::complex (0, 1) * amp[305] - std::complex (0, 1) * amp[306] - amp[307] - std::complex (0, 1) * amp[308] - amp[310] - std::complex (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 (0, 1) * amp[624] + amp[626] + amp[628] - std::complex (0, 1) * amp[630] + amp[632] + amp[634] + std::complex (0, 1) * amp[637] + amp[638] + std::complex (0, 1) * amp[639] + amp[640] + std::complex (0, 1) * amp[641] + std::complex (0, 1) * amp[643] + amp[644] + std::complex (0, 1) * amp[645] + amp[646] + std::complex (0, 1) * amp[647] - amp[662] - amp[661] - amp[665] - amp[664] - amp[668] - amp[667] - amp[671] - amp[670] - std::complex (0, 1) * amp[674] - std::complex (0, 1) * amp[676] - amp[677] + std::complex (0, 1) * amp[680] + std::complex (0, 1) * amp[679] - std::complex (0, 1) * amp[683] + amp[684] - std::complex (0, 1) * amp[685] + std::complex (0, 1) * amp[689] + std::complex (0, 1) * amp[688] - std::complex (0, 1) * amp[692] - std::complex (0, 1) * amp[694] - amp[695] + std::complex (0, 1) * amp[698] + std::complex (0, 1) * amp[697] - std::complex (0, 1) * amp[701] + amp[702] - std::complex (0, 1) * amp[703] + std::complex (0, 1) * amp[707] + std::complex (0, 1) * amp[706] - std::complex (0, 1) * amp[726] + std::complex (0, 1) * amp[732] - std::complex (0, 1) * amp[730] + std::complex (0, 1) * amp[734] - std::complex (0, 1) * amp[735] + amp[736] + std::complex (0, 1) * amp[741] - std::complex (0, 1) * amp[739] - std::complex (0, 1) * amp[744] + std::complex (0, 1) * amp[750] - std::complex (0, 1) * amp[748] + std::complex (0, 1) * amp[752] - std::complex (0, 1) * amp[753] + amp[754] + std::complex (0, 1) * amp[759] - std::complex (0, 1) * amp[757] + amp[761] - std::complex (0, 1) * amp[762] + amp[763] - std::complex (0, 1) * amp[765] + amp[766] + amp[769] - std::complex (0, 1) * amp[770] + amp[771] - std::complex (0, 1) * amp[773] + amp[774] - std::complex (0, 1) * amp[865] - std::complex (0, 1) * amp[866] - amp[867] + std::complex (0, 1) * amp[872] + std::complex (0, 1) * amp[871] - std::complex (0, 1) * amp[875] + std::complex (0, 1) * amp[881] + std::complex (0, 1) * amp[880] - std::complex (0, 1) * amp[883] - std::complex (0, 1) * amp[884] - amp[885] + std::complex (0, 1) * amp[890] + std::complex (0, 1) * amp[889] - std::complex (0, 1) * amp[893] + std::complex (0, 1) * amp[899] + std::complex (0, 1) * amp[898] + std::complex (0, 1) * amp[941] + std::complex (0, 1) * amp[940] - amp[944] - amp[943] + std::complex (0, 1) * amp[947] + std::complex (0, 1) * amp[946] + std::complex (0, 1) * amp[953] + std::complex (0, 1) * amp[952] - amp[956] - amp[955] + std::complex (0, 1) * amp[959] + std::complex (0, 1) * amp[958] + amp[962] - amp[960] + std::complex (0, 1) * amp[965] - std::complex (0, 1) * amp[963] + std::complex (0, 1) * amp[971] - std::complex (0, 1) * amp[969] + amp[974] - amp[972] + std::complex (0, 1) * amp[977] - std::complex (0, 1) * amp[975] + std::complex (0, 1) * amp[983] - std::complex (0, 1) * amp[981]; jamp[13] = +amp[216] + amp[222] + amp[245] + amp[246] + amp[248] + amp[251] + amp[252] + amp[254] - std::complex (0, 1) * amp[256] - std::complex (0, 1) * amp[257] - std::complex (0, 1) * amp[258] - std::complex (0, 1) * amp[259] - amp[289] - std::complex (0, 1) * amp[290] - amp[292] - amp[295] - std::complex (0, 1) * amp[296] - amp[298] + std::complex (0, 1) * amp[300] + amp[301] + std::complex (0, 1) * amp[302] + amp[304] + std::complex (0, 1) * amp[305] + std::complex (0, 1) * amp[306] + amp[307] + std::complex (0, 1) * amp[308] + amp[310] + std::complex (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 (0, 1) * amp[505] + amp[506] + std::complex (0, 1) * amp[507] + amp[508] + std::complex (0, 1) * amp[509] + std::complex (0, 1) * amp[511] + amp[512] + std::complex (0, 1) * amp[513] + amp[514] + std::complex (0, 1) * amp[515] - std::complex (0, 1) * amp[516] + amp[518] + amp[520] - std::complex (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 (0, 1) * amp[728] + std::complex (0, 1) * amp[730] + std::complex (0, 1) * amp[731] + std::complex (0, 1) * amp[733] - std::complex (0, 1) * amp[737] + amp[738] + std::complex (0, 1) * amp[739] + std::complex (0, 1) * amp[740] - std::complex (0, 1) * amp[746] + std::complex (0, 1) * amp[748] + std::complex (0, 1) * amp[749] + std::complex (0, 1) * amp[751] - std::complex (0, 1) * amp[755] + amp[756] + std::complex (0, 1) * amp[757] + std::complex (0, 1) * amp[758] - amp[761] + std::complex (0, 1) * amp[762] - amp[763] + std::complex (0, 1) * amp[765] - amp[766] - amp[769] + std::complex (0, 1) * amp[770] - amp[771] + std::complex (0, 1) * amp[773] - amp[774] - std::complex (0, 1) * amp[778] - amp[779] - std::complex (0, 1) * amp[780] + std::complex (0, 1) * amp[784] + std::complex (0, 1) * amp[783] - std::complex (0, 1) * amp[787] - std::complex (0, 1) * amp[789] + amp[790] + std::complex (0, 1) * amp[793] + std::complex (0, 1) * amp[792] - std::complex (0, 1) * amp[796] - amp[797] - std::complex (0, 1) * amp[798] + std::complex (0, 1) * amp[802] + std::complex (0, 1) * amp[801] - std::complex (0, 1) * amp[805] - std::complex (0, 1) * amp[807] + amp[808] + std::complex (0, 1) * amp[811] + std::complex (0, 1) * amp[810] + std::complex (0, 1) * amp[865] + std::complex (0, 1) * amp[866] + amp[867] - std::complex (0, 1) * amp[872] - std::complex (0, 1) * amp[871] + std::complex (0, 1) * amp[875] - std::complex (0, 1) * amp[881] - std::complex (0, 1) * amp[880] + std::complex (0, 1) * amp[883] + std::complex (0, 1) * amp[884] + amp[885] - std::complex (0, 1) * amp[890] - std::complex (0, 1) * amp[889] + std::complex (0, 1) * amp[893] - std::complex (0, 1) * amp[899] - std::complex (0, 1) * amp[898] + amp[960] + amp[961] + std::complex (0, 1) * amp[963] + std::complex (0, 1) * amp[964] + std::complex (0, 1) * amp[969] + std::complex (0, 1) * amp[970] + amp[972] + amp[973] + std::complex (0, 1) * amp[975] + std::complex (0, 1) * amp[976] + std::complex (0, 1) * amp[981] + std::complex (0, 1) * amp[982] + std::complex (0, 1) * amp[989] + std::complex (0, 1) * amp[988] - amp[992] - amp[991] + std::complex (0, 1) * amp[995] + std::complex (0, 1) * amp[994] + std::complex (0, 1) * amp[1001] + std::complex (0, 1) * amp[1000] - amp[1004] - amp[1003] + std::complex (0, 1) * amp[1007] + std::complex (0, 1) * amp[1006]; jamp[14] = +amp[219] + amp[225] + amp[260] + amp[263] + amp[265] + amp[266] + amp[269] + amp[271] + std::complex (0, 1) * amp[272] + std::complex (0, 1) * amp[273] + std::complex (0, 1) * amp[274] + std::complex (0, 1) * amp[275] + amp[277] + std::complex (0, 1) * amp[278] + amp[280] + amp[283] + std::complex (0, 1) * amp[284] + amp[286] - std::complex (0, 1) * amp[288] + amp[289] - std::complex (0, 1) * amp[291] + amp[292] - std::complex (0, 1) * amp[293] - std::complex (0, 1) * amp[294] + amp[295] - std::complex (0, 1) * amp[297] + amp[298] - std::complex (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 (0, 1) * amp[624] - amp[626] - amp[628] + std::complex (0, 1) * amp[630] - amp[632] - amp[634] + std::complex (0, 1) * amp[648] - amp[650] + std::complex (0, 1) * amp[651] - amp[652] + std::complex (0, 1) * amp[653] + std::complex (0, 1) * amp[654] - amp[656] + std::complex (0, 1) * amp[657] - amp[658] + std::complex (0, 1) * amp[659] + amp[662] - amp[660] + amp[665] - amp[663] + amp[668] - amp[666] + amp[671] - amp[669] + std::complex (0, 1) * amp[674] + std::complex (0, 1) * amp[676] + amp[677] - std::complex (0, 1) * amp[680] - std::complex (0, 1) * amp[679] + std::complex (0, 1) * amp[683] - amp[684] + std::complex (0, 1) * amp[685] - std::complex (0, 1) * amp[689] - std::complex (0, 1) * amp[688] + std::complex (0, 1) * amp[692] + std::complex (0, 1) * amp[694] + amp[695] - std::complex (0, 1) * amp[698] - std::complex (0, 1) * amp[697] + std::complex (0, 1) * amp[701] - amp[702] + std::complex (0, 1) * amp[703] - std::complex (0, 1) * amp[707] - std::complex (0, 1) * amp[706] - std::complex (0, 1) * amp[777] + std::complex (0, 1) * amp[778] + amp[779] - std::complex (0, 1) * amp[784] + std::complex (0, 1) * amp[782] + std::complex (0, 1) * amp[787] - std::complex (0, 1) * amp[793] + std::complex (0, 1) * amp[791] - std::complex (0, 1) * amp[795] + std::complex (0, 1) * amp[796] + amp[797] - std::complex (0, 1) * amp[802] + std::complex (0, 1) * amp[800] + std::complex (0, 1) * amp[805] - std::complex (0, 1) * amp[811] + std::complex (0, 1) * amp[809] + amp[812] + std::complex (0, 1) * amp[814] + amp[816] + std::complex (0, 1) * amp[817] + amp[819] + amp[820] + std::complex (0, 1) * amp[822] + amp[824] + std::complex (0, 1) * amp[825] + amp[827] + std::complex (0, 1) * amp[830] - std::complex (0, 1) * amp[836] - std::complex (0, 1) * amp[835] + std::complex (0, 1) * amp[838] + std::complex (0, 1) * amp[839] - amp[840] - std::complex (0, 1) * amp[845] - std::complex (0, 1) * amp[844] + std::complex (0, 1) * amp[848] - std::complex (0, 1) * amp[854] - std::complex (0, 1) * amp[853] + std::complex (0, 1) * amp[856] + std::complex (0, 1) * amp[857] - amp[858] - std::complex (0, 1) * amp[863] - std::complex (0, 1) * amp[862] - std::complex (0, 1) * amp[941] + std::complex (0, 1) * amp[939] + amp[944] - amp[942] - std::complex (0, 1) * amp[947] + std::complex (0, 1) * amp[945] - std::complex (0, 1) * amp[953] + std::complex (0, 1) * amp[951] + amp[956] - amp[954] - std::complex (0, 1) * amp[959] + std::complex (0, 1) * amp[957] - amp[962] - amp[961] - std::complex (0, 1) * amp[965] - std::complex (0, 1) * amp[964] - std::complex (0, 1) * amp[971] - std::complex (0, 1) * amp[970] - amp[974] - amp[973] - std::complex (0, 1) * amp[977] - std::complex (0, 1) * amp[976] - std::complex (0, 1) * amp[983] - std::complex (0, 1) * amp[982]; jamp[15] = +amp[218] + amp[224] + amp[229] + amp[230] + amp[232] + amp[235] + amp[236] + amp[238] - std::complex (0, 1) * amp[240] - std::complex (0, 1) * amp[241] - std::complex (0, 1) * amp[242] - std::complex (0, 1) * amp[243] + std::complex (0, 1) * amp[288] - amp[289] + std::complex (0, 1) * amp[291] - amp[292] + std::complex (0, 1) * amp[293] + std::complex (0, 1) * amp[294] - amp[295] + std::complex (0, 1) * amp[297] - amp[298] + std::complex (0, 1) * amp[299] + amp[301] - std::complex (0, 1) * amp[303] + amp[304] + amp[307] - std::complex (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 (0, 1) * amp[445] + amp[446] + std::complex (0, 1) * amp[447] + amp[448] + std::complex (0, 1) * amp[449] + std::complex (0, 1) * amp[451] + amp[452] + std::complex (0, 1) * amp[453] + amp[454] + std::complex (0, 1) * amp[455] - std::complex (0, 1) * amp[456] + amp[458] + amp[460] - std::complex (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 (0, 1) * amp[777] - std::complex (0, 1) * amp[778] - amp[779] + std::complex (0, 1) * amp[784] - std::complex (0, 1) * amp[782] - std::complex (0, 1) * amp[787] + std::complex (0, 1) * amp[793] - std::complex (0, 1) * amp[791] + std::complex (0, 1) * amp[795] - std::complex (0, 1) * amp[796] - amp[797] + std::complex (0, 1) * amp[802] - std::complex (0, 1) * amp[800] - std::complex (0, 1) * amp[805] + std::complex (0, 1) * amp[811] - std::complex (0, 1) * amp[809] - amp[812] - std::complex (0, 1) * amp[814] - amp[816] - std::complex (0, 1) * amp[817] - amp[819] - amp[820] - std::complex (0, 1) * amp[822] - amp[824] - std::complex (0, 1) * amp[825] - amp[827] + std::complex (0, 1) * amp[832] + std::complex (0, 1) * amp[834] + std::complex (0, 1) * amp[835] + std::complex (0, 1) * amp[837] + std::complex (0, 1) * amp[841] + amp[842] + std::complex (0, 1) * amp[843] + std::complex (0, 1) * amp[844] + std::complex (0, 1) * amp[850] + std::complex (0, 1) * amp[852] + std::complex (0, 1) * amp[853] + std::complex (0, 1) * amp[855] + std::complex (0, 1) * amp[859] + amp[860] + std::complex (0, 1) * amp[861] + std::complex (0, 1) * amp[862] + std::complex (0, 1) * amp[866] + amp[867] + std::complex (0, 1) * amp[868] - std::complex (0, 1) * amp[872] + std::complex (0, 1) * amp[870] + std::complex (0, 1) * amp[875] + std::complex (0, 1) * amp[877] + amp[878] - std::complex (0, 1) * amp[881] + std::complex (0, 1) * amp[879] + std::complex (0, 1) * amp[884] + amp[885] + std::complex (0, 1) * amp[886] - std::complex (0, 1) * amp[890] + std::complex (0, 1) * amp[888] + std::complex (0, 1) * amp[893] + std::complex (0, 1) * amp[895] + amp[896] - std::complex (0, 1) * amp[899] + std::complex (0, 1) * amp[897] + amp[960] + amp[961] + std::complex (0, 1) * amp[963] + std::complex (0, 1) * amp[964] + std::complex (0, 1) * amp[969] + std::complex (0, 1) * amp[970] + amp[972] + amp[973] + std::complex (0, 1) * amp[975] + std::complex (0, 1) * amp[976] + std::complex (0, 1) * amp[981] + std::complex (0, 1) * amp[982] - std::complex (0, 1) * amp[1013] - std::complex (0, 1) * amp[1012] - amp[1016] - amp[1015] - std::complex (0, 1) * amp[1019] - std::complex (0, 1) * amp[1018] - std::complex (0, 1) * amp[1025] - std::complex (0, 1) * amp[1024] - amp[1028] - amp[1027] - std::complex (0, 1) * amp[1031] - std::complex (0, 1) * amp[1030]; jamp[16] = +amp[221] + amp[227] + amp[244] + amp[247] + amp[249] + amp[250] + amp[253] + amp[255] + std::complex (0, 1) * amp[256] + std::complex (0, 1) * amp[257] + std::complex (0, 1) * amp[258] + std::complex (0, 1) * amp[259] - std::complex (0, 1) * amp[276] + amp[277] - std::complex (0, 1) * amp[279] + amp[280] - std::complex (0, 1) * amp[281] - std::complex (0, 1) * amp[282] + amp[283] - std::complex (0, 1) * amp[285] + amp[286] - std::complex (0, 1) * amp[287] + amp[289] + std::complex (0, 1) * amp[290] + amp[292] + amp[295] + std::complex (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 (0, 1) * amp[516] - amp[518] - amp[520] + std::complex (0, 1) * amp[522] - amp[524] - amp[526] - std::complex (0, 1) * amp[528] + amp[530] - std::complex (0, 1) * amp[531] + amp[532] - std::complex (0, 1) * amp[533] - std::complex (0, 1) * amp[534] + amp[536] - std::complex (0, 1) * amp[537] + amp[538] - std::complex (0, 1) * amp[539] + amp[540] + amp[541] + amp[543] + amp[544] + amp[546] + amp[547] + amp[549] + amp[550] - std::complex (0, 1) * amp[672] + std::complex (0, 1) * amp[676] + amp[677] - std::complex (0, 1) * amp[678] - std::complex (0, 1) * amp[679] + std::complex (0, 1) * amp[685] - std::complex (0, 1) * amp[687] - std::complex (0, 1) * amp[688] - std::complex (0, 1) * amp[690] + std::complex (0, 1) * amp[694] + amp[695] - std::complex (0, 1) * amp[696] - std::complex (0, 1) * amp[697] + std::complex (0, 1) * amp[703] - std::complex (0, 1) * amp[705] - std::complex (0, 1) * amp[706] - amp[708] - std::complex (0, 1) * amp[710] - amp[712] - std::complex (0, 1) * amp[713] - amp[715] - amp[716] - std::complex (0, 1) * amp[718] - amp[720] - std::complex (0, 1) * amp[721] - amp[723] + std::complex (0, 1) * amp[778] + amp[779] + std::complex (0, 1) * amp[780] - std::complex (0, 1) * amp[784] - std::complex (0, 1) * amp[783] + std::complex (0, 1) * amp[787] + std::complex (0, 1) * amp[789] - amp[790] - std::complex (0, 1) * amp[793] - std::complex (0, 1) * amp[792] + std::complex (0, 1) * amp[796] + amp[797] + std::complex (0, 1) * amp[798] - std::complex (0, 1) * amp[802] - std::complex (0, 1) * amp[801] + std::complex (0, 1) * amp[805] + std::complex (0, 1) * amp[807] - amp[808] - std::complex (0, 1) * amp[811] - std::complex (0, 1) * amp[810] - std::complex (0, 1) * amp[902] + std::complex (0, 1) * amp[908] + std::complex (0, 1) * amp[907] - std::complex (0, 1) * amp[910] - std::complex (0, 1) * amp[911] + amp[912] + std::complex (0, 1) * amp[917] + std::complex (0, 1) * amp[916] - std::complex (0, 1) * amp[920] + std::complex (0, 1) * amp[926] + std::complex (0, 1) * amp[925] - std::complex (0, 1) * amp[928] - std::complex (0, 1) * amp[929] + amp[930] + std::complex (0, 1) * amp[935] + std::complex (0, 1) * amp[934] - amp[962] - amp[961] - std::complex (0, 1) * amp[965] - std::complex (0, 1) * amp[964] - std::complex (0, 1) * amp[971] - std::complex (0, 1) * amp[970] - amp[974] - amp[973] - std::complex (0, 1) * amp[977] - std::complex (0, 1) * amp[976] - std::complex (0, 1) * amp[983] - std::complex (0, 1) * amp[982] - std::complex (0, 1) * amp[987] - std::complex (0, 1) * amp[988] + amp[990] + amp[991] - std::complex (0, 1) * amp[993] - std::complex (0, 1) * amp[994] - std::complex (0, 1) * amp[999] - std::complex (0, 1) * amp[1000] + amp[1002] + amp[1003] - std::complex (0, 1) * amp[1005] - std::complex (0, 1) * amp[1006]; jamp[17] = +amp[220] + amp[226] + amp[228] + amp[231] + amp[233] + amp[234] + amp[237] + amp[239] + std::complex (0, 1) * amp[240] + std::complex (0, 1) * amp[241] + std::complex (0, 1) * amp[242] + std::complex (0, 1) * amp[243] + std::complex (0, 1) * amp[276] - amp[277] + std::complex (0, 1) * amp[279] - amp[280] + std::complex (0, 1) * amp[281] + std::complex (0, 1) * amp[282] - amp[283] + std::complex (0, 1) * amp[285] - amp[286] + std::complex (0, 1) * amp[287] - amp[301] + std::complex (0, 1) * amp[303] - amp[304] - amp[307] + std::complex (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 (0, 1) * amp[456] - amp[458] - amp[460] + std::complex (0, 1) * amp[462] - amp[464] - amp[466] - std::complex (0, 1) * amp[468] + amp[470] - std::complex (0, 1) * amp[471] + amp[472] - std::complex (0, 1) * amp[473] - std::complex (0, 1) * amp[474] + amp[476] - std::complex (0, 1) * amp[477] + amp[478] - std::complex (0, 1) * amp[479] + amp[480] + amp[481] + amp[483] + amp[484] + amp[486] + amp[487] + amp[489] + amp[490] + std::complex (0, 1) * amp[672] - std::complex (0, 1) * amp[676] - amp[677] + std::complex (0, 1) * amp[678] + std::complex (0, 1) * amp[679] - std::complex (0, 1) * amp[685] + std::complex (0, 1) * amp[687] + std::complex (0, 1) * amp[688] + std::complex (0, 1) * amp[690] - std::complex (0, 1) * amp[694] - amp[695] + std::complex (0, 1) * amp[696] + std::complex (0, 1) * amp[697] - std::complex (0, 1) * amp[703] + std::complex (0, 1) * amp[705] + std::complex (0, 1) * amp[706] + amp[708] + std::complex (0, 1) * amp[710] + amp[712] + std::complex (0, 1) * amp[713] + amp[715] + amp[716] + std::complex (0, 1) * amp[718] + amp[720] + std::complex (0, 1) * amp[721] + amp[723] - std::complex (0, 1) * amp[866] - amp[867] - std::complex (0, 1) * amp[868] + std::complex (0, 1) * amp[872] - std::complex (0, 1) * amp[870] - std::complex (0, 1) * amp[875] - std::complex (0, 1) * amp[877] - amp[878] + std::complex (0, 1) * amp[881] - std::complex (0, 1) * amp[879] - std::complex (0, 1) * amp[884] - amp[885] - std::complex (0, 1) * amp[886] + std::complex (0, 1) * amp[890] - std::complex (0, 1) * amp[888] - std::complex (0, 1) * amp[893] - std::complex (0, 1) * amp[895] - amp[896] + std::complex (0, 1) * amp[899] - std::complex (0, 1) * amp[897] + std::complex (0, 1) * amp[904] - std::complex (0, 1) * amp[908] + std::complex (0, 1) * amp[906] - std::complex (0, 1) * amp[909] + std::complex (0, 1) * amp[913] + amp[914] - std::complex (0, 1) * amp[917] + std::complex (0, 1) * amp[915] + std::complex (0, 1) * amp[922] - std::complex (0, 1) * amp[926] + std::complex (0, 1) * amp[924] - std::complex (0, 1) * amp[927] + std::complex (0, 1) * amp[931] + amp[932] - std::complex (0, 1) * amp[935] + std::complex (0, 1) * amp[933] + amp[962] - amp[960] + std::complex (0, 1) * amp[965] - std::complex (0, 1) * amp[963] + std::complex (0, 1) * amp[971] - std::complex (0, 1) * amp[969] + amp[974] - amp[972] + std::complex (0, 1) * amp[977] - std::complex (0, 1) * amp[975] + std::complex (0, 1) * amp[983] - std::complex (0, 1) * amp[981] + std::complex (0, 1) * amp[1011] + std::complex (0, 1) * amp[1012] + amp[1014] + amp[1015] + std::complex (0, 1) * amp[1017] + std::complex (0, 1) * amp[1018] + std::complex (0, 1) * amp[1023] + std::complex (0, 1) * amp[1024] + amp[1026] + amp[1027] + std::complex (0, 1) * amp[1029] + std::complex (0, 1) * amp[1030]; jamp[18] = +amp[325] + amp[331] + amp[369] + amp[370] + amp[372] + amp[375] + amp[376] + amp[378] - std::complex (0, 1) * amp[380] - std::complex (0, 1) * amp[381] - std::complex (0, 1) * amp[382] - std::complex (0, 1) * amp[383] - amp[385] - std::complex (0, 1) * amp[386] - amp[388] - amp[391] - std::complex (0, 1) * amp[392] - amp[394] - std::complex (0, 1) * amp[408] - amp[409] - std::complex (0, 1) * amp[410] - amp[412] - std::complex (0, 1) * amp[413] - std::complex (0, 1) * amp[414] - amp[415] - std::complex (0, 1) * amp[416] - amp[418] - std::complex (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 (0, 1) * amp[564] + amp[566] + amp[568] - std::complex (0, 1) * amp[570] + amp[572] + amp[574] + std::complex (0, 1) * amp[577] + amp[578] + std::complex (0, 1) * amp[579] + amp[580] + std::complex (0, 1) * amp[581] + std::complex (0, 1) * amp[583] + amp[584] + std::complex (0, 1) * amp[585] + amp[586] + std::complex (0, 1) * amp[587] - amp[602] - amp[601] - amp[605] - amp[604] - amp[608] - amp[607] - amp[611] - amp[610] - std::complex (0, 1) * amp[674] - amp[675] - std::complex (0, 1) * amp[676] + std::complex (0, 1) * amp[680] + std::complex (0, 1) * amp[679] - std::complex (0, 1) * amp[683] - std::complex (0, 1) * amp[685] + amp[686] + std::complex (0, 1) * amp[689] + std::complex (0, 1) * amp[688] - std::complex (0, 1) * amp[692] - amp[693] - std::complex (0, 1) * amp[694] + std::complex (0, 1) * amp[698] + std::complex (0, 1) * amp[697] - std::complex (0, 1) * amp[701] - std::complex (0, 1) * amp[703] + amp[704] + std::complex (0, 1) * amp[707] + std::complex (0, 1) * amp[706] - std::complex (0, 1) * amp[778] + std::complex (0, 1) * amp[784] - std::complex (0, 1) * amp[782] + std::complex (0, 1) * amp[786] - std::complex (0, 1) * amp[787] + amp[788] + std::complex (0, 1) * amp[793] - std::complex (0, 1) * amp[791] - std::complex (0, 1) * amp[796] + std::complex (0, 1) * amp[802] - std::complex (0, 1) * amp[800] + std::complex (0, 1) * amp[804] - std::complex (0, 1) * amp[805] + amp[806] + std::complex (0, 1) * amp[811] - std::complex (0, 1) * amp[809] + amp[813] - std::complex (0, 1) * amp[814] + amp[815] - std::complex (0, 1) * amp[817] + amp[818] + amp[821] - std::complex (0, 1) * amp[822] + amp[823] - std::complex (0, 1) * amp[825] + amp[826] - std::complex (0, 1) * amp[829] - std::complex (0, 1) * amp[830] - amp[831] + std::complex (0, 1) * amp[836] + std::complex (0, 1) * amp[835] - std::complex (0, 1) * amp[839] + std::complex (0, 1) * amp[845] + std::complex (0, 1) * amp[844] - std::complex (0, 1) * amp[847] - std::complex (0, 1) * amp[848] - amp[849] + std::complex (0, 1) * amp[854] + std::complex (0, 1) * amp[853] - std::complex (0, 1) * amp[857] + std::complex (0, 1) * amp[863] + std::complex (0, 1) * amp[862] + amp[938] - amp[936] + std::complex (0, 1) * amp[941] - std::complex (0, 1) * amp[939] + std::complex (0, 1) * amp[947] - std::complex (0, 1) * amp[945] + amp[950] - amp[948] + std::complex (0, 1) * amp[953] - std::complex (0, 1) * amp[951] + std::complex (0, 1) * amp[959] - std::complex (0, 1) * amp[957] + std::complex (0, 1) * amp[965] + std::complex (0, 1) * amp[964] - amp[968] - amp[967] + std::complex (0, 1) * amp[971] + std::complex (0, 1) * amp[970] + std::complex (0, 1) * amp[977] + std::complex (0, 1) * amp[976] - amp[980] - amp[979] + std::complex (0, 1) * amp[983] + std::complex (0, 1) * amp[982]; jamp[19] = +amp[324] + amp[330] + amp[353] + amp[354] + amp[356] + amp[359] + amp[360] + amp[362] - std::complex (0, 1) * amp[364] - std::complex (0, 1) * amp[365] - std::complex (0, 1) * amp[366] - std::complex (0, 1) * amp[367] - amp[397] - std::complex (0, 1) * amp[398] - amp[400] - amp[403] - std::complex (0, 1) * amp[404] - amp[406] + std::complex (0, 1) * amp[408] + amp[409] + std::complex (0, 1) * amp[410] + amp[412] + std::complex (0, 1) * amp[413] + std::complex (0, 1) * amp[414] + amp[415] + std::complex (0, 1) * amp[416] + amp[418] + std::complex (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 (0, 1) * amp[504] + amp[506] + amp[508] - std::complex (0, 1) * amp[510] + amp[512] + amp[514] + std::complex (0, 1) * amp[517] + amp[518] + std::complex (0, 1) * amp[519] + amp[520] + std::complex (0, 1) * amp[521] + std::complex (0, 1) * amp[523] + amp[524] + std::complex (0, 1) * amp[525] + amp[526] + std::complex (0, 1) * amp[527] - amp[542] - amp[541] - amp[545] - amp[544] - amp[548] - amp[547] - amp[551] - amp[550] - std::complex (0, 1) * amp[726] - amp[727] - std::complex (0, 1) * amp[728] + std::complex (0, 1) * amp[732] + std::complex (0, 1) * amp[731] - std::complex (0, 1) * amp[735] - std::complex (0, 1) * amp[737] + amp[738] + std::complex (0, 1) * amp[741] + std::complex (0, 1) * amp[740] - std::complex (0, 1) * amp[744] - amp[745] - std::complex (0, 1) * amp[746] + std::complex (0, 1) * amp[750] + std::complex (0, 1) * amp[749] - std::complex (0, 1) * amp[753] - std::complex (0, 1) * amp[755] + amp[756] + std::complex (0, 1) * amp[759] + std::complex (0, 1) * amp[758] - std::complex (0, 1) * amp[780] + std::complex (0, 1) * amp[782] + std::complex (0, 1) * amp[783] + std::complex (0, 1) * amp[785] - std::complex (0, 1) * amp[789] + amp[790] + std::complex (0, 1) * amp[791] + std::complex (0, 1) * amp[792] - std::complex (0, 1) * amp[798] + std::complex (0, 1) * amp[800] + std::complex (0, 1) * amp[801] + std::complex (0, 1) * amp[803] - std::complex (0, 1) * amp[807] + amp[808] + std::complex (0, 1) * amp[809] + std::complex (0, 1) * amp[810] - amp[813] + std::complex (0, 1) * amp[814] - amp[815] + std::complex (0, 1) * amp[817] - amp[818] - amp[821] + std::complex (0, 1) * amp[822] - amp[823] + std::complex (0, 1) * amp[825] - amp[826] + std::complex (0, 1) * amp[829] + std::complex (0, 1) * amp[830] + amp[831] - std::complex (0, 1) * amp[836] - std::complex (0, 1) * amp[835] + std::complex (0, 1) * amp[839] - std::complex (0, 1) * amp[845] - std::complex (0, 1) * amp[844] + std::complex (0, 1) * amp[847] + std::complex (0, 1) * amp[848] + amp[849] - std::complex (0, 1) * amp[854] - std::complex (0, 1) * amp[853] + std::complex (0, 1) * amp[857] - std::complex (0, 1) * amp[863] - std::complex (0, 1) * amp[862] + amp[936] + amp[937] + std::complex (0, 1) * amp[939] + std::complex (0, 1) * amp[940] + std::complex (0, 1) * amp[945] + std::complex (0, 1) * amp[946] + amp[948] + amp[949] + std::complex (0, 1) * amp[951] + std::complex (0, 1) * amp[952] + std::complex (0, 1) * amp[957] + std::complex (0, 1) * amp[958] + std::complex (0, 1) * amp[989] + std::complex (0, 1) * amp[988] - amp[992] - amp[991] + std::complex (0, 1) * amp[995] + std::complex (0, 1) * amp[994] + std::complex (0, 1) * amp[1001] + std::complex (0, 1) * amp[1000] - amp[1004] - amp[1003] + std::complex (0, 1) * amp[1007] + std::complex (0, 1) * amp[1006]; jamp[20] = +amp[327] + amp[333] + amp[368] + amp[371] + amp[373] + amp[374] + amp[377] + amp[379] + std::complex (0, 1) * amp[380] + std::complex (0, 1) * amp[381] + std::complex (0, 1) * amp[382] + std::complex (0, 1) * amp[383] + amp[385] + std::complex (0, 1) * amp[386] + amp[388] + amp[391] + std::complex (0, 1) * amp[392] + amp[394] - std::complex (0, 1) * amp[396] + amp[397] - std::complex (0, 1) * amp[399] + amp[400] - std::complex (0, 1) * amp[401] - std::complex (0, 1) * amp[402] + amp[403] - std::complex (0, 1) * amp[405] + amp[406] - std::complex (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 (0, 1) * amp[564] - amp[566] - amp[568] + std::complex (0, 1) * amp[570] - amp[572] - amp[574] + std::complex (0, 1) * amp[588] - amp[590] + std::complex (0, 1) * amp[591] - amp[592] + std::complex (0, 1) * amp[593] + std::complex (0, 1) * amp[594] - amp[596] + std::complex (0, 1) * amp[597] - amp[598] + std::complex (0, 1) * amp[599] + amp[602] - amp[600] + amp[605] - amp[603] + amp[608] - amp[606] + amp[611] - amp[609] + std::complex (0, 1) * amp[674] + amp[675] + std::complex (0, 1) * amp[676] - std::complex (0, 1) * amp[680] - std::complex (0, 1) * amp[679] + std::complex (0, 1) * amp[683] + std::complex (0, 1) * amp[685] - amp[686] - std::complex (0, 1) * amp[689] - std::complex (0, 1) * amp[688] + std::complex (0, 1) * amp[692] + amp[693] + std::complex (0, 1) * amp[694] - std::complex (0, 1) * amp[698] - std::complex (0, 1) * amp[697] + std::complex (0, 1) * amp[701] + std::complex (0, 1) * amp[703] - amp[704] - std::complex (0, 1) * amp[707] - std::complex (0, 1) * amp[706] - std::complex (0, 1) * amp[725] + std::complex (0, 1) * amp[726] + amp[727] - std::complex (0, 1) * amp[732] + std::complex (0, 1) * amp[730] + std::complex (0, 1) * amp[735] - std::complex (0, 1) * amp[741] + std::complex (0, 1) * amp[739] - std::complex (0, 1) * amp[743] + std::complex (0, 1) * amp[744] + amp[745] - std::complex (0, 1) * amp[750] + std::complex (0, 1) * amp[748] + std::complex (0, 1) * amp[753] - std::complex (0, 1) * amp[759] + std::complex (0, 1) * amp[757] + amp[760] + std::complex (0, 1) * amp[762] + amp[764] + std::complex (0, 1) * amp[765] + amp[767] + amp[768] + std::complex (0, 1) * amp[770] + amp[772] + std::complex (0, 1) * amp[773] + amp[775] + std::complex (0, 1) * amp[866] - std::complex (0, 1) * amp[872] - std::complex (0, 1) * amp[871] + std::complex (0, 1) * amp[874] + std::complex (0, 1) * amp[875] - amp[876] - std::complex (0, 1) * amp[881] - std::complex (0, 1) * amp[880] + std::complex (0, 1) * amp[884] - std::complex (0, 1) * amp[890] - std::complex (0, 1) * amp[889] + std::complex (0, 1) * amp[892] + std::complex (0, 1) * amp[893] - amp[894] - std::complex (0, 1) * amp[899] - std::complex (0, 1) * amp[898] - amp[938] - amp[937] - std::complex (0, 1) * amp[941] - std::complex (0, 1) * amp[940] - std::complex (0, 1) * amp[947] - std::complex (0, 1) * amp[946] - amp[950] - amp[949] - std::complex (0, 1) * amp[953] - std::complex (0, 1) * amp[952] - std::complex (0, 1) * amp[959] - std::complex (0, 1) * amp[958] - std::complex (0, 1) * amp[965] + std::complex (0, 1) * amp[963] + amp[968] - amp[966] - std::complex (0, 1) * amp[971] + std::complex (0, 1) * amp[969] - std::complex (0, 1) * amp[977] + std::complex (0, 1) * amp[975] + amp[980] - amp[978] - std::complex (0, 1) * amp[983] + std::complex (0, 1) * amp[981]; jamp[21] = +amp[326] + amp[332] + amp[337] + amp[338] + amp[340] + amp[343] + amp[344] + amp[346] - std::complex (0, 1) * amp[348] - std::complex (0, 1) * amp[349] - std::complex (0, 1) * amp[350] - std::complex (0, 1) * amp[351] + std::complex (0, 1) * amp[396] - amp[397] + std::complex (0, 1) * amp[399] - amp[400] + std::complex (0, 1) * amp[401] + std::complex (0, 1) * amp[402] - amp[403] + std::complex (0, 1) * amp[405] - amp[406] + std::complex (0, 1) * amp[407] + amp[409] - std::complex (0, 1) * amp[411] + amp[412] + amp[415] - std::complex (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 (0, 1) * amp[444] + amp[446] + amp[448] - std::complex (0, 1) * amp[450] + amp[452] + amp[454] + std::complex (0, 1) * amp[457] + amp[458] + std::complex (0, 1) * amp[459] + amp[460] + std::complex (0, 1) * amp[461] + std::complex (0, 1) * amp[463] + amp[464] + std::complex (0, 1) * amp[465] + amp[466] + std::complex (0, 1) * amp[467] - amp[482] - amp[481] - amp[485] - amp[484] - amp[488] - amp[487] - amp[491] - amp[490] + std::complex (0, 1) * amp[725] - std::complex (0, 1) * amp[726] - amp[727] + std::complex (0, 1) * amp[732] - std::complex (0, 1) * amp[730] - std::complex (0, 1) * amp[735] + std::complex (0, 1) * amp[741] - std::complex (0, 1) * amp[739] + std::complex (0, 1) * amp[743] - std::complex (0, 1) * amp[744] - amp[745] + std::complex (0, 1) * amp[750] - std::complex (0, 1) * amp[748] - std::complex (0, 1) * amp[753] + std::complex (0, 1) * amp[759] - std::complex (0, 1) * amp[757] - amp[760] - std::complex (0, 1) * amp[762] - amp[764] - std::complex (0, 1) * amp[765] - amp[767] - amp[768] - std::complex (0, 1) * amp[770] - amp[772] - std::complex (0, 1) * amp[773] - amp[775] + std::complex (0, 1) * amp[830] + amp[831] + std::complex (0, 1) * amp[832] - std::complex (0, 1) * amp[836] + std::complex (0, 1) * amp[834] + std::complex (0, 1) * amp[839] + std::complex (0, 1) * amp[841] + amp[842] - std::complex (0, 1) * amp[845] + std::complex (0, 1) * amp[843] + std::complex (0, 1) * amp[848] + amp[849] + std::complex (0, 1) * amp[850] - std::complex (0, 1) * amp[854] + std::complex (0, 1) * amp[852] + std::complex (0, 1) * amp[857] + std::complex (0, 1) * amp[859] + amp[860] - std::complex (0, 1) * amp[863] + std::complex (0, 1) * amp[861] + std::complex (0, 1) * amp[868] + std::complex (0, 1) * amp[870] + std::complex (0, 1) * amp[871] + std::complex (0, 1) * amp[873] + std::complex (0, 1) * amp[877] + amp[878] + std::complex (0, 1) * amp[879] + std::complex (0, 1) * amp[880] + std::complex (0, 1) * amp[886] + std::complex (0, 1) * amp[888] + std::complex (0, 1) * amp[889] + std::complex (0, 1) * amp[891] + std::complex (0, 1) * amp[895] + amp[896] + std::complex (0, 1) * amp[897] + std::complex (0, 1) * amp[898] + amp[936] + amp[937] + std::complex (0, 1) * amp[939] + std::complex (0, 1) * amp[940] + std::complex (0, 1) * amp[945] + std::complex (0, 1) * amp[946] + amp[948] + amp[949] + std::complex (0, 1) * amp[951] + std::complex (0, 1) * amp[952] + std::complex (0, 1) * amp[957] + std::complex (0, 1) * amp[958] - std::complex (0, 1) * amp[1013] - std::complex (0, 1) * amp[1012] - amp[1016] - amp[1015] - std::complex (0, 1) * amp[1019] - std::complex (0, 1) * amp[1018] - std::complex (0, 1) * amp[1025] - std::complex (0, 1) * amp[1024] - amp[1028] - amp[1027] - std::complex (0, 1) * amp[1031] - std::complex (0, 1) * amp[1030]; jamp[22] = +amp[329] + amp[335] + amp[352] + amp[355] + amp[357] + amp[358] + amp[361] + amp[363] + std::complex (0, 1) * amp[364] + std::complex (0, 1) * amp[365] + std::complex (0, 1) * amp[366] + std::complex (0, 1) * amp[367] - std::complex (0, 1) * amp[384] + amp[385] - std::complex (0, 1) * amp[387] + amp[388] - std::complex (0, 1) * amp[389] - std::complex (0, 1) * amp[390] + amp[391] - std::complex (0, 1) * amp[393] + amp[394] - std::complex (0, 1) * amp[395] + amp[397] + std::complex (0, 1) * amp[398] + amp[400] + amp[403] + std::complex (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 (0, 1) * amp[504] - amp[506] - amp[508] + std::complex (0, 1) * amp[510] - amp[512] - amp[514] + std::complex (0, 1) * amp[528] - amp[530] + std::complex (0, 1) * amp[531] - amp[532] + std::complex (0, 1) * amp[533] + std::complex (0, 1) * amp[534] - amp[536] + std::complex (0, 1) * amp[537] - amp[538] + std::complex (0, 1) * amp[539] + amp[542] - amp[540] + amp[545] - amp[543] + amp[548] - amp[546] + amp[551] - amp[549] - std::complex (0, 1) * amp[673] + std::complex (0, 1) * amp[674] + amp[675] - std::complex (0, 1) * amp[680] + std::complex (0, 1) * amp[678] + std::complex (0, 1) * amp[683] - std::complex (0, 1) * amp[689] + std::complex (0, 1) * amp[687] - std::complex (0, 1) * amp[691] + std::complex (0, 1) * amp[692] + amp[693] - std::complex (0, 1) * amp[698] + std::complex (0, 1) * amp[696] + std::complex (0, 1) * amp[701] - std::complex (0, 1) * amp[707] + std::complex (0, 1) * amp[705] + amp[708] + std::complex (0, 1) * amp[710] + amp[712] + std::complex (0, 1) * amp[713] + amp[715] + amp[716] + std::complex (0, 1) * amp[718] + amp[720] + std::complex (0, 1) * amp[721] + amp[723] + std::complex (0, 1) * amp[726] + amp[727] + std::complex (0, 1) * amp[728] - std::complex (0, 1) * amp[732] - std::complex (0, 1) * amp[731] + std::complex (0, 1) * amp[735] + std::complex (0, 1) * amp[737] - amp[738] - std::complex (0, 1) * amp[741] - std::complex (0, 1) * amp[740] + std::complex (0, 1) * amp[744] + amp[745] + std::complex (0, 1) * amp[746] - std::complex (0, 1) * amp[750] - std::complex (0, 1) * amp[749] + std::complex (0, 1) * amp[753] + std::complex (0, 1) * amp[755] - amp[756] - std::complex (0, 1) * amp[759] - std::complex (0, 1) * amp[758] + std::complex (0, 1) * amp[902] - std::complex (0, 1) * amp[908] - std::complex (0, 1) * amp[907] + std::complex (0, 1) * amp[910] + std::complex (0, 1) * amp[911] - amp[912] - std::complex (0, 1) * amp[917] - std::complex (0, 1) * amp[916] + std::complex (0, 1) * amp[920] - std::complex (0, 1) * amp[926] - std::complex (0, 1) * amp[925] + std::complex (0, 1) * amp[928] + std::complex (0, 1) * amp[929] - amp[930] - std::complex (0, 1) * amp[935] - std::complex (0, 1) * amp[934] - amp[938] - amp[937] - std::complex (0, 1) * amp[941] - std::complex (0, 1) * amp[940] - std::complex (0, 1) * amp[947] - std::complex (0, 1) * amp[946] - amp[950] - amp[949] - std::complex (0, 1) * amp[953] - std::complex (0, 1) * amp[952] - std::complex (0, 1) * amp[959] - std::complex (0, 1) * amp[958] - std::complex (0, 1) * amp[989] + std::complex (0, 1) * amp[987] + amp[992] - amp[990] - std::complex (0, 1) * amp[995] + std::complex (0, 1) * amp[993] - std::complex (0, 1) * amp[1001] + std::complex (0, 1) * amp[999] + amp[1004] - amp[1002] - std::complex (0, 1) * amp[1007] + std::complex (0, 1) * amp[1005]; jamp[23] = +amp[328] + amp[334] + amp[336] + amp[339] + amp[341] + amp[342] + amp[345] + amp[347] + std::complex (0, 1) * amp[348] + std::complex (0, 1) * amp[349] + std::complex (0, 1) * amp[350] + std::complex (0, 1) * amp[351] + std::complex (0, 1) * amp[384] - amp[385] + std::complex (0, 1) * amp[387] - amp[388] + std::complex (0, 1) * amp[389] + std::complex (0, 1) * amp[390] - amp[391] + std::complex (0, 1) * amp[393] - amp[394] + std::complex (0, 1) * amp[395] - amp[409] + std::complex (0, 1) * amp[411] - amp[412] - amp[415] + std::complex (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 (0, 1) * amp[444] - amp[446] - amp[448] + std::complex (0, 1) * amp[450] - amp[452] - amp[454] + std::complex (0, 1) * amp[468] - amp[470] + std::complex (0, 1) * amp[471] - amp[472] + std::complex (0, 1) * amp[473] + std::complex (0, 1) * amp[474] - amp[476] + std::complex (0, 1) * amp[477] - amp[478] + std::complex (0, 1) * amp[479] + amp[482] - amp[480] + amp[485] - amp[483] + amp[488] - amp[486] + amp[491] - amp[489] + std::complex (0, 1) * amp[673] - std::complex (0, 1) * amp[674] - amp[675] + std::complex (0, 1) * amp[680] - std::complex (0, 1) * amp[678] - std::complex (0, 1) * amp[683] + std::complex (0, 1) * amp[689] - std::complex (0, 1) * amp[687] + std::complex (0, 1) * amp[691] - std::complex (0, 1) * amp[692] - amp[693] + std::complex (0, 1) * amp[698] - std::complex (0, 1) * amp[696] - std::complex (0, 1) * amp[701] + std::complex (0, 1) * amp[707] - std::complex (0, 1) * amp[705] - amp[708] - std::complex (0, 1) * amp[710] - amp[712] - std::complex (0, 1) * amp[713] - amp[715] - amp[716] - std::complex (0, 1) * amp[718] - amp[720] - std::complex (0, 1) * amp[721] - amp[723] - std::complex (0, 1) * amp[830] - amp[831] - std::complex (0, 1) * amp[832] + std::complex (0, 1) * amp[836] - std::complex (0, 1) * amp[834] - std::complex (0, 1) * amp[839] - std::complex (0, 1) * amp[841] - amp[842] + std::complex (0, 1) * amp[845] - std::complex (0, 1) * amp[843] - std::complex (0, 1) * amp[848] - amp[849] - std::complex (0, 1) * amp[850] + std::complex (0, 1) * amp[854] - std::complex (0, 1) * amp[852] - std::complex (0, 1) * amp[857] - std::complex (0, 1) * amp[859] - amp[860] + std::complex (0, 1) * amp[863] - std::complex (0, 1) * amp[861] - std::complex (0, 1) * amp[904] + std::complex (0, 1) * amp[908] - std::complex (0, 1) * amp[906] + std::complex (0, 1) * amp[909] - std::complex (0, 1) * amp[913] - amp[914] + std::complex (0, 1) * amp[917] - std::complex (0, 1) * amp[915] - std::complex (0, 1) * amp[922] + std::complex (0, 1) * amp[926] - std::complex (0, 1) * amp[924] + std::complex (0, 1) * amp[927] - std::complex (0, 1) * amp[931] - amp[932] + std::complex (0, 1) * amp[935] - std::complex (0, 1) * amp[933] + amp[938] - amp[936] + std::complex (0, 1) * amp[941] - std::complex (0, 1) * amp[939] + std::complex (0, 1) * amp[947] - std::complex (0, 1) * amp[945] + amp[950] - amp[948] + std::complex (0, 1) * amp[953] - std::complex (0, 1) * amp[951] + std::complex (0, 1) * amp[959] - std::complex (0, 1) * amp[957] + std::complex (0, 1) * amp[1013] - std::complex (0, 1) * amp[1011] + amp[1016] - amp[1014] + std::complex (0, 1) * amp[1019] - std::complex (0, 1) * amp[1017] + std::complex (0, 1) * amp[1025] - std::complex (0, 1) * amp[1023] + amp[1028] - amp[1026] + std::complex (0, 1) * amp[1031] - std::complex (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 kappaSupport(const DipoleSplittingInfo& dIndex) const; /** * Return the boundaries in between the momentum * fraction random number is to be sampled. */ virtual pair xiSupport(const DipoleSplittingInfo& dIndex) const; /** * Return the boundaries on the momentum fraction */ virtual pair 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 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 rotateToZ (Lorentz5Momentum& pTarget, Lorentz5Momentum& p1){ ThreeVector 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 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 { /** 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 : public ClassTraitsBase { /** 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 kappaSupport(const DipoleSplittingInfo& dIndex) const; /** * Return the boundaries in between the momentum * fraction random number is to be sampled. */ virtual pair xiSupport(const DipoleSplittingInfo& dIndex) const; /** * Return the boundaries on the momentum fraction */ virtual pair 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 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 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 { /** 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 : public ClassTraitsBase { /** 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 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 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 & vec) { // produce the children vector 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 Node::getNextOrderedNodes(bool normal, double hardScaleFactor) const { vector temp = children(); vector 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 zbounds = dipole()->tildeKinematics()->zBounds(pT(), hardpT); return (zbounds.first temp = getNextOrderedNodes(normal, hardScaleFactor); Energy minpt = Constants::MaxEnergy; Selector 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 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 describeHerwigNode("Herwig::Node", "HwDipoleShower.so"); void Node::Init() { static ClassDocumentation 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 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 void birth(const vector & 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 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 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 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::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 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::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::const_pointer beamParticle() const { return _beam; } /** * Set the beam particle data */ void setBeamParticle(Ptr::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); /** * Access to the intrinsic \f$p_T\f$ for inheriting classes */ map > & intrinsicpT() { return _intrinsic; } /** * find the maximally allowed pt acc to the hard process. */ void setupMaximumScales(const vector &,XCPtr); /** * find the relevant hard scales for profile scales. */ void setupHardScales(const vector &,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 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::const_pointer _beam; /** * Storage of the intrinsic \f$p_t\f$ of the particles */ map > _intrinsic; /** * Vetoes */ vector _vetoes; /** * Full Shower Vetoes */ vector _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 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 using ValT = decltype(std::declval() * std::declval()); /** * The value of the integral * @param lower The lower limit of integration. * @param upper The upper limit of integration. */ template inline ValT 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 > _weights; /** * The abscissae. */ std::vector< std::vector > _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 */