diff --git a/Decay/VectorMeson/OniumToOniumPiPiDecayer.cc b/Decay/VectorMeson/OniumToOniumPiPiDecayer.cc --- a/Decay/VectorMeson/OniumToOniumPiPiDecayer.cc +++ b/Decay/VectorMeson/OniumToOniumPiPiDecayer.cc @@ -1,461 +1,461 @@ // -*- C++ -*- // // OniumToOniumPiPiDecayer.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 OniumToOniumPiPiDecayer class. // #include "OniumToOniumPiPiDecayer.h" #include "ThePEG/Interface/ParVector.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h" #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h" #include "Herwig/PDT/ThreeBodyAllOnCalculator.h" #include "Herwig/Decay/GeneralDecayMatrixElement.h" using namespace Herwig; using namespace ThePEG::Helicity; void OniumToOniumPiPiDecayer::doinitrun() { DecayIntegrator::doinitrun(); for(unsigned int ix=0;ix<_maxweight.size();++ix) { if(initialize()) _maxweight[ix] = mode(ix)->maxWeight(); } } OniumToOniumPiPiDecayer::OniumToOniumPiPiDecayer() { // Upsilon(3S)->Upsilon(1S) pi pi _incoming.push_back(200553); _outgoing.push_back( 553); _maxweight.push_back(1.); _maxweight.push_back(1.); _coupling.push_back(3.92e-6); _reA.push_back( 1. /MeV2);_imA.push_back( ZERO); _reB.push_back(-2.523/MeV2);_imB.push_back( 1.189/MeV2); _reC.push_back( ZERO);_imC.push_back( ZERO); // Upsilon(3S)->Upsilon(2S) pi pi _incoming.push_back(200553); _outgoing.push_back(100553); _maxweight.push_back(1.); _maxweight.push_back(1.); _coupling.push_back(311e-6); _reA.push_back( 1. /MeV2);_imA.push_back( ZERO); _reB.push_back(-0.395/MeV2);_imB.push_back( 0.001/MeV2); _reC.push_back( ZERO);_imC.push_back( ZERO); // Upsilon(2S)->Upsilon(1S) pi pi _incoming.push_back(100553); _outgoing.push_back( 553); _maxweight.push_back(1.); _maxweight.push_back(1.); _coupling.push_back(61.4e-6); _reA.push_back( 1. /MeV2);_imA.push_back( ZERO); _reB.push_back(-0.753/MeV2);_imB.push_back( ZERO); _reC.push_back( ZERO);_imC.push_back( ZERO); // Upsilon(4S)->Upsilon(1S) pi pi _incoming.push_back(300553); _outgoing.push_back( 553); _maxweight.push_back(1.); _maxweight.push_back(1.); _coupling.push_back(1.77e-6); _reA.push_back( 1. /MeV2);_imA.push_back( ZERO); _reB.push_back( ZERO);_imB.push_back( ZERO); _reC.push_back( ZERO);_imC.push_back( ZERO); // Upsilon(4S)->Upsilon(2S) pi pi _incoming.push_back(300553); _outgoing.push_back(100553); _maxweight.push_back(1.); _maxweight.push_back(1.); _coupling.push_back(68.8e-6); _reA.push_back( 1. /MeV2);_imA.push_back( ZERO); _reB.push_back(-2.35 /MeV2);_imB.push_back( 0.55/MeV2); _reC.push_back( ZERO);_imC.push_back( ZERO); // psi(2s)->psi(1S) pi pi _incoming.push_back(100443); _outgoing.push_back( 443); _maxweight.push_back(1.); _maxweight.push_back(1.); _coupling.push_back(66.2e-6); _reA.push_back( 1. /MeV2);_imA.push_back( ZERO); _reB.push_back(-0.336/MeV2);_imB.push_back( ZERO); _reC.push_back( ZERO);_imC.push_back( ZERO); // psi(3770)->psi(1S) pi pi _incoming.push_back(30443); _outgoing.push_back( 443); _maxweight.push_back(1.); _maxweight.push_back(1.); _coupling.push_back(20.6e-6); _reA.push_back( 1. /MeV2);_imA.push_back( ZERO); _reB.push_back( ZERO);_imB.push_back( ZERO); _reC.push_back( ZERO);_imC.push_back( ZERO); // Initial size of the vectors _initsize=_incoming.size(); // don'y generate the intermediates in the phase-space generateIntermediates(false); } void OniumToOniumPiPiDecayer::doinit() { DecayIntegrator::doinit(); // check consistency of the vectors unsigned int isize=_incoming.size(); if(_outgoing.size()!=isize||_maxweight.size()!=2*isize|| _coupling.size()!=isize|| _reA .size()!=isize||_imA.size() !=isize|| _reB .size()!=isize||_imB.size() !=isize|| _reC .size()!=isize||_imC.size() !=isize) throw InitException() << "Inconsistent size of the parameter vectors in " << "OniumToOniumPiPiDecayer" << Exception::runerror; // construct the complex couplings for(unsigned int ix=0;ix<_incoming.size();++ix) { _cA.push_back(complex(_reA[ix],_imA[ix])); _cB.push_back(complex(_reB[ix],_imB[ix])); _cC.push_back(complex(_reC[ix],_imC[ix])); } // construct the decay channels tPDVector extpart(4); tPDPtr pip(getParticleData(ParticleID::piplus )); tPDPtr pim(getParticleData(ParticleID::piminus)); tPDPtr pi0(getParticleData(ParticleID::pi0 )); tPDPtr rho0(getParticleData(113)); DecayPhaseSpaceModePtr mode; DecayPhaseSpaceChannelPtr newchannel; vector dummyweights(1,1.); for(unsigned int ix=0;ixaddIntermediate(extpart[0],0, 0.0,1,-1); newchannel->addIntermediate(rho0,1,0.0, 2,3); mode->addChannel(newchannel); // reset the resonance parameters mode->resetIntermediate(rho0,2*extpart[0]->mass(),2*extpart[0]->mass()); // add the mode addMode(mode,_maxweight[2*ix+iy],dummyweights); } } } void OniumToOniumPiPiDecayer::persistentOutput(PersistentOStream & os) const { os << _incoming << _outgoing << _maxweight << _initsize << ounit(_reA,1./GeV2) << ounit(_imA,1./GeV2) << ounit(_cA,1./GeV2) << ounit(_reB,1./GeV2) << ounit(_imB,1./GeV2) << ounit(_cB,1./GeV2) << ounit(_reC,1./GeV2) << ounit(_imC,1./GeV2) << ounit(_cC,1./GeV2); } void OniumToOniumPiPiDecayer::persistentInput(PersistentIStream & is, int) { is >> _incoming >> _outgoing >> _maxweight >> _initsize >> iunit(_reA,1./GeV2) >> iunit(_imA,1./GeV2) >> iunit(_cA,1./GeV2) >> iunit(_reB,1./GeV2) >> iunit(_imB,1./GeV2) >> iunit(_cB,1./GeV2) >> iunit(_reC,1./GeV2) >> iunit(_imC,1./GeV2) >> iunit(_cC,1./GeV2); } ClassDescription OniumToOniumPiPiDecayer::initOniumToOniumPiPiDecayer; // Definition of the static class description member. void OniumToOniumPiPiDecayer::Init() { static ClassDocumentation documentation ("The OniumToOniumPiPiDecayer class uses the matrix element of " "Brown and Cahn, PRL35, 1 (1975), for" " the decay of onium resonaces to lighter states and pion pairs." " The results of hep-ex/9909038 are used for psi'->psi and " " arXiv:0706.2317 for Upsilon(3S) and Upsilon(2S) decays." " The remaining parameters are choosen to approximately reproduce" " the distributions from hep-ex/0604031 and hep-ex/0508023.", "The decays of onium resonances to lighter states and pion pairs were modelled" " using the matrix element of \\cite{Brown:1975dz}. The results of " "\\cite{Bai:1999mj} are used for $\\psi'\\to\\psi$ and " "\\cite{Cronin-Hennessy:2007sj} for $\\Upsilon(3S)$ and $\\Upsilon(2S)$ decays." " The remaining parameters are choosen to approximately reproduce" " the distributions from \\cite{Aubert:2006bm} and \\cite{Adam:2005mr}.", "\\bibitem{Brown:1975dz} L.~S.~Brown and R.~N.~Cahn," "Phys.\\ Rev.\\ Lett.\\ {\\bf 35} (1975) 1." "%%CITATION = PRLTA,35,1;%%\n" "\\bibitem{Bai:1999mj} J.~Z.~Bai {\\it et al.} [BES Collaboration]," "Phys.\\ Rev.\\ D {\\bf 62} (2000) 032002 [arXiv:hep-ex/9909038]." "%%CITATION = PHRVA,D62,032002;%%\n" "\\bibitem{Cronin-Hennessy:2007sj} D.~Cronin-Hennessy{\\it et al.} " "[CLEO Collaboration], arXiv:0706.2317 [hep-ex]." "%%CITATION = ARXIV:0706.2317;%%\n" "\\bibitem{Aubert:2006bm} B.~Aubert {\\it et al.} [BABAR Collaboration]," "Phys.\\ Rev.\\ Lett.\\ {\\bf 96} (2006) 232001 [arXiv:hep-ex/0604031]." "%%CITATION = PRLTA,96,232001;%%\n" "\\bibitem{Adam:2005mr} N.~E.~Adam {\\it et al.} [CLEO Collaboration]," "Phys.\\ Rev.\\ Lett.\\ {\\bf 96} (2006) 082004 [arXiv:hep-ex/0508023]." "%%CITATION = PRLTA,96,082004;%%"); static ParVector interfaceIncoming ("Incoming", "The PDG code for the incoming onium state", &OniumToOniumPiPiDecayer::_incoming, -1, long(0), -10000000, 10000000, false, false, Interface::limited); static ParVector interfaceOutgoing ("Outgoing", "The PDG code for the outgoing onium state", &OniumToOniumPiPiDecayer::_outgoing, -1, long(0), -10000000, 10000000, false, false, Interface::limited); static ParVector interfaceMaxWeight ("MaxWeight", "The maximum weight for the decay mode, there should be two " "for each mode as we have pi+ pi- and pi0 pi0", &OniumToOniumPiPiDecayer::_maxweight, -1, 1.0, 0.0, 10000.0, false, false, Interface::limited); static ParVector interfaceCoupling ("Coupling", "The overall coupling for the decay", &OniumToOniumPiPiDecayer::_coupling, -1, 1.0, 0.0, 10.0, false, false, Interface::limited); static ParVector interfaceReA ("ReA", "The real part of the A coupling", &OniumToOniumPiPiDecayer::_reA, 1./MeV2, -1, 1.0/MeV2, -1000.0/MeV2, 1000.0/MeV2, false, false, Interface::limited); static ParVector interfaceImA ("ImA", "The imaginary part of the A coupling", &OniumToOniumPiPiDecayer::_imA, 1./MeV2, -1, 1.0/MeV2, -1000.0/MeV2, 1000.0/MeV2, false, false, Interface::limited); static ParVector interfaceReB ("ReB", "The real part of the B coupling", &OniumToOniumPiPiDecayer::_reB, 1./MeV2, -1, 1.0/MeV2, -1000.0/MeV2, 1000.0/MeV2, false, false, Interface::limited); static ParVector interfaceImB ("ImB", "The imaginary part of the B coupling", &OniumToOniumPiPiDecayer::_imB, 1./MeV2, -1, 1.0/MeV2, -1000.0/MeV2, 1000.0/MeV2, false, false, Interface::limited); static ParVector interfaceReC ("ReC", "The real part of the C coupling", &OniumToOniumPiPiDecayer::_reC, 1./MeV2, -1, 1.0/MeV2, -1000.0/MeV2, 1000.0/MeV2, false, false, Interface::limited); static ParVector interfaceImC ("ImC", "The imaginary part of the C coupling", &OniumToOniumPiPiDecayer::_imC, 1./MeV2, -1, 1.0/MeV2, -1000.0/MeV2, 1000.0/MeV2, false, false, Interface::limited); } int OniumToOniumPiPiDecayer::modeNumber(bool & cc,tcPDPtr parent, const tPDVector & children) const { cc=false; int imode(-1); long idin(parent->id()); if(children.size()!=3) return -1; unsigned int npip(0),npim(0),npi0(0); long idother(0),id; for(tPDVector::const_iterator pit=children.begin(); pit!=children.end();++pit) { id=(**pit).id(); if(id==ParticleID::piplus) ++npip; else if(id==ParticleID::piminus) ++npim; else if(id==ParticleID::pi0) ++npi0; else idother=id; } // check pi+ pi- or pi0 pi0 and outgoing state if(!((npip==1&&npim==1)||npi0==2)||idother==0) return -1; unsigned int ix=0; do { if(idin==_incoming[ix]&&idother==_outgoing[ix]) imode=ix; ++ix; } while(ix<_incoming.size()&&imode<0); return npi0==2 ? 2*imode+1 : 2*imode; } double OniumToOniumPiPiDecayer::me2(const int, const Particle & inpart, const ParticleVector & decay, MEOption meopt) const { if(!ME()) ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1,PDT::Spin1,PDT::Spin0,PDT::Spin0))); useMe(); if(meopt==Initialize) { VectorWaveFunction::calculateWaveFunctions(_vectors[0],_rho, const_ptr_cast(&inpart), incoming,false); } if(meopt==Terminate) { VectorWaveFunction::constructSpinInfo(_vectors[0],const_ptr_cast(&inpart), incoming,true,false); VectorWaveFunction::constructSpinInfo(_vectors[1],decay[0], outgoing,true,false); for(unsigned int ix=1;ix<3;++ix) ScalarWaveFunction::constructSpinInfo(decay[ix],outgoing,true); return 0.; } VectorWaveFunction::calculateWaveFunctions(_vectors[1],decay[0],outgoing,false); // compute the matrix element complex A(_cA[imode()/2]),B(_cB[imode()/2]),C(_cC[imode()/2]); Energy2 q2 =(decay[1]->momentum()+decay[2]->momentum()).m2(); Energy2 mpi2=sqr(decay[1]->mass()); for(unsigned int ix=0;ix<3;++ix) { for(unsigned int iy=0;iy<3;++iy) { Complex dota = _vectors[0][ix].dot(_vectors[1][iy]); complex dotb = (_vectors[0][ix]*decay[1]->momentum())*(_vectors[1][iy]*decay[2]->momentum())+ (_vectors[0][ix]*decay[2]->momentum())*(_vectors[1][iy]*decay[1]->momentum()); (*ME())(ix,iy,0,0)= _coupling[imode()/2]* - (A*dota*(q2-2.*mpi2)+B*dota*decay[1]->momentum().e()*decay[2]->momentum().e() + Complex(A*dota*(q2-2.*mpi2)+B*dota*decay[1]->momentum().e()*decay[2]->momentum().e() +C*dotb); } } // matrix element double output=ME()->contract(_rho).real(); if(imode()%2==1) output*=0.5; // test of the matrix element // Energy2 s1=(decay[1]->momentum()+decay[2]->momentum()).m2(); // Energy2 s2=(decay[0]->momentum()+decay[2]->momentum()).m2(); // Energy2 s3=(decay[1]->momentum()+decay[0]->momentum()).m2(); // double test=threeBodyMatrixElement(imode(),sqr(inpart.mass()), // s3,s2,s1,decay[0]->mass(), // decay[1]->mass(),decay[2]->mass()); // return the answer return output; } // output the setup information for the particle database void OniumToOniumPiPiDecayer::dataBaseOutput(ofstream & output, bool header) const { if(header) output << "update decayers set parameters=\""; // parameters for the DecayIntegrator base class DecayIntegrator::dataBaseOutput(output,false); // the rest of the parameters for(unsigned int ix=0;ix<_incoming.size();++ix) { if(ix<_initsize) { output << "newdef " << name() << ":Incoming " << ix << " " << _incoming[ix] << "\n"; output << "newdef " << name() << ":Outgoing " << ix << " " << _outgoing[ix] << "\n"; output << "newdef " << name() << ":Coupling " << ix << " " << _coupling[ix] << "\n"; output << "newdef " << name() << ":ReA " << ix << " " << _reA[ix]*MeV2 << "\n"; output << "newdef " << name() << ":ImA " << ix << " " << _imA[ix]*MeV2 << "\n"; output << "newdef " << name() << ":ReB " << ix << " " << _reB[ix]*MeV2 << "\n"; output << "newdef " << name() << ":ImB " << ix << " " << _imB[ix]*MeV2 << "\n"; output << "newdef " << name() << ":ReC " << ix << " " << _reC[ix]*MeV2 << "\n"; output << "newdef " << name() << ":ImC " << ix << " " << _imC[ix]*MeV2 << "\n"; } else { output << "insert " << name() << ":Incoming " << ix << " " << _incoming[ix] << "\n"; output << "insert " << name() << ":Outgoing " << ix << " " << _outgoing[ix] << "\n"; output << "insert " << name() << ":Coupling " << ix << " " << _coupling[ix] << "\n"; output << "insert " << name() << ":ReA " << ix << " " << _reA[ix]*MeV2 << "\n"; output << "insert " << name() << ":ImA " << ix << " " << _imA[ix]*MeV2 << "\n"; output << "insert " << name() << ":ReB " << ix << " " << _reB[ix]*MeV2 << "\n"; output << "insert " << name() << ":ImB " << ix << " " << _imB[ix]*MeV2 << "\n"; output << "insert " << name() << ":ReC " << ix << " " << _reC[ix]*MeV2 << "\n"; output << "insert " << name() << ":ImC " << ix << " " << _imC[ix]*MeV2 << "\n"; } } for(unsigned int ix=0;ix<_maxweight.size();++ix) { if(ix<2*_initsize) { output << "newdef " << name() << ":MaxWeight " << ix << " " << _maxweight[ix] << "\n"; } else { output << "insert " << name() << ":MaxWeight " << ix << " " << _maxweight[ix] << "\n"; } } if(header) output << "\n\" where BINARY ThePEGName=\"" << fullName() << "\";" << endl; } WidthCalculatorBasePtr OniumToOniumPiPiDecayer:: threeBodyMEIntegrator(const DecayMode & dm) const { int imode(-1); long idin(dm.parent()->id()); unsigned int npip(0),npim(0),npi0(0); long idother(0),id; for(ParticleMSet::const_iterator pit=dm.products().begin(); pit!=dm.products().end();++pit) { id=(**pit).id(); if(id==ParticleID::piplus) ++npip; else if(id==ParticleID::piminus) ++npim; else if(id==ParticleID::pi0) ++npi0; else idother=id; } unsigned int ix=0; do { if(idin==_incoming[ix]&&idother==_outgoing[ix]) imode=ix; ++ix; } while(ix<_incoming.size()&&imode<0); imode = npi0==2 ? 2*imode+1 : 2*imode; // construct the integrator vector inweights(1,1.); Energy scale=getParticleData(_incoming[ix-1])->mass(); Energy m1=getParticleData(_outgoing[ix-1])->mass(); Energy mpi = npi0==2 ? getParticleData(ParticleID::pi0)->mass() : getParticleData(ParticleID::piplus)->mass(); vector intype(1,3); vector inmass (1,scale); vector inwidth(1,scale); vector inpow(1,0.0); return new_ptr(ThreeBodyAllOnCalculator (inweights,intype,inmass,inwidth,inpow, *this,imode,m1,mpi,mpi)); } double OniumToOniumPiPiDecayer:: threeBodyMatrixElement(const int imode, const Energy2 q2, const Energy2 s3, const Energy2 s2, const Energy2 s1, const Energy m1, const Energy m2, const Energy m3) const { Energy q=sqrt(q2); Energy e2 = 0.5*(q2+sqr(m2)-s2)/q; Energy e3 = 0.5*(q2+sqr(m3)-s3)/q; Complex amp = _cA[imode/2]*(s1-sqr(m2)-sqr(m3))+_cB[imode/2]*e2*e3; Energy2 dot = 0.5*(q2+sqr(m1)-s1); double output=(2.+sqr(dot/q/m1))*real(amp*conj(amp))*sqr(_coupling[imode/2])/3.; if(imode%2==1) output*=0.5; return output; } diff --git a/MatrixElement/Hadron/MEPP2Higgs.cc b/MatrixElement/Hadron/MEPP2Higgs.cc --- a/MatrixElement/Hadron/MEPP2Higgs.cc +++ b/MatrixElement/Hadron/MEPP2Higgs.cc @@ -1,1439 +1,1439 @@ // -*- 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/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/Core/Base/ShowerProgenitor.h" #include "Herwig/Shower/RealEmissionProcess.h" #include "Herwig/Shower/Core/Base/Branching.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) {} ClassDescription MEPP2Higgs::initMEPP2Higgs; // Definition of the static class description member. 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(ShowerProgenitorPtr initial, ShowerParticlePtr parent,Branching br) { if(parent->isFinalState()) return false; // check if me correction should be applied long id[2]={initial->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(br.ids[1]->id()!=ParticleID::g) return false; // get the pT Energy pT=br.kinematics->pT(); // check if hardest so far if(pThighestpT()) return false; // compute the invariants double kappa(sqr(br.kinematics->scale())/mh2_),z(br.kinematics->z()); Energy2 shat(mh2_/z*(1.+(1.-z)*kappa)),that(-(1.-z)*kappa*mh2_),uhat(-(1.-z)*shat); // check which type of process Energy2 me; // g g if(br.ids[0]->id()==ParticleID::g&&br.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(br.ids[0]->id() >= 1 && br.ids[0]->id() <= 5 && br.ids[2]->id()==br.ids[0]->id()) { double split = 4./3./z*(1.+sqr(1.-z)); me = qgME(shat,uhat,that)/split; } // qbar g else if(br.ids[0]->id() <= -1 && br.ids[0]->id() >= -5 && br.ids[2]->id()==br.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 " << br.ids[0]->id() << " " << br.ids[1]->id() << " " << br.ids[2]->id() << "\n"; // if not vetoed if(UseRandom::rndbool(wgt)) return false; // otherwise parent->vetoEmission(br.type,br.kinematics->scale()); return true; } 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); 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); 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.*(u*ci_[k]+t*ci_[j]+u1*ci_[k1]+t1*ci_[j1]-u*t*di_[i])/sqr(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); 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/Matchbox/Builtin/Amplitudes/MatchboxCurrents.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.cc --- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.cc +++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.cc @@ -1,2861 +1,2832 @@ // - * - C++ - * - // // MatchboxCurrents.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. // #include "MatchboxCurrents.h" #include "Herwig/Utilities/Maths.h" using namespace Herwig; using namespace Herwig::Math; using Constants::pi; namespace { - const static LorentzVector czero(0.,0.,0.,0.); + static const LorentzVector czero(0.,0.,0.,0.); inline Complex csqr(const Complex & a) { return a * a; } inline double theta(const double x) { if ( x >= 0. ) return 1.; return 0.; } inline double sign(const double x) { if ( x >= 0. ) return 1.; return -1.; } - // quick'n'dirty fix to template troubles - - Complex operator * (const Complex& a, const double b) { - return Complex(a.real() * b,a.imag() * b); - } - - Complex operator * (const double b, const Complex& a) { - return Complex(a.real() * b,a.imag() * b); - } - - Complex operator+(const Complex& a, const double b) { - return Complex(a.real()+b,a.imag()); - } - - Complex operator+(const double b, const Complex& a) { - return Complex(a.real()+b,a.imag()); - } - - Complex operator-(const Complex& a, const double b) { - return Complex(a.real()-b,a.imag()); - } - - Complex operator-(const double b, const Complex& a) { - return Complex(b-a.real(),-a.imag()); - } - - - // end fix, needs to be looked at in ThePEG/Config/ - } void MatchboxCurrents::setupLeptons(const int l, const Lorentz5Momentum& pl, const int lbar, const Lorentz5Momentum& plbar) { const Energy4 Delta = (sqr(pl*plbar) - (pl*pl)*(plbar*plbar)); const Energy2 prod = pl*plbar; // Variable to contain the sign of pl*plbar double sgn; if (prod < ZERO ) {sgn = -1;} else if (prod > ZERO) {sgn = 1;} else {sgn = 0;} InvEnergy2 fact = 0.5/(sgn*sqrt(Delta)); Lorentz5Momentum lmassless = ( double(fact*(sgn*sqrt(Delta) + prod))*pl - double(fact*( pl*pl))*plbar ); Lorentz5Momentum lbarmassless = ( double(fact*(sgn*sqrt(Delta) + prod))*plbar - double(fact*(plbar*plbar))*pl ); lmassless.setMass(ZERO); lmassless.rescaleEnergy(); lbarmassless.setMass(ZERO); lbarmassless.rescaleEnergy(); if ( pl.t() < ZERO ) lmassless.setT(-lmassless.t()); if ( plbar.t() < ZERO ) lbarmassless.setT(-lbarmassless.t()); momentum(l,lmassless,true,pl.mass()); momentum(lbar,lbarmassless,true,plbar.mass()); } void MatchboxCurrents::setupQuarks(const int q, const Lorentz5Momentum& pq, const int qbar, const Lorentz5Momentum& pqbar) { const Energy4 Delta = (sqr(pq*pqbar) - (pq*pq)*(pqbar*pqbar)); const Energy2 prod = pq*pqbar; // Variable to contain the sign of pq*pqbar double sgn; if (prod < ZERO) {sgn = -1;} else if (prod > ZERO) {sgn = 1;} else {sgn = 0;} InvEnergy2 fact = 0.5/(sgn*sqrt(Delta)); Lorentz5Momentum qmassless = ( double(fact*(sgn*sqrt(Delta) + prod))*pq - double(fact*(pq*pq))*pqbar ); Lorentz5Momentum qbarmassless = ( double(fact*(sgn*sqrt(Delta) + prod))*pqbar - double(fact*(pqbar*pqbar))*pq ); qmassless.setMass(ZERO); qmassless.rescaleEnergy(); qbarmassless.setMass(ZERO); qbarmassless.rescaleEnergy(); if ( pq.t() < ZERO ) qmassless.setT(-qmassless.t()); if ( pqbar.t() < ZERO ) qbarmassless.setT(-qbarmassless.t()); momentum(q,qmassless,true,pq.mass()); momentum(qbar,qbarmassless,true,pqbar.mass()); } const LorentzVector& MatchboxCurrents::llbarLeftCurrent(const int l, const int lHel, const int lbar, const int lbarHel) { if ( getCurrent(hash<0>(1,1,l,lHel,lbar,lbarHel)) ) { if ( lHel == 1 && lbarHel == 1 ) cacheCurrent(Complex(0.,1.) * minusCurrent(l,lbar)); if ( lHel == 1 && lbarHel == -1 ) cacheCurrent((Complex(0.,2.) * mass(lbar)/plusProduct(l,lbar)) * momentum(l)); if ( lHel == -1 && lbarHel == 1 ) cacheCurrent((Complex(0.,-2.) * mass(l)/minusProduct(l,lbar)) * momentum(lbar)); if ( lHel == -1 && lbarHel == -1 ) cacheCurrent((Complex(0.,1.) * mass(l) * mass(lbar)/invariant(l,lbar)) * minusCurrent(lbar,l)); } return cachedCurrent(); } const LorentzVector& MatchboxCurrents::llbarRightCurrent(const int l, const int lHel, const int lbar, const int lbarHel) { if ( getCurrent(hash<0>(2,1,l,lHel,lbar,lbarHel)) ) { if ( lHel == 1 && lbarHel == 1 ) cacheCurrent((Complex(0.,1.) * mass(l) * mass(lbar)/invariant(l,lbar)) * minusCurrent(l,lbar)); if ( lHel == 1 && lbarHel == -1 ) cacheCurrent((Complex(0.,-2.) * mass(l)/plusProduct(l,lbar)) * momentum(lbar)); if ( lHel == -1 && lbarHel == 1 ) cacheCurrent((Complex(0.,2.) * mass(lbar)/minusProduct(l,lbar)) * momentum(l)); if ( lHel == -1 && lbarHel == -1 ) cacheCurrent(Complex(0.,1.) * minusCurrent(lbar,l)); } return cachedCurrent(); } const LorentzVector& MatchboxCurrents::qqbarLeftCurrent(const int q, const int qHel, const int qbar, const int qbarHel) { if ( getCurrent(hash<1>(1,1,q,qHel,qbar,qbarHel)) ) { if ( qHel == 1 && qbarHel == 1 ) cacheCurrent(Complex(0.,1.) * minusCurrent(q,qbar)); if ( qHel == 1 && qbarHel == -1 ) cacheCurrent((Complex(0.,2.) * mass(qbar)/plusProduct(q,qbar)) * momentum(q)); if ( qHel == -1 && qbarHel == 1 ) cacheCurrent((Complex(0.,-2.) * mass(q)/minusProduct(q,qbar)) * momentum(qbar)); if ( qHel == -1 && qbarHel == -1 ) cacheCurrent((Complex(0.,1.) * mass(q) * mass(qbar)/invariant(q,qbar)) * minusCurrent(qbar,q)); } #ifdef CHECK_MatchboxCurrents checkCurrent("qqbarLeftCurrent",cachedCurrent(),momentum(q)+momentum(qbar)); #endif return cachedCurrent(); } const LorentzVector& MatchboxCurrents::qqbarRightCurrent(const int q, const int qHel, const int qbar, const int qbarHel) { if ( getCurrent(hash<1>(2,1,q,qHel,qbar,qbarHel)) ) { if ( qHel == 1 && qbarHel == 1 ) cacheCurrent((Complex(0.,1.) * mass(q) * mass(qbar)/invariant(q,qbar)) * minusCurrent(q,qbar)); if ( qHel == 1 && qbarHel == -1 ) cacheCurrent((Complex(0.,-2.) * mass(q)/plusProduct(q,qbar)) * momentum(qbar)); if ( qHel == -1 && qbarHel == 1 ) cacheCurrent((Complex(0.,2.) * mass(qbar)/minusProduct(q,qbar)) * momentum(q)); if ( qHel == -1 && qbarHel == -1 ) cacheCurrent(Complex(0.,1.) * minusCurrent(qbar,q)); } #ifdef CHECK_MatchboxCurrents checkCurrent("qqbarRightCurrent",cachedCurrent(),momentum(q)+momentum(qbar)); #endif return cachedCurrent(); } const LorentzVector& MatchboxCurrents::qqbargLeftCurrent(const int q, const int qHel, const int qbar, const int qbarHel, const int g, const int gHel) { if ( gHel == 1 ) { if ( getCurrent(hash<2>(1,1,q,qHel,qbar,qbarHel,g,gHel)) ) { // Invariant products from propagator denominators const Complex den_i = invariant(q,g) + (sqr(mass(q))/invariant(q,qbar))*invariant(qbar,g); const Complex den_j = invariant(qbar,g) + (sqr(mass(qbar))/invariant(q,qbar))*invariant(q,g); // 2*factor from the spinor definition of the negative helicity gluon // Note that the gluon is outgoing so the polarisation vector of the hel=+1 gluon is conjugated to give the hel=-1 vector const Complex cminus = sqrt(2.0) / minusProduct(g,q); if ( qHel == 1 && qbarHel == 1 ) cacheCurrent( Complex(0.,1.)*cminus*( ((sqr(mass(q))*plusProduct(qbar,g)/(plusProduct(qbar,q)*den_i)) - (minusProduct(qbar,q)*plusProduct(g,qbar)/den_j))*minusCurrent(q, qbar) - (minusProduct(g,q)*plusProduct(g,qbar)/den_j)*minusCurrent(q,g) ) ); if ( qHel == 1 && qbarHel == -1 ) cacheCurrent( Complex(0.,1.)*cminus*(-mass(qbar)/plusProduct(qbar,q)) * ( ((sqr(mass(q))*plusProduct(qbar,g)/(plusProduct(qbar,q)*den_i)) - (plusProduct(qbar,g)*minusProduct(q,qbar)/den_j))*2*momentum(q) + (invariant(q,g)/den_j)*minusCurrent(q,g) ) ); if ( qHel == -1 && qbarHel == 1 ) cacheCurrent( Complex(0.,1.)*cminus*(mass(q)/minusProduct(qbar,q)) * ( ((sqr(mass(q))*plusProduct(g,qbar)/(plusProduct(q,qbar)*den_i)) - (plusProduct(g,qbar)*minusProduct(qbar,q)/den_j))*2*momentum(qbar) - (minusProduct(g,q)*plusProduct(g,qbar)/den_j)*minusCurrent(qbar,g) ) ); if ( qHel == -1 && qbarHel == -1 ) cacheCurrent( Complex(0.,1.)*cminus*(mass(qbar)*mass(q)/(invariant(q,qbar))) * ( ((sqr(mass(q))*plusProduct(g,qbar)/(plusProduct(q,qbar)*den_i)) - (minusProduct(q,qbar)*plusProduct(qbar,g)/den_j))*minusCurrent(qbar,q) + (invariant(q,g)/den_j)*minusCurrent(qbar,g) ) ); } #ifdef CHECK_MatchboxCurrents checkCurrent("qqbargLeftCurrent",cachedCurrent(),momentum(q)+momentum(qbar)+momentum(g)); #endif return cachedCurrent(); } if ( gHel == -1 ) { if ( getCurrent(hash<2>(1,1,q,qHel,qbar,qbarHel,g,gHel)) ) { // Invariant products from propagator denominators const Complex den_i = invariant(q,g) + (sqr(mass(q))/invariant(q,qbar))*invariant(qbar,g); const Complex den_j = invariant(qbar,g) + (sqr(mass(qbar))/invariant(q,qbar))*invariant(q,g); // 2*factor from the spinor definition of the positive helicity gluon const Complex cplus = sqrt(2.0) / plusProduct(q,g); if ( qHel == 1 && qbarHel == 1 ) cacheCurrent( Complex(0.,1.)*cplus*( ((sqr(mass(q))*minusProduct(g,qbar)/(minusProduct(q,qbar)*den_i)) - (minusProduct(qbar,g)*plusProduct(q,qbar)/den_j))*minusCurrent(q, qbar) - (invariant(q,g)/den_i)*minusCurrent(g,qbar) ) ); if ( qHel == 1 && qbarHel == -1 ) cacheCurrent( Complex(0.,1.)*cplus*(-mass(qbar)/plusProduct(qbar,q)) * ( ((sqr(mass(q))*minusProduct(g,qbar)/(minusProduct(q,qbar)*den_i)) - (plusProduct(qbar,q)*minusProduct(g,qbar)/den_j))*2*momentum(q) - (invariant(q,g)/den_i)*minusCurrent(g,q) ) ); if ( qHel == -1 && qbarHel == 1 ) cacheCurrent( Complex(0.,1.)*cplus*(mass(q)/minusProduct(qbar,q)) * ( ((sqr(mass(q))*minusProduct(qbar,g)/(minusProduct(qbar,q)*den_i)) - (minusProduct(qbar,g)*plusProduct(q,qbar)/den_j))*2*momentum(qbar) + (minusProduct(qbar,g)*plusProduct(q,g)/den_i)*minusCurrent(g,qbar) ) ); if ( qHel == -1 && qbarHel == -1 ) cacheCurrent( Complex(0.,1.)*cplus*(mass(qbar)*mass(q)/(invariant(q,qbar))) * ( ((sqr(mass(q))*minusProduct(qbar,g)/(minusProduct(qbar,q)*den_i)) - (plusProduct(qbar,q)*minusProduct(g,qbar)/den_j))*minusCurrent(qbar, q) + (minusProduct(qbar,g)*plusProduct(q,g)/den_i)*minusCurrent(g,q) ) ); } #ifdef CHECK_MatchboxCurrents checkCurrent("qqbargLeftCurrent",cachedCurrent(),momentum(q)+momentum(qbar)+momentum(g)); #endif return cachedCurrent(); } return czero; } const LorentzVector& MatchboxCurrents::qqbargRightCurrent(const int q, const int qHel, const int qbar, const int qbarHel, const int g, const int gHel) { if ( gHel == 1 ) { if ( getCurrent(hash<2>(2,1,q,qHel,qbar,qbarHel,g,gHel)) ) { // Invariant products from propagator denominators const Complex den_i = invariant(q,g) + (sqr(mass(q))/invariant(q,qbar))*invariant(qbar,g); const Complex den_j = invariant(qbar,g) + (sqr(mass(qbar))/invariant(q,qbar))*invariant(q,g); // 2*factor from the spinor definition of the positive helicity gluon const Complex cminus = sqrt(2.0) / minusProduct(g,q); if ( qHel == 1 && qbarHel == 1 ) cacheCurrent( Complex(0.,1.)*cminus*(mass(qbar)*mass(q)/(invariant(q,qbar))) * ( ((sqr(mass(q))*plusProduct(qbar,g)/(plusProduct(qbar,q)*den_i)) - (minusProduct(qbar,q)*plusProduct(g,qbar)/den_j))*plusCurrent(qbar, q) + (plusProduct(qbar,g)*minusProduct(q,g)/den_i)*plusCurrent(g,q) ) ); if ( qHel == 1 && qbarHel == -1 ) cacheCurrent( Complex(0.,1.)*cminus*(mass(q)/plusProduct(qbar,q)) * ( ((sqr(mass(q))*plusProduct(qbar,g)/(plusProduct(qbar,q)*den_i)) - (plusProduct(qbar,g)*minusProduct(q,qbar)/den_j))*2*momentum(qbar) + (plusProduct(qbar,g)*minusProduct(q,g)/den_i)*plusCurrent(g,qbar) ) ); if ( qHel == -1 && qbarHel == 1 ) cacheCurrent( Complex(0.,1.)*cminus*(-mass(qbar)/minusProduct(qbar,q)) * ( ((sqr(mass(q))*plusProduct(g,qbar)/(plusProduct(q,qbar)*den_i)) - (minusProduct(qbar,q)*plusProduct(g,qbar)/den_j))*2*momentum(q) - (invariant(q,g)/den_i)*plusCurrent(g,q) ) ); if ( qHel == -1 && qbarHel == -1 ) cacheCurrent( Complex(0.,1.)*cminus*( ((sqr(mass(q))*plusProduct(g,qbar)/(plusProduct(q,qbar)*den_i)) - (plusProduct(qbar,g)*minusProduct(q,qbar)/den_j))*plusCurrent(q, qbar) - (invariant(q,g)/den_i)*plusCurrent(g,qbar) ) ); } #ifdef CHECK_MatchboxCurrents checkCurrent("qqbargRightCurrent",cachedCurrent(),momentum(q)+momentum(qbar)+momentum(g)); #endif return cachedCurrent(); } if ( gHel == -1 ) { if ( getCurrent(hash<2>(2,1,q,qHel,qbar,qbarHel,g,gHel)) ) { // Invariant products from propagator denominators const Complex den_i = invariant(q,g) + (sqr(mass(q))/invariant(q,qbar))*invariant(qbar,g); const Complex den_j = invariant(qbar,g) + (sqr(mass(qbar))/invariant(q,qbar))*invariant(q,g); // 2*factor from the spinor definition of the positive helicity gluon const Complex cplus = sqrt(2.0) / plusProduct(q,g); if ( qHel == 1 && qbarHel == 1 ) cacheCurrent( Complex(0.,1.)*cplus*(mass(qbar)*mass(q)/(invariant(q,qbar))) * ( ((sqr(mass(q))*minusProduct(g,qbar)/(minusProduct(q,qbar)*den_i)) - (plusProduct(q,qbar)*minusProduct(qbar,g)/den_j))*plusCurrent(qbar, q) + (invariant(q,g)/den_j)*plusCurrent(qbar,g) ) ); if ( qHel == 1 && qbarHel == -1 ) cacheCurrent( Complex(0.,1.)*cplus*(mass(q)/plusProduct(qbar,q)) * ( ((sqr(mass(q))*minusProduct(g,qbar)/(minusProduct(q,qbar)*den_i)) - (minusProduct(g,qbar)*plusProduct(qbar,q)/den_j))*2*momentum(qbar) - (plusProduct(g,q)*minusProduct(g,qbar)/den_j)*plusCurrent(qbar,g) ) ); if ( qHel == -1 && qbarHel == 1 ) cacheCurrent( Complex(0.,1.)*cplus*(-mass(qbar)/minusProduct(qbar,q)) * ( ((sqr(mass(q))*minusProduct(qbar,g)/(minusProduct(qbar,q)*den_i)) - (minusProduct(qbar,g)*plusProduct(q,qbar)/den_j))*2*momentum(q) + (invariant(q,g)/den_j)*plusCurrent(q,g) ) ); if ( qHel == -1 && qbarHel == -1 ) cacheCurrent( Complex(0.,1.)*cplus*( ((sqr(mass(q))*minusProduct(qbar,g)/(minusProduct(qbar,q)*den_i)) - (plusProduct(qbar,q)*minusProduct(g,qbar)/den_j))*plusCurrent(q, qbar) - (plusProduct(g,q)*minusProduct(g,qbar)/den_j)*plusCurrent(q,g) ) ); } #ifdef CHECK_MatchboxCurrents checkCurrent("qqbargRightCurrent",cachedCurrent(),momentum(q)+momentum(qbar)+momentum(g)); #endif return cachedCurrent(); } return czero; } LorentzVector MatchboxCurrents::qqbarggGeneralLeftCurrent(const int i, const int, const int j, const int, const int k, const int g1Hel, const int l, const int g2Hel, const int n) { const double ik = invariant(i,k); const double il = invariant(i,l); const double jk = invariant(j,k); const double jl = invariant(j,l); const double kl = invariant(k,l); const Complex plusP_ik = plusProduct(i,k); const Complex plusP_il = plusProduct(i,l); const Complex plusP_in = plusProduct(i,n); const Complex plusP_jk = plusProduct(j,k); const Complex plusP_jl = plusProduct(j,l); const Complex plusP_jn = plusProduct(j,n); const Complex plusP_kl = plusProduct(k,l); const Complex plusP_kn = plusProduct(k,n); const Complex plusP_ln = plusProduct(l,n); const Complex minusP_ik = minusProduct(i,k); const Complex minusP_il = minusProduct(i,l); const Complex minusP_in = minusProduct(i,n); const Complex minusP_jk = minusProduct(j,k); const Complex minusP_jl = minusProduct(j,l); const Complex minusP_jn = minusProduct(j,n); const Complex minusP_kl = minusProduct(k,l); const Complex minusP_kn = minusProduct(k,n); const Complex minusP_ln = minusProduct(l,n); const LorentzVector & minusC_ij = minusCurrent(i,j); const LorentzVector & minusC_ik = minusCurrent(i,k); const LorentzVector & minusC_il = minusCurrent(i,l); const LorentzVector & minusC_kj = minusCurrent(k,j); const LorentzVector & minusC_kl = minusCurrent(k,l); const LorentzVector & minusC_lj = minusCurrent(l,j); if ( g1Hel == 1 && g2Hel == 1 ) { return (Complex(0,-2) * plusP_jl * plusP_kl * minusC_ik)/ (jl * (jk + jl + kl)) - (Complex(0,2) * plusP_jl * plusP_kl * minusC_ik)/ (kl * (jk + jl + kl)) - (Complex(0,2) * plusP_jk * plusP_kl * minusC_il)/ (kl * (jk + jl + kl)) + (Complex(0,2) * plusP_il * plusP_kl * minusC_ij * minusP_in)/ (kl * (ik + il + kl) * minusP_kn) - (Complex(0,2) * plusP_ik * plusP_jl * minusC_il * minusP_in)/ (ik * jl * minusP_kn) + (Complex(0,2) * sqr(plusP_kl) * minusC_kj * minusP_in)/ (kl * (ik + il + kl) * minusP_kn) - (Complex(0,2) * plusP_jl * plusP_kl * minusC_ij * minusP_jn)/ (jl * (jk + jl + kl) * minusP_kn) - (Complex(0,2) * plusP_jl * plusP_kl * minusC_ij * minusP_jn)/ (kl * (jk + jl + kl) * minusP_kn) + (Complex(0,2) * plusP_jk * plusP_jl * minusC_il * minusP_jn)/ (jl * (jk + jl + kl) * minusP_kn) + (Complex(0,2) * plusP_ik * plusP_kl * minusC_ij * minusP_in)/ (kl * (ik + il + kl) * minusP_ln) - (Complex(0,2) * sqr(plusP_kl) * minusC_lj * minusP_in)/ (kl * (ik + il + kl) * minusP_ln) - (Complex(0,2) * plusP_jk * plusP_kl * minusC_ij * minusP_jn)/ (kl * (jk + jl + kl) * minusP_ln) + (Complex(0,2) * plusP_jk * plusP_jl * minusC_ik * minusP_jn)/ (jl * (jk + jl + kl) * minusP_ln) + (Complex(0,2) * plusP_ik * plusP_il * minusC_ij * sqr(minusP_in))/ (ik * (ik + il + kl) * minusP_kn * minusP_ln) + (Complex(0,2) * plusP_ik * plusP_kl * minusC_kj * sqr(minusP_in))/ (ik * (ik + il + kl) * minusP_kn * minusP_ln) - (Complex(0,2) * plusP_ik * plusP_jl * minusC_ij * minusP_in * minusP_jn)/ (ik * jl * minusP_kn * minusP_ln) + (Complex(0,2) * plusP_jk * plusP_jl * minusC_ij * sqr(minusP_jn))/ (jl * (jk + jl + kl) * minusP_kn * minusP_ln) - (Complex(0,2) * plusP_jk * plusP_kl * minusC_ik * minusP_kn)/ (kl * (jk + jl + kl) * minusP_ln) - (Complex(0,2) * plusP_jl * plusP_kl * minusC_il * minusP_ln)/ (jl * (jk + jl + kl) * minusP_kn) - (Complex(0,2) * plusP_jl * plusP_kl * minusC_il * minusP_ln)/ (kl * (jk + jl + kl) * minusP_kn); } if ( g1Hel == 1 && g2Hel == -1 ) { return (Complex(0,-2) * plusP_jk * plusP_jn * minusC_ik * minusP_jl)/ (jl * (jk + jl + kl) * plusP_ln) + (Complex(0,2) * plusP_jk * plusP_kn * minusC_ik * minusP_kl)/ (kl * (jk + jl + kl) * plusP_ln) - (Complex(0,2) * plusP_ik * plusP_in * minusC_ij * minusP_il * minusP_in)/ (ik * (ik + il + kl) * plusP_ln * minusP_kn) - (Complex(0,2) * plusP_ik * plusP_kn * minusC_kj * minusP_il * minusP_in)/ (ik * (ik + il + kl) * plusP_ln * minusP_kn) - (Complex(0,2) * plusP_ik * minusC_lj * minusP_il * minusP_in)/ (ik * (ik + il + kl) * minusP_kn) + (Complex(0,2) * plusP_ik * plusP_jn * minusC_ij * minusP_in * minusP_jl)/ (ik * jl * plusP_ln * minusP_kn) - (Complex(0,2) * plusP_jk * plusP_jn * minusC_ij * minusP_jl * minusP_jn)/ (jl * (jk + jl + kl) * plusP_ln * minusP_kn) - (Complex(0,2) * plusP_ik * plusP_kn * minusC_ij * minusP_in * minusP_kl)/ (kl * (ik + il + kl) * plusP_ln * minusP_kn) + (Complex(0,2) * plusP_kl * plusP_kn * minusC_lj * minusP_in * minusP_kl)/ (kl * (ik + il + kl) * plusP_ln * minusP_kn) + (Complex(0,2) * plusP_jk * plusP_kn * minusC_ij * minusP_jn * minusP_kl)/ (kl * (jk + jl + kl) * plusP_ln * minusP_kn) - (Complex(0,1) * plusP_ik * plusP_kn * minusC_ij * minusP_ik * minusP_ln)/ (kl * (ik + il + kl) * plusP_ln * minusP_kn) + (Complex(0,1) * plusP_kl * plusP_kn * minusC_lj * minusP_ik * minusP_ln)/ (kl * (ik + il + kl) * plusP_ln * minusP_kn) - (Complex(0,2) * plusP_in * plusP_kl * minusC_ij * minusP_il * minusP_ln)/ (kl * (ik + il + kl) * plusP_ln * minusP_kn) + (Complex(0,1) * plusP_il * plusP_kn * minusC_ij * minusP_il * minusP_ln)/ (kl * (ik + il + kl) * plusP_ln * minusP_kn) - (Complex(0,1) * plusP_kl * plusP_kn * minusC_kj * minusP_il * minusP_ln)/ (kl * (ik + il + kl) * plusP_ln * minusP_kn) - (Complex(0,2) * plusP_kl * minusC_lj * minusP_il * minusP_ln)/ (kl * (ik + il + kl) * minusP_kn) + (Complex(0,1) * plusP_jk * plusP_kn * minusC_ij * minusP_jk * minusP_ln)/ (kl * (jk + jl + kl) * plusP_ln * minusP_kn) + (Complex(0,2) * plusP_jn * plusP_kl * minusC_ij * minusP_jl * minusP_ln)/ (kl * (jk + jl + kl) * plusP_ln * minusP_kn) - (Complex(0,1) * plusP_jl * plusP_kn * minusC_ij * minusP_jl * minusP_ln)/ (kl * (jk + jl + kl) * plusP_ln * minusP_kn) - (Complex(0,2) * plusP_jk * plusP_jn * minusC_il * minusP_jl * minusP_ln)/ (jl * (jk + jl + kl) * plusP_ln * minusP_kn) + (Complex(0,2) * plusP_jn * plusP_kl * minusC_ik * minusP_kl * minusP_ln)/ (kl * (jk + jl + kl) * plusP_ln * minusP_kn) - (Complex(0,1) * plusP_jl * plusP_kn * minusC_ik * minusP_kl * minusP_ln)/ (kl * (jk + jl + kl) * plusP_ln * minusP_kn) + (Complex(0,1) * plusP_jk * plusP_kn * minusC_il * minusP_kl * minusP_ln)/ (kl * (jk + jl + kl) * plusP_ln * minusP_kn); } if ( g1Hel == -1 && g2Hel == 1 ) { return (Complex(0,2) * plusP_in * plusP_jl * minusC_il * minusP_ik)/ (ik * jl * plusP_kn) + (Complex(0,2) * plusP_jl * minusC_kl * minusP_ik)/(ik * jl) - (Complex(0,2) * plusP_jl * plusP_ln * minusC_ij * minusP_jk)/ (jl * (jk + jl + kl) * plusP_kn) + (Complex(0,2) * plusP_jl * plusP_ln * minusC_il * minusP_kl)/ (jl * (jk + jl + kl) * plusP_kn) + (Complex(0,2) * plusP_jl * plusP_ln * minusC_il * minusP_kl)/ (kl * (jk + jl + kl) * plusP_kn) - (Complex(0,2) * plusP_il * plusP_in * minusC_ij * minusP_ik * minusP_in)/ (ik * (ik + il + kl) * plusP_kn * minusP_ln) - (Complex(0,2) * plusP_in * plusP_kl * minusC_kj * minusP_ik * minusP_in)/ (ik * (ik + il + kl) * plusP_kn * minusP_ln) + (Complex(0,2) * plusP_in * plusP_jl * minusC_ij * minusP_ik * minusP_jn)/ (ik * jl * plusP_kn * minusP_ln) + (Complex(0,2) * plusP_jl * minusC_kj * minusP_ik * minusP_jn)/ (ik * jl * minusP_ln) - (Complex(0,2) * plusP_jl * plusP_jn * minusC_ij * minusP_jk * minusP_jn)/ (jl * (jk + jl + kl) * plusP_kn * minusP_ln) - (Complex(0,2) * plusP_il * plusP_ln * minusC_ij * minusP_in * minusP_kl)/ (kl * (ik + il + kl) * plusP_kn * minusP_ln) - (Complex(0,2) * plusP_kl * plusP_ln * minusC_kj * minusP_in * minusP_kl)/ (kl * (ik + il + kl) * plusP_kn * minusP_ln) + (Complex(0,2) * plusP_jl * plusP_ln * minusC_ij * minusP_jn * minusP_kl)/ (kl * (jk + jl + kl) * plusP_kn * minusP_ln) + (Complex(0,2) * plusP_jl * plusP_jn * minusC_il * minusP_jn * minusP_kl)/ (jl * (jk + jl + kl) * plusP_kn * minusP_ln) - (Complex(0,2) * plusP_il * minusC_ij * minusP_ik * minusP_kn)/ (ik * (ik + il + kl) * minusP_ln) - (Complex(0,2) * plusP_in * plusP_kl * minusC_ij * minusP_ik * minusP_kn)/ (kl * (ik + il + kl) * plusP_kn * minusP_ln) - (Complex(0,1) * plusP_ik * plusP_ln * minusC_ij * minusP_ik * minusP_kn)/ (kl * (ik + il + kl) * plusP_kn * minusP_ln) - (Complex(0,2) * plusP_kl * minusC_kj * minusP_ik * minusP_kn)/ (ik * (ik + il + kl) * minusP_ln) - (Complex(0,2) * plusP_kl * minusC_kj * minusP_ik * minusP_kn)/ (kl * (ik + il + kl) * minusP_ln) - (Complex(0,1) * plusP_kl * plusP_ln * minusC_lj * minusP_ik * minusP_kn)/ (kl * (ik + il + kl) * plusP_kn * minusP_ln) + (Complex(0,1) * plusP_il * plusP_ln * minusC_ij * minusP_il * minusP_kn)/ (kl * (ik + il + kl) * plusP_kn * minusP_ln) + (Complex(0,1) * plusP_kl * plusP_ln * minusC_kj * minusP_il * minusP_kn)/ (kl * (ik + il + kl) * plusP_kn * minusP_ln) + (Complex(0,2) * plusP_jn * plusP_kl * minusC_ij * minusP_jk * minusP_kn)/ (kl * (jk + jl + kl) * plusP_kn * minusP_ln) + (Complex(0,1) * plusP_jk * plusP_ln * minusC_ij * minusP_jk * minusP_kn)/ (kl * (jk + jl + kl) * plusP_kn * minusP_ln) - (Complex(0,1) * plusP_jl * plusP_ln * minusC_ij * minusP_jl * minusP_kn)/ (kl * (jk + jl + kl) * plusP_kn * minusP_ln) + (Complex(0,1) * plusP_jl * plusP_ln * minusC_ik * minusP_kl * minusP_kn)/ (kl * (jk + jl + kl) * plusP_kn * minusP_ln) - (Complex(0,2) * plusP_jn * plusP_kl * minusC_il * minusP_kl * minusP_kn)/ (kl * (jk + jl + kl) * plusP_kn * minusP_ln) - (Complex(0,1) * plusP_jk * plusP_ln * minusC_il * minusP_kl * minusP_kn)/ (kl * (jk + jl + kl) * plusP_kn * minusP_ln); } if ( g1Hel == -1 && g2Hel == -1 ) { return (Complex(0,2) * sqr(plusP_in) * minusC_ij * minusP_ik * minusP_il)/ (ik * (ik + il + kl) * plusP_kn * plusP_ln) + (Complex(0,2) * plusP_in * minusC_kj * minusP_ik * minusP_il)/ (ik * (ik + il + kl) * plusP_ln) + (Complex(0,2) * plusP_in * minusC_lj * minusP_ik * minusP_il)/ (ik * (ik + il + kl) * plusP_kn) - (Complex(0,2) * plusP_in * plusP_jn * minusC_ij * minusP_ik * minusP_jl)/ (ik * jl * plusP_kn * plusP_ln) - (Complex(0,2) * plusP_jn * minusC_kj * minusP_ik * minusP_jl)/ (ik * jl * plusP_ln) + (Complex(0,2) * sqr(plusP_jn) * minusC_ij * minusP_jk * minusP_jl)/ (jl * (jk + jl + kl) * plusP_kn * plusP_ln) + (Complex(0,2) * plusP_in * minusC_ij * minusP_ik * minusP_kl)/ (ik * (ik + il + kl) * plusP_ln) + (Complex(0,2) * plusP_in * minusC_ij * minusP_ik * minusP_kl)/ (kl * (ik + il + kl) * plusP_ln) + (Complex(0,2) * plusP_kn * minusC_kj * minusP_ik * minusP_kl)/ (ik * (ik + il + kl) * plusP_ln) + (Complex(0,2) * plusP_kn * minusC_kj * minusP_ik * minusP_kl)/ (kl * (ik + il + kl) * plusP_ln) + (Complex(0,2) * minusC_lj * minusP_ik * minusP_kl)/ (ik * (ik + il + kl)) + (Complex(0,2) * minusC_lj * minusP_ik * minusP_kl)/ (kl * (ik + il + kl)) + (Complex(0,2) * plusP_in * minusC_ij * minusP_il * minusP_kl)/ (kl * (ik + il + kl) * plusP_kn) + (Complex(0,2) * minusC_kj * minusP_il * minusP_kl)/ (kl * (ik + il + kl)) + (Complex(0,2) * plusP_ln * minusC_lj * minusP_il * minusP_kl)/ (kl * (ik + il + kl) * plusP_kn) - (Complex(0,2) * plusP_jn * minusC_ij * minusP_jk * minusP_kl)/ (kl * (jk + jl + kl) * plusP_ln) - (Complex(0,2) * plusP_jn * minusC_ij * minusP_jl * minusP_kl)/ (kl * (jk + jl + kl) * plusP_kn) - (Complex(0,2) * sqr(plusP_jn) * minusC_il * minusP_jl * minusP_kl)/ (jl * (jk + jl + kl) * plusP_kn * plusP_ln) - (Complex(0,2) * plusP_jn * minusC_ik * sqr(minusP_kl))/ (kl * (jk + jl + kl) * plusP_kn) + (Complex(0,2) * plusP_jn * minusC_il * sqr(minusP_kl))/ (kl * (jk + jl + kl) * plusP_ln); } return czero; } LorentzVector MatchboxCurrents::qqbarggFixedLeftCurrent(const int i, const int, const int j, const int, const int k, const int g1Hel, const int l, const int g2Hel) { const double ik = invariant(i,k); const double il = invariant(i,l); const double jk = invariant(j,k); const double jl = invariant(j,l); const double kl = invariant(k,l); const Complex plusP_ij = plusProduct(i,j); const Complex plusP_ik = plusProduct(i,k); const Complex plusP_il = plusProduct(i,l); const Complex plusP_jk = plusProduct(j,k); const Complex plusP_jl = plusProduct(j,l); const Complex plusP_kl = plusProduct(k,l); const Complex minusP_ij = minusProduct(i,j); const Complex minusP_ik = minusProduct(i,k); const Complex minusP_il = minusProduct(i,l); const Complex minusP_jk = minusProduct(j,k); const Complex minusP_jl = minusProduct(j,l); const Complex minusP_kl = minusProduct(k,l); const LorentzVector & minusC_ij = minusCurrent(i,j); const LorentzVector & minusC_ik = minusCurrent(i,k); const LorentzVector & minusC_il = minusCurrent(i,l); const LorentzVector & minusC_kj = minusCurrent(k,j); const LorentzVector & minusC_kl = minusCurrent(k,l); const LorentzVector & minusC_lj = minusCurrent(l,j); if ( g1Hel == 1 && g2Hel == 1 ) { return (Complex(0,-2) * plusP_jl * plusP_kl * minusC_ik)/ (jl * (jk + jl + kl)) - (Complex(0,2) * plusP_jl * plusP_kl * minusC_ik)/ (kl * (jk + jl + kl)) - (Complex(0,2) * plusP_jk * plusP_kl * minusC_il)/ (kl * (jk + jl + kl)) - (Complex(0,2) * plusP_jl * plusP_kl * minusC_ij * minusP_ij)/ (jl * (jk + jl + kl) * minusP_ik) - (Complex(0,2) * plusP_jl * plusP_kl * minusC_ij * minusP_ij)/ (kl * (jk + jl + kl) * minusP_ik) + (Complex(0,2) * plusP_jk * plusP_jl * minusC_il * minusP_ij)/ (jl * (jk + jl + kl) * minusP_ik) - (Complex(0,2) * plusP_jk * plusP_kl * minusC_ij * minusP_ij)/ (kl * (jk + jl + kl) * minusP_il) + (Complex(0,2) * plusP_jk * plusP_jl * minusC_ik * minusP_ij)/ (jl * (jk + jl + kl) * minusP_il) + (Complex(0,2) * plusP_jk * plusP_jl * minusC_ij * sqr(minusP_ij))/ (jl * (jk + jl + kl) * minusP_ik * minusP_il) - (Complex(0,2) * plusP_jk * plusP_kl * minusC_ik * minusP_ik)/ (kl * (jk + jl + kl) * minusP_il) - (Complex(0,2) * plusP_jl * plusP_kl * minusC_il * minusP_il)/ (jl * (jk + jl + kl) * minusP_ik) - (Complex(0,2) * plusP_jl * plusP_kl * minusC_il * minusP_il)/ (kl * (jk + jl + kl) * minusP_ik); } if ( g1Hel == 1 && g2Hel == -1 ) { return (Complex(0,-1) * sqr(plusP_ik) * minusC_ij * minusP_il)/ (kl * (ik + il + kl) * plusP_il) + (Complex(0,1) * plusP_ik * plusP_kl * minusC_lj * minusP_il)/ (kl * (ik + il + kl) * plusP_il) + (Complex(0,1) * plusP_ik * minusC_ij * sqr(minusP_il))/ (kl * (ik + il + kl) * minusP_ik) - (Complex(0,1) * plusP_ik * plusP_kl * minusC_kj * sqr(minusP_il))/ (kl * (ik + il + kl) * plusP_il * minusP_ik) - (Complex(0,2) * plusP_kl * minusC_lj * sqr(minusP_il))/ (kl * (ik + il + kl) * minusP_ik) + (Complex(0,1) * plusP_ik * plusP_jk * minusC_ij * minusP_il * minusP_jk)/ (kl * (jk + jl + kl) * plusP_il * minusP_ik) - (Complex(0,2) * plusP_ij * plusP_jk * minusC_ik * minusP_jl)/ (jl * (jk + jl + kl) * plusP_il) - (Complex(0,2) * plusP_ij * plusP_jk * minusC_ij * minusP_ij * minusP_jl)/ (jl * (jk + jl + kl) * plusP_il * minusP_ik) - (Complex(0,1) * plusP_ik * plusP_jl * minusC_ij * minusP_il * minusP_jl)/ (kl * (jk + jl + kl) * plusP_il * minusP_ik) + (Complex(0,2) * plusP_ij * plusP_kl * minusC_ij * minusP_il * minusP_jl)/ (kl * (jk + jl + kl) * plusP_il * minusP_ik) - (Complex(0,2) * plusP_ij * plusP_jk * minusC_il * minusP_il * minusP_jl)/ (jl * (jk + jl + kl) * plusP_il * minusP_ik) + (Complex(0,2) * plusP_ik * plusP_jk * minusC_ik * minusP_kl)/ (kl * (jk + jl + kl) * plusP_il) + (Complex(0,2) * plusP_ik * plusP_jk * minusC_ij * minusP_ij * minusP_kl)/ (kl * (jk + jl + kl) * plusP_il * minusP_ik) - (Complex(0,1) * plusP_ik * plusP_jl * minusC_ik * minusP_il * minusP_kl)/ (kl * (jk + jl + kl) * plusP_il * minusP_ik) + (Complex(0,2) * plusP_ij * plusP_kl * minusC_ik * minusP_il * minusP_kl)/ (kl * (jk + jl + kl) * plusP_il * minusP_ik) + (Complex(0,1) * plusP_ik * plusP_jk * minusC_il * minusP_il * minusP_kl)/ (kl * (jk + jl + kl) * plusP_il * minusP_ik); } if ( g1Hel == -1 && g2Hel == 1 ) { return (Complex(0,1) * sqr(plusP_il) * minusC_ij * minusP_ik)/ (kl * (ik + il + kl) * plusP_ik) + (Complex(0,1) * plusP_il * plusP_kl * minusC_kj * minusP_ik)/ (kl * (ik + il + kl) * plusP_ik) + (Complex(0,2) * plusP_jl * minusC_kl * minusP_ik)/(ik * jl) + (Complex(0,2) * plusP_jl * minusC_kj * minusP_ij * minusP_ik)/ (ik * jl * minusP_il) - (Complex(0,2) * plusP_il * minusC_ij * sqr(minusP_ik))/ (ik * (ik + il + kl) * minusP_il) - (Complex(0,1) * plusP_il * minusC_ij * sqr(minusP_ik))/ (kl * (ik + il + kl) * minusP_il) - (Complex(0,2) * plusP_kl * minusC_kj * sqr(minusP_ik))/ (ik * (ik + il + kl) * minusP_il) - (Complex(0,2) * plusP_kl * minusC_kj * sqr(minusP_ik))/ (kl * (ik + il + kl) * minusP_il) - (Complex(0,1) * plusP_il * plusP_kl * minusC_lj * sqr(minusP_ik))/ (kl * (ik + il + kl) * plusP_ik * minusP_il) - (Complex(0,2) * plusP_il * plusP_jl * minusC_ij * minusP_jk)/ (jl * (jk + jl + kl) * plusP_ik) - (Complex(0,2) * plusP_ij * plusP_jl * minusC_ij * minusP_ij * minusP_jk)/ (jl * (jk + jl + kl) * plusP_ik * minusP_il) + (Complex(0,1) * plusP_il * plusP_jk * minusC_ij * minusP_ik * minusP_jk)/ (kl * (jk + jl + kl) * plusP_ik * minusP_il) + (Complex(0,2) * plusP_ij * plusP_kl * minusC_ij * minusP_ik * minusP_jk)/ (kl * (jk + jl + kl) * plusP_ik * minusP_il) - (Complex(0,1) * plusP_il * plusP_jl * minusC_ij * minusP_ik * minusP_jl)/ (kl * (jk + jl + kl) * plusP_ik * minusP_il) + (Complex(0,2) * plusP_il * plusP_jl * minusC_il * minusP_kl)/ (jl * (jk + jl + kl) * plusP_ik) + (Complex(0,2) * plusP_il * plusP_jl * minusC_il * minusP_kl)/ (kl * (jk + jl + kl) * plusP_ik) + (Complex(0,2) * plusP_il * plusP_jl * minusC_ij * minusP_ij * minusP_kl)/ (kl * (jk + jl + kl) * plusP_ik * minusP_il) + (Complex(0,2) * plusP_ij * plusP_jl * minusC_il * minusP_ij * minusP_kl)/ (jl * (jk + jl + kl) * plusP_ik * minusP_il) + (Complex(0,1) * plusP_il * plusP_jl * minusC_ik * minusP_ik * minusP_kl)/ (kl * (jk + jl + kl) * plusP_ik * minusP_il) - (Complex(0,1) * plusP_il * plusP_jk * minusC_il * minusP_ik * minusP_kl)/ (kl * (jk + jl + kl) * plusP_ik * minusP_il) - (Complex(0,2) * plusP_ij * plusP_kl * minusC_il * minusP_ik * minusP_kl)/ (kl * (jk + jl + kl) * plusP_ik * minusP_il); } if ( g1Hel == -1 && g2Hel == -1 ) { return (Complex(0,-2) * plusP_ij * minusC_kj * minusP_ik * minusP_jl)/ (ik * jl * plusP_il) + (Complex(0,2) * sqr(plusP_ij) * minusC_ij * minusP_jk * minusP_jl)/ (jl * (jk + jl + kl) * plusP_ik * plusP_il) + (Complex(0,2) * plusP_ik * minusC_kj * minusP_ik * minusP_kl)/ (ik * (ik + il + kl) * plusP_il) + (Complex(0,2) * plusP_ik * minusC_kj * minusP_ik * minusP_kl)/ (kl * (ik + il + kl) * plusP_il) + (Complex(0,2) * minusC_lj * minusP_ik * minusP_kl)/ (ik * (ik + il + kl)) + (Complex(0,2) * minusC_lj * minusP_ik * minusP_kl)/ (kl * (ik + il + kl)) + (Complex(0,2) * minusC_kj * minusP_il * minusP_kl)/ (kl * (ik + il + kl)) + (Complex(0,2) * plusP_il * minusC_lj * minusP_il * minusP_kl)/ (kl * (ik + il + kl) * plusP_ik) - (Complex(0,2) * plusP_ij * minusC_ij * minusP_jk * minusP_kl)/ (kl * (jk + jl + kl) * plusP_il) - (Complex(0,2) * plusP_ij * minusC_ij * minusP_jl * minusP_kl)/ (kl * (jk + jl + kl) * plusP_ik) - (Complex(0,2) * sqr(plusP_ij) * minusC_il * minusP_jl * minusP_kl)/ (jl * (jk + jl + kl) * plusP_ik * plusP_il) - (Complex(0,2) * plusP_ij * minusC_ik * sqr(minusP_kl))/ (kl * (jk + jl + kl) * plusP_ik) + (Complex(0,2) * plusP_ij * minusC_il * sqr(minusP_kl))/ (kl * (jk + jl + kl) * plusP_il); } return czero; } LorentzVector MatchboxCurrents::qqbarggGeneralRightCurrent(const int i, const int, const int j, const int, const int k, const int g1Hel, const int l, const int g2Hel, const int n) { const double ik = invariant(i,k); const double il = invariant(i,l); const double jk = invariant(j,k); const double jl = invariant(j,l); const double kl = invariant(k,l); const Complex plusP_ik = plusProduct(i,k); const Complex plusP_il = plusProduct(i,l); const Complex plusP_in = plusProduct(i,n); const Complex plusP_jk = plusProduct(j,k); const Complex plusP_jl = plusProduct(j,l); const Complex plusP_jn = plusProduct(j,n); const Complex plusP_kl = plusProduct(k,l); const Complex plusP_kn = plusProduct(k,n); const Complex plusP_ln = plusProduct(l,n); const Complex minusP_ik = minusProduct(i,k); const Complex minusP_il = minusProduct(i,l); const Complex minusP_in = minusProduct(i,n); const Complex minusP_jk = minusProduct(j,k); const Complex minusP_jl = minusProduct(j,l); const Complex minusP_jn = minusProduct(j,n); const Complex minusP_kl = minusProduct(k,l); const Complex minusP_kn = minusProduct(k,n); const Complex minusP_ln = minusProduct(l,n); const LorentzVector & minusC_ji = minusCurrent(j,i); const LorentzVector & minusC_jk = minusCurrent(j,k); const LorentzVector & minusC_jl = minusCurrent(j,l); const LorentzVector & minusC_ki = minusCurrent(k,i); const LorentzVector & minusC_li = minusCurrent(l,i); const LorentzVector & minusC_lk = minusCurrent(l,k); if ( g1Hel == 1 && g2Hel == 1 ) { return (Complex(0,2) * plusP_il * plusP_kl * minusC_jk)/ (kl * (ik + il + kl)) + (Complex(0,2) * plusP_ik * plusP_kl * minusC_jl)/ (ik * (ik + il + kl)) + (Complex(0,2) * plusP_ik * plusP_kl * minusC_jl)/ (kl * (ik + il + kl)) + (Complex(0,2) * plusP_il * plusP_kl * minusC_ji * minusP_in)/ (kl * (ik + il + kl) * minusP_kn) + (Complex(0,2) * plusP_ik * plusP_il * minusC_jl * minusP_in)/ (ik * (ik + il + kl) * minusP_kn) - (Complex(0,2) * plusP_jl * plusP_kl * minusC_ji * minusP_jn)/ (kl * (jk + jl + kl) * minusP_kn) - (Complex(0,2) * sqr(plusP_kl) * minusC_ki * minusP_jn)/ (kl * (jk + jl + kl) * minusP_kn) + (Complex(0,2) * plusP_ik * plusP_kl * minusC_ji * minusP_in)/ (ik * (ik + il + kl) * minusP_ln) + (Complex(0,2) * plusP_ik * plusP_kl * minusC_ji * minusP_in)/ (kl * (ik + il + kl) * minusP_ln) + (Complex(0,2) * plusP_ik * plusP_il * minusC_jk * minusP_in)/ (ik * (ik + il + kl) * minusP_ln) - (Complex(0,2) * plusP_jk * plusP_kl * minusC_ji * minusP_jn)/ (kl * (jk + jl + kl) * minusP_ln) - (Complex(0,2) * plusP_ik * plusP_jl * minusC_jk * minusP_jn)/ (ik * jl * minusP_ln) + (Complex(0,2) * sqr(plusP_kl) * minusC_li * minusP_jn)/ (kl * (jk + jl + kl) * minusP_ln) + (Complex(0,2) * plusP_ik * plusP_il * minusC_ji * sqr(minusP_in))/ (ik * (ik + il + kl) * minusP_kn * minusP_ln) - (Complex(0,2) * plusP_ik * plusP_jl * minusC_ji * minusP_in * minusP_jn)/ (ik * jl * minusP_kn * minusP_ln) + (Complex(0,2) * plusP_jk * plusP_jl * minusC_ji * sqr(minusP_jn))/ (jl * (jk + jl + kl) * minusP_kn * minusP_ln) - (Complex(0,2) * plusP_jl * plusP_kl * minusC_li * sqr(minusP_jn))/ (jl * (jk + jl + kl) * minusP_kn * minusP_ln) + (Complex(0,2) * plusP_ik * plusP_kl * minusC_jk * minusP_kn)/ (ik * (ik + il + kl) * minusP_ln) + (Complex(0,2) * plusP_ik * plusP_kl * minusC_jk * minusP_kn)/ (kl * (ik + il + kl) * minusP_ln) + (Complex(0,2) * plusP_il * plusP_kl * minusC_jl * minusP_ln)/ (kl * (ik + il + kl) * minusP_kn); } if ( g1Hel == 1 && g2Hel == -1 ) { return (Complex(0,-2) * plusP_ik * plusP_kn * minusC_ji * minusP_il)/ (ik * (ik + il + kl) * plusP_ln) + (Complex(0,2) * plusP_ik * plusP_jn * minusC_jk * minusP_jl)/ (ik * jl * plusP_ln) + (Complex(0,2) * plusP_ik * minusC_lk * minusP_jl)/(ik * jl) - (Complex(0,2) * plusP_ik * plusP_kn * minusC_jk * minusP_kl)/ (ik * (ik + il + kl) * plusP_ln) - (Complex(0,2) * plusP_ik * plusP_kn * minusC_jk * minusP_kl)/ (kl * (ik + il + kl) * plusP_ln) - (Complex(0,2) * plusP_ik * plusP_in * minusC_ji * minusP_il * minusP_in)/ (ik * (ik + il + kl) * plusP_ln * minusP_kn) + (Complex(0,2) * plusP_ik * plusP_jn * minusC_ji * minusP_in * minusP_jl)/ (ik * jl * plusP_ln * minusP_kn) + (Complex(0,2) * plusP_ik * minusC_li * minusP_in * minusP_jl)/ (ik * jl * minusP_kn) - (Complex(0,2) * plusP_jk * plusP_jn * minusC_ji * minusP_jl * minusP_jn)/ (jl * (jk + jl + kl) * plusP_ln * minusP_kn) + (Complex(0,2) * plusP_jn * plusP_kl * minusC_li * minusP_jl * minusP_jn)/ (jl * (jk + jl + kl) * plusP_ln * minusP_kn) - (Complex(0,2) * plusP_ik * plusP_kn * minusC_ji * minusP_in * minusP_kl)/ (kl * (ik + il + kl) * plusP_ln * minusP_kn) - (Complex(0,2) * plusP_ik * plusP_in * minusC_jk * minusP_in * minusP_kl)/ (ik * (ik + il + kl) * plusP_ln * minusP_kn) + (Complex(0,2) * plusP_jk * plusP_kn * minusC_ji * minusP_jn * minusP_kl)/ (kl * (jk + jl + kl) * plusP_ln * minusP_kn) - (Complex(0,2) * plusP_kl * plusP_kn * minusC_li * minusP_jn * minusP_kl)/ (kl * (jk + jl + kl) * plusP_ln * minusP_kn) - (Complex(0,1) * plusP_ik * plusP_kn * minusC_ji * minusP_ik * minusP_ln)/ (kl * (ik + il + kl) * plusP_ln * minusP_kn) - (Complex(0,2) * plusP_in * plusP_kl * minusC_ji * minusP_il * minusP_ln)/ (kl * (ik + il + kl) * plusP_ln * minusP_kn) + (Complex(0,1) * plusP_il * plusP_kn * minusC_ji * minusP_il * minusP_ln)/ (kl * (ik + il + kl) * plusP_ln * minusP_kn) + (Complex(0,1) * plusP_jk * plusP_kn * minusC_ji * minusP_jk * minusP_ln)/ (kl * (jk + jl + kl) * plusP_ln * minusP_kn) - (Complex(0,1) * plusP_kl * plusP_kn * minusC_li * minusP_jk * minusP_ln)/ (kl * (jk + jl + kl) * plusP_ln * minusP_kn) - (Complex(0,2) * plusP_jk * minusC_ji * minusP_jl * minusP_ln)/ (jl * (jk + jl + kl) * minusP_kn) + (Complex(0,2) * plusP_jn * plusP_kl * minusC_ji * minusP_jl * minusP_ln)/ (kl * (jk + jl + kl) * plusP_ln * minusP_kn) - (Complex(0,1) * plusP_jl * plusP_kn * minusC_ji * minusP_jl * minusP_ln)/ (kl * (jk + jl + kl) * plusP_ln * minusP_kn) + (Complex(0,1) * plusP_kl * plusP_kn * minusC_ki * minusP_jl * minusP_ln)/ (kl * (jk + jl + kl) * plusP_ln * minusP_kn) + (Complex(0,2) * plusP_kl * minusC_li * minusP_jl * minusP_ln)/ (jl * (jk + jl + kl) * minusP_kn) + (Complex(0,2) * plusP_kl * minusC_li * minusP_jl * minusP_ln)/ (kl * (jk + jl + kl) * minusP_kn) - (Complex(0,2) * plusP_in * plusP_kl * minusC_jk * minusP_kl * minusP_ln)/ (kl * (ik + il + kl) * plusP_ln * minusP_kn) + (Complex(0,1) * plusP_il * plusP_kn * minusC_jk * minusP_kl * minusP_ln)/ (kl * (ik + il + kl) * plusP_ln * minusP_kn) - (Complex(0,1) * plusP_ik * plusP_kn * minusC_jl * minusP_kl * minusP_ln)/ (kl * (ik + il + kl) * plusP_ln * minusP_kn); } if ( g1Hel == -1 && g2Hel == 1 ) { return (Complex(0,-2) * plusP_il * plusP_in * minusC_jl * minusP_ik)/ (ik * (ik + il + kl) * plusP_kn) - (Complex(0,2) * plusP_il * plusP_ln * minusC_jl * minusP_kl)/ (kl * (ik + il + kl) * plusP_kn) - (Complex(0,2) * plusP_il * plusP_in * minusC_ji * minusP_ik * minusP_in)/ (ik * (ik + il + kl) * plusP_kn * minusP_ln) + (Complex(0,2) * plusP_in * plusP_jl * minusC_ji * minusP_ik * minusP_jn)/ (ik * jl * plusP_kn * minusP_ln) - (Complex(0,2) * plusP_jl * plusP_jn * minusC_ji * minusP_jk * minusP_jn)/ (jl * (jk + jl + kl) * plusP_kn * minusP_ln) - (Complex(0,2) * plusP_jl * minusC_ki * minusP_jk * minusP_jn)/ (jl * (jk + jl + kl) * minusP_ln) - (Complex(0,2) * plusP_jl * plusP_ln * minusC_li * minusP_jk * minusP_jn)/ (jl * (jk + jl + kl) * plusP_kn * minusP_ln) - (Complex(0,2) * plusP_il * plusP_ln * minusC_ji * minusP_in * minusP_kl)/ (kl * (ik + il + kl) * plusP_kn * minusP_ln) + (Complex(0,2) * plusP_jl * plusP_ln * minusC_ji * minusP_jn * minusP_kl)/ (kl * (jk + jl + kl) * plusP_kn * minusP_ln) + (Complex(0,2) * plusP_kl * plusP_ln * minusC_ki * minusP_jn * minusP_kl)/ (kl * (jk + jl + kl) * plusP_kn * minusP_ln) - (Complex(0,2) * plusP_in * plusP_kl * minusC_ji * minusP_ik * minusP_kn)/ (kl * (ik + il + kl) * plusP_kn * minusP_ln) - (Complex(0,1) * plusP_ik * plusP_ln * minusC_ji * minusP_ik * minusP_kn)/ (kl * (ik + il + kl) * plusP_kn * minusP_ln) - (Complex(0,2) * plusP_il * plusP_in * minusC_jk * minusP_ik * minusP_kn)/ (ik * (ik + il + kl) * plusP_kn * minusP_ln) + (Complex(0,1) * plusP_il * plusP_ln * minusC_ji * minusP_il * minusP_kn)/ (kl * (ik + il + kl) * plusP_kn * minusP_ln) + (Complex(0,2) * plusP_jn * plusP_kl * minusC_ji * minusP_jk * minusP_kn)/ (kl * (jk + jl + kl) * plusP_kn * minusP_ln) + (Complex(0,1) * plusP_jk * plusP_ln * minusC_ji * minusP_jk * minusP_kn)/ (kl * (jk + jl + kl) * plusP_kn * minusP_ln) + (Complex(0,2) * plusP_kl * minusC_ki * minusP_jk * minusP_kn)/ (kl * (jk + jl + kl) * minusP_ln) + (Complex(0,1) * plusP_kl * plusP_ln * minusC_li * minusP_jk * minusP_kn)/ (kl * (jk + jl + kl) * plusP_kn * minusP_ln) - (Complex(0,1) * plusP_jl * plusP_ln * minusC_ji * minusP_jl * minusP_kn)/ (kl * (jk + jl + kl) * plusP_kn * minusP_ln) - (Complex(0,1) * plusP_kl * plusP_ln * minusC_ki * minusP_jl * minusP_kn)/ (kl * (jk + jl + kl) * plusP_kn * minusP_ln) - (Complex(0,1) * plusP_il * plusP_ln * minusC_jk * minusP_kl * minusP_kn)/ (kl * (ik + il + kl) * plusP_kn * minusP_ln) + (Complex(0,2) * plusP_in * plusP_kl * minusC_jl * minusP_kl * minusP_kn)/ (kl * (ik + il + kl) * plusP_kn * minusP_ln) + (Complex(0,1) * plusP_ik * plusP_ln * minusC_jl * minusP_kl * minusP_kn)/ (kl * (ik + il + kl) * plusP_kn * minusP_ln); } if ( g1Hel == -1 && g2Hel == -1 ) { return (Complex(0,2) * sqr(plusP_in) * minusC_ji * minusP_ik * minusP_il)/ (ik * (ik + il + kl) * plusP_kn * plusP_ln) - (Complex(0,2) * plusP_in * plusP_jn * minusC_ji * minusP_ik * minusP_jl)/ (ik * jl * plusP_kn * plusP_ln) - (Complex(0,2) * plusP_in * minusC_li * minusP_ik * minusP_jl)/ (ik * jl * plusP_kn) + (Complex(0,2) * sqr(plusP_jn) * minusC_ji * minusP_jk * minusP_jl)/ (jl * (jk + jl + kl) * plusP_kn * plusP_ln) + (Complex(0,2) * plusP_jn * minusC_ki * minusP_jk * minusP_jl)/ (jl * (jk + jl + kl) * plusP_ln) + (Complex(0,2) * plusP_jn * minusC_li * minusP_jk * minusP_jl)/ (jl * (jk + jl + kl) * plusP_kn) + (Complex(0,2) * plusP_in * minusC_ji * minusP_ik * minusP_kl)/ (kl * (ik + il + kl) * plusP_ln) + (Complex(0,2) * sqr(plusP_in) * minusC_jk * minusP_ik * minusP_kl)/ (ik * (ik + il + kl) * plusP_kn * plusP_ln) + (Complex(0,2) * plusP_in * minusC_ji * minusP_il * minusP_kl)/ (kl * (ik + il + kl) * plusP_kn) - (Complex(0,2) * plusP_jn * minusC_ji * minusP_jk * minusP_kl)/ (kl * (jk + jl + kl) * plusP_ln) - (Complex(0,2) * plusP_kn * minusC_ki * minusP_jk * minusP_kl)/ (kl * (jk + jl + kl) * plusP_ln) - (Complex(0,2) * minusC_li * minusP_jk * minusP_kl)/ (kl * (jk + jl + kl)) - (Complex(0,2) * plusP_jn * minusC_ji * minusP_jl * minusP_kl)/ (jl * (jk + jl + kl) * plusP_kn) - (Complex(0,2) * plusP_jn * minusC_ji * minusP_jl * minusP_kl)/ (kl * (jk + jl + kl) * plusP_kn) - (Complex(0,2) * minusC_ki * minusP_jl * minusP_kl)/ (jl * (jk + jl + kl)) - (Complex(0,2) * minusC_ki * minusP_jl * minusP_kl)/ (kl * (jk + jl + kl)) - (Complex(0,2) * plusP_ln * minusC_li * minusP_jl * minusP_kl)/ (jl * (jk + jl + kl) * plusP_kn) - (Complex(0,2) * plusP_ln * minusC_li * minusP_jl * minusP_kl)/ (kl * (jk + jl + kl) * plusP_kn) + (Complex(0,2) * plusP_in * minusC_jk * sqr(minusP_kl))/ (kl * (ik + il + kl) * plusP_kn) - (Complex(0,2) * plusP_in * minusC_jl * sqr(minusP_kl))/ (kl * (ik + il + kl) * plusP_ln); } return czero; } LorentzVector MatchboxCurrents::qqbarggFixedRightCurrent(const int i, const int, const int j, const int, const int k, const int g1Hel, const int l, const int g2Hel) { const double ik = invariant(i,k); const double il = invariant(i,l); const double jk = invariant(j,k); const double jl = invariant(j,l); const double kl = invariant(k,l); const Complex plusP_ij = plusProduct(i,j); const Complex plusP_ik = plusProduct(i,k); const Complex plusP_il = plusProduct(i,l); const Complex plusP_jk = plusProduct(j,k); const Complex plusP_jl = plusProduct(j,l); const Complex plusP_kl = plusProduct(k,l); const Complex minusP_ij = minusProduct(i,j); const Complex minusP_ik = minusProduct(i,k); const Complex minusP_il = minusProduct(i,l); const Complex minusP_jk = minusProduct(j,k); const Complex minusP_jl = minusProduct(j,l); const Complex minusP_kl = minusProduct(k,l); const LorentzVector & minusC_ji = minusCurrent(j,i); const LorentzVector & minusC_jk = minusCurrent(j,k); const LorentzVector & minusC_jl = minusCurrent(j,l); const LorentzVector & minusC_ki = minusCurrent(k,i); const LorentzVector & minusC_li = minusCurrent(l,i); const LorentzVector & minusC_lk = minusCurrent(l,k); if ( g1Hel == 1 && g2Hel == 1 ) { return (Complex(0,2) * plusP_il * plusP_kl * minusC_jk)/ (kl * (ik + il + kl)) + (Complex(0,2) * plusP_ik * plusP_kl * minusC_jl)/ (ik * (ik + il + kl)) + (Complex(0,2) * plusP_ik * plusP_kl * minusC_jl)/ (kl * (ik + il + kl)) - (Complex(0,2) * plusP_jl * plusP_kl * minusC_ji * minusP_ij)/ (kl * (jk + jl + kl) * minusP_ik) - (Complex(0,2) * sqr(plusP_kl) * minusC_ki * minusP_ij)/ (kl * (jk + jl + kl) * minusP_ik) - (Complex(0,2) * plusP_jk * plusP_kl * minusC_ji * minusP_ij)/ (kl * (jk + jl + kl) * minusP_il) - (Complex(0,2) * plusP_ik * plusP_jl * minusC_jk * minusP_ij)/ (ik * jl * minusP_il) + (Complex(0,2) * sqr(plusP_kl) * minusC_li * minusP_ij)/ (kl * (jk + jl + kl) * minusP_il) + (Complex(0,2) * plusP_jk * plusP_jl * minusC_ji * sqr(minusP_ij))/ (jl * (jk + jl + kl) * minusP_ik * minusP_il) - (Complex(0,2) * plusP_jl * plusP_kl * minusC_li * sqr(minusP_ij))/ (jl * (jk + jl + kl) * minusP_ik * minusP_il) + (Complex(0,2) * plusP_ik * plusP_kl * minusC_jk * minusP_ik)/ (ik * (ik + il + kl) * minusP_il) + (Complex(0,2) * plusP_ik * plusP_kl * minusC_jk * minusP_ik)/ (kl * (ik + il + kl) * minusP_il) + (Complex(0,2) * plusP_il * plusP_kl * minusC_jl * minusP_il)/ (kl * (ik + il + kl) * minusP_ik); } if ( g1Hel == 1 && g2Hel == -1 ) { return (Complex(0,-2) * sqr(plusP_ik) * minusC_ji * minusP_il)/ (ik * (ik + il + kl) * plusP_il) - (Complex(0,1) * sqr(plusP_ik) * minusC_ji * minusP_il)/ (kl * (ik + il + kl) * plusP_il) + (Complex(0,1) * plusP_ik * minusC_ji * sqr(minusP_il))/ (kl * (ik + il + kl) * minusP_ik) + (Complex(0,1) * plusP_ik * plusP_jk * minusC_ji * minusP_il * minusP_jk)/ (kl * (jk + jl + kl) * plusP_il * minusP_ik) - (Complex(0,1) * plusP_ik * plusP_kl * minusC_li * minusP_il * minusP_jk)/ (kl * (jk + jl + kl) * plusP_il * minusP_ik) + (Complex(0,2) * plusP_ij * plusP_ik * minusC_jk * minusP_jl)/ (ik * jl * plusP_il) + (Complex(0,2) * plusP_ik * minusC_lk * minusP_jl)/(ik * jl) - (Complex(0,2) * plusP_ij * plusP_jk * minusC_ji * minusP_ij * minusP_jl)/ (jl * (jk + jl + kl) * plusP_il * minusP_ik) + (Complex(0,2) * plusP_ij * plusP_kl * minusC_li * minusP_ij * minusP_jl)/ (jl * (jk + jl + kl) * plusP_il * minusP_ik) - (Complex(0,2) * plusP_jk * minusC_ji * minusP_il * minusP_jl)/ (jl * (jk + jl + kl) * minusP_ik) - (Complex(0,1) * plusP_ik * plusP_jl * minusC_ji * minusP_il * minusP_jl)/ (kl * (jk + jl + kl) * plusP_il * minusP_ik) + (Complex(0,2) * plusP_ij * plusP_kl * minusC_ji * minusP_il * minusP_jl)/ (kl * (jk + jl + kl) * plusP_il * minusP_ik) + (Complex(0,1) * plusP_ik * plusP_kl * minusC_ki * minusP_il * minusP_jl)/ (kl * (jk + jl + kl) * plusP_il * minusP_ik) + (Complex(0,2) * plusP_kl * minusC_li * minusP_il * minusP_jl)/ (jl * (jk + jl + kl) * minusP_ik) + (Complex(0,2) * plusP_kl * minusC_li * minusP_il * minusP_jl)/ (kl * (jk + jl + kl) * minusP_ik) - (Complex(0,2) * sqr(plusP_ik) * minusC_jk * minusP_kl)/ (ik * (ik + il + kl) * plusP_il) - (Complex(0,2) * sqr(plusP_ik) * minusC_jk * minusP_kl)/ (kl * (ik + il + kl) * plusP_il) + (Complex(0,2) * plusP_ik * plusP_jk * minusC_ji * minusP_ij * minusP_kl)/ (kl * (jk + jl + kl) * plusP_il * minusP_ik) - (Complex(0,2) * plusP_ik * plusP_kl * minusC_li * minusP_ij * minusP_kl)/ (kl * (jk + jl + kl) * plusP_il * minusP_ik) + (Complex(0,1) * plusP_ik * minusC_jk * minusP_il * minusP_kl)/ (kl * (ik + il + kl) * minusP_ik) - (Complex(0,1) * sqr(plusP_ik) * minusC_jl * minusP_il * minusP_kl)/ (kl * (ik + il + kl) * plusP_il * minusP_ik); } if ( g1Hel == -1 && g2Hel == 1 ) { return (Complex(0,1) * sqr(plusP_il) * minusC_ji * minusP_ik)/ (kl * (ik + il + kl) * plusP_ik) - (Complex(0,1) * plusP_il * minusC_ji * sqr(minusP_ik))/ (kl * (ik + il + kl) * minusP_il) - (Complex(0,2) * plusP_ij * plusP_jl * minusC_ji * minusP_ij * minusP_jk)/ (jl * (jk + jl + kl) * plusP_ik * minusP_il) - (Complex(0,2) * plusP_jl * minusC_ki * minusP_ij * minusP_jk)/ (jl * (jk + jl + kl) * minusP_il) - (Complex(0,2) * plusP_il * plusP_jl * minusC_li * minusP_ij * minusP_jk)/ (jl * (jk + jl + kl) * plusP_ik * minusP_il) + (Complex(0,1) * plusP_il * plusP_jk * minusC_ji * minusP_ik * minusP_jk)/ (kl * (jk + jl + kl) * plusP_ik * minusP_il) + (Complex(0,2) * plusP_ij * plusP_kl * minusC_ji * minusP_ik * minusP_jk)/ (kl * (jk + jl + kl) * plusP_ik * minusP_il) + (Complex(0,2) * plusP_kl * minusC_ki * minusP_ik * minusP_jk)/ (kl * (jk + jl + kl) * minusP_il) + (Complex(0,1) * plusP_il * plusP_kl * minusC_li * minusP_ik * minusP_jk)/ (kl * (jk + jl + kl) * plusP_ik * minusP_il) - (Complex(0,1) * plusP_il * plusP_jl * minusC_ji * minusP_ik * minusP_jl)/ (kl * (jk + jl + kl) * plusP_ik * minusP_il) - (Complex(0,1) * plusP_il * plusP_kl * minusC_ki * minusP_ik * minusP_jl)/ (kl * (jk + jl + kl) * plusP_ik * minusP_il) - (Complex(0,2) * sqr(plusP_il) * minusC_jl * minusP_kl)/ (kl * (ik + il + kl) * plusP_ik) + (Complex(0,2) * plusP_il * plusP_jl * minusC_ji * minusP_ij * minusP_kl)/ (kl * (jk + jl + kl) * plusP_ik * minusP_il) + (Complex(0,2) * plusP_il * plusP_kl * minusC_ki * minusP_ij * minusP_kl)/ (kl * (jk + jl + kl) * plusP_ik * minusP_il) - (Complex(0,1) * sqr(plusP_il) * minusC_jk * minusP_ik * minusP_kl)/ (kl * (ik + il + kl) * plusP_ik * minusP_il) + (Complex(0,1) * plusP_il * minusC_jl * minusP_ik * minusP_kl)/ (kl * (ik + il + kl) * minusP_il); } if ( g1Hel == -1 && g2Hel == -1 ) { return (Complex(0,2) * sqr(plusP_ij) * minusC_ji * minusP_jk * minusP_jl)/ (jl * (jk + jl + kl) * plusP_ik * plusP_il) + (Complex(0,2) * plusP_ij * minusC_ki * minusP_jk * minusP_jl)/ (jl * (jk + jl + kl) * plusP_il) + (Complex(0,2) * plusP_ij * minusC_li * minusP_jk * minusP_jl)/ (jl * (jk + jl + kl) * plusP_ik) - (Complex(0,2) * plusP_ij * minusC_ji * minusP_jk * minusP_kl)/ (kl * (jk + jl + kl) * plusP_il) - (Complex(0,2) * plusP_ik * minusC_ki * minusP_jk * minusP_kl)/ (kl * (jk + jl + kl) * plusP_il) - (Complex(0,2) * minusC_li * minusP_jk * minusP_kl)/ (kl * (jk + jl + kl)) - (Complex(0,2) * plusP_ij * minusC_ji * minusP_jl * minusP_kl)/ (jl * (jk + jl + kl) * plusP_ik) - (Complex(0,2) * plusP_ij * minusC_ji * minusP_jl * minusP_kl)/ (kl * (jk + jl + kl) * plusP_ik) - (Complex(0,2) * minusC_ki * minusP_jl * minusP_kl)/ (jl * (jk + jl + kl)) - (Complex(0,2) * minusC_ki * minusP_jl * minusP_kl)/ (kl * (jk + jl + kl)) - (Complex(0,2) * plusP_il * minusC_li * minusP_jl * minusP_kl)/ (jl * (jk + jl + kl) * plusP_ik) - (Complex(0,2) * plusP_il * minusC_li * minusP_jl * minusP_kl)/ (kl * (jk + jl + kl) * plusP_ik); } return czero; } const LorentzVector& MatchboxCurrents::qqbarggLeftCurrent(const int q, const int qHel, const int qbar, const int qbarHel, const int g1, const int g1Hel, const int g2, const int g2Hel) { if ( qHel != 1 || qbarHel != 1 ) return czero; if ( getCurrent(hash<3>(1,1,q,qHel,qbar,qbarHel,g1,g1Hel,g2,g2Hel)) ) { #ifdef CHECK_MatchboxCurrents LorentzVector ni = qqbarggGeneralLeftCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,g2,g2Hel,q); LorentzVector nj = qqbarggGeneralLeftCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,g2,g2Hel,qbar); LorentzVector nl = qqbarggGeneralLeftCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,g2,g2Hel,0); LorentzVector nlbar = qqbarggGeneralLeftCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,g2,g2Hel,1); LorentzVector fixed = qqbarggFixedLeftCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,g2,g2Hel); LorentzVector x1 = fixed - ni; LorentzVector x2 = fixed - nj; LorentzVector x3 = fixed - nl; LorentzVector x4 = fixed - nlbar; double c1 = real(x1.t() * conj(x1.t())) + real(x1.x() * conj(x1.x())) + real(x1.y() * conj(x1.y())) + real(x1.z() * conj(x1.z())); double c2 = real(x2.t() * conj(x2.t())) + real(x2.x() * conj(x2.x())) + real(x2.y() * conj(x2.y())) + real(x2.z() * conj(x2.z())); double c3 = real(x3.t() * conj(x3.t())) + real(x3.x() * conj(x3.x())) + real(x3.y() * conj(x3.y())) + real(x3.z() * conj(x3.z())); double c4 = real(x4.t() * conj(x4.t())) + real(x4.x() * conj(x4.x())) + real(x4.y() * conj(x4.y())) + real(x4.z() * conj(x4.z())); ostream& ncheck = checkStream("qqbarggLeftCurrentNChoice"); ncheck << (c1 != 0. ? log10(abs(c1)) : 0.) << " " << (c2 != 0. ? log10(abs(c2)) : 0.) << " " << (c3 != 0. ? log10(abs(c3)) : 0.) << " " << (c4 != 0. ? log10(abs(c4)) : 0.) << " " << "\n" << flush; #endif cacheCurrent(qqbarggFixedLeftCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,g2,g2Hel)); } #ifdef CHECK_MatchboxCurrents checkCurrent("qqbarggLeftCurrent",cachedCurrent(),momentum(q)+momentum(qbar)+momentum(g1)+momentum(g2)); #endif return cachedCurrent(); } const LorentzVector& MatchboxCurrents::qqbarggRightCurrent(const int q, const int qHel, const int qbar, const int qbarHel, const int g1, const int g1Hel, const int g2, const int g2Hel) { if ( qHel != -1 || qbarHel != -1 ) return czero; if ( getCurrent(hash<3>(2,1,q,qHel,qbar,qbarHel,g1,g1Hel,g2,g2Hel)) ) { #ifdef CHECK_MatchboxCurrents LorentzVector ni = qqbarggGeneralRightCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,g2,g2Hel,q); LorentzVector nj = qqbarggGeneralRightCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,g2,g2Hel,qbar); LorentzVector nl = qqbarggGeneralRightCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,g2,g2Hel,0); LorentzVector nlbar = qqbarggGeneralRightCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,g2,g2Hel,1); LorentzVector fixed = qqbarggFixedRightCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,g2,g2Hel); LorentzVector x1 = fixed - ni; LorentzVector x2 = fixed - nj; LorentzVector x3 = fixed - nl; LorentzVector x4 = fixed - nlbar; double c1 = real(x1.t() * conj(x1.t())) + real(x1.x() * conj(x1.x())) + real(x1.y() * conj(x1.y())) + real(x1.z() * conj(x1.z())); double c2 = real(x2.t() * conj(x2.t())) + real(x2.x() * conj(x2.x())) + real(x2.y() * conj(x2.y())) + real(x2.z() * conj(x2.z())); double c3 = real(x3.t() * conj(x3.t())) + real(x3.x() * conj(x3.x())) + real(x3.y() * conj(x3.y())) + real(x3.z() * conj(x3.z())); double c4 = real(x4.t() * conj(x4.t())) + real(x4.x() * conj(x4.x())) + real(x4.y() * conj(x4.y())) + real(x4.z() * conj(x4.z())); ostream& ncheck = checkStream("qqbarggRightCurrentNChoice"); ncheck << (c1 != 0. ? log10(abs(c1)) : 0.) << " " << (c2 != 0. ? log10(abs(c2)) : 0.) << " " << (c3 != 0. ? log10(abs(c3)) : 0.) << " " << (c4 != 0. ? log10(abs(c4)) : 0.) << " " << "\n" << flush; #endif cacheCurrent(qqbarggFixedRightCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,g2,g2Hel)); } #ifdef CHECK_MatchboxCurrents checkCurrent("qqbarggRightCurrent",cachedCurrent(),momentum(q)+momentum(qbar)+momentum(g1)+momentum(g2)); #endif return cachedCurrent(); } const LorentzVector& MatchboxCurrents::qqbarqqbarLeftCurrent(const int q, const int qHel, const int qbar, const int qbarHel, const int k, const int kHel, const int kbar, const int kbarHel) { if ( qHel != 1 || qbarHel != 1 || abs(kHel+kbarHel) != 2 ) return czero; const int i = q; const int j = qbar; const int l = kbar; const double ik = invariant(i,k); const double il = invariant(i,l); const double jk = invariant(j,k); const double jl = invariant(j,l); const double kl = invariant(k,l); const Complex plusP_ik = plusProduct(i,k); const Complex plusP_il = plusProduct(i,l); const Complex plusP_kj = plusProduct(k,j); const Complex plusP_kl = plusProduct(k,l); const Complex plusP_lj = plusProduct(l,j); const Complex plusP_lk = plusProduct(l,k); const Complex minusP_ik = minusProduct(i,k); const Complex minusP_il = minusProduct(i,l); const Complex minusP_jk = minusProduct(j,k); const Complex minusP_jl = minusProduct(j,l); const Complex minusP_ki = minusProduct(k,i); const Complex minusP_kl = minusProduct(k,l); const Complex minusP_li = minusProduct(l,i); const Complex minusP_lk = minusProduct(l,k); const LorentzVector & minusC_ij = minusCurrent(i,j); const LorentzVector & minusC_ik = minusCurrent(i,k); const LorentzVector & minusC_il = minusCurrent(i,l); const LorentzVector & minusC_kj = minusCurrent(k,j); const LorentzVector & minusC_lj = minusCurrent(l,j); if ( kHel == 1 && kbarHel == 1 ) { if ( getCurrent(hash<4>(1,1,q,qHel,qbar,qbarHel,k,kHel,kbar,kbarHel)) ) { cacheCurrent((Complex(0.,-2.)/kl)* ((minusP_ki * plusP_il * minusC_ij+ minusP_ik * plusP_lk * minusC_kj)/ (kl+il+ik)- (minusP_jk * plusP_lj * minusC_ij+ minusP_lk * plusP_lj * minusC_il)/ (kl+jl+jk))); } #ifdef CHECK_MatchboxCurrents checkCurrent("qqbarqqbarLeftCurrent",cachedCurrent(),momentum(q)+momentum(qbar)+momentum(k)+momentum(kbar)); #endif return cachedCurrent(); } if ( kHel == -1 && kbarHel == -1 ) { if ( getCurrent(hash<4>(1,1,q,qHel,qbar,qbarHel,k,kHel,kbar,kbarHel)) ) { cacheCurrent((Complex(0.,-2.)/kl)* ((minusP_li * plusP_ik * minusC_ij+ minusP_il * plusP_kl * minusC_lj)/ (kl+il+ik)- (minusP_jl * plusP_kj * minusC_ij+ minusP_kl * plusP_kj * minusC_ik)/ (kl+jl+jk))); } #ifdef CHECK_MatchboxCurrents checkCurrent("qqbarqqbarLeftCurrent",cachedCurrent(),momentum(q)+momentum(qbar)+momentum(k)+momentum(kbar)); #endif return cachedCurrent(); } return czero; } const LorentzVector& MatchboxCurrents::qqbarqqbarRightCurrent(const int q, const int qHel, const int qbar, const int qbarHel, const int k, const int kHel, const int kbar, const int kbarHel) { if ( qHel != -1 || qbarHel != -1 || abs(kHel+kbarHel) != 2 ) return czero; const int i = q; const int j = qbar; const int l = kbar; const double ik = invariant(i,k); const double il = invariant(i,l); const double jk = invariant(j,k); const double jl = invariant(j,l); const double kl = invariant(k,l); const Complex plusP_ik = plusProduct(i,k); const Complex plusP_il = plusProduct(i,l); const Complex plusP_ki = plusProduct(k,i); const Complex plusP_kj = plusProduct(k,j); const Complex plusP_kl = plusProduct(k,l); const Complex plusP_li = plusProduct(l,i); const Complex plusP_lj = plusProduct(l,j); const Complex plusP_lk = plusProduct(l,k); const Complex minusP_jk = minusProduct(j,k); const Complex minusP_jl = minusProduct(j,l); const Complex minusP_ki = minusProduct(k,i); const Complex minusP_kl = minusProduct(k,l); const Complex minusP_li = minusProduct(l,i); const Complex minusP_lk = minusProduct(l,k); const LorentzVector & minusC_ji = minusCurrent(j,i); const LorentzVector & minusC_jk = minusCurrent(j,k); const LorentzVector & minusC_jl = minusCurrent(j,l); const LorentzVector & minusC_ki = minusCurrent(k,i); const LorentzVector & minusC_li = minusCurrent(l,i); if ( kHel == 1 && kbarHel == 1 ) { if ( getCurrent(hash<4>(2,1,q,qHel,qbar,qbarHel,k,kHel,kbar,kbarHel)) ) { cacheCurrent((Complex(0.,-2.)/kl)* ((minusP_ki * plusP_il * minusC_ji+ minusP_lk * plusP_li * minusC_jl)/ (kl+il+ik)- (minusP_jk * plusP_lj * minusC_ji+ minusP_jk * plusP_lk * minusC_ki)/ (kl+jl+jk))); } #ifdef CHECK_MatchboxCurrents checkCurrent("qqbarqqbarRightCurrent",cachedCurrent(),momentum(q)+momentum(qbar)+momentum(k)+momentum(kbar)); #endif return cachedCurrent(); } if ( kHel == -1 && kbarHel == -1 ) { if ( getCurrent(hash<4>(2,1,q,qHel,qbar,qbarHel,k,kHel,kbar,kbarHel)) ) { cacheCurrent((Complex(0.,-2.)/kl)* ((minusP_li * plusP_ik * minusC_ji+ minusP_kl * plusP_ki * minusC_jk)/ (kl+il+ik)- (minusP_jl * plusP_kj * minusC_ji+ minusP_jl * plusP_kl * minusC_li)/ (kl+jl+jk))); } #ifdef CHECK_MatchboxCurrents checkCurrent("qqbarqqbarRightCurrent",cachedCurrent(),momentum(q)+momentum(qbar)+momentum(k)+momentum(kbar)); #endif return cachedCurrent(); } return czero; } // Definition of sqrt to enable calculation of the sqrt of a negative double inline Complex sqrt1 (double a) { if (a > 0.) { return Complex(sqrt(a), 0.) ;} else if (a < 0.) { return Complex(0., sqrt(abs(a))) ;} else { return Complex(0., 0.); } } // Definition of sqrt to enable calculation of the sqrt of Complex arguments inline Complex sqrt1 (Complex a) { const double real_part = sqrt(abs(a))*cos(0.5*arg(a)); const double imag_part = sqrt(abs(a))*sin(0.5*arg(a)); return Complex(real_part, imag_part) ; } // Definition of log to enable continuation of the log of a negative double inline Complex log1 (double a) { if (a < 0.) { return Complex(log(abs(a)), Constants::pi) ;} else { return Complex(log(a), 0.) ;} } // Definition of log to enable continuation of the log of a Complex argument with a negative real part inline Complex log1 (Complex a) { return Complex(log(abs(a)), arg(a)) ; } const LorentzVector& MatchboxCurrents::qqbarLeftOneLoopCurrent(const int q, const int qHel, const int qbar, const int qbarHel) { // Note this cannot currently handle the case of one massive quark and one massless quark assert( (mass(q) == 0 && mass(qbar) == 0) || (mass(q) != 0 && mass(qbar) != 0) ); // Massless quarks if ( mass(q) == 0 && mass(qbar) == 0 ) { if ( qHel != 1 || qbarHel != 1 ) return czero; const LorentzVector& tree = qqbarLeftCurrent(q,qHel,qbar,qbarHel); if ( getCurrent(hash<1>(1,2,q,qHel,qbar,qbarHel)) ) { cacheCurrent( 0.5*CF*( -8. - 3.*log1(-1./invariant(q,qbar)) - sqr(log1(-1./invariant(q,qbar))) ) * tree ); } #ifdef CHECK_MatchboxCurrents checkCurrent("qqbarLeftOneLoopCurrent",cachedCurrent(),momentum(q)+momentum(qbar)); #endif return cachedCurrent(); } // Massive quarks else { const LorentzVector& momQ = momentum(q) + (sqr(mass(q))/invariant(q,qbar))*momentum(qbar); const LorentzVector& momQbar = momentum(qbar) + (sqr(mass(qbar))/invariant(q,qbar))*momentum(q); const Complex s = (momQ+momQbar).dot(momQ+momQbar); const Complex inv12 = s - sqr(mass(q)) - sqr(mass(qbar)); // Coefficient of the left-handed born-level current const Complex coeffLeftTree = -1.0*log1(1./sqr(mass(q)))-1.0*log1(1./sqr(mass(qbar)))-4.0 + 0.5*((2.*log1(sqr(mass(q))/sqr(mass(qbar)))*(0.5*inv12+sqr(mass(q))))/(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))-(2.*inv12*Li2(0.5-(0.25*inv12)/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))-(0.5*sqr(mass(qbar)))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))+(2.*inv12*Li2((0.5*(0.5*inv12+sqr(mass(q))+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))-(1.*inv12*log1(-((0.5*inv12+sqr(mass(q))-1.*sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))))/(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))))*log1(-((1.*inv12+sqr(mass(q))+sqr(mass(qbar)))/(0.5*inv12+sqr(mass(q))+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))+(2.*inv12*log1((2*sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))))/(1.*inv12+sqr(mass(q))+sqr(mass(qbar))))*log1((-0.5*inv12-1.*sqr(mass(qbar))+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))))/(0.5*inv12+sqr(mass(q))+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))+(1.*inv12*log1((1.*inv12+sqr(mass(q))+sqr(mass(qbar)))/(0.5*inv12+sqr(mass(qbar))-1.*sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))*log1((0.5*inv12+sqr(mass(qbar))+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))))/(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))+(0.5*inv12*sqr(log1(-((0.5*inv12+sqr(mass(q))-1.*sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))))/(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))+(0.5*inv12*sqr(log1((1.*inv12+sqr(mass(q))+sqr(mass(qbar)))/(0.5*inv12+sqr(mass(qbar))-1.*sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))-(0.5*inv12*sqr(log1(-((1.*inv12+sqr(mass(q))+sqr(mass(qbar)))/(0.5*inv12+sqr(mass(q))+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))))))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))-(0.5*inv12*sqr(log1((0.5*inv12+sqr(mass(qbar))+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))))/(1.*inv12+sqr(mass(q))+sqr(mass(qbar))))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))+(4*log1((-1.*mass(q)*mass(qbar))/(0.5*inv12+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))*(-0.25*(3+2*log1(1./(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))))*sqr(inv12)+sqr(mass(q))*sqr(mass(qbar))-0.5*inv12*(1.+log1(1./(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))))*(sqr(mass(q))+sqr(mass(qbar)))))/((1.*inv12+sqr(mass(q))+sqr(mass(qbar)))*sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))))); // Coefficient of the right-handed born-level current const Complex coeffRightTree = (2*log1((-1.*mass(q)*mass(qbar))/(0.5*inv12+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))*mass(q)*mass(qbar))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))); const LorentzVector& leftTree = qqbarLeftCurrent(q,qHel,qbar,qbarHel); const LorentzVector& rightTree = qqbarRightCurrent(q,qHel,qbar,qbarHel); if ( getCurrent(hash<1>(1,2,q,qHel,qbar,qbarHel)) ) { if ( qHel == 1 && qbarHel == 1 ) { cacheCurrent( 0.5*CF*( coeffLeftTree*leftTree + coeffRightTree*rightTree) ); } if ( qHel == 1 && qbarHel == -1 ) { // Coefficients of the left and right handed products of massive spinors const LorentzVector& coeffLeftProd = ( (mass(qbar)*(-2.*(momQ+momQbar)*(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))+log1(sqr(mass(q))/sqr(mass(qbar)))*(1.*inv12*(2.*momQ+momQbar)+(3.*momQ+2.*momQbar)*sqr(mass(q))+momQ*sqr(mass(qbar)))-(2.*log1((-1.*mass(q)*mass(qbar))/(0.5*inv12+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))*(0.5*(2.*momQ+momQbar)*sqr(inv12)-momQbar*sqr(mass(q))*sqr(mass(qbar))+0.5*inv12*((5.*momQ+2.*momQbar)*sqr(mass(q))+momQ*sqr(mass(qbar)))+(2.*momQ+momQbar)*sqr(sqr(mass(q)))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))/sqr(1.*inv12+sqr(mass(q))+sqr(mass(qbar))) ); const LorentzVector& coeffRightProd = ( (mass(q)*(2.*(momQ+momQbar)*(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))+log1(sqr(mass(q))/sqr(mass(qbar)))*(1.*inv12*(momQ+2.*momQbar)+momQbar*sqr(mass(q))+(2.*momQ+3.*momQbar)*sqr(mass(qbar)))+(2.*log1((-1.*mass(q)*mass(qbar))/(0.5*inv12+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))*(0.5*(momQ+2.*momQbar)*sqr(inv12)-momQ*sqr(mass(q))*sqr(mass(qbar))+0.5*inv12*(momQbar*sqr(mass(q))+(2.*momQ+5.*momQbar)*sqr(mass(qbar)))+(momQ+2.*momQbar)*sqr(sqr(mass(qbar)))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))/sqr(1.*inv12+sqr(mass(q))+sqr(mass(qbar))) ); const Complex leftProd = Complex(0.,1.) * minusProduct(q,qbar); const Complex rightProd = Complex(0.,1.) * mass(q)*mass(qbar)/plusProduct(q,qbar); cacheCurrent( 0.5*CF*( coeffLeftTree*leftTree + coeffRightTree*rightTree + coeffLeftProd*leftProd + coeffRightProd*rightProd ) ); } if ( qHel == -1 && qbarHel == 1 ){ // Coefficients of the left and right handed products of massive spinors const LorentzVector& coeffLeftProd = ( (mass(qbar)*(-2.*(momQ+momQbar)*(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))+log1(sqr(mass(q))/sqr(mass(qbar)))*(1.*inv12*(2.*momQ+momQbar)+(3.*momQ+2.*momQbar)*sqr(mass(q))+momQ*sqr(mass(qbar)))-(2.*log1((-1.*mass(q)*mass(qbar))/(0.5*inv12+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))*(0.5*(2.*momQ+momQbar)*sqr(inv12)-momQbar*sqr(mass(q))*sqr(mass(qbar))+0.5*inv12*((5.*momQ+2.*momQbar)*sqr(mass(q))+momQ*sqr(mass(qbar)))+(2.*momQ+momQbar)*sqr(sqr(mass(q)))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))/sqr(1.*inv12+sqr(mass(q))+sqr(mass(qbar))) ); const LorentzVector& coeffRightProd = ( (mass(q)*(2.*(momQ+momQbar)*(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))+log1(sqr(mass(q))/sqr(mass(qbar)))*(1.*inv12*(momQ+2.*momQbar)+momQbar*sqr(mass(q))+(2.*momQ+3.*momQbar)*sqr(mass(qbar)))+(2.*log1((-1.*mass(q)*mass(qbar))/(0.5*inv12+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))*(0.5*(momQ+2.*momQbar)*sqr(inv12)-momQ*sqr(mass(q))*sqr(mass(qbar))+0.5*inv12*(momQbar*sqr(mass(q))+(2.*momQ+5.*momQbar)*sqr(mass(qbar)))+(momQ+2.*momQbar)*sqr(sqr(mass(qbar)))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))/sqr(1.*inv12+sqr(mass(q))+sqr(mass(qbar))) ); const Complex leftProd = Complex(0.,1.) * mass(q)*mass(qbar)/minusProduct(q,qbar); const Complex rightProd = Complex(0.,1.) * plusProduct(q,qbar); cacheCurrent( 0.5*CF*( coeffLeftTree*leftTree + coeffRightTree*rightTree + coeffLeftProd*leftProd + coeffRightProd*rightProd ) ); } if ( qHel == -1 && qbarHel == -1 ){ cacheCurrent( 0.5*CF*( coeffLeftTree*leftTree + coeffRightTree*rightTree ) ); } } #ifdef CHECK_MatchboxCurrents checkCurrent("qqbarLeftOneLoopCurrent",cachedCurrent(),momentum(q)+momentum(qbar)); #endif return cachedCurrent(); } } const LorentzVector& MatchboxCurrents::qqbarRightOneLoopCurrent(const int q, const int qHel, const int qbar, const int qbarHel) { // Note this cannot currently handle the case of one massive quark and one massless quark assert( (mass(q) == 0 && mass(qbar) == 0) || (mass(q) != 0 && mass(qbar) != 0) ); // Massless quarks if ( mass(q) == 0 && mass(qbar) ==0 ) { if ( qHel != -1 || qbarHel != -1 ) return czero; const LorentzVector& tree = qqbarRightCurrent(q,qHel,qbar,qbarHel); if ( getCurrent(hash<1>(2,2,q,qHel,qbar,qbarHel)) ) { cacheCurrent( 0.5*CF*( -8. - 3.*log1(-1./invariant(q,qbar)) - sqr(log1(-1./invariant(q,qbar))) ) * tree ); } #ifdef CHECK_MatchboxCurrents checkCurrent("qqbarRightOneLoopCurrent",cachedCurrent(),momentum(q)+momentum(qbar)); #endif return cachedCurrent(); } // Massive quarks else { const LorentzVector& momQ = momentum(q) + (sqr(mass(q))/invariant(q,qbar))*momentum(qbar); const LorentzVector& momQbar = momentum(qbar) + (sqr(mass(qbar))/invariant(q,qbar))*momentum(q); const Complex s = (momQ+momQbar).dot(momQ+momQbar); const Complex inv12 = s - sqr(mass(q)) - sqr(mass(qbar)); // Coefficient of the right-handed born-level current const Complex coeffRightTree = -1.0*log1(1./sqr(mass(q)))-1.0*log1(1./sqr(mass(qbar)))-4.0 + 0.5*((2.*log1(sqr(mass(q))/sqr(mass(qbar)))*(0.5*inv12+sqr(mass(q))))/(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))-(2.*inv12*Li2(0.5-(0.25*inv12)/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))-(0.5*sqr(mass(qbar)))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))+(2.*inv12*Li2((0.5*(0.5*inv12+sqr(mass(q))+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))-(1.*inv12*log1(-((0.5*inv12+sqr(mass(q))-1.*sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))))/(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))))*log1(-((1.*inv12+sqr(mass(q))+sqr(mass(qbar)))/(0.5*inv12+sqr(mass(q))+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))+(2.*inv12*log1((2*sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))))/(1.*inv12+sqr(mass(q))+sqr(mass(qbar))))*log1((-0.5*inv12-1.*sqr(mass(qbar))+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))))/(0.5*inv12+sqr(mass(q))+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))+(1.*inv12*log1((1.*inv12+sqr(mass(q))+sqr(mass(qbar)))/(0.5*inv12+sqr(mass(qbar))-1.*sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))*log1((0.5*inv12+sqr(mass(qbar))+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))))/(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))+(0.5*inv12*sqr(log1(-((0.5*inv12+sqr(mass(q))-1.*sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))))/(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))+(0.5*inv12*sqr(log1((1.*inv12+sqr(mass(q))+sqr(mass(qbar)))/(0.5*inv12+sqr(mass(qbar))-1.*sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))-(0.5*inv12*sqr(log1(-((1.*inv12+sqr(mass(q))+sqr(mass(qbar)))/(0.5*inv12+sqr(mass(q))+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))))))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))-(0.5*inv12*sqr(log1((0.5*inv12+sqr(mass(qbar))+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))))/(1.*inv12+sqr(mass(q))+sqr(mass(qbar))))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))+(4*log1((-1.*mass(q)*mass(qbar))/(0.5*inv12+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))*(-0.25*(3+2*log1(1./(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))))*sqr(inv12)+sqr(mass(q))*sqr(mass(qbar))-0.5*inv12*(1.+log1(1./(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))))*(sqr(mass(q))+sqr(mass(qbar)))))/((1.*inv12+sqr(mass(q))+sqr(mass(qbar)))*sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))))); // Coefficient of the left-handed born-level current const Complex coeffLeftTree = (2*log1((-1.*mass(q)*mass(qbar))/(0.5*inv12+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))*mass(q)*mass(qbar))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar))); const LorentzVector& leftTree = qqbarLeftCurrent(q,qHel,qbar,qbarHel); const LorentzVector& rightTree = qqbarRightCurrent(q,qHel,qbar,qbarHel); if ( getCurrent(hash<1>(2,2,q,qHel,qbar,qbarHel)) ) { if ( qHel == 1 && qbarHel == 1 ) { cacheCurrent( 0.5*CF*( coeffLeftTree*leftTree + coeffRightTree*rightTree ) ); } if ( qHel == 1 && qbarHel == -1 ) { // Coefficients of the right and left handed products of massive spinors const LorentzVector& coeffRightProd = ( (mass(qbar)*(-2.*(momQ+momQbar)*(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))+log1(sqr(mass(q))/sqr(mass(qbar)))*(1.*inv12*(2.*momQ+momQbar)+(3.*momQ+2.*momQbar)*sqr(mass(q))+momQ*sqr(mass(qbar)))-(2.*log1((-1.*mass(q)*mass(qbar))/(0.5*inv12+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))*(0.5*(2.*momQ+momQbar)*sqr(inv12)-momQbar*sqr(mass(q))*sqr(mass(qbar))+0.5*inv12*((5.*momQ+2.*momQbar)*sqr(mass(q))+momQ*sqr(mass(qbar)))+(2.*momQ+momQbar)*sqr(sqr(mass(q)))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))/sqr(1.*inv12+sqr(mass(q))+sqr(mass(qbar))) ); const LorentzVector& coeffLeftProd = ( (mass(q)*(2.*(momQ+momQbar)*(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))+log1(sqr(mass(q))/sqr(mass(qbar)))*(1.*inv12*(momQ+2.*momQbar)+momQbar*sqr(mass(q))+(2.*momQ+3.*momQbar)*sqr(mass(qbar)))+(2.*log1((-1.*mass(q)*mass(qbar))/(0.5*inv12+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))*(0.5*(momQ+2.*momQbar)*sqr(inv12)-momQ*sqr(mass(q))*sqr(mass(qbar))+0.5*inv12*(momQbar*sqr(mass(q))+(2.*momQ+5.*momQbar)*sqr(mass(qbar)))+(momQ+2.*momQbar)*sqr(sqr(mass(qbar)))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))/sqr(1.*inv12+sqr(mass(q))+sqr(mass(qbar))) ); const Complex leftProd = Complex(0.,1.) * minusProduct(q,qbar); const Complex rightProd = Complex(0.,1.) * mass(q)*mass(qbar)/plusProduct(q,qbar); cacheCurrent( 0.5*CF*( coeffLeftTree*leftTree + coeffRightTree*rightTree + coeffLeftProd*leftProd + coeffRightProd*rightProd ) ); } if ( qHel == -1 && qbarHel == 1 ){ // Coefficients of the right and left handed products of massive spinors const LorentzVector& coeffRightProd = ( (mass(qbar)*(-2.*(momQ+momQbar)*(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))+log1(sqr(mass(q))/sqr(mass(qbar)))*(1.*inv12*(2.*momQ+momQbar)+(3.*momQ+2.*momQbar)*sqr(mass(q))+momQ*sqr(mass(qbar)))-(2.*log1((-1.*mass(q)*mass(qbar))/(0.5*inv12+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))*(0.5*(2.*momQ+momQbar)*sqr(inv12)-momQbar*sqr(mass(q))*sqr(mass(qbar))+0.5*inv12*((5.*momQ+2.*momQbar)*sqr(mass(q))+momQ*sqr(mass(qbar)))+(2.*momQ+momQbar)*sqr(sqr(mass(q)))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))/sqr(1.*inv12+sqr(mass(q))+sqr(mass(qbar))) ); const LorentzVector& coeffLeftProd = ( (mass(q)*(2.*(momQ+momQbar)*(1.*inv12+sqr(mass(q))+sqr(mass(qbar)))+log1(sqr(mass(q))/sqr(mass(qbar)))*(1.*inv12*(momQ+2.*momQbar)+momQbar*sqr(mass(q))+(2.*momQ+3.*momQbar)*sqr(mass(qbar)))+(2.*log1((-1.*mass(q)*mass(qbar))/(0.5*inv12+sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))*(0.5*(momQ+2.*momQbar)*sqr(inv12)-momQ*sqr(mass(q))*sqr(mass(qbar))+0.5*inv12*(momQbar*sqr(mass(q))+(2.*momQ+5.*momQbar)*sqr(mass(qbar)))+(momQ+2.*momQbar)*sqr(sqr(mass(qbar)))))/sqrt1(0.25*sqr(inv12)-sqr(mass(q))*sqr(mass(qbar)))))/sqr(1.*inv12+sqr(mass(q))+sqr(mass(qbar))) ); const Complex leftProd = Complex(0.,1.) * mass(q)*mass(qbar)/minusProduct(q,qbar); const Complex rightProd = Complex(0.,1.) * plusProduct(q,qbar); cacheCurrent( 0.5*CF*( coeffLeftTree*leftTree + coeffRightTree*rightTree + coeffLeftProd*leftProd + coeffRightProd*rightProd ) ); } if ( qHel == -1 && qbarHel == -1 ){ cacheCurrent( 0.5*CF*( coeffLeftTree*leftTree + coeffRightTree*rightTree ) ); } } #ifdef CHECK_MatchboxCurrents checkCurrent("qqbarRightOneLoopCurrent",cachedCurrent(),momentum(q)+momentum(qbar)); #endif return cachedCurrent(); } } // ln(s(a+i0)) inline Complex log(double s, double a) { return s < 0. ? Complex(log(abs(a)),-pi * theta(a)) : Complex(log(abs(a)),pi * theta(-a)); } // ln(s(a+i0)/(b+i0)) inline Complex log(double s, double a, double b) { return s < 0. ? Complex(log(abs(a/b)),-pi * theta(a/b) * sign(b-a)) : Complex(log(abs(a/b)),pi * theta(-a/b) * sign(b-a)); } // Li2(-(a+i0)/(b+i0)) inline Complex Li2(double a, double b) { if ( -a/b < 1. ) return Complex(Herwig::Math::ReLi2(-a/b),0.0); return Complex(Herwig::Math::ReLi2(-a/b),-pi * log(-a/b) * sign(b-a)); } Complex MatchboxCurrents::box6(const int i, const int j, const int k) { const double sij = invariant(i,j); const double sik = invariant(i,k); const double sjk = invariant(j,k); return -( Li2(sik+sjk,sij) + Li2(sik+sij,sjk) + 0.5 * csqr(log(1.,sij,sjk)) + sqr(pi)/6. )/8.; } void MatchboxCurrents::qqbargLoopCoefficients(const int i, const int j, const int k) { // use a dummy cache entry to check if we need to get some work done static Complex dummy; if ( getAmplitude(hash<5>(1,2,i,0,j,0,k,0)) ) { dummy = 0.; cacheAmplitude(dummy); cachedAmplitude(); } else { cachedAmplitude(); return; } qqbargLoops.resize(13); // get the transcendentals const double ij = invariant(i,j); const double ij2 = sqr(ij); const double ij3 = ij2 * ij; const double ik = invariant(i,k); const double ik2 = sqr(ik); //const double ik3 = ik2 * ik; const double jk = invariant(j,k); const double jk2 = sqr(jk); const double jk3 = jk2 * jk; const double ij_ik = ij + ik; const double ij_ik_2 = sqr(ij_ik); const double ij_jk = ij + jk; const double ij_jk_2 = sqr(ij_jk); const double ik_jk = ik + jk; const double ik_jk_2 = sqr(ik_jk); const double Q2 = ij + ik + jk; // checked for LEP that virtuals + I operator are mu2 independent //double xmu2 = 10 * GeV2/sqr(amplitudeScale()); const double xmu2 = 1.; const Complex Lijk = log(1.,-xmu2/Q2); const Complex Lij = log(1.,Q2,ij); const Complex Lik = log(1.,Q2,ik); const Complex Ljk = log(1.,Q2,jk); const Complex Box6ijk = box6(i,j,k); const Complex Box6ikj = box6(i,k,j); const Complex Box6jik = box6(j,i,k); // get the coefficients qqbargLoops[0] = ( (2 * CF * ij2) - (32 * CA * Box6ijk * ij2) + (64 * CF * Box6ijk * ij2) - (8 * CA * Box6jik * ij2) + (16 * CF * Box6jik * ij2) + (2 * CA * Lij * ij2) - (4 * CF * Lij * ij2) - (CA * Lik * ij2) - (2 * CF * Lik * ij2) - (4 * CF * Ljk * ij2) - (16 * CA * Box6ijk * ij3) / ik + (32 * CF * Box6ijk * ij3) / ik + (CA * Lij * ij3) / ik - (2 * CF * Lij * ij3) / ik + (2 * CF * ij * ik) - (16 * CA * Box6ijk * ij * ik) + (32 * CF * Box6ijk * ij * ik) - (16 * CA * Box6jik * ij * ik) + (32 * CF * Box6jik * ij * ik) + (CA * Lij * ij * ik) - (2 * CF * Lij * ij * ik) - (2 * CA * Lik * ij * ik) - (4 * CF * Lik * ij * ik) - (4 * CF * Ljk * ij * ik) - (8 * CA * Box6jik * ik2) + (16 * CF * Box6jik * ik2) - (CA * Lik * ik2) - (2 * CF * Lik * ik2) - (8 * CA * Box6jik * ij3) / jk + (16 * CF * Box6jik * ij3) / jk - (16 * CA * Box6jik * ij2 * ik) / jk + (32 * CF * Box6jik * ij2 * ik) / jk - (8 * CA * Box6jik * ij * ik2) / jk + (16 * CF * Box6jik * ij * ik2) / jk + (2 * CF * ij * jk) - (40 * CA * Box6ijk * ij * jk) + (80 * CF * Box6ijk * ij * jk) + (24 * CA * Box6ikj * ij * jk) + (2 * CA * Lij * ij * jk) - (4 * CF * Lij * ij * jk) - (CA * Lik * ij * jk) - (4 * CF * Lik * ij * jk) - (12 * CF * Ljk * ij * jk) - (8 * CA * Box6ijk * ij3 * jk) / ik2 + (16 * CF * Box6ijk * ij3 * jk) / ik2 - (32 * CA * Box6ijk * ij2 * jk) / ik + (64 * CF * Box6ijk * ij2 * jk) / ik + (CA * Lij * ij2 * jk) / ik - (2 * CF * Lij * ij2 * jk) / ik + (CA * Ljk * ij2 * jk) / ik - (2 * CF * Ljk * ij2 * jk) / ik + (2 * CF * ik * jk) - (16 * CA * Box6ijk * ik * jk) + (32 * CF * Box6ijk * ik * jk) + (48 * CA * Box6ikj * ik * jk) + (CA * Lij * ik * jk) - (2 * CF * Lij * ik * jk) - (2 * CA * Lik * ik * jk) - (8 * CF * Lik * ik * jk) - (CA * Ljk * ik * jk) - (8 * CF * Ljk * ik * jk) + (24 * CA * Box6ikj * ik2 * jk) / ij - (CA * Lik * ik2 * jk) / ij - (4 * CF * Lik * ik2 * jk) / ij - (8 * CA * Box6ijk * jk2) + (16 * CF * Box6ijk * jk2) + (24 * CA * Box6ikj * jk2) - (8 * CF * Ljk * jk2) - (8 * CA * Box6ijk * ij2 * jk2) / ik2 + (16 * CF * Box6ijk * ij2 * jk2) / ik2 - (16 * CA * Box6ijk * ij * jk2) / ik + (32 * CF * Box6ijk * ij * jk2) / ik + (CA * Ljk * ij * jk2) / ik - (2 * CF * Ljk * ij * jk2) / ik + (48 * CA * Box6ikj * ik * jk2) / ij - (CA * Ljk * ik * jk2) / ij - (4 * CF * Ljk * ik * jk2) / ij + (24 * CA * Box6ikj * ik2 * jk2) / ij2 ) / (ij_ik_2 * ij_jk); qqbargLoops[1] = ( (-2 * CF * ij2) + (8 * CA * Box6ijk * ij2) - (16 * CF * Box6ijk * ij2) + (32 * CA * Box6jik * ij2) - (64 * CF * Box6jik * ij2) - (2 * CA * Lij * ij2) + (4 * CF * Lij * ij2) + (4 * CF * Lik * ij2) + (CA * Ljk * ij2) + (2 * CF * Ljk * ij2) + (8 * CA * Box6ijk * ij3) / ik - (16 * CF * Box6ijk * ij3) / ik - (2 * CF * ij * ik) - (24 * CA * Box6ikj * ij * ik) + (40 * CA * Box6jik * ij * ik) - (80 * CF * Box6jik * ij * ik) - (2 * CA * Lij * ij * ik) + (4 * CF * Lij * ij * ik) + (12 * CF * Lik * ij * ik) + (CA * Ljk * ij * ik) + (4 * CF * Ljk * ij * ik) - (24 * CA * Box6ikj * ik2) + (8 * CA * Box6jik * ik2) - (16 * CF * Box6jik * ik2) + (8 * CF * Lik * ik2) + (8 * CA * Box6jik * ij3 * ik) / jk2 - (16 * CF * Box6jik * ij3 * ik) / jk2 + (8 * CA * Box6jik * ij2 * ik2) / jk2 - (16 * CF * Box6jik * ij2 * ik2) / jk2 + (16 * CA * Box6jik * ij3) / jk - (32 * CF * Box6jik * ij3) / jk - (CA * Lij * ij3) / jk + (2 * CF * Lij * ij3) / jk + (32 * CA * Box6jik * ij2 * ik) / jk - (64 * CF * Box6jik * ij2 * ik) / jk - (CA * Lij * ij2 * ik) / jk + (2 * CF * Lij * ij2 * ik) / jk - (CA * Lik * ij2 * ik) / jk + (2 * CF * Lik * ij2 * ik) / jk + (16 * CA * Box6jik * ij * ik2) / jk - (32 * CF * Box6jik * ij * ik2) / jk - (CA * Lik * ij * ik2) / jk + (2 * CF * Lik * ij * ik2) / jk - (2 * CF * ij * jk) + (16 * CA * Box6ijk * ij * jk) - (32 * CF * Box6ijk * ij * jk) + (16 * CA * Box6jik * ij * jk) - (32 * CF * Box6jik * ij * jk) - (CA * Lij * ij * jk) + (2 * CF * Lij * ij * jk) + (4 * CF * Lik * ij * jk) + (2 * CA * Ljk * ij * jk) + (4 * CF * Ljk * ij * jk) + (16 * CA * Box6ijk * ij2 * jk) / ik - (32 * CF * Box6ijk * ij2 * jk) / ik - (2 * CF * ik * jk) - (48 * CA * Box6ikj * ik * jk) + (16 * CA * Box6jik * ik * jk) - (32 * CF * Box6jik * ik * jk) - (CA * Lij * ik * jk) + (2 * CF * Lij * ik * jk) + (CA * Lik * ik * jk) + (8 * CF * Lik * ik * jk) + (2 * CA * Ljk * ik * jk) + (8 * CF * Ljk * ik * jk) - (48 * CA * Box6ikj * ik2 * jk) / ij + (CA * Lik * ik2 * jk) / ij + (4 * CF * Lik * ik2 * jk) / ij + (8 * CA * Box6ijk * jk2) - (16 * CF * Box6ijk * jk2) + (CA * Ljk * jk2) + (2 * CF * Ljk * jk2) + (8 * CA * Box6ijk * ij * jk2) / ik - (16 * CF * Box6ijk * ij * jk2) / ik - (24 * CA * Box6ikj * ik * jk2) / ij + (CA * Ljk * ik * jk2) / ij + (4 * CF * Ljk * ik * jk2) / ij - (24 * CA * Box6ikj * ik2 * jk2) / ij2 ) / (ij_ik * ij_jk_2); qqbargLoops[2] = -3 * CF * Lijk + ( (-4 * CA * Box6jik * ij3) + (8 * CF * Box6jik * ij3) + (CA * Lij * ij3) / 2. - (CF * Lij * ij3) + (CA * ij2 * ik) - (9 * CF * ij2 * ik) + (8 * CA * Box6ijk * ij2 * ik) - (16 * CF * Box6ijk * ij2 * ik) - (8 * CA * Box6ikj * ij2 * ik) - (8 * CA * Box6jik * ij2 * ik) + (16 * CF * Box6jik * ij2 * ik) + (CA * Lij * ij2 * ik) / 2. - (CF * Lij * ij2 * ik) + (CA * Lik * ij2 * ik) / 2. - (CF * Lik * ij2 * ik) + (CA * ij * ik2) - (9 * CF * ij * ik2) + (8 * CA * Box6ijk * ij * ik2) - (16 * CF * Box6ijk * ij * ik2) - (8 * CA * Box6ikj * ij * ik2) - (4 * CA * Box6jik * ij * ik2) + (8 * CF * Box6jik * ij * ik2) + (CA * Lik * ij * ik2) / 2. - (CF * Lik * ij * ik2) - (4 * CA * Box6jik * ij3 * ik) / jk + (8 * CF * Box6jik * ij3 * ik) / jk - (4 * CA * Box6jik * ij2 * ik2) / jk + (8 * CF * Box6jik * ij2 * ik2) / jk + (CA * ij2 * jk) - (9 * CF * ij2 * jk) + (12 * CA * Box6ijk * ij2 * jk) - (24 * CF * Box6ijk * ij2 * jk) - (8 * CA * Box6ikj * ij2 * jk) - (4 * CA * Box6jik * ij2 * jk) + (8 * CF * Box6jik * ij2 * jk) + (CA * Lik * ij2 * jk) / 2. - (CF * Lik * ij2 * jk) - (CA * Ljk * ij2 * jk) / 2. + (CF * Ljk * ij2 * jk) + (4 * CA * Box6ijk * ij3 * jk) / ik - (8 * CF * Box6ijk * ij3 * jk) / ik - (CA * Lij * ij3 * jk) / (2. * ik) + (CF * Lij * ij3 * jk) / ik + (2 * CA * ij * ik * jk) - (18 * CF * ij * ik * jk) + (16 * CA * Box6ijk * ij * ik * jk) - (32 * CF * Box6ijk * ij * ik * jk) - (28 * CA * Box6ikj * ij * ik * jk) - (4 * CA * Box6jik * ij * ik * jk) + (8 * CF * Box6jik * ij * ik * jk) + (CA * Lij * ij * ik * jk) / 2. - (CF * Lij * ij * ik * jk) + (CA * Lik * ij * ik * jk) - (CF * Lik * ij * ik * jk) - (CA * Ljk * ij * ik * jk) / 2. + (3 * CF * Ljk * ij * ik * jk) + (CA * ik2 * jk) - (9 * CF * ik2 * jk) + (8 * CA * Box6ijk * ik2 * jk) - (16 * CF * Box6ijk * ik2 * jk) - (20 * CA * Box6ikj * ik2 * jk) + (CA * Lik * ik2 * jk) / 2. + (CA * ij * jk2) - (9 * CF * ij * jk2) + (12 * CA * Box6ijk * ij * jk2) - (24 * CF * Box6ijk * ij * jk2) - (20 * CA * Box6ikj * ij * jk2) - (CA * Lij * ij * jk2) / 2. + (CF * Lij * ij * jk2) + (CA * Lik * ij * jk2) / 2. - (CA * Ljk * ij * jk2) + (4 * CF * Ljk * ij * jk2) + (4 * CA * Box6ijk * ij3 * jk2) / ik2 - (8 * CF * Box6ijk * ij3 * jk2) / ik2 + (8 * CA * Box6ijk * ij2 * jk2) / ik - (16 * CF * Box6ijk * ij2 * jk2) / ik - (CA * Lij * ij2 * jk2) / (2. * ik) + (CF * Lij * ij2 * jk2) / ik - (CA * Ljk * ij2 * jk2) / (2. * ik) + (CF * Ljk * ij2 * jk2) / ik + (CA * ik * jk2) - (9 * CF * ik * jk2) + (8 * CA * Box6ijk * ik * jk2) - (16 * CF * Box6ijk * ik * jk2) - (32 * CA * Box6ikj * ik * jk2) + (CA * Lik * ik * jk2) / 2. - (CA * Ljk * ik * jk2) / 2. + (3 * CF * Ljk * ik * jk2) - (12 * CA * Box6ikj * ik2 * jk2) / ij - (12 * CA * Box6ikj * jk3) - (CA * Ljk * jk3) / 2. + (3 * CF * Ljk * jk3) + (4 * CA * Box6ijk * ij2 * jk3) / ik2 - (8 * CF * Box6ijk * ij2 * jk3) / ik2 + (4 * CA * Box6ijk * ij * jk3) / ik - (8 * CF * Box6ijk * ij * jk3) / ik - (CA * Ljk * ij * jk3) / (2. * ik) + (CF * Ljk * ij * jk3) / ik - (12 * CA * Box6ikj * ik * jk3) / ij ) / (ij_ik * ij_jk * ik_jk); qqbargLoops[3] = 3 * CF * Lijk + ( (8 * CF * ij2) - (8 * CA * Box6ijk * ij2) + (16 * CF * Box6ijk * ij2) + (8 * CA * Box6ikj * ij2) - (8 * CA * Box6jik * ij2) + (16 * CF * Box6jik * ij2) + (CA * Lij * ij2) / 2. - (CF * Lij * ij2) + (8 * CF * ij * ik) - (8 * CA * Box6ijk * ij * ik) + (16 * CF * Box6ijk * ij * ik) + (8 * CA * Box6ikj * ij * ik) - (12 * CA * Box6jik * ij * ik) + (24 * CF * Box6jik * ij * ik) + (CA * Lij * ij * ik) / 2. - (CF * Lij * ij * ik) + (CA * Lik * ij * ik) / 2. - (CF * Lik * ij * ik) - (4 * CA * Box6jik * ik2) + (8 * CF * Box6jik * ik2) + (CA * Lik * ik2) / 2. - (CF * Lik * ik2) - (4 * CA * Box6jik * ij2 * ik) / jk + (8 * CF * Box6jik * ij2 * ik) / jk - (4 * CA * Box6jik * ij * ik2) / jk + (8 * CF * Box6jik * ij * ik2) / jk + (8 * CF * ij * jk) - (12 * CA * Box6ijk * ij * jk) + (24 * CF * Box6ijk * ij * jk) + (8 * CA * Box6ikj * ij * jk) - (8 * CA * Box6jik * ij * jk) + (16 * CF * Box6jik * ij * jk) + (CA * Lij * ij * jk) / 2. - (CF * Lij * ij * jk) + (CA * Ljk * ij * jk) / 2. - (CF * Ljk * ij * jk) - (4 * CA * Box6ijk * ij2 * jk) / ik + (8 * CF * Box6ijk * ij2 * jk) / ik + (8 * CF * ik * jk) - (8 * CA * Box6ijk * ik * jk) + (16 * CF * Box6ijk * ik * jk) - (4 * CA * Box6ikj * ik * jk) - (8 * CA * Box6jik * ik * jk) + (16 * CF * Box6jik * ik * jk) + (CA * Lij * ik * jk) / 2. - (CF * Lij * ik * jk) + (CA * Lik * ik * jk) / 2. + (2 * CF * Lik * ik * jk) + (CA * Ljk * ik * jk) / 2. + (2 * CF * Ljk * ik * jk) - (12 * CA * Box6ikj * ik2 * jk) / ij + (CA * Lik * ik2 * jk) / (2. * ij) + (2 * CF * Lik * ik2 * jk) / ij - (4 * CA * Box6ijk * jk2) + (8 * CF * Box6ijk * jk2) + (CA * Ljk * jk2) / 2. - (CF * Ljk * jk2) - (4 * CA * Box6ijk * ij * jk2) / ik + (8 * CF * Box6ijk * ij * jk2) / ik - (12 * CA * Box6ikj * ik * jk2) / ij + (CA * Ljk * ik * jk2) / (2. * ij) + (2 * CF * Ljk * ik * jk2) / ij - (12 * CA * Box6ikj * ik2 * jk2) / ij2 ) / (ij_ik * ij_jk); qqbargLoops[4] = -3 * CF * Lijk + ( (-8 * CF * ij2) + (8 * CA * Box6ijk * ij2) - (16 * CF * Box6ijk * ij2) - (8 * CA * Box6ikj * ij2) + (8 * CA * Box6jik * ij2) - (16 * CF * Box6jik * ij2) - (CA * Lij * ij2) / 2. + (CF * Lij * ij2) - (8 * CF * ij * ik) + (8 * CA * Box6ijk * ij * ik) - (16 * CF * Box6ijk * ij * ik) - (8 * CA * Box6ikj * ij * ik) + (12 * CA * Box6jik * ij * ik) - (24 * CF * Box6jik * ij * ik) - (CA * Lij * ij * ik) / 2. + (CF * Lij * ij * ik) - (CA * Lik * ij * ik) / 2. + (CF * Lik * ij * ik) + (4 * CA * Box6jik * ik2) - (8 * CF * Box6jik * ik2) - (CA * Lik * ik2) / 2. + (CF * Lik * ik2) + (4 * CA * Box6jik * ij2 * ik) / jk - (8 * CF * Box6jik * ij2 * ik) / jk + (4 * CA * Box6jik * ij * ik2) / jk - (8 * CF * Box6jik * ij * ik2) / jk - (8 * CF * ij * jk) + (12 * CA * Box6ijk * ij * jk) - (24 * CF * Box6ijk * ij * jk) - (8 * CA * Box6ikj * ij * jk) + (8 * CA * Box6jik * ij * jk) - (16 * CF * Box6jik * ij * jk) - (CA * Lij * ij * jk) / 2. + (CF * Lij * ij * jk) - (CA * Ljk * ij * jk) / 2. + (CF * Ljk * ij * jk) + (4 * CA * Box6ijk * ij2 * jk) / ik - (8 * CF * Box6ijk * ij2 * jk) / ik - (8 * CF * ik * jk) + (8 * CA * Box6ijk * ik * jk) - (16 * CF * Box6ijk * ik * jk) + (4 * CA * Box6ikj * ik * jk) + (8 * CA * Box6jik * ik * jk) - (16 * CF * Box6jik * ik * jk) - (CA * Lij * ik * jk) / 2. + (CF * Lij * ik * jk) - (CA * Lik * ik * jk) / 2. - (2 * CF * Lik * ik * jk) - (CA * Ljk * ik * jk) / 2. - (2 * CF * Ljk * ik * jk) + (12 * CA * Box6ikj * ik2 * jk) / ij - (CA * Lik * ik2 * jk) / (2. * ij) - (2 * CF * Lik * ik2 * jk) / ij + (4 * CA * Box6ijk * jk2) - (8 * CF * Box6ijk * jk2) - (CA * Ljk * jk2) / 2. + (CF * Ljk * jk2) + (4 * CA * Box6ijk * ij * jk2) / ik - (8 * CF * Box6ijk * ij * jk2) / ik + (12 * CA * Box6ikj * ik * jk2) / ij - (CA * Ljk * ik * jk2) / (2. * ij) - (2 * CF * Ljk * ik * jk2) / ij + (12 * CA * Box6ikj * ik2 * jk2) / ij2 ) / (ij_ik * ij_jk); qqbargLoops[5] = 3 * CF * Lijk + ( (-4 * CA * Box6jik * ij2) + (8 * CF * Box6jik * ij2) + (CA * Lij * ij2) / 2. - (CF * Lij * ij2) - (CA * ij * ik) + (9 * CF * ij * ik) - (8 * CA * Box6ijk * ij * ik) + (16 * CF * Box6ijk * ij * ik) + (8 * CA * Box6ikj * ij * ik) - (4 * CA * Box6jik * ij * ik) + (8 * CF * Box6jik * ij * ik) + (CA * Lij * ij * ik) / 2. - (CF * Lij * ij * ik) + (CA * Lik * ij * ik) / 2. - (CF * Lik * ij * ik) - (CA * ik2) + (9 * CF * ik2) - (8 * CA * Box6ijk * ik2) + (16 * CF * Box6ijk * ik2) + (8 * CA * Box6ikj * ik2) + (CA * Lik * ik2) / 2. - (CF * Lik * ik2) - (4 * CA * Box6jik * ij2 * ik) / jk + (8 * CF * Box6jik * ij2 * ik) / jk - (4 * CA * Box6jik * ij * ik2) / jk + (8 * CF * Box6jik * ij * ik2) / jk - (CA * ij * jk) + (9 * CF * ij * jk) - (4 * CA * Box6ijk * ij * jk) + (8 * CF * Box6ijk * ij * jk) + (8 * CA * Box6ikj * ij * jk) - (CA * Lij * ij * jk) / 2. + (CF * Lij * ij * jk) + (CA * Lik * ij * jk) / 2. - (CF * Lik * ij * jk) - (CA * Ljk * ij * jk) / 2. + (CF * Ljk * ij * jk) + (4 * CA * Box6ijk * ij2 * jk) / ik - (8 * CF * Box6ijk * ij2 * jk) / ik - (CA * Lij * ij2 * jk) / (2. * ik) + (CF * Lij * ij2 * jk) / ik - (CA * ik * jk) + (9 * CF * ik * jk) - (8 * CA * Box6ijk * ik * jk) + (16 * CF * Box6ijk * ik * jk) + (20 * CA * Box6ikj * ik * jk) + (CA * Lik * ik * jk) / 2. - (CF * Lik * ik * jk) - (CA * Ljk * ik * jk) / 2. - (2 * CF * Ljk * ik * jk) + (12 * CA * Box6ikj * ik2 * jk) / ij + (12 * CA * Box6ikj * jk2) - (CA * Ljk * jk2) / 2. - (2 * CF * Ljk * jk2) + (4 * CA * Box6ijk * ij2 * jk2) / ik2 - (8 * CF * Box6ijk * ij2 * jk2) / ik2 + (4 * CA * Box6ijk * ij * jk2) / ik - (8 * CF * Box6ijk * ij * jk2) / ik - (CA * Ljk * ij * jk2) / (2. * ik) + (CF * Ljk * ij * jk2) / ik + (12 * CA * Box6ikj * ik * jk2) / ij ) / (ij_ik * ik_jk); qqbargLoops[6] = ( (-2 * CF * ij) + (32 * CA * Box6ijk * ij) - (64 * CF * Box6ijk * ij) - (4 * CA * Lij * ij) + (8 * CF * Lij * ij) + (4 * CF * Ljk * ij) + (16 * CA * Box6ijk * ij2) / ik - (32 * CF * Box6ijk * ij2) / ik - (2 * CA * Lij * ij2) / ik + (4 * CF * Lij * ij2) / ik - (2 * CF * ik) + (16 * CA * Box6ijk * ik) - (32 * CF * Box6ijk * ik) - (2 * CA * Lij * ik) + (4 * CF * Lij * ik) + (4 * CF * Ljk * ik) + (16 * CA * Box6ijk * jk) - (32 * CF * Box6ijk * jk) - (2 * CA * Ljk * jk) + (6 * CF * Ljk * jk) + (16 * CA * Box6ijk * ij2 * jk) / ik2 - (32 * CF * Box6ijk * ij2 * jk) / ik2 + (32 * CA * Box6ijk * ij * jk) / ik - (64 * CF * Box6ijk * ij * jk) / ik - (2 * CA * Ljk * ij * jk) / ik + (4 * CF * Ljk * ij * jk) / ik ) / ij_ik_2; qqbargLoops[7] = ( (8 * CA * Box6jik * ij) - (16 * CF * Box6jik * ij) + (CA * Lij * ij) - (2 * CF * Lij * ij) + (CA * Lik * ij) + (2 * CF * Lik * ij) + (CA * Lij * ij2) / ik - (2 * CF * Lij * ij2) / ik + (8 * CA * Box6jik * ik) - (16 * CF * Box6jik * ik) + (CA * Lik * ik) + (2 * CF * Lik * ik) + (8 * CA * Box6jik * ij2) / jk - (16 * CF * Box6jik * ij2) / jk + (8 * CA * Box6jik * ij * ik) / jk - (16 * CF * Box6jik * ij * ik) / jk - (24 * CA * Box6ikj * jk) + (CA * Lij * jk) - (2 * CF * Lij * jk) + (CA * Lik * jk) + (4 * CF * Lik * jk) + (CA * Ljk * jk) + (4 * CF * Ljk * jk) - (8 * CA * Box6ijk * ij2 * jk) / ik2 + (16 * CF * Box6ijk * ij2 * jk) / ik2 - (8 * CA * Box6ijk * ij * jk) / ik + (16 * CF * Box6ijk * ij * jk) / ik + (CA * Lij * ij * jk) / ik - (2 * CF * Lij * ij * jk) / ik + (CA * Ljk * ij * jk) / ik - (2 * CF * Ljk * ij * jk) / ik - (24 * CA * Box6ikj * ik * jk) / ij + (CA * Lik * ik * jk) / ij + (4 * CF * Lik * ik * jk) / ij - (24 * CA * Box6ikj * jk2) / ij + (CA * Ljk * jk2) / ij + (4 * CF * Ljk * jk2) / ij - (8 * CA * Box6ijk * ij * jk2) / ik2 + (16 * CF * Box6ijk * ij * jk2) / ik2 - (8 * CA * Box6ijk * jk2) / ik + (16 * CF * Box6ijk * jk2) / ik + (CA * Ljk * jk2) / ik - (2 * CF * Ljk * jk2) / ik - (24 * CA * Box6ikj * ik * jk2) / ij2 ) / (ij_ik * ij_jk); qqbargLoops[8] = ( (-8 * CA * Box6ijk * ij) + (16 * CF * Box6ijk * ij) - (CA * Lij * ij) + (2 * CF * Lij * ij) - (CA * Ljk * ij) - (2 * CF * Ljk * ij) - (8 * CA * Box6ijk * ij2) / ik + (16 * CF * Box6ijk * ij2) / ik + (24 * CA * Box6ikj * ik) - (CA * Lij * ik) + (2 * CF * Lij * ik) - (CA * Lik * ik) - (4 * CF * Lik * ik) - (CA * Ljk * ik) - (4 * CF * Ljk * ik) + (24 * CA * Box6ikj * ik2) / ij - (CA * Lik * ik2) / ij - (4 * CF * Lik * ik2) / ij + (8 * CA * Box6jik * ij2 * ik) / jk2 - (16 * CF * Box6jik * ij2 * ik) / jk2 + (8 * CA * Box6jik * ij * ik2) / jk2 - (16 * CF * Box6jik * ij * ik2) / jk2 - (CA * Lij * ij2) / jk + (2 * CF * Lij * ij2) / jk + (8 * CA * Box6jik * ij * ik) / jk - (16 * CF * Box6jik * ij * ik) / jk - (CA * Lij * ij * ik) / jk + (2 * CF * Lij * ij * ik) / jk - (CA * Lik * ij * ik) / jk + (2 * CF * Lik * ij * ik) / jk + (8 * CA * Box6jik * ik2) / jk - (16 * CF * Box6jik * ik2) / jk - (CA * Lik * ik2) / jk + (2 * CF * Lik * ik2) / jk - (8 * CA * Box6ijk * jk) + (16 * CF * Box6ijk * jk) - (CA * Ljk * jk) - (2 * CF * Ljk * jk) - (8 * CA * Box6ijk * ij * jk) / ik + (16 * CF * Box6ijk * ij * jk) / ik + (24 * CA * Box6ikj * ik * jk) / ij - (CA * Ljk * ik * jk) / ij - (4 * CF * Ljk * ik * jk) / ij + (24 * CA * Box6ikj * ik2 * jk) / ij2 ) / (ij_ik * ij_jk); qqbargLoops[9] = ( (2 * CF * ij) - (32 * CA * Box6jik * ij) + (64 * CF * Box6jik * ij) + (4 * CA * Lij * ij) - (8 * CF * Lij * ij) - (4 * CF * Lik * ij) - (16 * CA * Box6jik * ik) + (32 * CF * Box6jik * ik) + (2 * CA * Lik * ik) - (6 * CF * Lik * ik) - (16 * CA * Box6jik * ij2 * ik) / jk2 + (32 * CF * Box6jik * ij2 * ik) / jk2 - (16 * CA * Box6jik * ij2) / jk + (32 * CF * Box6jik * ij2) / jk + (2 * CA * Lij * ij2) / jk - (4 * CF * Lij * ij2) / jk - (32 * CA * Box6jik * ij * ik) / jk + (64 * CF * Box6jik * ij * ik) / jk + (2 * CA * Lik * ij * ik) / jk - (4 * CF * Lik * ij * ik) / jk + (2 * CF * jk) - (16 * CA * Box6jik * jk) + (32 * CF * Box6jik * jk) + (2 * CA * Lij * jk) - (4 * CF * Lij * jk) - (4 * CF * Lik * jk) ) / ij_jk_2; qqbargLoops[10] = ( (-8 * CA * Box6ijk * ij2 * jk) + (16 * CF * Box6ijk * ij2 * jk) + (2 * CA * Lij * ij2 * jk) - (4 * CF * Lij * ij2 * jk) - (CA * ij * ik * jk) + (2 * CF * ij * ik * jk) - (8 * CA * Box6ijk * ij * ik * jk) + (16 * CF * Box6ijk * ij * ik * jk) + (3 * CA * Lij * ij * ik * jk) - (6 * CF * Lij * ij * ik * jk) + (CA * Ljk * ij * ik * jk) - (2 * CF * Ljk * ij * ik * jk) - (CA * ik2 * jk) + (2 * CF * ik2 * jk) + (CA * Lij * ik2 * jk) - (2 * CF * Lij * ik2 * jk) + (CA * Ljk * ik2 * jk) - (CF * Ljk * ik2 * jk) - (CA * ij * jk2) + (2 * CF * ij * jk2) - (16 * CA * Box6ijk * ij * jk2) + (32 * CF * Box6ijk * ij * jk2) + (2 * CA * Lij * ij * jk2) - (4 * CF * Lij * ij * jk2) + (2 * CA * Ljk * ij * jk2) - (4 * CF * Ljk * ij * jk2) - (16 * CA * Box6ijk * ij2 * jk2) / ik + (32 * CF * Box6ijk * ij2 * jk2) / ik + (CA * Lij * ij2 * jk2) / ik - (2 * CF * Lij * ij2 * jk2) / ik - (CA * ik * jk2) + (2 * CF * ik * jk2) + (CA * Lij * ik * jk2) - (2 * CF * Lij * ik * jk2) + (2 * CA * Ljk * ik * jk2) - (2 * CF * Ljk * ik * jk2) + (CA * Ljk * jk3) - (CF * Ljk * jk3) - (8 * CA * Box6ijk * ij2 * jk3) / ik2 + (16 * CF * Box6ijk * ij2 * jk3) / ik2 - (8 * CA * Box6ijk * ij * jk3) / ik + (16 * CF * Box6ijk * ij * jk3) / ik + (CA * Ljk * ij * jk3) / ik - (2 * CF * Ljk * ij * jk3) / ik ) / (ij_ik * ik_jk_2); qqbargLoops[11] = ( (16 * CA * Box6jik * ij2 * ik) - (32 * CF * Box6jik * ij2 * ik) - (CA * Lij * ij2 * ik) + (2 * CF * Lij * ij2 * ik) + (8 * CA * Box6jik * ij * ik2) - (16 * CF * Box6jik * ij * ik2) - (CA * Lik * ij * ik2) + (2 * CF * Lik * ij * ik2) + (8 * CA * Box6jik * ij2 * ik2) / jk - (16 * CF * Box6jik * ij2 * ik2) / jk + (8 * CA * Box6jik * ij2 * jk) - (16 * CF * Box6jik * ij2 * jk) - (2 * CA * Lij * ij2 * jk) + (4 * CF * Lij * ij2 * jk) + (CA * ij * ik * jk) - (2 * CF * ij * ik * jk) + (16 * CA * Box6jik * ij * ik * jk) - (32 * CF * Box6jik * ij * ik * jk) - (2 * CA * Lij * ij * ik * jk) + (4 * CF * Lij * ij * ik * jk) - (2 * CA * Lik * ij * ik * jk) + (4 * CF * Lik * ij * ik * jk) - (CA * Lik * ik2 * jk) + (CF * Lik * ik2 * jk) + (CA * ij * jk2) - (2 * CF * ij * jk2) + (8 * CA * Box6jik * ij * jk2) - (16 * CF * Box6jik * ij * jk2) - (3 * CA * Lij * ij * jk2) + (6 * CF * Lij * ij * jk2) - (CA * Lik * ij * jk2) + (2 * CF * Lik * ij * jk2) + (CA * ik * jk2) - (2 * CF * ik * jk2) - (CA * Lij * ik * jk2) + (2 * CF * Lij * ik * jk2) - (2 * CA * Lik * ik * jk2) + (2 * CF * Lik * ik * jk2) + (CA * jk3) - (2 * CF * jk3) - (CA * Lij * jk3) + (2 * CF * Lij * jk3) - (CA * Lik * jk3) + (CF * Lik * jk3) ) / (ij_jk * ik_jk_2); qqbargLoops[12] = -3 * CF * Lijk + ( (CA * ij2 * ik) - (9 * CF * ij2 * ik) + (8 * CA * Box6ijk * ij2 * ik) - (16 * CF * Box6ijk * ij2 * ik) - (8 * CA * Box6ikj * ij2 * ik) + (CA * ij * ik2) - (9 * CF * ij * ik2) + (8 * CA * Box6ijk * ij * ik2) - (16 * CF * Box6ijk * ij * ik2) - (8 * CA * Box6ikj * ij * ik2) + (CA * ij2 * jk) - (9 * CF * ij2 * jk) - (8 * CA * Box6ikj * ij2 * jk) + (8 * CA * Box6jik * ij2 * jk) - (16 * CF * Box6jik * ij2 * jk) + (2 * CA * ij * ik * jk) - (18 * CF * ij * ik * jk) + (8 * CA * Box6ijk * ij * ik * jk) - (16 * CF * Box6ijk * ij * ik * jk) - (40 * CA * Box6ikj * ij * ik * jk) + (8 * CA * Box6jik * ij * ik * jk) - (16 * CF * Box6jik * ij * ik * jk) + (3 * CF * Lik * ij * ik * jk) + (3 * CF * Ljk * ij * ik * jk) + (CA * ik2 * jk) - (9 * CF * ik2 * jk) + (8 * CA * Box6ijk * ik2 * jk) - (16 * CF * Box6ijk * ik2 * jk) - (32 * CA * Box6ikj * ik2 * jk) + (3 * CF * Lik * ik2 * jk) + (CA * ij * jk2) - (9 * CF * ij * jk2) - (8 * CA * Box6ikj * ij * jk2) + (8 * CA * Box6jik * ij * jk2) - (16 * CF * Box6jik * ij * jk2) + (CA * ik * jk2) - (9 * CF * ik * jk2) - (32 * CA * Box6ikj * ik * jk2) + (8 * CA * Box6jik * ik * jk2) - (16 * CF * Box6jik * ik * jk2) + (3 * CF * Ljk * ik * jk2) - (24 * CA * Box6ikj * ik2 * jk2) / ij ) / (ij_ik * ij_jk * ik_jk); /* // idendities implied by gauge invariance and current conservation; checked analytically and numerically Complex c1 = qqbargLoops[0] + qqbargLoops[6] + qqbargLoops[7]; Complex c2 = qqbargLoops[1] + qqbargLoops[8] + qqbargLoops[9]; Complex c3 = qqbargLoops[3] + qqbargLoops[4]; Complex c4 = qqbargLoops[2] + qqbargLoops[5] + qqbargLoops[10] + qqbargLoops[11]; Complex c5 = 2. * qqbargLoops[3]/ik + 2. * qqbargLoops[5]/jk + qqbargLoops[6] * (1.+ij/ik) + qqbargLoops[8] * (jk+ij)/ik + 2. * qqbargLoops[10] * (1./ik+1./jk) + 2. * qqbargLoops[12] * (1./ik+1./jk); Complex c6 = 2. * qqbargLoops[4]/jk + 2. * qqbargLoops[5]/jk + qqbargLoops[7] * (ik+ij)/jk + qqbargLoops[9] * (1.+ij/jk) + 2. * qqbargLoops[11] * (ik/jk2+1./jk); Complex c7 = 0.5 * qqbargLoops[0] * (ij+ik) + 0.5 * qqbargLoops[1] * (ij+jk) + qqbargLoops[2] * (1.+ik/jk) - qqbargLoops[12] * (1.+ik/jk); double x1 = c1 != 0. ? log(abs(real(c1 * conj(c1)))) : 0.; double x2 = c2 != 0. ? log(abs(real(c2 * conj(c2)))) : 0.; double x3 = c3 != 0. ? log(abs(real(c3 * conj(c3)))) : 0.; double x4 = c4 != 0. ? log(abs(real(c4 * conj(c4)))) : 0.; double x5 = c5 != 0. ? log(abs(real(c5 * conj(c5)))) : 0.; double x6 = c6 != 0. ? log(abs(real(c6 * conj(c6)))) : 0.; double x7 = c7 != 0. ? log(abs(real(c7 * conj(c7)))) : 0.; cerr << x1 << " " << x2 << " " << x3 << " " << x4 << " " << x5 << " " << x6 << " " << x7 << "\n"; */ } LorentzVector MatchboxCurrents::qqbargGeneralLeftLoopCurrent(const int i, const int, const int j, const int, const int k, const int gHel, const int n) { qqbargLoopCoefficients(i,j,k); const double ik = invariant(i,k); const double jk = invariant(j,k); const Complex plusP_ik = plusProduct(i,k); const Complex plusP_in = plusProduct(i,n); const Complex plusP_jk = plusProduct(j,k); const Complex plusP_jn = plusProduct(j,n); const Complex plusP_kn = plusProduct(k,n); const Complex minusP_ik = minusProduct(i,k); const Complex minusP_in = minusProduct(i,n); const Complex minusP_jk = minusProduct(j,k); const Complex minusP_jn = minusProduct(j,n); const Complex minusP_kn = minusProduct(k,n); const LorentzVector & minusC_ij = minusCurrent(i,j); const LorentzVector & minusC_nk = minusCurrent(n,k); const LorentzVector & minusC_kj = minusCurrent(k,j); const LorentzVector & minusC_kn = minusCurrent(k,n); Complex c1 = qqbargLoops[0]; Complex c2 = qqbargLoops[1]; Complex c3 = qqbargLoops[2]; Complex c4 = qqbargLoops[3]; Complex c5 = qqbargLoops[4]; Complex c6 = qqbargLoops[5]; Complex c7 = qqbargLoops[6]; Complex c8 = qqbargLoops[7]; Complex c9 = qqbargLoops[8]; Complex c10 = qqbargLoops[9]; Complex c11 = qqbargLoops[10]; Complex c12 = qqbargLoops[11]; Complex c13 = qqbargLoops[12]; if ( gHel == 1 ) { return (sqrt(2) * c6 * plusP_jk * minusC_nk * minusP_ik)/(jk * minusP_kn) + (sqrt(2) * c1 * plusP_jk * momentum(i) * minusP_in)/minusP_kn + (sqrt(2) * c2 * plusP_jk * momentum(j) * minusP_in)/minusP_kn + (2 * sqrt(2) * c3 * plusP_jk * momentum(k) * minusP_in)/(jk * minusP_kn) + (sqrt(2) * c4 * plusP_ik * minusC_ij * minusP_in)/(ik * minusP_kn) - (sqrt(2) * c7 * plusP_ik * plusP_jk * momentum(i) * minusP_ik * minusP_in)/(ik * minusP_kn) - (sqrt(2) * c9 * plusP_ik * plusP_jk * momentum(j) * minusP_ik * minusP_in)/(ik * minusP_kn) - (2 * sqrt(2) * c11 * plusP_ik * plusP_jk * momentum(k) * minusP_ik * minusP_in)/(ik * jk * minusP_kn) + (sqrt(2) * c5 * plusP_jk * minusC_ij * minusP_jn)/(jk * minusP_kn) - (sqrt(2) * c8 * sqr(plusP_jk) * momentum(i) * minusP_ik * minusP_jn)/(jk * minusP_kn) - (sqrt(2) * c10 * sqr(plusP_jk) * momentum(j) * minusP_ik * minusP_jn)/(jk * minusP_kn) - (2 * sqrt(2) * c12 * sqr(plusP_jk) * momentum(k) * minusP_ik * minusP_jn)/(sqr(jk) * minusP_kn); } if ( gHel == -1 ) { return -((sqrt(2) * c1 * plusP_jn * momentum(i) * minusP_ik)/plusP_kn) - (sqrt(2) * c2 * plusP_jn * momentum(j) * minusP_ik)/plusP_kn - (2 * sqrt(2) * c3 * plusP_jn * momentum(k) * minusP_ik)/(jk * plusP_kn) - (sqrt(2) * c4 * plusP_in * minusC_ij * minusP_ik)/(ik * plusP_kn) + (sqrt(2) * c13 * minusC_kj * minusP_ik)/ik + (sqrt(2) * c13 * minusC_kj * minusP_ik)/jk - (sqrt(2) * c6 * plusP_jk * minusC_kn * minusP_ik)/(jk * plusP_kn) + (sqrt(2) * c7 * plusP_in * plusP_jk * momentum(i) * sqr(minusP_ik))/(ik * plusP_kn) + (sqrt(2) * c9 * plusP_in * plusP_jk * momentum(j) * sqr(minusP_ik))/(ik * plusP_kn) + (2 * sqrt(2) * c11 * plusP_in * plusP_jk * momentum(k) * sqr(minusP_ik))/(ik * jk * plusP_kn) - (sqrt(2) * c5 * plusP_jn * minusC_ij * minusP_jk)/(jk * plusP_kn) + (sqrt(2) * c8 * plusP_jk * plusP_jn * momentum(i) * minusP_ik * minusP_jk)/(jk * plusP_kn) + (sqrt(2) * c10 * plusP_jk * plusP_jn * momentum(j) * minusP_ik * minusP_jk)/(jk * plusP_kn) + (2 * sqrt(2) * c12 * plusP_jk * plusP_jn * momentum(k) * minusP_ik * minusP_jk)/(sqr(jk) * plusP_kn); } return czero; } LorentzVector MatchboxCurrents::qqbargFixedLeftLoopCurrent(const int i, const int, const int j, const int, const int k, const int gHel) { qqbargLoopCoefficients(i,j,k); const double ik = invariant(i,k); const double jk = invariant(j,k); const Complex plusP_ij = plusProduct(i,j); const Complex plusP_jk = plusProduct(j,k); const Complex minusP_ij = minusProduct(i,j); const Complex minusP_ik = minusProduct(i,k); const LorentzVector & minusC_ij = minusCurrent(i,j); const LorentzVector & minusC_ik = minusCurrent(i,k); const LorentzVector & minusC_kj = minusCurrent(k,j); //Complex c1 = qqbargLoops[0]; Complex c2 = qqbargLoops[1]; Complex c3 = qqbargLoops[2]; Complex c4 = qqbargLoops[3]; Complex c5 = qqbargLoops[4]; Complex c6 = qqbargLoops[5]; Complex c7 = qqbargLoops[6]; Complex c8 = qqbargLoops[7]; Complex c9 = qqbargLoops[8]; Complex c10 = qqbargLoops[9]; Complex c11 = qqbargLoops[10]; Complex c12 = qqbargLoops[11]; Complex c13 = qqbargLoops[12]; if ( gHel == 1 ) { return -((sqrt(2) * c6 * plusP_jk * minusC_ik)/jk) - (sqrt(2) * c8 * sqr(plusP_jk) * momentum(i) * minusP_ij)/jk - (sqrt(2) * c10 * sqr(plusP_jk) * momentum(j) * minusP_ij)/jk - (2 * sqrt(2) * c12 * sqr(plusP_jk) * momentum(k) * minusP_ij)/sqr(jk) + (sqrt(2) * c5 * plusP_jk * minusC_ij * minusP_ij)/(jk * minusP_ik); } if ( gHel == -1 ) { return (sqrt(2) * c4 * plusP_ij * minusC_ij * minusP_ik)/(ik * plusP_jk) + (sqrt(2) * c13 * minusC_kj * minusP_ik)/ik + (sqrt(2) * c13 * minusC_kj * minusP_ik)/jk + (sqrt(2) * c6 * minusC_kj * minusP_ik)/jk - (sqrt(2) * c7 * plusP_ij * momentum(i)* sqr(minusP_ik))/ik - (sqrt(2) * c9 * plusP_ij * momentum(j) * sqr(minusP_ik))/ik - (2 * sqrt(2) * c11 * plusP_ij * momentum(k) * sqr(minusP_ik))/(ik * jk); } return czero; } LorentzVector MatchboxCurrents::qqbargGeneralRightLoopCurrent(const int i, const int, const int j, const int, const int k, const int gHel, const int n) { qqbargLoopCoefficients(i,j,k); const double ik = invariant(i,k); const double jk = invariant(j,k); const Complex plusP_ik = plusProduct(i,k); const Complex plusP_in = plusProduct(i,n); const Complex plusP_jk = plusProduct(j,k); const Complex plusP_jn = plusProduct(j,n); const Complex plusP_kn = plusProduct(k,n); const Complex minusP_ik = minusProduct(i,k); const Complex minusP_in = minusProduct(i,n); const Complex minusP_jk = minusProduct(j,k); const Complex minusP_jn = minusProduct(j,n); const Complex minusP_kn = minusProduct(k,n); const LorentzVector & minusC_ji = minusCurrent(j,i); const LorentzVector & minusC_jk = minusCurrent(j,k); const LorentzVector & minusC_nk = minusCurrent(n,k); const LorentzVector & minusC_kn = minusCurrent(k,n); Complex c1 = qqbargLoops[0]; Complex c2 = qqbargLoops[1]; Complex c3 = qqbargLoops[2]; Complex c4 = qqbargLoops[3]; Complex c5 = qqbargLoops[4]; Complex c6 = qqbargLoops[5]; Complex c7 = qqbargLoops[6]; Complex c8 = qqbargLoops[7]; Complex c9 = qqbargLoops[8]; Complex c10 = qqbargLoops[9]; Complex c11 = qqbargLoops[10]; Complex c12 = qqbargLoops[11]; Complex c13 = qqbargLoops[12]; if ( gHel == 1 ) { return -((sqrt(2) * c13 * plusP_ik * minusC_jk)/ik) - (sqrt(2) * c13 * plusP_ik * minusC_jk)/jk + (sqrt(2) * c4 * plusP_ik * minusC_ji * minusP_in)/(ik * minusP_kn) + (sqrt(2) * c6 * plusP_ik * minusC_nk * minusP_jk)/(jk * minusP_kn) - (sqrt(2) * c7 * sqr(plusP_ik) * momentum(i) * minusP_in * minusP_jk)/(ik * minusP_kn) - (sqrt(2) * c9 * sqr(plusP_ik) * momentum(j) * minusP_in * minusP_jk)/(ik * minusP_kn) - (2 * sqrt(2) * c11 * sqr(plusP_ik) * momentum(k) * minusP_in * minusP_jk)/(ik * jk * minusP_kn) + (sqrt(2) * c1 * plusP_ik * momentum(i) * minusP_jn)/minusP_kn + (sqrt(2) * c2 * plusP_ik * momentum(j) * minusP_jn)/minusP_kn + (2 * sqrt(2) * c3 * plusP_ik * momentum(k) * minusP_jn)/(jk * minusP_kn) + (sqrt(2) * c5 * plusP_jk * minusC_ji * minusP_jn)/(jk * minusP_kn) - (sqrt(2) * c8 * plusP_ik * plusP_jk * momentum(i) * minusP_jk * minusP_jn)/(jk * minusP_kn) - (sqrt(2) * c10 * plusP_ik * plusP_jk * momentum(j) * minusP_jk * minusP_jn)/(jk * minusP_kn) - (2 * sqrt(2) * c12 * plusP_ik * plusP_jk * momentum(k) * minusP_jk * minusP_jn)/(sqr(jk) * minusP_kn); } if ( gHel == -1 ) { return -((sqrt(2) * c4 * plusP_in * minusC_ji * minusP_ik)/(ik * plusP_kn)) - (sqrt(2) * c1 * plusP_in * momentum(i) * minusP_jk)/plusP_kn - (sqrt(2) * c2 * plusP_in * momentum(j) * minusP_jk)/plusP_kn - (2 * sqrt(2) * c3 * plusP_in * momentum(k) * minusP_jk)/(jk * plusP_kn) - (sqrt(2) * c5 * plusP_jn * minusC_ji * minusP_jk)/(jk * plusP_kn) - (sqrt(2) * c6 * plusP_ik * minusC_kn * minusP_jk)/(jk * plusP_kn) + (sqrt(2) * c7 * plusP_ik * plusP_in * momentum(i) * minusP_ik * minusP_jk)/(ik * plusP_kn) + (sqrt(2) * c9 * plusP_ik * plusP_in * momentum(j) * minusP_ik * minusP_jk)/(ik * plusP_kn) + (2 * sqrt(2) * c11 * plusP_ik * plusP_in * momentum(k) * minusP_ik * minusP_jk)/ (ik * jk * plusP_kn) + (sqrt(2) * c8 * plusP_ik * plusP_jn * momentum(i) * sqr(minusP_jk))/(jk * plusP_kn) + (sqrt(2) * c10 * plusP_ik * plusP_jn * momentum(j) * sqr(minusP_jk))/(jk * plusP_kn) + (2 * sqrt(2) * c12 * plusP_ik * plusP_jn * momentum(k) * sqr(minusP_jk))/(sqr(jk) * plusP_kn); } return czero; } LorentzVector MatchboxCurrents::qqbargFixedRightLoopCurrent(const int i, const int, const int j, const int, const int k, const int gHel) { qqbargLoopCoefficients(i,j,k); const double ik = invariant(i,k); const double jk = invariant(j,k); const Complex plusP_ij = plusProduct(i,j); const Complex plusP_ik = plusProduct(i,k); const Complex minusP_ij = minusProduct(i,j); const Complex minusP_jk = minusProduct(j,k); const LorentzVector & minusC_ji = minusCurrent(j,i); const LorentzVector & minusC_jk = minusCurrent(j,k); const LorentzVector & minusC_ki = minusCurrent(k,i); //Complex c1 = qqbargLoops[0]; Complex c2 = qqbargLoops[1]; Complex c3 = qqbargLoops[2]; Complex c4 = qqbargLoops[3]; Complex c5 = qqbargLoops[4]; Complex c6 = qqbargLoops[5]; Complex c7 = qqbargLoops[6]; Complex c8 = qqbargLoops[7]; Complex c9 = qqbargLoops[8]; Complex c10 = qqbargLoops[9]; Complex c11 = qqbargLoops[10]; Complex c12 = qqbargLoops[11]; Complex c13 = qqbargLoops[12]; if ( gHel == 1 ) { return -((sqrt(2) * c13 * plusP_ik * minusC_jk)/ik) - (sqrt(2) * c13 * plusP_ik * minusC_jk)/jk - (sqrt(2) * c6 * plusP_ik * minusC_jk)/jk + (sqrt(2) * c7 * sqr(plusP_ik) * momentum(i) * minusP_ij)/ik + (sqrt(2) * c9 * sqr(plusP_ik) * momentum(j) * minusP_ij)/ik + (2 * sqrt(2) * c11 * sqr(plusP_ik) * momentum(k) * minusP_ij)/(ik * jk) - (sqrt(2) * c4 * plusP_ik * minusC_ji * minusP_ij)/(ik * minusP_jk); } if ( gHel == -1 ) { return -((sqrt(2) * c5 * plusP_ij * minusC_ji * minusP_jk)/(jk * plusP_ik)) + (sqrt(2) * c6 * minusC_ki * minusP_jk)/jk + (sqrt(2) * c8 * plusP_ij * momentum(i) * sqr(minusP_jk))/jk + (sqrt(2) * c10 * plusP_ij * momentum(j) * sqr(minusP_jk))/jk + (2 * sqrt(2) * c12 * plusP_ij * momentum(k) * sqr(minusP_jk))/sqr(jk); } return czero; } const LorentzVector& MatchboxCurrents::qqbargLeftOneLoopCurrent(const int q, const int qHel, const int qbar, const int qbarHel, const int g1, const int g1Hel) { if ( qHel != 1 || qbarHel != 1 ) return czero; if ( getCurrent(hash<2>(1,2,q,qHel,qbar,qbarHel,g1,g1Hel)) ) { #ifdef CHECK_MatchboxCurrents LorentzVector ni = Complex(0.,0.5) * qqbargGeneralLeftLoopCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,q); LorentzVector nj = Complex(0.,0.5) * qqbargGeneralLeftLoopCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,qbar); LorentzVector nl = Complex(0.,0.5) * qqbargGeneralLeftLoopCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,0); LorentzVector nlbar = Complex(0.,0.5) * qqbargGeneralLeftLoopCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,1); LorentzVector fixed = Complex(0.,0.5) * qqbargFixedLeftLoopCurrent(q,qHel,qbar,qbarHel,g1,g1Hel); LorentzVector x1 = fixed - ni; LorentzVector x2 = fixed - nj; LorentzVector x3 = fixed - nl; LorentzVector x4 = fixed - nlbar; double c1 = real(x1.t() * conj(x1.t())) + real(x1.x() * conj(x1.x())) + real(x1.y() * conj(x1.y())) + real(x1.z() * conj(x1.z())); double c2 = real(x2.t() * conj(x2.t())) + real(x2.x() * conj(x2.x())) + real(x2.y() * conj(x2.y())) + real(x2.z() * conj(x2.z())); double c3 = real(x3.t() * conj(x3.t())) + real(x3.x() * conj(x3.x())) + real(x3.y() * conj(x3.y())) + real(x3.z() * conj(x3.z())); double c4 = real(x4.t() * conj(x4.t())) + real(x4.x() * conj(x4.x())) + real(x4.y() * conj(x4.y())) + real(x4.z() * conj(x4.z())); ostream& ncheck = checkStream("qqbargLeftLoopCurrentNChoice"); ncheck << (c1 != 0. ? log10(abs(c1)) : 0.) << " " << (c2 != 0. ? log10(abs(c2)) : 0.) << " " << (c3 != 0. ? log10(abs(c3)) : 0.) << " " << (c4 != 0. ? log10(abs(c4)) : 0.) << " " << "\n" << flush; #endif cacheCurrent(Complex(0.,0.5) * qqbargFixedLeftLoopCurrent(q,qHel,qbar,qbarHel,g1,g1Hel)); } #ifdef CHECK_MatchboxCurrents checkCurrent("qqbargLeftLoopCurrent",cachedCurrent(),momentum(q)+momentum(qbar)+momentum(g1)); #endif return cachedCurrent(); } const LorentzVector& MatchboxCurrents::qqbargRightOneLoopCurrent(const int q, const int qHel, const int qbar, const int qbarHel, const int g1, const int g1Hel) { if ( qHel != -1 || qbarHel != -1 ) return czero; if ( getCurrent(hash<2>(2,2,q,qHel,qbar,qbarHel,g1,g1Hel)) ) { #ifdef CHECK_MatchboxCurrents LorentzVector ni = Complex(0.,0.5) * qqbargGeneralRightLoopCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,q); LorentzVector nj = Complex(0.,0.5) * qqbargGeneralRightLoopCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,qbar); LorentzVector nl = Complex(0.,0.5) * qqbargGeneralRightLoopCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,0); LorentzVector nlbar = Complex(0.,0.5) * qqbargGeneralRightLoopCurrent(q,qHel,qbar,qbarHel,g1,g1Hel,1); LorentzVector fixed = Complex(0.,0.5) * qqbargFixedRightLoopCurrent(q,qHel,qbar,qbarHel,g1,g1Hel); LorentzVector x1 = fixed - ni; LorentzVector x2 = fixed - nj; LorentzVector x3 = fixed - nl; LorentzVector x4 = fixed - nlbar; double c1 = real(x1.t() * conj(x1.t())) + real(x1.x() * conj(x1.x())) + real(x1.y() * conj(x1.y())) + real(x1.z() * conj(x1.z())); double c2 = real(x2.t() * conj(x2.t())) + real(x2.x() * conj(x2.x())) + real(x2.y() * conj(x2.y())) + real(x2.z() * conj(x2.z())); double c3 = real(x3.t() * conj(x3.t())) + real(x3.x() * conj(x3.x())) + real(x3.y() * conj(x3.y())) + real(x3.z() * conj(x3.z())); double c4 = real(x4.t() * conj(x4.t())) + real(x4.x() * conj(x4.x())) + real(x4.y() * conj(x4.y())) + real(x4.z() * conj(x4.z())); ostream& ncheck = checkStream("qqbargRightLoopCurrentNChoice"); ncheck << (c1 != 0. ? log10(abs(c1)) : 0.) << " " << (c2 != 0. ? log10(abs(c2)) : 0.) << " " << (c3 != 0. ? log10(abs(c3)) : 0.) << " " << (c4 != 0. ? log10(abs(c4)) : 0.) << " " << "\n" << flush; #endif cacheCurrent(Complex(0.,0.5) * qqbargFixedRightLoopCurrent(q,qHel,qbar,qbarHel,g1,g1Hel)); } #ifdef CHECK_MatchboxCurrents checkCurrent("qqbargRightLoopCurrent",cachedCurrent(),momentum(q)+momentum(qbar)+momentum(g1)); #endif return cachedCurrent(); } #ifdef CHECK_MatchboxCurrents map& MatchboxCurrents::checkStreams() { static map theMap; return theMap; } ostream& MatchboxCurrents::checkStream(const string& id) { map::iterator ret = checkStreams().find(id); if ( ret == checkStreams().end() ) { checkStreams()[id] = new ofstream(id.c_str()); ret = checkStreams().find(id); } return *(ret->second); } void MatchboxCurrents::checkCurrent(const string& id, const LorentzVector& current, const LorentzVector& q) { Complex c = current.dot(q); double ac = abs(real(conj(c) * c)); if ( ! isfinite(ac) ) { cerr << "ooops ... nan encountered in current conservation\n" << flush; return; } checkStream(id) << (ac > 0. ? log10(ac) : 0.) << "\n"; } #endif // CHECK_MatchboxCurrents diff --git a/Models/ADD/ADDModelFFWGRVertex.cc b/Models/ADD/ADDModelFFWGRVertex.cc --- a/Models/ADD/ADDModelFFWGRVertex.cc +++ b/Models/ADD/ADDModelFFWGRVertex.cc @@ -1,195 +1,195 @@ // -*- C++ -*- // // ADDModelFFWGRVertex.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 ADDModelFFWGRVertex class. // #include "ADDModelFFWGRVertex.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/Models/StandardModel/StandardCKM.h" using namespace Herwig; using namespace ThePEG; ADDModelFFWGRVertex::ADDModelFFWGRVertex() : charge_(17,0.), gl_(17,0.), gr_(17,0.), ckm_(3,vector(3,0.0)), couplast_(0.), q2last_(ZERO), kappa_(ZERO), r_(ZERO) { orderInGem(2); orderInGs (0); } void ADDModelFFWGRVertex::doinit() { for(int ix=1;ix<7;++ix) { addToList(-ix,ix,22,39); addToList(-ix,ix,23,39); } for(int ix=11;ix<17;++ix) { addToList(-ix,ix,22,39); addToList(-ix,ix,23,39); } // particles for outgoing W- // quarks for(int ix=1;ix<6;ix+=2) { for(int iy=2;iy<7;iy+=2) { addToList(-ix, iy, -24,39); } } // leptons for(int ix=11;ix<17;ix+=2) { addToList(-ix, ix+1, -24,39); } // particles for outgoing W+ // quarks for(int ix=2;ix<7;ix+=2) { for(int iy=1;iy<6;iy+=2) { addToList(-ix, iy, 24,39); } } // leptons for(int ix=11;ix<17;ix+=2) { addToList(-ix-1, ix, 24,39); } FFVTVertex::doinit(); tcHwADDPtr hwADD=dynamic_ptr_cast(generator()->standardModel()); if(!hwADD) throw Exception() << "Must have ADDModel in ADDModelFFWGRVertex::doinit()" << Exception::runerror; double sw2 = sin2ThetaW(); double fact = 0.25/sqrt(sw2*(1.-sw2)); for(int ix=1;ix<4;++ix) { charge_[2*ix-1] = hwADD->ed(); charge_[2*ix ] = hwADD->eu(); charge_[2*ix+9 ] = hwADD->ee(); charge_[2*ix+10] = hwADD->enu(); gl_[2*ix-1] = fact*(hwADD->vd() + hwADD->ad() ); gl_[2*ix ] = fact*(hwADD->vu() + hwADD->au() ); gl_[2*ix+9 ] = fact*(hwADD->ve() + hwADD->ae() ); gl_[2*ix+10] = fact*(hwADD->vnu() + hwADD->anu()); gr_[2*ix-1] = fact*(hwADD->vd() - hwADD->ad() ); gr_[2*ix ] = fact*(hwADD->vu() - hwADD->au() ); gr_[2*ix+9 ] = fact*(hwADD->ve() - hwADD->ae() ); gr_[2*ix+10] = fact*(hwADD->vnu() - hwADD->anu()); } kappa_=2./hwADD->MPlanckBar(); r_ = sqr(hwADD->LambdaT())/hwADD->MPlanckBar(); Ptr::transient_pointer CKM = generator()->standardModel()->CKM(); // cast the CKM object to the HERWIG one ThePEG::Ptr::transient_const_pointer hwCKM = ThePEG::dynamic_ptr_cast< ThePEG::Ptr:: transient_const_pointer>(CKM); if(hwCKM) { vector< vector > CKM; CKM = hwCKM->getUnsquaredMatrix(generator()->standardModel()->families()); for(unsigned int ix=0;ix<3;++ix) { for(unsigned int iy=0;iy<3;++iy) { ckm_[ix][iy]=CKM[ix][iy]; } } } else { throw Exception() << "Must have access to the Herwig::StandardCKM object" << "for the CKM matrix in SMFFWVertex::doinit()" << Exception::runerror; } } void ADDModelFFWGRVertex::persistentOutput(PersistentOStream & os) const { os << charge_ << gl_ << gr_ << ounit(kappa_,InvGeV) << ckm_ << ounit(r_,GeV); } void ADDModelFFWGRVertex::persistentInput(PersistentIStream & is, int) { is >> charge_ >> gl_ >> gr_ >> iunit(kappa_,InvGeV) >> ckm_ >> iunit(r_,GeV); } ClassDescription ADDModelFFWGRVertex::initADDModelFFWGRVertex; // Definition of the static class description member. void ADDModelFFWGRVertex::Init() { static ClassDocumentation documentation ("The ADDModelFFWGRVertexxs class is the implementation" " of the two fermion vector coupling for the ADD model."); } void ADDModelFFWGRVertex::setCoupling(Energy2 q2,tcPDPtr aa,tcPDPtr bb, tcPDPtr cc, tcPDPtr) { // work out the particles int iferm= abs(aa->id()); int ibos = abs(cc->id()); Complex coup; // overall factor assert( ibos >= 22 && ibos <= 24 ); if( q2last_ != q2 || couplast_ == 0. ) { couplast_ = electroMagneticCoupling(q2); q2last_ = q2; } // photon if(ibos==22) { // alpha coup = UnitRemoval::E * kappa_ * couplast_; // _charge of particle assert((iferm>=1 && iferm<=6)||(iferm>=11 &&iferm<=16)); coup *= charge_[iferm]; left (1.); right(1.); } // Z boson else if(ibos==23) { coup = UnitRemoval::E * kappa_ * couplast_; // _charge of particle assert((iferm>=1 && iferm<=6)||(iferm>=11 &&iferm<=16)); left (gl_[iferm]); right(gr_[iferm]); } else if(ibos==24) { - coup = UnitRemoval::E * kappa_ * couplast_ * + coup = Complex(UnitRemoval::E * kappa_ * couplast_) * sqrt(0.5) / sqrt(sin2ThetaW()); // the left and right couplings int iferm=abs(aa->id()); int ianti=abs(bb->id()); // quarks if(iferm>=1 && iferm <=6) { int iu,id; // up type first if(iferm%2==0) { iu = iferm/2; id = (ianti+1)/2; } // down type first else { iu = ianti/2; id = (iferm+1)/2; } assert( iu>=1 && iu<=3 && id>=1 && id<=3); left(ckm_[iu-1][id-1]); right(0.); } // leptons else if(iferm>=11 && iferm <=16) { left(1.); right(0.); } else assert(false); } // set the coupling norm(coup); } Complex ADDModelFFWGRVertex::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/RSModel/RSModelFFWGRVertex.cc b/Models/RSModel/RSModelFFWGRVertex.cc --- a/Models/RSModel/RSModelFFWGRVertex.cc +++ b/Models/RSModel/RSModelFFWGRVertex.cc @@ -1,187 +1,187 @@ // -*- C++ -*- // // RSModelFFWGRVertex.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 RSModelFFWGRVertex class. // #include "RSModelFFWGRVertex.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/Models/StandardModel/StandardCKM.h" using namespace Herwig; using namespace ThePEG; RSModelFFWGRVertex::RSModelFFWGRVertex() : charge_(17,0.), gl_(17,0.), gr_(17,0.), ckm_(3,vector(3,0.0)), couplast_(0.), q2last_(ZERO), kappa_(ZERO) { orderInGem(2); orderInGs (0); } void RSModelFFWGRVertex::doinit() { for(int ix=11;ix<17;++ix) { addToList(-ix,ix,22,39); addToList(-ix,ix,23,39); } for(int ix=1;ix<7;++ix) { addToList(-ix,ix,22,39); addToList(-ix,ix,23,39); } // particles for outgoing W- // quarks for(int ix=1;ix<6;ix+=2) { for(int iy=2;iy<7;iy+=2) { addToList(-ix, iy, -24,39); } } // leptons for(int ix=11;ix<17;ix+=2) { addToList(-ix, ix+1, -24,39); } // particles for outgoing W+ // quarks for(int ix=2;ix<7;ix+=2) { for(int iy=1;iy<6;iy+=2) { addToList(-ix, iy, 24,39); } } // leptons for(int ix=11;ix<17;ix+=2) { addToList(-ix-1, ix, 24,39); } FFVTVertex::doinit(); tcHwRSPtr hwRS=dynamic_ptr_cast(generator()->standardModel()); if(!hwRS) throw Exception() << "Must have RSModel in RSModelFFWGRVertex::doinit()" << Exception::runerror; double sw2 = sin2ThetaW(); double fact = 0.25/sqrt(sw2*(1.-sw2)); for(int ix=1;ix<4;++ix) { charge_[2*ix-1] = hwRS->ed(); charge_[2*ix ] = hwRS->eu(); charge_[2*ix+9 ] = hwRS->ee(); charge_[2*ix+10] = hwRS->enu(); gl_[2*ix-1] = fact*(hwRS->vd() + hwRS->ad() ); gl_[2*ix ] = fact*(hwRS->vu() + hwRS->au() ); gl_[2*ix+9 ] = fact*(hwRS->ve() + hwRS->ae() ); gl_[2*ix+10] = fact*(hwRS->vnu() + hwRS->anu()); gr_[2*ix-1] = fact*(hwRS->vd() - hwRS->ad() ); gr_[2*ix ] = fact*(hwRS->vu() - hwRS->au() ); gr_[2*ix+9 ] = fact*(hwRS->ve() - hwRS->ae() ); gr_[2*ix+10] = fact*(hwRS->vnu() - hwRS->anu()); } kappa_ = 2./hwRS->lambda_pi(); Ptr::transient_pointer CKM = generator()->standardModel()->CKM(); // cast the CKM object to the HERWIG one ThePEG::Ptr::transient_const_pointer hwCKM = ThePEG::dynamic_ptr_cast< ThePEG::Ptr:: transient_const_pointer>(CKM); if(hwCKM) { vector< vector > CKM; CKM = hwCKM->getUnsquaredMatrix(generator()->standardModel()->families()); for(unsigned int ix=0;ix<3;++ix) { for(unsigned int iy=0;iy<3;++iy) { ckm_[ix][iy]=CKM[ix][iy]; } } } else { throw Exception() << "Must have access to the Herwig::StandardCKM object" << "for the CKM matrix in SMFFWVertex::doinit()" << Exception::runerror; } } void RSModelFFWGRVertex::persistentOutput(PersistentOStream & os) const { os << charge_ << gl_ << gr_ << ounit(kappa_,InvGeV) << ckm_; } void RSModelFFWGRVertex::persistentInput(PersistentIStream & is, int) { is >> charge_ >> gl_ >> gr_ >> iunit(kappa_,InvGeV) >> ckm_; } ClassDescription RSModelFFWGRVertex::initRSModelFFWGRVertex; // Definition of the static class description member. void RSModelFFWGRVertex::Init() { static ClassDocumentation documentation ("The RSModelFFWGRVertexxs class is the implementation" " of the two fermion vector coupling for the RS model."); } // FFWGR coupling void RSModelFFWGRVertex::setCoupling(Energy2 q2,tcPDPtr aa,tcPDPtr bb, tcPDPtr cc, tcPDPtr) { // work out the particles int iferm= abs(aa->id()); int ibos = abs(cc->id()); Complex coup; // overall factor assert( ibos >= 22 && ibos <= 24 ); if( q2last_ != q2 || couplast_ == 0. ) { couplast_ = electroMagneticCoupling(q2); q2last_ = q2; } // photon if(ibos==22) { // alpha coup = UnitRemoval::E * kappa_ * couplast_; // _charge of particle assert((iferm>=1 && iferm<=6)||(iferm>=11 &&iferm<=16)); coup *= charge_[iferm]; left (1.); right(1.); } // Z boson else if(ibos==23) { coup = UnitRemoval::E * kappa_ * couplast_; // _charge of particle assert((iferm>=1 && iferm<=6)||(iferm>=11 &&iferm<=16)); left (gl_[iferm]); right(gr_[iferm]); } else if(ibos==24) { - coup = UnitRemoval::E * kappa_ * couplast_ * + coup = Complex(UnitRemoval::E * kappa_ * couplast_) * sqrt(0.5) / sqrt(sin2ThetaW()); // the left and right couplings int iferm=abs(aa->id()); int ianti=abs(bb->id()); // quarks if(iferm>=1 && iferm <=6) { int iu,id; // up type first if(iferm%2==0) { iu = iferm/2; id = (ianti+1)/2; } // down type first else { iu = ianti/2; id = (iferm+1)/2; } assert( iu>=1 && iu<=3 && id>=1 && id<=3); left(ckm_[iu-1][id-1]); right(0.); } // leptons else if(iferm>=11 && iferm <=16) { left(1.); right(0.); } else assert(false); } // set the coupling norm(coup); } diff --git a/Models/UED/UEDF1F0H1Vertex.cc b/Models/UED/UEDF1F0H1Vertex.cc --- a/Models/UED/UEDF1F0H1Vertex.cc +++ b/Models/UED/UEDF1F0H1Vertex.cc @@ -1,202 +1,202 @@ // -*- C++ -*- // // UEDF1F0H1Vertex.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 UEDF1F0H1Vertex class. // #include "UEDF1F0H1Vertex.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace ThePEG::Helicity; using namespace Herwig; UEDF1F0H1Vertex::UEDF1F0H1Vertex() : theRadius(ZERO), theMw(ZERO), theSinThetaW(0.), theq2Last(ZERO), theCoupLast(0.), theLeftLast(0.), theRightLast(0.), theAntiLast(0), theFermLast(0), theHLast(0) { orderInGs(0); orderInGem(1); } void UEDF1F0H1Vertex::doinit() { long heavy[3] = {5, 6, 15}; //h0 - for( unsigned int i = 0; i < 3; ++i ) { + for( int i = 0; i < 3; ++i ) { addToList(-5100000 - i, 5100000 + i, 25); addToList(-6100000 - i, 6100000 + i, 25); addToList(-5100000 - i, 6100000 + i, 25); addToList(-6100000 - i, 5100000 + i, 25); } // Neutral KK-Higgs long higgs[2] = {5100025, 5100036}; for( unsigned int h = 0; h < 2; ++h ) { - for( unsigned int i = 0; i < 3; ++i ) { + for( int i = 0; i < 3; ++i ) { addToList(-heavy[i], 5100000 + heavy[i], higgs[h]); addToList(-5100000 - heavy[i], heavy[i], higgs[h]); addToList(-heavy[i], 6100000 + heavy[i], higgs[h]); addToList(-6100000 - heavy[i], heavy[i], higgs[h]); } } //KK-charged higgs //outgoing H+ addToList(-5100006, 5, 5100037); addToList(-6100006, 5, 5100037); addToList(-6, 5100005, 5100037); addToList(-6, 6100005, 5100037); addToList(-5100016, 15, 5100037); addToList(-6100016, 15, 5100037); addToList(-16, 5100015, 5100037); addToList(-16, 6100015, 5100037); //outgoing H- addToList(-5100005, 6,-5100037); addToList(-6100005, 6,-5100037); addToList(-5, 5100006,-5100037); addToList(-5, 6100006,-5100037); addToList(-5100015, 16,-5100037); addToList(-6100015, 16,-5100037); addToList(-15, 5100016,-5100037); addToList(-15, 6100016,-5100037); FFSVertex::doinit(); tUEDBasePtr UEDBase = dynamic_ptr_cast(generator()->standardModel()); if(!UEDBase) throw InitException() << "UEDF1F0H1Vertex::doinit() - The pointer to " << "the UEDBase object is null!" << Exception::runerror; theRadius = UEDBase->compactRadius(); theSinThetaW = sqrt(sin2ThetaW()); theCosThetaW = sqrt(1. - sin2ThetaW()); theMw = getParticleData(24)->mass(); theMz = getParticleData(23)->mass(); } void UEDF1F0H1Vertex::persistentOutput(PersistentOStream & os) const { os << ounit(theRadius,1/GeV) << ounit(theMw,GeV) << theSinThetaW << ounit(theMz, GeV) << theCosThetaW; } void UEDF1F0H1Vertex::persistentInput(PersistentIStream & is, int) { is >> iunit(theRadius,1/GeV) >> iunit(theMw,GeV) >> theSinThetaW >> iunit(theMz, GeV) >> theCosThetaW; } ClassDescription UEDF1F0H1Vertex::initUEDF1F0H1Vertex; // Definition of the static class description member. void UEDF1F0H1Vertex::Init() { static ClassDocumentation documentation ("The coupling involving a KK-Higgs and a pair of fermions."); } void UEDF1F0H1Vertex::setCoupling(Energy2 q2, tcPDPtr part1, tcPDPtr part2, tcPDPtr part3) { long anti(abs(part1->id())), ferm(abs(part2->id())), higgs(part3->id()); if( ferm > 17 ) swap( ferm, anti); if( anti != theAntiLast || ferm != theFermLast || higgs != theHLast ) { theAntiLast = anti; theFermLast = ferm; theHLast = higgs; tcPDPtr pd; if( higgs != 25 ) { pd = getParticleData(ferm); } else { long smid = ( ferm/1000000 == 5 ) ? ferm - 5100000 : ferm - 6100000; pd = getParticleData(smid); } Energy mf = pd->mass(); double alpha = mf*theRadius/2.; double salpha = sin(alpha); double calpha = cos(alpha); double fact(0.); if( abs(higgs) == 5100037 ) { fact = theRadius/2./sqrt(1. + sqr(theMw*theRadius)) * UnitRemoval::E; theRightLast = theRadius*theMw; if(anti/1000000 == 5) { Energy mfk = getParticleData(anti - 5100000)->mass(); theLeftLast = (theMw*calpha - (mfk*salpha/theRadius/theMw)) * UnitRemoval::InvE; theRightLast *= calpha*mfk* UnitRemoval::InvE; } else { Energy mfk = getParticleData(anti - 6100000)->mass(); theLeftLast = (theMw*salpha +(mfk*calpha/theRadius/theMw)) * UnitRemoval::InvE; theRightLast *= -salpha*mfk*UnitRemoval::InvE; } theLeftLast *= fact; theRightLast *= fact; if( higgs < 0 ) swap( theLeftLast, theRightLast ); } else if( higgs == 5100025 ) { fact = mf/theMw/2.; if( anti/1000000 == 5 ) theLeftLast = salpha + calpha; else theLeftLast = salpha - calpha; theRightLast = theLeftLast; theLeftLast *= fact; theRightLast *= fact; } else if( higgs == 5100036 ) { fact = theRadius/theCosThetaW/sqrt(1.+sqr(theMz*theRadius))*UnitRemoval::E; double i3f = ( ferm % 2 == 0 ) ? 0.5 : -0.5; double qf = pd->charge()/eplus; if( anti/1000000 == 5 ) { theLeftLast = (theMz*calpha*(i3f - qf*sqr(theSinThetaW)) - mf*salpha/theRadius/theMw) * UnitRemoval::InvE; theRightLast = (-theMz*salpha*qf*sqr(theSinThetaW) + mf*calpha/theRadius/theMw) * UnitRemoval::InvE; } else { theLeftLast = (theMz*salpha*(i3f - qf*sqr(theSinThetaW)) - mf*calpha/theRadius/theMw) * UnitRemoval::InvE; theRightLast = (-theMz*calpha*qf*sqr(theSinThetaW) + mf*salpha/theRadius/theMw)*UnitRemoval::InvE; } theLeftLast *= fact; theRightLast *= fact; } else { theLeftLast = mf*calpha*salpha/2./theMw; if( ferm/1000000 == 5 ) theLeftLast *= -1.; theRightLast = theLeftLast; } } if(q2 != theq2Last || theCoupLast == 0.) { theq2Last = q2; theCoupLast = weakCoupling(q2); } norm(theCoupLast); left(theLeftLast); right(theRightLast); } diff --git a/Sampling/exsample/binary_tree.h b/Sampling/exsample/binary_tree.h --- a/Sampling/exsample/binary_tree.h +++ b/Sampling/exsample/binary_tree.h @@ -1,883 +1,877 @@ // -*- C++ -*- // // binary_tree.h is part of ExSample -- A Library for Sampling Sudakov-Type Distributions // // Copyright (C) 2008-2017 Simon Platzer -- simon.plaetzer@desy.de, The Herwig Collaboration // // ExSample is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // #ifndef EXSAMPLE_binary_tree_h_included #define EXSAMPLE_binary_tree_h_included #include "utility.h" namespace exsample { /// \brief binary_tree represents a binary tree with the ability to /// `cascade' visitor objects down the tree template class binary_tree { public: ///@name type definitions //@{ /// define the object type typedef Value value_type; //@} public: ///@name constructors //@{ /// default constructor binary_tree() : neighbours_(), parent_(), value_(), children_() { } /// construct giving key/cell and parent binary_tree(const value_type& thevalue, binary_tree * theparent = 0) : neighbours_(), parent_(theparent), value_(new value_type(thevalue)), children_() { } /// binary_tree has a strict ownership; on copying /// binary trees ownership is transferred binary_tree(const binary_tree& x) : neighbours_(x.neighbours_), parent_(x.parent_), value_(), children_() { assert(x.root()); binary_tree& nc_x = const_cast(x); value_.swap(nc_x.value_); children_.first.swap(nc_x.children_.first); children_.second.swap(nc_x.children_.second); nc_x.parent_ = 0; nc_x.neighbours_.first = 0; nc_x.neighbours_.second = 0; } /// binary_tree has a strict ownership; on copying /// binary trees ownership is transferred binary_tree& operator=(const binary_tree& x) { if (this == &x) return *this; assert(x.root()); binary_tree& nc_x = const_cast(x); value_.swap(nc_x.value_); children_.first.swap(nc_x.children_.first); children_.second.swap(nc_x.children_.second); neighbours_ = x.neighbours_; parent_ = x.parent_; nc_x.parent_ = 0; nc_x.neighbours_.first = 0; nc_x.neighbours_.second = 0; return *this; } //@} ///@name standard-conforming leaf iterators //@{ public: class const_iterator; /// iterator class iterator { public: ///@name type definitions for iterator traits //@{ /// define the iterator category typedef std::bidirectional_iterator_tag iterator_category; /// define the difference_type typedef int difference_type; /// define the value type typedef Value value_type; /// define the reference type typedef value_type& reference; /// define the pointer type typedef value_type * pointer; //@} public: ///@name constructors //@{ /// default constructor iterator() : pointee(0), post_end(0), pre_begin(0) { } /// constructor taking pointee iterator(binary_tree * p, std::size_t end = 0) : pointee(p), post_end(end), pre_begin(0) { } //@ public: ///@name comparisons //@{ /// comparison bool operator==(const iterator& x) const { return ((pointee == x.pointee) && (post_end == x.post_end) && (pre_begin == x.pre_begin)); } /// comparison bool operator!=(const iterator& x) const { return !(*this == x); } //@} public: ///@name derefrence and indirection //@{ /// dereference reference operator*() { return pointee->value(); } /// indirection pointer operator->() { return &**this; } /// return reference to the node binary_tree& node() { return *pointee; } //@} /// return raw pointer to the element pointed to binary_tree * get() const { return pointee; } ///@name biderectional iterator increment/decrements //@{ /// pre-increment iterator& operator++() { if (post_end) { ++post_end; return *this; } if (pre_begin) { --pre_begin; return *this; } if(!(pointee->right_neighbour())) { post_end = 1; return *this; } pointee = pointee->right_neighbour(); return *this; } /// pre-decrement iterator& operator--() { if (post_end) { --post_end; return *this; } if (pre_begin) { ++pre_begin; return *this; } if(!(pointee->left_neighbour())) { pre_begin = 1; return *this; } pointee = pointee->left_neighbour(); return *this; } /// post-increment iterator operator++(int) { iterator tmp = *this; ++(*this); return tmp; } /// post-decrement iterator operator--(int) { iterator tmp = *this; --(*this); return tmp; } //@} private: /// friend for conversion friend class const_iterator; /// the node pointed to binary_tree * pointee; /// the distance from --end() (if above --end()) std::size_t post_end; /// the distance from begin() (if below begin()) std::size_t pre_begin; }; /// return begin iterator iterator begin() { return iterator(left_most()); } /// return end iterator iterator end() { return iterator(right_most(),1); } /// return global begin iterator iterator global_begin() { if (!root()) return parent().global_begin(); return iterator(left_most()); } /// return global end iterator iterator global_end() { if (!root()) return parent().global_end(); return iterator(right_most(),1); } /// const_iterator class const_iterator { public: ///@name type definitions for iterator traits //@{ /// define the iterator category typedef std::bidirectional_iterator_tag iterator_category; /// define the difference type typedef int difference_type; /// define the value type typedef const Value value_type; /// define the reference type typedef const value_type& reference; /// define the pointer type typedef const value_type * pointer; //@} public: ///@name constructors //@{ /// default constructor const_iterator() : pointee(0), post_end(0), pre_begin(0) { } /// constructor taking pointee const_iterator(const binary_tree * p, std::size_t end = 0) : pointee(p), post_end(end), pre_begin(0) { } /// conversion from iterator const_iterator(const iterator& x) : pointee(x.pointee), post_end(x.post_end), pre_begin(x.pre_begin) { } //@} public: ///@name comparisons //@{ /// comparison bool operator==(const const_iterator& x) const { return ((pointee == x.pointee) && (post_end == x.post_end) && (pre_begin == x.pre_begin)); } /// comparison bool operator!=(const const_iterator& x) const { return !(*this == x); } //@} public: ///@name dereference and indirection //@{ /// dereference reference operator*() const { return pointee->value(); } /// indirection pointer operator->() const { return &**this; } /// return reference to the node const binary_tree& node() const { return *pointee; } //@} ///@name biderectional iterator increment/decrements //@{ /// pre-increment const_iterator& operator++() { if (post_end) { ++post_end; return *this; } if (pre_begin) { --pre_begin; return *this; } if(!(pointee->right_neighbour())) { post_end = 1; return *this; } pointee = pointee->right_neighbour(); return *this; } /// pre-decrement const_iterator& operator--() { if (post_end) { --post_end; return *this; } if (pre_begin) { ++pre_begin; return *this; } if(!(pointee->left_neighbour())) { pre_begin = 1; return *this; } pointee = pointee->left_neighbour(); return *this; } /// post-increment const_iterator operator++(int) { const_iterator tmp = *this; ++(*this); return tmp; } /// post-decrement const_iterator operator--(int) { const_iterator tmp = *this; --(*this); return tmp; } //@} private: /// the node pointed to const binary_tree * pointee; /// the distance from --end() (if above --end()) std::size_t post_end; /// the distance from begin() (if below begin()) std::size_t pre_begin; }; /// return begin const_iterator const_iterator begin() const { return const_iterator(left_most()); } /// return end const_iterator const_iterator end() const { return const_iterator(right_most(),1); } /// return global begin iterator const_iterator global_begin() const { if (!root()) return parent().global_begin(); return iterator(left_most()); } /// return global end iterator const_iterator global_end() const { if (!root()) return parent().global_end(); return iterator(right_most(),1); } private: /// set the left neighbour void left_neighbour(binary_tree * n) { neighbours_.first = n; } /// set the right neighbour void right_neighbour(binary_tree * n) { neighbours_.second = n; } /// get the left neighbour binary_tree * left_neighbour() const { return neighbours_.first; } /// get the right neighbour binary_tree * right_neighbour() const { return neighbours_.second; } /// return the left-most leaf binary_tree * left_most() { if(leaf()) return this; return left_child().left_most(); } /// return the right-most leaf binary_tree * right_most() { if(leaf()) return this; return right_child().right_most(); } /// return the left-most leaf const binary_tree * left_most() const { if(leaf()) return this; return left_child().left_most(); } /// return the right-most leaf const binary_tree * right_most() const { if(leaf()) return this; return right_child().right_most(); } - /// the iterator is a good friend - friend class binary_tree::iterator; - - /// the iterator is a good friend - friend class binary_tree::const_iterator; - /// the left and right neighbours of this node std::pair neighbours_; //@} public: /// return true, if this node is empty bool empty() const { return root() && leaf() && !value_; } /// clear this node void clear() { neighbours_ = std::make_pair(0,0); parent_ = 0; value_.reset(0); if (!leaf()) { left_child().clear(); right_child().clear(); } children_.first.reset(0); children_.second.reset(0); } public: /// split this node std::pair split(std::pair children) { assert(leaf()); children_.first.reset(new binary_tree(children.first,this)); children_.second.reset(new binary_tree(children.second,this)); children_.first->left_neighbour(neighbours_.first); children_.first->right_neighbour(children_.second.get()); children_.second->left_neighbour(children_.first.get()); children_.second->right_neighbour(neighbours_.second); // adjust original neighbours if(neighbours_.first) { neighbours_.first->right_neighbour(children_.first.get()); } if (neighbours_.second) { neighbours_.second->left_neighbour(children_.second.get()); } neighbours_.first = 0; neighbours_.second = 0; return std::make_pair(iterator(children_.first.get()),iterator(children_.second.get())); } public: /// select using a selector template iterator select(const Selector& selector) { if(leaf()) { bool use = selector.use(value()); if (use) return iterator(this); return global_end(); } std::pair which(selector.use(value(),left_child().value(),right_child().value())); assert(!which.first || !which.second); if (!which.first && !which.second) { return global_end(); } if (which.first) { return left_child().select(selector); } else { return right_child().select(selector); } return global_end(); } /// generate a hash value for the sub-tree /// selected by the given selector object template void subtree_hash(const Selector& selector, bit_container& bhash) { bhash = bit_container(); unsigned long pos = 0; do_subtree_hash(selector,bhash,pos); } /// accumulate values using a binary function /// and accessor object template typename BinaryOp::result_type accumulate(const Accessor& acc, BinaryOp binary_op) const { if (!leaf()) { return binary_op(left_child().accumulate(acc,binary_op), right_child().accumulate(acc,binary_op)); } return acc.get(value(),true); } /// accumulate values only from branches /// matching a Selector template typename BinaryOp::result_type accumulate(const Selector& selector, const Accessor& acc, BinaryOp binary_op) const { if (!leaf()) { std::pair which(selector.use(value(),left_child().value(),right_child().value())); assert(which.first || which.second); if (which.first && which.second) { return binary_op(left_child().accumulate(selector,acc,binary_op), right_child().accumulate(selector,acc,binary_op)); } else if (which.first) { return left_child().accumulate(selector,acc,binary_op); } else if (which.second) { return right_child().accumulate(selector,acc,binary_op); } } return acc.get(value(),true); } /// accumulate values using a binary function /// and accessor object, storing intermediate /// values in nodes template typename BinaryOp::result_type tree_accumulate(const Accessor& acc, BinaryOp binary_op) { if (!leaf()) { acc.set(value()) = binary_op(left_child().tree_accumulate(acc,binary_op), right_child().tree_accumulate(acc,binary_op)); return acc.get(value(),false); } acc.set(value()) = acc.get(value(),true); return acc.get(value(),true); } /// accumulate values only from branches /// matching a Selector template typename BinaryOp::result_type tree_accumulate(const Selector& selector, const Accessor& acc, BinaryOp binary_op) { if (!leaf()) { std::pair which(selector.use(value(),left_child().value(),right_child().value())); assert(which.first || which.second); if (which.first && which.second) { acc.set(value()) = binary_op(left_child().tree_accumulate(selector,acc,binary_op), right_child().tree_accumulate(selector,acc,binary_op)); } else if (which.first) { acc.set(value()) = left_child().tree_accumulate(selector,acc,binary_op); } else if (which.second) { acc.set(value()) = right_child().tree_accumulate(selector,acc,binary_op); } return acc.get(value(),false); } acc.set(value()) = acc.get(value(),true); return acc.get(value(),true); } /// forward propagate a visitor to all children nodes template void cascade(Visitor visitor) const { if (leaf()) { visitor.visit(value()); return; } else visitor.visit(value(),left_child().value(),right_child().value()); left_child().cascade(visitor); right_child().cascade(visitor); } /// succesively split using a generator template void generate(Generator generator) { if (root()) value_.reset(new value_type(generator.root())); if (generator.split()) { std::pair ch = split(generator.generate(value())); ch.first.node().generate(generator); ch.second.node().generate(generator); } } public: ///@name Public member access //@{ /// return the value held by this node value_type& value() { return *value_; } /// return the value held by this node const value_type& value() const { return *value_; } /// return true, if this is the root node bool root() const { return !parent_; } /// return true, if this node has got children bool leaf() const { return !(children_.first.get() && children_.second.get()); } //@} public: ///@name put and get from streams //@{ /// forward visitor writing out the tree to given ostream template struct ostream_visitor { /// construct from ostream reference explicit ostream_visitor(OStream& os) : os_(&os), first_time_(true) {} /// visit a leaf node void visit(const value_type&) { (*os_) << "end_branch"; ostream_traits::separator(*os_); } /// visit a branching void visit(const value_type& parent, const value_type& left, const value_type& right) { if (first_time_) { (*os_) << "root_node"; ostream_traits::separator(*os_); parent.put(*os_); first_time_ = false; } (*os_) << "left_child"; ostream_traits::separator(*os_); left.put(*os_); (*os_) << "right_child"; ostream_traits::separator(*os_); right.put(*os_); } private: /// pointer to the ostream to write to OStream* os_; /// whether we are at the or not bool first_time_; }; /// generator reading binary tree from istream template struct istream_generator { /// construct from istream reference explicit istream_generator(IStream& is) : is_(&is), children_(), tag_("") {} /// copy constructor istream_generator(const istream_generator& x) : is_(x.is_), children_(), tag_("") {} /// read the root node value_type root() { *is_ >> tag_; assert(tag_ == "root_node"); value_type rnode; rnode.get(*is_); return rnode; } /// read children nodes bool split() { *is_ >> tag_; if (tag_ == "end_branch") { return false; } assert (tag_ == "left_child"); children_.first.get(*is_); *is_ >> tag_; assert(tag_ == "right_child"); children_.second.get(*is_); return true; } /// return the children generated std::pair generate(const value_type&) { return children_; } /// initialize a leaf void initialize_leaf(const value_type&) {} private: /// pointer to the istream used IStream* is_; /// the children currently handled std::pair children_; /// temporary storage for tags std::string tag_; }; /// put to ostream template void put(OStream& os) const { if (empty()) { os << "empty"; ostream_traits::separator(os); return; } else if (root() && leaf()) { os << "root_only"; ostream_traits::separator(os); value().put(os); return; } else { os << "non_empty"; ostream_traits::separator(os); } assert(root()); cascade(ostream_visitor(os)); } /// get from istream template void get(IStream& is) { std::string state; is >> state; if (state == "empty") { return; } if (state == "root_only") { value_.reset(new value_type()); value().get(is); return; } assert(empty()); generate(istream_generator(is)); } //@} private: /// calculate hash value template void do_subtree_hash(const Selector& selector, bit_container& current, unsigned long& position, bool selected = true) const { if (!leaf()) { std::pair which(false,false); if (selected) which = selector.use(value(),left_child().value(),right_child().value()); current.bit(position,which.first); current.bit(position+1,which.second); position += 2; left_child().do_subtree_hash(selector,current,position,which.first && selected); right_child().do_subtree_hash(selector,current,position,which.second && selected); } } private: ///@name private member access //@{ /// return the parent of this node binary_tree& parent() { assert(parent_); return *parent_; } /// return the parent of this node const binary_tree& parent() const { assert(parent_); return *parent_; } /// return the left child of this node binary_tree& left_child() { assert(children_.first.get()); return *children_.first; } /// return the left child of this node const binary_tree& left_child() const { assert(children_.first.get()); return *children_.first; } /// return the right child of this node binary_tree& right_child() { assert(children_.second.get()); return *children_.second; } /// return the right child of this node const binary_tree& right_child() const { assert(children_.second.get()); return *children_.second; } //@} private: /// the parent of this node binary_tree * parent_; /// the cell held by this node std::unique_ptr value_; /// the children of this node std::pair, std::unique_ptr > children_; }; } #endif // EXSAMPLE_binary_tree_h_included diff --git a/Shower/Core/Base/ShowerBasis.fh b/Shower/Core/Base/ShowerBasis.fh --- a/Shower/Core/Base/ShowerBasis.fh +++ b/Shower/Core/Base/ShowerBasis.fh @@ -1,21 +1,21 @@ // -*- C++ -*- // // This is the forward declaration of the ShowerBasis class. // #ifndef Herwig_ShowerBasis_FH #define Herwig_ShowerBasis_FH #include "ThePEG/Config/ThePEG.h" namespace Herwig { class ShowerBasis; } namespace ThePEG { ThePEG_DECLARE_POINTERS(Herwig::ShowerBasis,ShowerBasisPtr); } -#endif \ No newline at end of file +#endif diff --git a/Shower/Dipole/Merging/Merger.h b/Shower/Dipole/Merging/Merger.h --- a/Shower/Dipole/Merging/Merger.h +++ b/Shower/Dipole/Merging/Merger.h @@ -1,408 +1,408 @@ /// -*- C++ -*- // /// Merger.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_Merger_H #define HERWIG_Merger_H // /// This is the declaration of the Merger class. // #include "MergingFactory.fh" #include "Node.fh" #include "ThePEG/Handlers/HandlerBase.h" #include "Herwig/Shower/Dipole/DipoleShowerHandler.h" //#include "Herwig/Shower/Dipole/Base/DipoleSplittingGenerator.h" #include "Herwig/MatrixElement/Matchbox/Base/MergerBase.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.h" #include "ThePEG/Cuts/JetFinder.h" #include "ThePEG/Cuts/Cuts.h" namespace Herwig { using namespace ThePEG; class Merger; ThePEG_DECLARE_POINTERS(Merger , MergerPtr ); typedef vector NodePtrVec; //definition of a history step struct HistoryStep { /// containing the full information NodePtr node; /// current sudakov weight of the history double weight; /// current scale of the history Energy scale; }; typedef vector< HistoryStep > History; typedef multimap::ptr> GeneratorMap2; /** * \ingroup DipoleShower * \author Johannes Bellm * * \brief Merger handles the Merger ....... //TODO . * * @see \ref MergerInterfaces "The interfaces" * defined for Merger. */ class Merger: public MergerBase { friend class MergingFactory; friend class Node; public: // define the ME region for a particle vector. bool matrixElementRegion(PVector incoming, PVector outgoing, Energy winnerScale = ZERO, Energy cutscale = ZERO)const; /// return the current merging scale, /// gets smeared around the central merging scale in generate kinematics. Energy mergingScale()const{return theMergePt;} /// return the current merging pt (should be unified with mergingScale) Energy mergePt()const {return theMergePt;} /// legsize of highest process with NLO corrections int M()const; /// legsize of the highest LO merged process int N()const; /// legsize of the production process int N0()const{return theN0;} /// cross section of as given by the merging CrossSection MergingDSigDR(); /// ***** virtual functions of the base class ****/// /// set the current xcomb, called from ME void setXComb( tStdXCombPtr ); /// set kinematics, called from ME void setKinematics(); /// clear kinematics, called from ME void clearKinematics(); /// generate kinematics, called from ME bool generateKinematics( const double * ); /// generate kinematics, called from ME void flushCaches(); /// return the current maximum legs, the shower should veto size_t maxLegs() const {return theCurrentMaxLegs;} /// set the current ME void setME(MatchboxMEBasePtr me){ theCurrentME=me; assert(theFirstNodeMap.count(theCurrentME)); theCurrentNode=theFirstNodeMap[theCurrentME]; } /// allow emissions with a given probability.in the ME region double emissionProbability() const{ return theEmissionProbability; } /// set a probability of allowed emission into ME region. void setEmissionProbability(double x){theEmissionProbability=x;} protected: /// the merging factory needs to set the legsize of the production process void N0(int n){ theN0=n;} /// return the large-N basis (TODO: implement check if born ME works with the choice) Ptr::ptr largeNBasis()const{return theLargeNBasis;} /// smear the merging pt void smearMergePt(){ const double factor = 1. + (-1. + 2.*UseRandom::rnd() ) * smear(); theMergePt = factor * centralMergePt(); } /// true if the phase space for initial emissions should not be restricted in z. int openZBoundaries()const{return DSH()->showerPhaseSpaceOption();} /// return the current ME MatchboxMEBasePtr currentME() const { return theCurrentME; } /// return the current Node NodePtr currentNode() const { return theCurrentNode; } /// the gamma parameter to subtract dipoles above a alpha parameter /// and subtract the corresponding IPK operator double gamma()const{return theGamma;} private: /// calculate a single sudakov step for a given dipole double singlesudakov(Dipole, Energy, Energy, pair); /// calculate the sudakov supression for a clusternode between /// the current running scale and next scale bool dosudakov(NodePtr Born, Energy running, Energy next, double& sudakov0_n); /// cleanup void cleanup(NodePtr); /// return true if the cluster node has the matching number of /// legs to the current projector stage bool isProjectorStage( NodePtr , int )const; /** * Calculate the staring scale: * if Node is part of the production process, calculate according to the * scale choice object in the merging scale objekt, else * return max(scale as scalechoice , min(Mass(i, j))) */ Energy CKKW_StartScale(NodePtr) const; /// prepare the sudakov calculation void CKKW_PrepareSudakov(NodePtr, Energy); /// number of active flavours as given by the shower double Nf(Energy scale)const{return DSH()->Nf(scale);} /// pointer to the factory MergingFactoryPtr treefactory() const; /// map from ME to first clusternode map firstNodeMap() const ; /// set the current merging pt, smeared in generate kinematics void mergePt(Energy x) {theMergePt = x;} /// return the central merging pt Energy centralMergePt() const {return theCentralMergePt;} private: /// calculate the history weighted born cross section CrossSection MergingDSigDRBornStandard(); /** * calculate the history weighted born cross section * add the difference of IPK with and without alpha parameter * subtract the dipoles above the alpha parameter */ CrossSection MergingDSigDRBornGamma(); /// calculate the history weighted virtual contribution CrossSection MergingDSigDRVirtualStandard(); /** * calculate the history weighted real contribution * splitted into 3 differnt contibutions */ CrossSection MergingDSigDRRealStandard(); /// calculate the history weighted real contribution /// all dipoles above: /// N*(R rnd(i)-Dip_i) history_i U(\phi^n_i) CrossSection MergingDSigDRRealAllAbove(); /// calculate the history weighted real contribution /// not all dipoles above: /// (R - sum PS_i) history_rnd U(\phi^n+1) CrossSection MergingDSigDRRealBelowSubReal(); /// calculate the history weighted real contribution /// not all dipoles above: /// rnd(i)-> N*(PS_i - Dip_i) history_i U(\phi^n_i) CrossSection MergingDSigDRRealBelowSubInt(); /// max legssize the shower should veto for LO size_t maxLegsLO() const {return N0()+N();} /// Calculate the LO partonic cross section. /// if diffalpha != 1, add the difference of IPK(1)-IPK(diffalpha) CrossSection TreedSigDR(Energy startscale, double diffalpha=1.); /// fill the projecting xcomb Energy fillProjector(int); /// fill the history, including calculation of sudakov supression void fillHistory(Energy, NodePtr, NodePtr ); /// calculate the pdf ratio for the given clusternode double pdfratio(NodePtr, Energy, Energy, int, bool fromIsME, bool toIsME); /// return the pdf-ratio reweight for the history double pdfReweight(); /// return the alpha_s reweight for the history double alphaReweight(bool nocmw=false); /// max legssize the shower should veto for NLO size_t maxLegsNLO()const {return N0()+M();} /// calculate the virtual contribution. CrossSection LoopdSigDR(Energy startscale ); /// calculate alpha_s expansion of the pdf-ratios double sumPdfReweightExpansion()const; /// calculate alpha_s expansion of the alpha_s-ratios, including K_g double sumAlphaSReweightExpansion()const; /// calculate alpha_s expansion of the sudakov exponents double sumFillHistoryExpansion(); /// calculate alpha_s expansion of the single step alpha_s-ratio, including K_g double alphasExpansion( Energy next, Energy fixedScale)const; /// calculate alpha_s expansion of the single step pdf-ratio double pdfExpansion(NodePtr, int, Energy, Energy, double, int, Energy)const; /// calculate alpha_s expansion of the single step sudakov exponent bool doHistExpansion(NodePtr Born, Energy running, Energy next, Energy fixedScale, double& HistExpansion); /// calculate alpha_s expansion of the single dipole sudakov exponent double singleHistExpansion(Dipole, Energy, Energy, Energy, pair); //alpha_s as given in the shower double as(Energy q)const{return DSH()->as(q);} // set the pointer to the Mergingfactory. void setFactory(MergingFactoryPtr f){theTreeFactory=f;} // set the pointer to the DipoleShower. void setDipoleShower(DipoleShowerHandlerPtr dsh){theDipoleShowerHandler=dsh;} //return the dipole shower handler DipoleShowerHandlerPtr DSH(){return theDipoleShowerHandler;} //return the const dipole shower handler cDipoleShowerHandlerPtr DSH()const{return theDipoleShowerHandler;} /// insert map from ME to first clusternode void firstNodeMap(MatchboxMEBasePtr, NodePtr); /// history choice: weighted history choice int chooseHistory()const {return theChooseHistory;} /// the smearing factor for the merging scale double smear()const{return theSmearing;} /// return the large-N colour basis void largeNBasis(Ptr::ptr x){theLargeNBasis=x;} /// helper function to check the only multi condition. bool notOnlyMulti()const; /// Calculate the CMW AlphaS double cmwAlphaS(Energy q)const; /// debug output for virtual void debugVirt(double, double, double, double, CrossSection, double, double, double, NodePtr,CrossSection) const; /// debug output for reals void debugReal( string, double, CrossSection, CrossSection) const; private: /// calculate the history expansion unsigned int theShowerExpansionWeights = 2; /// use CMW scheme unsigned int theCMWScheme = 0; /// true if current point should be projected bool projected = true; /// true if LO cross sections should be unitarised bool isUnitarized = true; /// true if NLO contributions should be unitarised bool isNLOUnitarized = true; /// history weight choice int theChooseHistory = 0; /// legsize of production process int theN0 = 0; /// calculate only the N particle contribution int theOnlyN = -1; /// the current maxlegs (either LO or NLO maxlegs) - size_t theCurrentMaxLegs = -1; + int theCurrentMaxLegs = -1; /// current weight and weight of clustered born double weight = 1.0; double weightCB = 1.0; /// subtract the dipole contribution above a given gamma double theGamma = 1.0; /// smearing factor for merging scale double theSmearing = 0.; /** * Allow emissions for the unitarising LO contributions * according to the prob 1-min(B_n/sum Dip_n,Dip_n/B_n) */ bool emitDipoleMEDiff = false; /// The conditional emission probability if emitDipoleMEDiff is true. double theEmissionProbability = 0.; /// cutoff for real emission contribution Energy theIRSafePT = 1_GeV; /// current merging scale Energy theMergePt = 4_GeV; /// central merging scale Energy theCentralMergePt = 4_GeV; /// below mergingscale/theRealSubtractionRatio the dipoles are used to subtract. /// above the shower approximation is in use. double theRealSubtractionRatio=3.; /// current cluster histoy including sudakov weights History history; /// pointer to the large-N basis Ptr::ptr theLargeNBasis; /// current Node NodePtr theCurrentNode; /// current ME MatchboxMEBasePtr theCurrentME; /// Tilde kinematics pointers, only to use lastPt(emitter, emission, spectator) Ptr::ptr FFLTK = new_ptr( FFLightTildeKinematics() ); Ptr::ptr FILTK = new_ptr( FILightTildeKinematics() ); Ptr::ptr IFLTK = new_ptr( IFLightTildeKinematics() ); Ptr::ptr IILTK = new_ptr( IILightTildeKinematics() ); Ptr::ptr FFMTK = new_ptr( FFMassiveTildeKinematics() ); Ptr::ptr FIMTK = new_ptr( FIMassiveTildeKinematics() ); Ptr::ptr IFMTK = new_ptr( IFMassiveTildeKinematics() ); //pointer to the shower handler DipoleShowerHandlerPtr theDipoleShowerHandler; /// pointer to the MergingFactory MergingFactoryPtr theTreeFactory; /// map from ME to first Node map theFirstNodeMap; /// map from ME to highest ME weight so far map theHighMeWeightMap; 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(); //@} 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. */ Merger & operator=(const Merger &) = delete; }; } #endif /* HERWIG_Merger_H */ diff --git a/Shower/Dipole/Merging/MergingFactory.h b/Shower/Dipole/Merging/MergingFactory.h --- a/Shower/Dipole/Merging/MergingFactory.h +++ b/Shower/Dipole/Merging/MergingFactory.h @@ -1,168 +1,168 @@ /// -*- C++ -*- // /// MergingFactory.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_MergingFactory_H #define HERWIG_MergingFactory_H // /// This is the declaration of the MergingFactory class. // #include "MergingFactory.fh" #include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h" #include "Node.fh" #include "Merger.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Johannes Bellm * * \brief MergingFactory automatically sets up a NLO * QCD merging. * * @see \ref MergingFactoryInterfaces "The interfaces" * defined for MergeboxFactory. */ class MergingFactory : public MatchboxFactory { public: ///Check consistency and switch to porduction mode. void productionMode(); /// main method to setup the ME vector virtual void setup(); /// fill all amplitudes, stored in pureMEsMap void fillMEsMap(); /// prepare the Born and virtual matrix elements. void prepare_BV(int i); /// prepare the real emission matrix elements. void prepare_R(int i); /// push the born contributions to the ME vector. void pushB(MatchboxMEBasePtr, int); //push the virtual contributions to the ME vector. void pushV(MatchboxMEBasePtr, int); /// push the real contributions to the ME vector. void pushR(MatchboxMEBasePtr, int); /// order matrix elements from one loop provider. void orderOLPs(); /// Debugging: push only multiplicities to the ME vector /// in range of specified mulltiplicity. int onlymulti()const { - return theonlymulti==-1?-1:(theonlymulti+processMap.find(0)->second.size()); + return theonlymulti==-1?-1:(theonlymulti+int(processMap.find(0)->second.size())); } /// pointer to the merging helper. MergerPtr MH() {return theMergingHelper;} /// maximal NLO mulitplicity: 0=NLO corrections to the productio process. int M() const {return theM-1;} /// leg size of highest multiplicity. int N() const {return theN;} /// Return the Map of matrix elements to be considered /// (the Key is the number of additional jets) const map >& pureMEsMap() const { return thePureMEsMap; } /// Access the Map of matrix elements to be considered /// (the Key is the number of additional jets) map >& pureMEsMap() { return thePureMEsMap; } //Parse a process description virtual vector parseProcess(string); // fill the virtuals vector (these are IPK-operators) void getVirtuals(MatchboxMEBasePtr nlo, bool clone ); // In the merged setup we only produce single phase space points. bool subProcessGroups() const { return false;} // Cut on non-QCD observables. Ptr::ptr nonQCDCuts(){return theNonQCDCuts;} 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); //@} static void Init(); 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: /** @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; //@} private: /// unitarise the LO contributions. bool unitarized = true; /// did run setup. bool ransetup = false; /// Debugging: push only multiplicities to the ME vector /// in range of specified mulltiplicity. int theonlymulti = -1; /// maximal legsize for NLO corrections. int theM = -1; /// maximal legsize for LO contributions. int theN = -1; /// map for processes. map< int, vector > processMap; //The matrix elements: int = number of additional jets map< int, vector > thePureMEsMap; /// the merging helper MergerPtr theMergingHelper; /// Cut on non-QCD modified observables. Ptr::ptr theNonQCDCuts; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ MergingFactory & operator=(const MergingFactory &) = delete; }; } #endif /* HERWIG_MergingFactory_H */ diff --git a/Shower/QTilde/Base/FullShowerVeto.cc b/Shower/QTilde/Base/FullShowerVeto.cc --- a/Shower/QTilde/Base/FullShowerVeto.cc +++ b/Shower/QTilde/Base/FullShowerVeto.cc @@ -1,158 +1,158 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the FullShowerVeto class. // #include "FullShowerVeto.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "Herwig/Shower/ShowerHandler.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; void FullShowerVeto::persistentOutput(PersistentOStream & os) const { os << type_ << behaviour_; } void FullShowerVeto::persistentInput(PersistentIStream & is, int) { is >> type_ >> behaviour_; } void FullShowerVeto::doinit() { Interfaced::doinit(); // check reweighting if(behaviour_==1&&type_!=2) throw Exception() << "Reweighting in the FullShowerVeto is only" << " supported for the primary hard process\n" << Exception::runerror; } DescribeAbstractClass describeHerwigFullShowerVeto("Herwig::FullShowerVeto", "HwShower.so"); void FullShowerVeto::Init() { static ClassDocumentation documentation ("The FullShowerVeto class allows the parton shower generated from a configuration to be vetoed."); static Switch interfaceType ("Type", "Which type of processes to consider", &FullShowerVeto::type_, 1, false, false); static SwitchOption interfaceTypeAll (interfaceType, "All", "All Processes", 0); static SwitchOption interfaceTypeScattering (interfaceType, "Scattering", "Only apply to scattering processes and not decays", 1); static SwitchOption interfaceTypePrimary (interfaceType, "Primary", "Only apply to the primary scattering process", 2); static SwitchOption interfaceTypeDecay (interfaceType, "Decay", "Only apply to decays", 3); static Switch interfaceBehaviour ("Behaviour", "What to do if the shower if vetoed", &FullShowerVeto::behaviour_, 0, false, false); static SwitchOption interfaceBehaviourShower (interfaceBehaviour, "Shower", "Veto the shower and try showering the process again", 0); static SwitchOption interfaceBehaviourShowerReweight (interfaceBehaviour, "ShowerReweight", "Veto the shower and reweight the event to take this into account, only supported for the primary process", 1); static SwitchOption interfaceBehaviourEvent (interfaceBehaviour, "Event", "Veto the event, cross section automatically reweigted", 2); } int FullShowerVeto::applyVeto(ShowerTreePtr tree) { // return if veto should not be calculated // decay process and only doing hard processes // or vice versa if(((type_ == 1 || type_ ==2 ) && tree->isDecay() ) || ( type_ == 3 && tree->isHard())) return -1; // not primary process and only doing those if( type_ == 2 && !ShowerHandler::currentHandler()->firstInteraction() ) return -1; // extract the incoming and outgoing particles from the ShowerTree finalState_.clear(); incoming_.clear(); outgoing_.clear(); // incoming for(map::const_iterator it=tree->incomingLines().begin(); it!=tree->incomingLines().end();++it) { incoming_.push_back(it->first->progenitor()); } // outgoing for(map::const_iterator it=tree->outgoingLines().begin(); it!=tree->outgoingLines().end();++it) { outgoing_.push_back(it->first->progenitor()); } // call function in inheriting class to decide what to do bool vetoed = vetoShower(); // clear storage finalState_.clear(); incoming_.clear(); outgoing_.clear(); // return the answer - return vetoed ? behaviour_ : -1; + return vetoed ? int(behaviour_) : -1; } namespace { void addFinal(vector & finalState, tPPtr particle) { if(particle->children().empty()) { finalState.push_back(particle); return; } for(unsigned int ix=0;ixchildren().size();++ix) { addFinal(finalState,particle->children()[ix]); } } } // extract the incoming and outgoing particles const vector & FullShowerVeto::finalState() { if(!finalState_.empty()) return finalState_; // incoming for(unsigned int ix=0;ixparents().empty()) continue; tPPtr parent = incoming_[ix]->parents()[0]; while (parent) { addFinal(finalState_,parent->children()[1]); if(parent->parents().empty()) break; parent = parent->parents()[0]; } } // outgoing for(unsigned int ix=0;ixbranchingParticle(); } /** * find showering particle for progenitors */ tShowerParticlePtr SHOWERINGPARTICLE(ShowerProgenitorPtr a) { return a->progenitor(); } /** * Return colour line progenitor pointer for ShowerProgenitor */ template Ptr::transient_pointer CL(Value a, unsigned int index=0) { return const_ptr_cast(SHOWERINGPARTICLE(a)->colourInfo()->colourLines()[index]); } /** * Return progenitor colour line size for ShowerProgenitor */ template unsigned int CLSIZE(Value a) { return SHOWERINGPARTICLE(a)->colourInfo()->colourLines().size(); } /** * Return anti-colour line progenitor pointer for ShowerProgenitor */ template Ptr::transient_pointer ACL(Value a, unsigned int index=0) { return const_ptr_cast(SHOWERINGPARTICLE(a)->colourInfo()->antiColourLines()[index]); } /** * Return progenitor anti-colour line size for ShowerProgenitor */ template unsigned int ACLSIZE(Value a) { return SHOWERINGPARTICLE(a)->colourInfo()->antiColourLines().size(); } } template void QTildeReconstructor:: findPartners(Value jet,set & done, const set & jets, vector & system) const { tShowerParticlePtr part=SHOWERINGPARTICLE(jet); unsigned int partNumColourLines = part->colourInfo()-> colourLines().size(); unsigned int partNumAColourLines = part->colourInfo()->antiColourLines().size(); for(typename set::const_iterator cit=jets.begin();cit!=jets.end();++cit) { if(done.find(*cit)!=done.end()||!SHOWERINGPARTICLE(*cit)->coloured()) continue; bool isPartner = false; // one initial one final if(part->isFinalState()!=SHOWERINGPARTICLE(*cit)->isFinalState()) { //loop over all the colours of both for(unsigned int ix=0; ixcolourLine()) { for(unsigned int ix=0; ixantiColourLine()&&!isPartner) { for(unsigned int ix=0; ixcolourLine()) { if(part->colourLine()->sourceNeighbours().first) { tColinePair lines = part->colourLine()->sourceNeighbours(); if(lines.first == CL(*cit) || lines.first == ACL(*cit) || lines.second == CL(*cit) || lines.second == ACL(*cit) ) isPartner = true; } if(part->colourLine()->sinkNeighbours().first) { tColinePair lines = part->colourLine()->sinkNeighbours(); if(lines.first == CL(*cit) || lines.first == ACL(*cit) || lines.second == CL(*cit) || lines.second == ACL(*cit) ) isPartner = true; } } if(part->antiColourLine()) { if(part->antiColourLine()->sourceNeighbours().first) { tColinePair lines = part->antiColourLine()->sourceNeighbours(); if(lines.first == CL(*cit) || lines.first == ACL(*cit) || lines.second == CL(*cit) || lines.second == ACL(*cit) ) isPartner = true; } if(part->antiColourLine()->sinkNeighbours().first) { tColinePair lines = part->antiColourLine()->sinkNeighbours(); if(lines.first == CL(*cit) || lines.first == ACL(*cit) || lines.second == CL(*cit) || lines.second == ACL(*cit) ) isPartner = true; } } if(isPartner) { system.push_back(*cit); done.insert(*cit); findPartners(*cit,done,jets,system); } } } template typename Herwig::ColourSinglet::VecType QTildeReconstructor:: identifySystems(set jets, unsigned int & nnun,unsigned int & nnii,unsigned int & nnif, unsigned int & nnf ,unsigned int & nni ) const { vector > systems; set done; for(typename set::const_iterator it=jets.begin();it!=jets.end();++it) { // if not treated create new system if(done.find(*it)!=done.end()) continue; done.insert(*it); systems.push_back(ColourSinglet (UNDEFINED,*it)); if(!SHOWERINGPARTICLE(*it)->coloured()) continue; findPartners(*it,done,jets,systems.back().jets); } for(unsigned int ix=0;ixisFinalState()) ++nf; else ++ni; } // type // initial-initial if(ni==2&&nf==0) { systems[ix].type = II; ++nnii; } // initial only else if(ni==1&&nf==0) { systems[ix].type = I; ++nni; } // initial-final else if(ni==1&&nf>0) { systems[ix].type = IF; ++nnif; } // final only else if(ni==0&&nf>0) { systems[ix].type = F; ++nnf; } // otherwise unknown else { systems[ix].type = UNDEFINED; ++nnun; } } return systems; } template void QTildeReconstructor::combineFinalState(vector > & systems) const { // check that 1 particle final-state systems which can be combine bool canCombine(true); for(unsigned int ix=0;ix > oldsystems=systems; systems.clear(); ColourSinglet finalState; finalState.type = F; for(unsigned int ix=0;ix