diff --git a/Decay/Baryon/Baryon1MesonDecayerBase.cc b/Decay/Baryon/Baryon1MesonDecayerBase.cc --- a/Decay/Baryon/Baryon1MesonDecayerBase.cc +++ b/Decay/Baryon/Baryon1MesonDecayerBase.cc @@ -1,961 +1,961 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the Baryon1MesonDecayerBase class. // #include "Baryon1MesonDecayerBase.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/PDT/DecayMode.h" #include "Herwig/Utilities/Kinematics.h" #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h" #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h" #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h" #include "ThePEG/Helicity/WaveFunction/RSSpinorWaveFunction.h" #include "ThePEG/Helicity/WaveFunction/RSSpinorBarWaveFunction.h" #include "ThePEG/Helicity/LorentzPolarizationVector.h" #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h" #include "Herwig/Decay/TwoBodyDecayMatrixElement.h" #include "ThePEG/Helicity/HelicityFunctions.h" using namespace Herwig; using namespace ThePEG::Helicity; // The following static variable is needed for the type // description system in ThePEG. DescribeAbstractNoPIOClass describeHerwigBaryon1MesonDecayerBase("Herwig::Baryon1MesonDecayerBase", "HwBaryonDecay.so"); void Baryon1MesonDecayerBase::Init() { static ClassDocumentation documentation ("The Baryon1MesonDecayerBase class is the base class for" " the decays of the baryons to a baryon and a pseudoscalar or vector meson."); } void Baryon1MesonDecayerBase:: constructSpinInfo(const Particle & part, ParticleVector decay) const { // for the decaying particle if(part.id()>0) { // incoming particle if(part.dataPtr()->iSpin()==PDT::Spin1Half) { SpinorWaveFunction:: constructSpinInfo(_inHalf,const_ptr_cast(&part),incoming,true); } else if(part.dataPtr()->iSpin()==PDT::Spin3Half) { RSSpinorWaveFunction:: constructSpinInfo(_inThreeHalf,const_ptr_cast(&part),incoming,true); } else assert(false); // outgoing fermion if(decay[0]->dataPtr()->iSpin()==PDT::Spin1Half) { SpinorBarWaveFunction::constructSpinInfo(_inHalfBar,decay[0],outgoing,true); } else if(decay[0]->dataPtr()->iSpin()==PDT::Spin3Half) { RSSpinorBarWaveFunction::constructSpinInfo(_inThreeHalfBar, decay[0],outgoing,true); } else assert(false); } else { // incoming particle if(part.dataPtr()->iSpin()==PDT::Spin1Half) { SpinorBarWaveFunction:: constructSpinInfo(_inHalfBar,const_ptr_cast(&part),incoming,true); } else if(part.dataPtr()->iSpin()==PDT::Spin3Half) { RSSpinorBarWaveFunction:: constructSpinInfo(_inThreeHalfBar,const_ptr_cast(&part),incoming,true); } else assert(false); // outgoing fermion if(decay[0]->dataPtr()->iSpin()==PDT::Spin1Half) { SpinorWaveFunction::constructSpinInfo(_inHalf,decay[0],outgoing,true); } else if(decay[0]->dataPtr()->iSpin()==PDT::Spin3Half) { RSSpinorWaveFunction::constructSpinInfo(_inThreeHalf, decay[0],outgoing,true); } else assert(false); } // outgoing meson if(decay[1]->dataPtr()->iSpin()==PDT::Spin0) { ScalarWaveFunction::constructSpinInfo(decay[1],outgoing,true); } else if(decay[1]->dataPtr()->iSpin()==PDT::Spin1) { VectorWaveFunction::constructSpinInfo(_inVec,decay[1],outgoing,true, decay[1]->id()==ParticleID::gamma); } else assert(false); } // return the matrix element squared for a given mode and phase-space channel // (inherited from DecayIntegrator and implemented here) double Baryon1MesonDecayerBase::me2(const int ichan,const Particle & part, const tPDVector & outgoing, const vector & momenta, MEOption meopt) const { double me(0.); // decide which matrix element we are doing // incoming spin-1/2 particle if(part.dataPtr()->iSpin()==2) { // decay to spin-1/2 particle if(outgoing[0]->iSpin()==2) { // scalar meson if(outgoing[1]->iSpin()==1) me=halfHalfScalar(ichan,part,outgoing,momenta,meopt); // vector meson else if(outgoing[1]->iSpin()==3) me=halfHalfVector(ichan,part,outgoing,momenta,meopt); else throw DecayIntegratorError() << "Unknown outgoing meson spin in " << "Baryon1MesonDecayerBase::me2()" << Exception::abortnow; } // decay to spin-3/2 particle else if(outgoing[0]->iSpin()==4) { // scalar meson if(outgoing[1]->iSpin()==1) me=halfThreeHalfScalar(ichan,part,outgoing,momenta,meopt); // vector meson else if(outgoing[1]->iSpin()==3) me=halfThreeHalfVector(ichan,part,outgoing,momenta,meopt); else throw DecayIntegratorError() << "Unknown outgoing meson spin in " << "Baryon1MesonDecayerBase::me2()" << Exception::abortnow; } // unknown else throw DecayIntegratorError() << "Unknown outgoing baryon spin in " << "Baryon1MesonDecayerBase::me2()" << Exception::abortnow; } // incoming spin-3/2 particle else if(part.dataPtr()->iSpin()==4) { // decay to spin-1/2 particle if(outgoing[0]->iSpin()==2) { // scalar meson if(outgoing[1]->iSpin()==1) me=threeHalfHalfScalar(ichan,part,outgoing,momenta,meopt); // vector meson else if(outgoing[1]->iSpin()==3) me=threeHalfHalfVector(ichan,part,outgoing,momenta,meopt); else throw DecayIntegratorError() << "Unknown outgoing meson spin in " << "Baryon1MesonDecayerBase::me2()" << Exception::abortnow; } // decay to spin-3/2 particle else if(outgoing[0]->iSpin()==4) { // scalar meson if(outgoing[1]->iSpin()==1) me=threeHalfThreeHalfScalar(ichan,part,outgoing,momenta,meopt); else throw DecayIntegratorError() << "Unknown outgoing meson spin in " << "Baryon1MesonDecayerBase::me2()" << Exception::abortnow; } // unknown else throw DecayIntegratorError() << "Unknown outgoing baryon spin in " << "Baryon1MesonDecayerBase::me2()" << Exception::abortnow; } // unknown else throw DecayIntegratorError() << "Unknown incoming spin in " << "Baryon1MesonDecayerBase::me2()" << Exception::abortnow; return me; } // matrix element for the decay of a spin-1/2 fermion to a spin-1/2 fermion and // a pseudoscalar meson double Baryon1MesonDecayerBase:: halfHalfScalar(const int,const Particle & part, const tPDVector & outgoing, const vector & momenta, MEOption meopt) const { if(!ME()) ME(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin0))); // spinors etc for the decaying particle if(meopt==Initialize) { // spinors and rho if(part.id()>0) SpinorWaveFunction ::calculateWaveFunctions(_inHalf,_rho, const_ptr_cast(&part), incoming); else SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,_rho, const_ptr_cast(&part), incoming); // matrix element } // spinors for the decay product if(part.id()>0) { _inHalfBar.resize(2); for(unsigned int ix=0;ix<2;++ix) _inHalfBar[ix] = HelicityFunctions::dimensionedSpinorBar(-momenta[0],ix,Helicity::outgoing); } else { _inHalf.resize(2); for(unsigned int ix=0;ix<2;++ix) _inHalf[ix] = HelicityFunctions::dimensionedSpinor (-momenta[0],ix,Helicity::outgoing); } // get the couplings Complex A,B; halfHalfScalarCoupling(imode(),part.mass(),momenta[0].mass(),momenta[1].mass(),A,B); - Complex left,right,meout; + Complex left,right; // coupling for an incoming particle if(part.id()>0) { left = (A-B); right = (A+B); } // coupling for an incoming antiparticle else { left = conj(A+B); right = conj(A-B); } // calculate the matrix element vector ispin(3,0); unsigned int ix,iy; // Complex output(0.); for(ix=0;ix<2;++ix) { for(iy=0;iy<2;++iy) { if(outgoing[0]->id()>0){ispin[0]=iy;ispin[1]=ix;} else{ispin[0]=ix;ispin[1]=iy;} (*ME())(ispin)=Complex(_inHalf[iy].generalScalar(_inHalfBar[ix],left,right)/part.mass()); } } // test of the matrix element // Energy m1(part.mass()),m2(momenta[0].mass()),m3(momenta[1].mass()); // Energy Qp(sqrt(sqr(m1+m2)-sqr(m3))),Qm(sqrt(sqr(m1-m2)-sqr(m3))); // Complex h1(2.*Qp*A/part.mass()),h2(-2.*Qm*B/part.mass()); // cout << "testing 1/2->1/2 0 " // << 0.5*output << " " // << 0.25*(h1*conj(h1)+h2*conj(h2)) << " " // << 0.5*(h1*conj(h1)+h2*conj(h2))/output << endl; // cout << "testing alpha " << // (norm(0.5*(h1+h2))-norm(0.5*(h1-h2)))/ // (norm(0.5*(h1+h2))+norm(0.5*(h1-h2))) << "\n"; // store the matrix element return (ME()->contract(_rho)).real(); } // matrix element for the decay of a spin-1/2 fermion to a spin-1/2 fermion and // a vector meson double Baryon1MesonDecayerBase:: halfHalfVector(const int,const Particle & part, const tPDVector & outgoing, const vector & momenta, MEOption meopt) const { if(!ME()) ME(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1))); // check if the outgoing meson is really a photon bool photon=outgoing[1]->id()==ParticleID::gamma; // spinors etc for the decaying particle if(meopt==Initialize) { // spinors and rho if(part.id()>0) SpinorWaveFunction ::calculateWaveFunctions(_inHalf,_rho, const_ptr_cast(&part), incoming); else SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,_rho, const_ptr_cast(&part), incoming); // matrix element } // spinors for the decay product if(part.id()>0) { _inHalfBar.resize(2); for(unsigned int ix=0;ix<2;++ix) _inHalfBar[ix] = HelicityFunctions::dimensionedSpinorBar(-momenta[0],ix,Helicity::outgoing); } else { _inHalf.resize(2); for(unsigned int ix=0;ix<2;++ix) _inHalf[ix] = HelicityFunctions::dimensionedSpinor (-momenta[0],ix,Helicity::outgoing); } _inVec.resize(3); for(unsigned int ix=0;ix<3;++ix) { if(photon && ix==1) continue; _inVec[ix] = HelicityFunctions::polarizationVector(-momenta[1],ix,Helicity::outgoing); } // get the couplings Complex A1,A2,B1,B2; halfHalfVectorCoupling(imode(),part.mass(),momenta[0].mass(),momenta[1].mass(), A1,A2,B1,B2); Complex lS,rS,lV,rV; complex scalar; // couplings for an incoming particle if(part.id()>0) { lS = (A2-B2); rS = (A2+B2); lV = (A1-B1); rV = (A1+B1); } else { lS = -conj(A2+B2); rS = -conj(A2-B2); lV = conj(A1-B1); rV = conj(A1+B1); } // calculate the matrix element // decide which type of mode to do Energy msum(part.mass()+momenta[0].mass()); vector ispin(3); LorentzVector > svec; Complex prod; // Complex output(0.); unsigned int ix,iy; for(ix=0;ix<2;++ix) { for(iy=0;iy<2;++iy) { // scalar like piece scalar = _inHalf[iy].generalScalar(_inHalfBar[ix],lS,rS); // vector like piece svec = _inHalf[iy].generalCurrent(_inHalfBar[ix],lV,rV); if(outgoing[0]->id()>0) { ispin[0] = iy; ispin[1] = ix; } else { ispin[0] = ix; ispin[1] = iy; } for(ispin[2]=0;ispin[2]<3;++ispin[2]) { ispin[2]=ispin[2]; prod=_inVec[ispin[2]].dot(part.momentum())/msum; (*ME())(ispin)=(svec.dot(_inVec[ispin[2]])+prod*scalar)/part.mass(); // output += norm((*ME())(ispin)); } } } // test of the matrix element // Energy m1(part.mass()),m2(momenta[0].mass()),m3(momenta[1].mass()); // Energy Qp(sqrt(sqr(m1+m2)-sqr(m3))),Qm(sqrt(sqr(m1-m2)-sqr(m3))); // double r2(sqrt(2.)); // Energy pcm(Kinematics::pstarTwoBodyDecay(m1,m2,m3)); // if(m3!=ZERO) { // Complex h1(2.*r2*Qp*B1/part.mass()),h2(-2.*r2*Qm*A1/part.mass()), // h3(2./m3*(Qp*(m1-m2)*B1-Qm*m1*B2*pcm/(m1+m2))/part.mass()), // h4(2./m3*(Qm*(m1+m2)*A1+Qp*m1*A2*pcm/(m1+m2))/part.mass()); // generator()->log() << "testing 1/2->1/2 1 " // << 0.5*output << " " // << 0.25*(h1*conj(h1)+h2*conj(h2)+h3*conj(h3)+h4*conj(h4)) << " " // << 0.50*(h1*conj(h1)+h2*conj(h2)+h3*conj(h3)+h4*conj(h4))/output // << "\n"; // generator()->log() << "alpha = " << 2.*(norm(h3)+norm(h4))/(norm(h1)+norm(h2))-1. // << "\n"; // generator()->log() << "masses " << m1/GeV << " " << m2/GeV << " " << m3/GeV << "\n"; // } // return the answer return (ME()->contract(_rho)).real(); } // matrix element for the decay of a spin-1/2 fermion to a spin-3/2 fermion and // a scalar meson double Baryon1MesonDecayerBase:: halfThreeHalfScalar(const int,const Particle & part, const tPDVector & outgoing, const vector & momenta, MEOption meopt) const { if(!ME()) ME(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin3Half,PDT::Spin0))); // spinors etc for the decaying particle if(meopt==Initialize) { // spinors and rho if(part.id()>0) SpinorWaveFunction ::calculateWaveFunctions(_inHalf,_rho, const_ptr_cast(&part), incoming); else SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,_rho, const_ptr_cast(&part), incoming); // matrix element } // spinors for the decay product LorentzPolarizationVector in=UnitRemoval::InvE*part.momentum(); if(part.id()>0) { RSSpinorBarWaveFunction swave(momenta[0],outgoing[0],Helicity::outgoing); _inThreeHalfBar.resize(4); _inHalfBar.resize(4); for(unsigned int ihel=0;ihel<4;++ihel) { swave.reset(ihel); _inThreeHalfBar[ihel]=swave.dimensionedWf(); _inHalfBar[ihel] = _inThreeHalfBar[ihel].dot(in); } } else { RSSpinorWaveFunction swave(momenta[0],outgoing[0],Helicity::outgoing); _inThreeHalf.resize(4); _inHalf.resize(4); for(unsigned int ihel=0;ihel<4;++ihel) { swave.reset(ihel); _inThreeHalf[ihel]=swave.dimensionedWf(); _inHalf[ihel] = _inThreeHalf[ihel].dot(in); } } // get the couplings Complex A,B,left,right; Energy msum(part.mass()+momenta[0].mass()); halfThreeHalfScalarCoupling(imode(),part.mass(),momenta[0].mass(),momenta[1].mass(), A,B); // incoming particle if(part.id()>0) { left=(A-B); right=(A+B); } // incoming anti-particle else { left=conj(A+B); right=conj(A-B); } vector ispin(3,0); for(unsigned ixa=0;ixa<2;++ixa) { for(unsigned int iya=0;iya<4;++iya) { unsigned int ix(iya),iy(ixa); if(outgoing[0]->id()<0) swap(ix,iy); ispin[0]=ixa; ispin[1]=iya; complex value = _inHalf[iy].generalScalar(_inHalfBar[ix],left,right) *UnitRemoval::E/part.mass()/msum; (*ME())(ispin) = value; } } double output = (ME()->contract(_rho)).real(); // test of the matrix element // Energy m1(part.mass()),m2(momenta[0].mass()),m3(momenta[1].mass()); // Energy Qp(sqrt(sqr(m1+m2)-sqr(m3))),Qm(sqrt(sqr(m1-m2)-sqr(m3))); // double r23(sqrt(2./3.)); // Energy pcm(Kinematics::pstarTwoBodyDecay(m1,m2,m3)); // complex h1(-2.*r23*pcm*m1/m2*Qm*B/(m1+m2)),h2( 2.*r23*pcm*m1/m2*Qp*A/(m1+m2)); // cout << "testing 1/2->3/2 0 " << part.id() << " " // << output << " " // << 0.25*(h1*conj(h1)+h2*conj(h2))/sqr(part.mass()) << " " // << 0.25*(h1*conj(h1)+h2*conj(h2))/sqr(part.mass())/output << endl; // return the answer return output; } // matrix element for the decay of a spin-1/2 fermion to a spin-3/2 fermion and // a vector meson double Baryon1MesonDecayerBase:: halfThreeHalfVector(const int,const Particle & part, const tPDVector & outgoing, const vector & momenta, MEOption meopt) const { if(!ME()) ME(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin3Half,PDT::Spin1))); // check if the outgoing meson is really a photon bool photon=outgoing[1]->id()==ParticleID::gamma; // spinors etc for the decaying particle if(meopt==Initialize) { // spinors and rho if(part.id()>0) SpinorWaveFunction ::calculateWaveFunctions(_inHalf,_rho, const_ptr_cast(&part), incoming); else SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,_rho, const_ptr_cast(&part), incoming); // matrix element } LorentzPolarizationVector in=UnitRemoval::InvE*part.momentum(); // wavefunctions for outgoing fermion if(part.id()>0) { RSSpinorBarWaveFunction swave(momenta[0],outgoing[0],Helicity::outgoing); _inThreeHalfBar.resize(4); _inHalfBar.resize(4); for(unsigned int ihel=0;ihel<4;++ihel) { swave.reset(ihel); _inThreeHalfBar[ihel]=swave.dimensionedWf(); _inHalfBar[ihel] = _inThreeHalfBar[ihel].dot(in); } } else { RSSpinorWaveFunction swave(momenta[0],outgoing[0],Helicity::outgoing); _inThreeHalf.resize(4); _inHalf.resize(4); for(unsigned int ihel=0;ihel<4;++ihel) { swave.reset(ihel); _inThreeHalf[ihel]=swave.dimensionedWf(); _inHalf[ihel] = _inThreeHalf[ihel].dot(in); } } ME()->zero(); _inVec.resize(3); for(unsigned int ix=0;ix<3;++ix) { if(photon && ix==1) continue; _inVec[ix] = HelicityFunctions::polarizationVector(-momenta[1],ix,Helicity::outgoing); } // get the couplings Complex A1,A2,A3,B1,B2,B3; halfThreeHalfVectorCoupling(imode(),part.mass(),momenta[0].mass(),momenta[1].mass(), A1,A2,A3,B1,B2,B3); Energy msum(part.mass()+momenta[0].mass()); Complex lS,rS,lV,rV,left,right; // incoming particle if(part.id()>0) { lS=(A3-B3);rS=(A3+B3); lV=(A2-B2);rV=(A2+B2); left=(A1-B1);right=(A1+B1); } // incoming anti-particle else { lS=conj(A3+B3);rS=conj(A3-B3); lV=-conj(A2-B2);rV=-conj(A2+B2); left=conj(A1+B1);right=conj(A1-B1); } // compute the matrix element vector ispin(3); LorentzVector > svec; Complex prod; complex scalar; LorentzSpinor stemp; LorentzSpinorBar sbtemp; for(unsigned iya=0;iya<4;++iya) { ispin[1]=iya; // piece where the vector-spinor is dotted with the momentum of the // incoming fermion for(unsigned ixa=0;ixa<2;++ixa) { unsigned int ix(iya),iy(ixa); if(outgoing[0]->id()<0) swap(ix,iy); scalar = _inHalf[iy].generalScalar (_inHalfBar[ix],lS,rS); svec = _inHalf[iy].generalCurrent(_inHalfBar[ix],lV,rV); ispin[0]=ixa; for(unsigned int iz=0;iz<3;++iz) { ispin[2]=iz; prod=_inVec[iz].dot(part.momentum())/msum; (*ME())(ispin) += (svec.dot(_inVec[iz])+prod*scalar)* UnitRemoval::E/msum/part.mass(); } } // the piece where the vector spinor is dotted with the polarization vector for(unsigned int iz=0;iz<3;++iz) { ispin[2]=iz; if(outgoing[0]->id()>0) sbtemp = _inThreeHalfBar[iya].dot(_inVec[iz]); else stemp = _inThreeHalf[iya].dot(_inVec[iz]); for(unsigned int ixa=0;ixa<2;++ixa) { ispin[0]=ixa; if(outgoing[0]->id()>0) stemp = _inHalf[ixa]; else (*ME())(ispin) += Complex(stemp.generalScalar(sbtemp,left,right)/part.mass()); } } } double output = (ME()->contract(_rho)).real(); // test of the matrix element // Energy m1(part.mass()),m2(momenta[0].mass()),m3(momenta[1].mass()); // Energy2 m12(m1*m1),m22(m2*m2),m32(m3*m3); // Energy Qp(sqrt(sqr(m1+m2)-sqr(m3))),Qm(sqrt(sqr(m1-m2)-sqr(m3))); // double r2(sqrt(2.)),r3(sqrt(3.)); // Energy pcm(Kinematics::pstarTwoBodyDecay(m1,m2,m3)); // complex h1(-2.*Qp*A1),h2(2.*Qm*B1); // complex h3(-2./r3*Qp*(A1-Qm*Qm/m2*A2/msum)); // complex h4( 2./r3*Qm*(B1-Qp*Qp/m2*B2/msum)); // complex h5(-2.*r2/r3/m2/m3*Qp*(0.5*(m12-m22-m32)*A1+0.5*Qm*Qm*(m1+m2)*A2/msum // +m12*pcm*pcm*A3/msum/msum)); // complex h6( 2.*r2/r3/m2/m3*Qm*(0.5*(m12-m22-m32)*B1-0.5*Qp*Qp*(m1-m2)*B2/msum // +m12*pcm*pcm*B3/msum/msum)); // cout << "testing 1/2->3/2 1 " << part.id() << " " // << output << " " // << 0.25*(h1*conj(h1)+h2*conj(h2)+h3*conj(h3)+ // h4*conj(h4)+h5*conj(h5)+h6*conj(h6))/sqr(part.mass()) << " " // << 0.25*(h1*conj(h1)+h2*conj(h2)+h3*conj(h3)+ // h4*conj(h4)+h5*conj(h5)+h6*conj(h6))/sqr(part.mass())/output << endl; // return the answer return output; } // matrix element for the decay of a spin-3/2 fermion to a spin-1/2 fermion and // a scalar meson double Baryon1MesonDecayerBase:: threeHalfHalfScalar(const int,const Particle & part, const tPDVector & outgoing, const vector & momenta, MEOption meopt) const { if(!ME()) ME(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin3Half,PDT::Spin1Half,PDT::Spin0))); // spinors etc for the decaying particle if(meopt==Initialize) { // spinors and rho if(part.id()>0) { RSSpinorWaveFunction ::calculateWaveFunctions(_inThreeHalf,_rho, const_ptr_cast(&part), incoming); } else { RSSpinorBarWaveFunction::calculateWaveFunctions(_inThreeHalfBar,_rho, const_ptr_cast(&part), incoming); } } // spinors for the decay product if(part.id()>0) { _inHalfBar.resize(2); for(unsigned int ix=0;ix<2;++ix) _inHalfBar[ix] = HelicityFunctions::dimensionedSpinorBar(-momenta[0],ix,Helicity::outgoing); } else { _inHalf.resize(2); for(unsigned int ix=0;ix<2;++ix) _inHalf[ix] = HelicityFunctions::dimensionedSpinor (-momenta[0],ix,Helicity::outgoing); } LorentzPolarizationVector out=UnitRemoval::InvE*momenta[0]; if(part.id()>0) { _inHalf.resize(_inThreeHalf.size()); for(unsigned int ix=0;ix<_inThreeHalf.size();++ix) _inHalf[ix] = _inThreeHalf[ix].dot(out); } else { _inHalfBar.resize(_inThreeHalfBar.size()); for(unsigned int ix=0;ix<_inThreeHalfBar.size();++ix) _inHalfBar[ix] = _inThreeHalfBar[ix].dot(out); } // get the couplings Complex A,B; Energy msum=part.mass()+momenta[0].mass(); threeHalfHalfScalarCoupling(imode(),part.mass(),momenta[0].mass(),momenta[1].mass(), A,B); Complex left,right; // incoming particle if(part.id()>0) { left=(A-B); right=(A+B); } // incoming anti-particle else { left=conj(A+B); right=conj(A-B); } // compute the matrix element vector ispin(3,0); for(unsigned ixa=0;ixa<2;++ixa) { for(unsigned iya=0;iya<4;++iya) { unsigned int iy=iya,ix=ixa; if(outgoing[0]->id()<0) swap(ix,iy); ispin[0]=iya; ispin[1]=ixa; (*ME())(ispin) = Complex(_inHalf[iy].generalScalar(_inHalfBar[ix],left,right)* UnitRemoval::E/msum/part.mass()); } } double output = (ME()->contract(_rho)).real(); // test of the matrix element // Energy m1(part.mass()),m2(momenta[0].mass()),m3(momenta[1].mass()); // Energy Qp(sqrt(sqr(m1+m2)-sqr(m3))),Qm(sqrt(sqr(m1-m2)-sqr(m3))); // double r23(sqrt(2./3.)); // Energy pcm(Kinematics::pstarTwoBodyDecay(m1,m2,m3)); // complex h1(-2.*r23*pcm*Qm*B/(m1+m2)),h2( 2.*r23*pcm*Qp*A/(m1+m2)); // generator()->log() << "testing 3/2->1/2 0 " << part.id() << " " // << output << " " // << 0.125*(h1*conj(h1)+h2*conj(h2))/sqr(part.mass()) << " " // << 0.125*(h1*conj(h1)+h2*conj(h2))/sqr(part.mass())/output << endl; // return the answer return output; } // matrix element for the decay of a spin-3/2 fermion to a spin-3/2 fermion and // a scalar meson double Baryon1MesonDecayerBase::threeHalfThreeHalfScalar(const int, const Particle & part, const tPDVector & outgoing, const vector & momenta, MEOption meopt) const { if(!ME()) ME(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin3Half,PDT::Spin3Half,PDT::Spin0))); // spinors etc for the decaying particle if(meopt==Initialize) { // spinors and rho if(part.id()>0) { RSSpinorWaveFunction ::calculateWaveFunctions(_inThreeHalf,_rho, const_ptr_cast(&part), incoming); } else { RSSpinorBarWaveFunction::calculateWaveFunctions(_inThreeHalfBar,_rho, const_ptr_cast(&part), incoming); } // matrix element } // spinors for the decay product // wavefunctions for outgoing fermion if(part.id()>0) { RSSpinorBarWaveFunction swave(momenta[0],outgoing[0],Helicity::outgoing); _inThreeHalfBar.resize(4); for(unsigned int ihel=0;ihel<4;++ihel) { swave.reset(ihel); _inThreeHalfBar[ihel]=swave.dimensionedWf(); } } else { RSSpinorWaveFunction swave(momenta[0],outgoing[0],Helicity::outgoing); _inThreeHalf.resize(4); for(unsigned int ihel=0;ihel<4;++ihel) { swave.reset(ihel); _inThreeHalf[ihel]=swave.dimensionedWf(); } } LorentzPolarizationVector in = UnitRemoval::InvE*part.momentum(); _inHalf.resize(_inThreeHalf.size()); _inHalfBar.resize(_inThreeHalfBar.size()); for(unsigned int ix=0;ix<_inThreeHalf.size();++ix) { _inHalf[ix] = _inThreeHalf[ix].dot(in); _inHalfBar[ix] = _inThreeHalfBar[ix].dot(in); } // get the couplings Complex A1,B1,A2,B2; Energy msum(part.mass()+momenta[0].mass()); threeHalfThreeHalfScalarCoupling(imode(),part.mass(),momenta[0].mass(), momenta[1].mass(),A1,A2,B1,B2); Complex left1,right1,left2,right2; // incoming particle if(part.id()>0) { left1=(A1-B1); right1=(A1+B1); left2=(A2-B2); right2=(A2+B2); } // incoming anti-particle else { left1=(A1+B1); right1=(A1-B1); left2=(A2+B2); right2=(A2-B2); } // compute the matrix element vector ispin(3,0); for(unsigned ixa=0;ixa<4;++ixa) { for(unsigned iya=0;iya<4;++iya) { unsigned int iy=iya,ix=ixa; if(outgoing[0]->id()<0) swap(ix,iy); ispin[0]=iya; ispin[1]=ixa; (*ME())(ispin)=Complex((_inThreeHalf[iy].generalScalar(_inThreeHalfBar[ix],left1,right1) +_inHalf[iy].generalScalar( _inHalfBar[ix],left2,right2) *UnitRemoval::E2/sqr(msum))/part.mass()); } } // return the answer return (ME()->contract(_rho)).real(); } // matrix element for the decay of a spin-3/2 fermion to a spin-1/2 fermion and // a vector meson double Baryon1MesonDecayerBase:: threeHalfHalfVector(const int,const Particle & part, const tPDVector & outgoing, const vector & momenta, MEOption meopt) const { if(!ME()) ME(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin3Half,PDT::Spin1Half,PDT::Spin1))); // check if the outgoing meson is really a photon bool photon=outgoing[1]->id()==ParticleID::gamma; // spinors etc for the decaying particle if(meopt==Initialize) { // spinors and rho if(part.id()>0) { RSSpinorWaveFunction ::calculateWaveFunctions(_inThreeHalf,_rho, const_ptr_cast(&part), incoming); } else { RSSpinorBarWaveFunction::calculateWaveFunctions(_inThreeHalfBar,_rho, const_ptr_cast(&part), incoming); } } if(part.id()>0) { _inHalfBar.resize(2); for(unsigned int ix=0;ix<2;++ix) _inHalfBar[ix] = HelicityFunctions::dimensionedSpinorBar(-momenta[0],ix,Helicity::outgoing); } else { _inHalf.resize(2); for(unsigned int ix=0;ix<2;++ix) _inHalf[ix] = HelicityFunctions::dimensionedSpinor (-momenta[0],ix,Helicity::outgoing); } LorentzPolarizationVector out=UnitRemoval::InvE*momenta[0]; if(part.id()>0) { _inHalf.resize(_inThreeHalf.size()); for(unsigned int ix=0;ix<_inThreeHalf.size();++ix) _inHalf[ix] = _inThreeHalf[ix].dot(out); } else { _inHalfBar.resize(_inThreeHalfBar.size()); for(unsigned int ix=0;ix<_inThreeHalfBar.size();++ix) _inHalfBar[ix] = _inThreeHalfBar[ix].dot(out); } // wavefunctions for outgoing fermion ME()->zero(); _inVec.resize(3); for(unsigned int ix=0;ix<3;++ix) { if(photon && ix==1) continue; _inVec[ix] = HelicityFunctions::polarizationVector(-momenta[1],ix,Helicity::outgoing); } // get the couplings - Complex A1,A2,A3,B1,B2,B3,prod,meout; + Complex A1,A2,A3,B1,B2,B3,prod; threeHalfHalfVectorCoupling(imode(),part.mass(),momenta[0].mass(),momenta[1].mass(), A1,A2,A3,B1,B2,B3); Energy msum(part.mass()+momenta[0].mass()); Complex lS,rS,lV,rV,left,right; // incoming particle if(part.id()>0) { lS=(A3-B3);rS=(A3+B3); lV=(A2-B2);rV=(A2+B2); left=(A1-B1);right=(A1+B1); } // incoming anti-particle else { lS=conj(A3+B3);rS=conj(A3-B3); lV=-conj(A2-B2);rV=-conj(A2+B2); left=conj(A1+B1);right=conj(A1-B1); } // compute the matrix element vector ispin(3); LorentzVector > svec; LorentzSpinor stemp; LorentzSpinorBar sbtemp; complex scalar; for(unsigned iya=0;iya<4;++iya) { ispin[0]=iya; for(unsigned ixa=0;ixa<2;++ixa) { unsigned int iy=iya,ix=ixa; if(outgoing[0]->id()<0) swap(ix,iy); scalar = _inHalf[iy].generalScalar( _inHalfBar[ix],lS,rS); svec = _inHalf[iy].generalCurrent(_inHalfBar[ix],lV,rV); ispin[1]=ixa; for(unsigned int iz=0;iz<3;++iz) { ispin[2]=iz; prod=_inVec[iz].dot(momenta[0])/msum; (*ME())(ispin) += (svec.dot(_inVec[iz])+prod*scalar)* UnitRemoval::E/msum/part.mass(); } } // the piece where the vector spinor is dotted with the polarization vector for(unsigned iz=0;iz<3;++iz) { ispin[2]=iz; if(outgoing[0]->id()>0) stemp = _inThreeHalf[iya].dot(_inVec[iz]); else sbtemp = _inThreeHalfBar[iya].dot(_inVec[iz]); for(unsigned int ixa=0;ixa<2;++ixa) { ispin[1]=ixa; if(outgoing[0]->id()>0) sbtemp = _inHalfBar[ixa]; else stemp = _inHalf[ixa]; (*ME())(ispin) += Complex(stemp.generalScalar(sbtemp,left,right)/part.mass()); } } } double output = (ME()->contract(_rho)).real(); // testing code // Energy m1(part.mass()),m2(momenta[0].mass()),m3(momenta[1].mass()); // Energy2 m12(m1*m1),m22(m2*m2),m32(m3*m3); // Energy Qp(sqrt(sqr(m1+m2)-sqr(m3))),Qm(sqrt(sqr(m1-m2)-sqr(m3))); // double r2(sqrt(2.)),r3(sqrt(3.)); // Energy pcm(Kinematics::pstarTwoBodyDecay(m1,m2,m3)); // complex h1(-2.*Qp*A1),h2(2.*Qm*B1); // complex h3(-2./r3*Qp*(A1-Qm*Qm/m1*A2/msum)); // complex h4( 2./r3*Qm*(B1-Qp*Qp/m1*B2/msum)); // complex h5(ZERO),h6(ZERO); // if(m3!=ZERO) { // h5 = (-2.*r2/r3/m1/m3*Qp*(0.5*(m22-m12-m32)*A1+0.5*Qm*Qm*(m1+m2)*A2/msum // +m12*pcm*pcm*A3/msum/msum)); // h6 = ( 2.*r2/r3/m1/m3*Qm*(0.5*(m22-m12-m32)*B1-0.5*Qp*Qp*(m2-m1)*B2/msum // +m22*pcm*pcm*B3/msum/msum)); // } // cout << "testing 3/2->1/2 1 " << part.id() << " " // << output << " " // << 0.25*(h1*conj(h1)+h2*conj(h2)+h3*conj(h3)+ // h4*conj(h4)+h5*conj(h5)+h6*conj(h6))/sqr(part.mass()) << " " // << 0.25*(h1*conj(h1)+h2*conj(h2)+h3*conj(h3)+ // h4*conj(h4)+h5*conj(h5)+h6*conj(h6))/sqr(part.mass())/output << endl; // return the answer return output; } void Baryon1MesonDecayerBase::halfHalfScalarCoupling(int,Energy,Energy,Energy, Complex&,Complex&) const { throw DecayIntegratorError() << "Baryon1MesonDecayerBase::halfHalfScalarCoupling()" << " called from base class this must be implemented" << " in the inheriting class" << Exception::abortnow; } void Baryon1MesonDecayerBase::halfHalfVectorCoupling(int,Energy,Energy,Energy, Complex&,Complex&, Complex&,Complex&) const { throw DecayIntegratorError() << "Baryon1MesonDecayerBase::halfHalfVectorCoupling()" << " called from base class this must be implemented " << "in the inheriting class" << Exception::abortnow; } void Baryon1MesonDecayerBase::halfThreeHalfScalarCoupling(int,Energy,Energy,Energy, Complex&,Complex&) const { throw DecayIntegratorError() << "Baryon1MesonDecayerBase::halfThreeHalfScalarCoupling" << "() called from base class this must be implemented" << " in the inheriting class" << Exception::abortnow; } void Baryon1MesonDecayerBase::halfThreeHalfVectorCoupling(int,Energy,Energy,Energy, Complex&,Complex&, Complex&,Complex&, Complex&,Complex&) const { throw DecayIntegratorError() << "Baryon1MesonDecayerBase::halfThreeHalfVectorCoupling" << "() called from base class this must be implemented " << "in the inheriting class" << Exception::abortnow; } void Baryon1MesonDecayerBase::threeHalfHalfScalarCoupling(int,Energy,Energy,Energy, Complex&,Complex&) const { throw DecayIntegratorError() << "Baryon1MesonDecayerBase::threeHalfHalfScalarCoupling" << "() called from base class this must be implemented" << " in the inheriting class" << Exception::abortnow; } void Baryon1MesonDecayerBase::threeHalfHalfVectorCoupling(int,Energy,Energy,Energy, Complex&,Complex&, Complex&,Complex&, Complex&,Complex&) const { throw DecayIntegratorError() << "Baryon1MesonDecayerBase::threeHalfHalfVectorCoupling" << "() called from base class this must be implemented " << "in the inheriting class" << Exception::abortnow; } void Baryon1MesonDecayerBase::threeHalfThreeHalfScalarCoupling(int,Energy,Energy, Energy,Complex&, Complex&,Complex&, Complex&) const { throw DecayIntegratorError() << "Baryon1MesonDecayerBase::threeHalfThreeHalfScalar" << "Coupling() called from base class this must be " << "implemented in the inheriting class" << Exception::abortnow; } bool Baryon1MesonDecayerBase::twoBodyMEcode(const DecayMode & dm,int & mecode, double & coupling) const { coupling=1.; unsigned int inspin(dm.parent()->iSpin()),outspin,outmes; ParticleMSet::const_iterator pit(dm.products().begin()); bool order; if((**pit).iSpin()%2==0) { order=true; outspin=(**pit).iSpin(); ++pit;outmes=(**pit).iSpin(); } else { order=false; outmes=(**pit).iSpin();++pit; outspin=(**pit).iSpin(); } mecode=-1; if(inspin==2) { if(outspin==2){if(outmes==1){mecode=101;}else{mecode=102;}} else if(outspin==4){if(outmes==1){mecode=103;}else{mecode=104;}} } else if(inspin==4) { if(outspin==2){if(outmes==1){mecode=105;}else{mecode=106;}} else if(outspin==4){if(outmes==1){mecode=107;}else{mecode=108;}} } return order; } void Baryon1MesonDecayerBase::dataBaseOutput(ofstream & os,bool header) const { DecayIntegrator::dataBaseOutput(os,header); } diff --git a/Decay/FormFactors/ChengHeavyBaryonFormFactor.cc b/Decay/FormFactors/ChengHeavyBaryonFormFactor.cc --- a/Decay/FormFactors/ChengHeavyBaryonFormFactor.cc +++ b/Decay/FormFactors/ChengHeavyBaryonFormFactor.cc @@ -1,443 +1,443 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the ChengHeavyBaryonFormFactor class. // #include "ChengHeavyBaryonFormFactor.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/ParVector.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; using namespace ThePEG; ChengHeavyBaryonFormFactor::ChengHeavyBaryonFormFactor() { // consituent quark masses _mu = 338*MeV; _md = 322*MeV; _ms = 510*MeV; _mc = 1.6*GeV; _mb = 5.0*GeV; // masses for the q^2 dependence _mVbc = 6.34*GeV; _mVbs = 5.42*GeV; _mVcs = 2.11*GeV; _mVbd = 5.32*GeV; _mVcu = 2.01*GeV; _mAbc = 6.73*GeV; _mAbs = 5.86*GeV; _mAcs = 2.54*GeV; _mAbd = 5.71*GeV; _mAcu = 2.42*GeV; double one3(1./sqrt(3.)),one2(1./sqrt(2.)); // lambda_b to lambda_c addFormFactor(5122,4122,2,2,1,2,5,4);_Nfi.push_back(1. );_eta.push_back(1.); // lambda_b to lambda addFormFactor(5122,3122,2,2,1,2,5,3);_Nfi.push_back(one3 );_eta.push_back(1.); // lambda_b to n addFormFactor(5122,2112,2,2,1,2,5,1);_Nfi.push_back(one2 );_eta.push_back(1.); // xi_b to xi_c addFormFactor(5232,4232,2,2,2,3,5,4);_Nfi.push_back(1. );_eta.push_back(1.); addFormFactor(5132,4132,2,2,1,3,5,4);_Nfi.push_back(1. );_eta.push_back(1.); // xi_b to xi addFormFactor(5232,3322,2,2,2,3,5,3);_Nfi.push_back(one2 );_eta.push_back(1.); addFormFactor(5132,3312,2,2,1,3,5,3);_Nfi.push_back(one2 );_eta.push_back(1.); // xi_b to sigma addFormFactor(5232,3212,2,2,2,3,5,1);_Nfi.push_back(0.5 );_eta.push_back(1.); addFormFactor(5132,3112,2,2,1,3,5,1);_Nfi.push_back(0.5 );_eta.push_back(1.); // xi_b to lambda addFormFactor(5232,3122,2,2,2,3,5,1);_Nfi.push_back(one3/2.);_eta.push_back(1.); // omega_b to omega_c addFormFactor(5332,4332,2,2,3,3,5,4);_Nfi.push_back(1. );_eta.push_back(-1./3.); // omega_b to xi addFormFactor(5332,3312,2,2,3,3,5,1);_Nfi.push_back(one3 );_eta.push_back(-1./3.); // omega_b to omega_c* addFormFactor(5332,4334,2,4,3,3,5,4);_Nfi.push_back(1. );_eta.push_back(0.); // omega_b to omega addFormFactor(5332,3334,2,4,3,3,5,3);_Nfi.push_back(1. );_eta.push_back(0.); // omega_b to xi* addFormFactor(5332,3314,2,4,3,3,5,1);_Nfi.push_back(one3 );_eta.push_back(0.); // omega_c to omega addFormFactor(4332,3334,2,4,3,3,4,3);_Nfi.push_back(1. );_eta.push_back(0.); // omega_c to xi* addFormFactor(4332,3324,2,4,3,3,4,2);_Nfi.push_back(one3 );_eta.push_back(0.); // lambda_c to lambda_0 addFormFactor(4122,3122,2,2,1,2,4,3);_Nfi.push_back(1./sqrt(3.));_eta.push_back(1.); // xi_c to xi addFormFactor(4232,3322,2,2,2,3,4,3);_Nfi.push_back(1./sqrt(3.));_eta.push_back(1.); addFormFactor(4132,3312,2,2,1,3,4,3);_Nfi.push_back(1./sqrt(3.));_eta.push_back(1.); // initial number of form factors initialModes(numberOfFactors()); } void ChengHeavyBaryonFormFactor::doinit() { BaryonFormFactor::doinit(); // check the parameters are consistent unsigned int isize(numberOfFactors()); if(isize!=_eta.size()||isize!=_Nfi.size()) {throw InitException() << "Inconsistent paramters in ChengHeavyBaryon" << "FormFactor::doinit() " << Exception::abortnow;} Energy mi,mf,mq,mQ,lambda,delta,msum; int id0,id1,inspin,outspin,isp1,isp2,inq,outq; for(unsigned int ix=0;ixmass(); mf=getParticleData(id1)->mass(); msum=mi+mf; // masses of the incoming and outgoing quarks if((id0==4122&&id1==3122)||(id0==4232&&id1==3322)||(id0==4132&&id1==3312)|| (id0==4332&&id1==3334)) {mq=_ms;mQ=_mc;} else if((id0==4332&&id1==3322)||(id0==4332&&id1==3324)) {mq=_mu;mQ=_mc;} else if((id0==5122&&id1==4122)||(id0==5232&&id1==4232)||(id0==5132&&id1==4132)|| (id0==5332&&id1==4332)||(id0==5332&&id1==4334)) {mq=_mc;mQ=_mb;} else if((id0==5122&&id1==3122)||(id0==5132&&id1==3312)||(id0==5232&&id1==3322)|| (id0==5332&&id1==3334)) {mq=_ms;mQ=_mb;} else if((id0==5122&&id1==2112)||(id0==5132&&id1==3112)||(id0==5232&&id1==3212)|| (id0==5332&&id1==3312)||(id0==5232&&id1==3122)||(id0==5332&&id1==3314)) {mq=_md;mQ=_mb;} else {throw InitException() << "Unknown decay in ChengHeavyBaryon" << "FormFactor::doinit() " << Exception::abortnow;} // parameters lambda = mf-mq; delta = mi-mf; // compute the form-factors if(inspin==2&&outspin==2) { _f1.push_back(_Nfi[ix]*(1.-0.5*delta/mi +0.25*delta/mi/mq*(1.-0.5*lambda/mf)* (mi+mf-_eta[ix]*delta) -0.125*delta/mi/mf/mQ*lambda*(mi+mf+_eta[ix]*delta))); _f2.push_back(_Nfi[ix]*msum*(0.5/mi+0.25/mi/mq*(1.-0.5*lambda/mf)* (delta-(mi+mf)*_eta[ix]) -0.125*lambda/mi/mf/mQ*(delta+(mi+mf)*_eta[ix]))); _f3.push_back(_Nfi[ix]*msum*(0.5/mi-0.25/mi/mq*(1.-0.5*lambda/mf)* (mi+mf-_eta[ix]*delta) +0.125*lambda/mi/mf/mQ*(mi+mf+_eta[ix]*delta))); _g1.push_back(_Nfi[ix]*_eta[ix]*(1.+0.25*delta*lambda*(1./mi/mq-1./mf/mQ))); _g2.push_back(-0.25*msum*_Nfi[ix]*_eta[ix]*lambda*(1./mi/mq-1./mf/mQ)); _g3.push_back(-0.25*msum*_Nfi[ix]*_eta[ix]*lambda*(1./mi/mq+1./mf/mQ)); } else if(inspin==2&&outspin==4) { _f1.push_back(2.*_Nfi[ix]/sqrt(3.)*(1.+0.5*lambda*(1./mq+1./mQ))); _f2.push_back(_Nfi[ix]*msum/sqrt(3.)/mi*(1.+0.5*lambda*(1./mq+1./mQ))); _f3.push_back(-_Nfi[ix]*msum*msum/mi/mf/sqrt(3.)* (1.+0.5*lambda*(1./mq+1./mQ))); _g1.push_back(-2./sqrt(3.)*_Nfi[ix]); _g2.push_back(-_Nfi[ix]*msum/sqrt(3.)*lambda/mq/mi); _g3.push_back(-_f3.back()); } else {throw InitException() << "Unknown spin combination in ChengHeavyBaryon" << "FormFactor::doinit() " << Exception::abortnow;} } for(unsigned int ix=0;ixmass(); tcPDPtr part1=getParticleData(id1); Energy m1=part1->mass(); if ( part1->iSpin() == 2 ) { - Complex f1v,f2v,f3v,f4v,f1a,f2a,f3a,f4a; // dummy variables + Complex f1v,f2v,f3v,f1a,f2a,f3a; // dummy variables SpinHalfSpinHalfFormFactor(ZERO,ix,id0,id1,m0,m1,f1v,f2v,f3v,f1a,f2a,f3a,FlavourInfo()); } else { Complex f1v,f2v,f3v,f4v,f1a,f2a,f3a,f4a; // dummy variables SpinHalfSpinThreeHalfFormFactor(ZERO,ix,id0,id1,m0,m1,f1v,f2v,f3v, f4v,f1a,f2a,f3a,f4a,FlavourInfo()); } } } void ChengHeavyBaryonFormFactor::persistentOutput(PersistentOStream & os) const { os << ounit(_mu,MeV) << ounit(_md,MeV) << ounit(_ms,MeV) << ounit(_mc,MeV) << ounit(_mb,MeV) << _Nfi << _eta << _f1 << _f2 << _f3 << _g1 << _g2 << _g3 << ounit(_mVbc,MeV) << ounit(_mVbs,MeV) << ounit(_mVcs,MeV) << ounit(_mVbd,MeV) << ounit(_mVcu,MeV) << ounit(_mAbc,MeV) << ounit(_mAbs,MeV) << ounit(_mAcs,MeV) << ounit(_mAbd,MeV) << ounit(_mAcu,MeV); } void ChengHeavyBaryonFormFactor::persistentInput(PersistentIStream & is, int) { is >> iunit(_mu,MeV) >> iunit(_md,MeV) >> iunit(_ms,MeV) >> iunit(_mc,MeV) >> iunit(_mb,MeV) >> _Nfi >> _eta >> _f1 >> _f2 >> _f3 >> _g1 >> _g2 >> _g3 >> iunit(_mVbc,MeV) >> iunit(_mVbs,MeV) >> iunit(_mVcs,MeV) >> iunit(_mVbd,MeV) >> iunit(_mVcu,MeV) >> iunit(_mAbc,MeV) >> iunit(_mAbs,MeV) >> iunit(_mAcs,MeV) >> iunit(_mAbd,MeV) >> iunit(_mAcu,MeV); } // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeHerwigChengHeavyBaryonFormFactor("Herwig::ChengHeavyBaryonFormFactor", "HwFormFactors.so"); void ChengHeavyBaryonFormFactor::Init() { static ClassDocumentation documentation ("The ChengHeavyBaryonFormFactor class is the implementation" " of the form-factors of PRD53, 1457 and PRD56, 2799 for the weak decay of" "baryons containing a heavy quark. This model can be used for either" "semi-leptonic decays, or with the factorization approximation for" " non-leptonic weak decays", "The weak decay of baryons containing a heavy quark used form factors from " "\\cite{Cheng:1995fe,Cheng:1996cs}.", "%\\cite{Cheng:1995fe}\n" "\\bibitem{Cheng:1995fe}\n" " H.~Y.~Cheng and B.~Tseng,\n" " %``1/M corrections to baryonic form-factors in the quark model,''\n" " Phys.\\ Rev.\\ D {\\bf 53} (1996) 1457\n" " [Erratum-ibid.\\ D {\\bf 55} (1997) 1697]\n" " [arXiv:hep-ph/9502391].\n" " %%CITATION = PHRVA,D53,1457;%%\n" "%\\cite{Cheng:1996cs}\n" "\\bibitem{Cheng:1996cs}\n" " H.~Y.~Cheng,\n" " %``Nonleptonic weak decays of bottom baryons,''\n" " Phys.\\ Rev.\\ D {\\bf 56} (1997) 2799\n" " [arXiv:hep-ph/9612223].\n" " %%CITATION = PHRVA,D56,2799;%%\n" ); static Parameter interfaceUpMass ("DownMass", "The consituent mass of the down quark", &ChengHeavyBaryonFormFactor::_md, GeV, 0.322*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter interfaceDownMass ("UpMass", "The consituent mass of the up quark", &ChengHeavyBaryonFormFactor::_mu, GeV, 0.338*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter interfacStrangeMass ("StrangeMass", "The consituent mass of the strange quark", &ChengHeavyBaryonFormFactor::_ms, GeV, 0.510*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter interfaceCharmMass ("CharmMass", "The consituent mass of the charm quark", &ChengHeavyBaryonFormFactor::_mc, GeV, 1.6*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter interfaceBottomMass ("BottomMass", "The consituent mass of the bottom quark", &ChengHeavyBaryonFormFactor::_mb, GeV, 5.0*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter interfaceVectorMassbc ("VectorMassbc", "The vector mass for the b->c transitions.", &ChengHeavyBaryonFormFactor::_mVbc, GeV, 6.34*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter interfaceAxialMassbc ("AxialMassbc", "The axial-vector mass for the b->c transitions.", &ChengHeavyBaryonFormFactor::_mAbc, GeV, 6.73*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter interfaceVectorMassbs ("VectorMassbs", "The vector mass for the b->s transitions.", &ChengHeavyBaryonFormFactor::_mVbs, GeV, 5.42*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter interfaceAxialMassbs ("AxialMassbs", "The axial-vector mass for the b->s transitions.", &ChengHeavyBaryonFormFactor::_mAbs, GeV, 5.86*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter interfaceVectorMassbd ("VectorMassbd", "The vector mass for the b->d transitions.", &ChengHeavyBaryonFormFactor::_mVbd, GeV, 5.32*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter interfaceAxialMassbd ("AxialMassbd", "The axial-vector mass for the b->d transitions.", &ChengHeavyBaryonFormFactor::_mAbd, GeV, 5.71*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter interfaceVectorMasscs ("VectorMasscs", "The vector mass for the c->s transitions.", &ChengHeavyBaryonFormFactor::_mVcs, GeV, 2.11*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter interfaceAxialMasscs ("AxialMasscs", "The axial-vector mass for the c->s transitions.", &ChengHeavyBaryonFormFactor::_mAcs, GeV, 2.54*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter interfaceVectorMasscu ("VectorMasscu", "The vector mass for the c->u transitions.", &ChengHeavyBaryonFormFactor::_mVcu, GeV, 2.01*GeV, ZERO, 10.0*GeV, false, false, true); static Parameter interfaceAxialMasscu ("AxialMasscu", "The axial-vector mass for the c->u transitions.", &ChengHeavyBaryonFormFactor::_mAcu, GeV, 2.42*GeV, ZERO, 10.0*GeV, false, false, true); static ParVector interfaceNfi ("Nfi", "The prefactor for a given form factor", &ChengHeavyBaryonFormFactor::_Nfi, -1, 1.0, -10.0, 10.0, false, false, true); static ParVector interfaceEta ("Eta", "The eta parameter for the form factor", &ChengHeavyBaryonFormFactor::_eta, -1, 0.0, -10.0, 10.0, false, false, true); } // form factor for spin-1/2 to spin-1/2 void ChengHeavyBaryonFormFactor:: SpinHalfSpinHalfFormFactor(Energy2 q2,int iloc,int id0,int id1, Energy m0,Energy m1, Complex & f1v,Complex & f2v,Complex & f3v, Complex & f1a,Complex & f2a,Complex & f3a, FlavourInfo , Virtuality virt) { assert(virt==SpaceLike); useMe(); id0=abs(id0); id1=abs(id1); // masses for the energy dependence of the form-factors Energy mV(ZERO),mA(ZERO); if((id0==4122&&id1==3122)||(id0==4232&&id1==3322)||(id0==4132&&id1==3312)|| (id0==4332&&id1==3334)) {mA=_mAcs;mV=_mVcs;} else if((id0==4332&&id1==3322)||(id0==4332&&id1==3324)) {mA=_mAcu;mV=_mVcu;} else if((id0==5122&&id1==4122)||(id0==5232&&id1==4232)||(id0==5132&&id1==4132)|| (id0==5332&&id1==4332)||(id0==5332&&id1==4334)) {mA=_mAbc;mV=_mVbc;} else if((id0==5122&&id1==3122)||(id0==5132&&id1==3312)||(id0==5232&&id1==3322)|| (id0==5332&&id1==3334)) {mA=_mAbs;mV=_mVbs;} else if((id0==5122&&id1==2112)||(id0==5132&&id1==3112)||(id0==5232&&id1==3212)|| (id0==5332&&id1==3312)||(id0==5232&&id1==3122)||(id0==5332&&id1==3314)) {mA=_mAbd;mV=_mVbd;} Energy delta=m0-m1; double Vfact = (1.-delta*delta/mV/mV)/(1.-q2/mV/mV); Vfact *=Vfact; double Afact = (1.-delta*delta/mA/mA)/(1.-q2/mA/mA); Afact *=Afact; f1v = _f1[iloc]*Vfact; f2v = _f2[iloc]*Vfact; f3v = _f3[iloc]*Vfact; f1a =-_g1[iloc]*Afact; f2a =-_g2[iloc]*Afact; f3a =-_g3[iloc]*Afact; } // form factor for spin-1/2 to spin-3/2 void ChengHeavyBaryonFormFactor:: SpinHalfSpinThreeHalfFormFactor(Energy2 q2,int iloc, int id0, int id1, Energy m0, Energy m1, Complex & g1v,Complex & g2v,Complex & g3v, Complex & g4v,Complex & g1a,Complex & g2a, Complex & g3a,Complex & g4a, FlavourInfo , Virtuality virt) { assert(virt==SpaceLike); useMe(); id0=abs(id0); id1=abs(id1); // masses for the energy dependence of the form-factors Energy mV(ZERO),mA(ZERO); if((id0==4122&&id1==3122)||(id0==4232&&id1==3322)||(id0==4132&&id1==3312)|| (id0==4332&&id1==3334)) {mA=_mAcs;mV=_mVcs;} else if((id0==4332&&id1==3322)||(id0==4332&&id1==3324)) {mA=_mAcu;mV=_mVcu;} else if((id0==5122&&id1==4122)||(id0==5232&&id1==4232)||(id0==5132&&id1==4132)|| (id0==5332&&id1==4332)||(id0==5332&&id1==4334)) {mA=_mAbc;mV=_mVbc;} else if((id0==5122&&id1==3122)||(id0==5132&&id1==3312)||(id0==5232&&id1==3322)|| (id0==5332&&id1==3334)) {mA=_mAbs;mV=_mVbs;} else if((id0==5122&&id1==2112)||(id0==5132&&id1==3112)||(id0==5232&&id1==3212)|| (id0==5332&&id1==3312)||(id0==5232&&id1==3122)||(id0==5332&&id1==3314)) {mA=_mAbd;mV=_mVbd;} Energy delta=m0-m1; double Vfact = (1.-delta*delta/mV/mV)/(1.-q2/mV/mV); Vfact *=Vfact; double Afact = (1.-delta*delta/mA/mA)/(1.-q2/mA/mA); Afact *=Afact; g1v = _f1[iloc]*Vfact; g2v = _f2[iloc]*Vfact; g3v = _f3[iloc]*Vfact; g4v = 0.; g1a =-_g1[iloc]*Afact; g2a =-_g2[iloc]*Afact; g3a =-_g3[iloc]*Afact; g4a = 0.; } // output the information for the database void ChengHeavyBaryonFormFactor::dataBaseOutput(ofstream& output,bool header, bool create) const { if(header){output << "update decayers set parameters=\"";} if(create) {output << "create Herwig::ChengHeavyBaryonFormFactor " << name() << " \n";} output << "newdef " << name() << ":DownMass " << _md/GeV << " \n"; output << "newdef " << name() << ":UpMass " << _mu/GeV << " \n"; output << "newdef " << name() << ":StrangeMass " << _ms/GeV << " \n"; output << "newdef " << name() << ":CharmMass " << _mc/GeV << " \n"; output << "newdef " << name() << ":BottomMass " << _mb/GeV << " \n"; output << "newdef " << name() << ":VectorMassbc " << _mVbc/GeV << " \n"; output << "newdef " << name() << ":AxialMassbc " << _mAbc/GeV << " \n"; output << "newdef " << name() << ":VectorMassbs " << _mVbs/GeV << " \n"; output << "newdef " << name() << ":AxialMassbs " << _mAbs/GeV << " \n"; output << "newdef " << name() << ":VectorMassbd " << _mVbd/GeV << " \n"; output << "newdef " << name() << ":AxialMassbd " << _mAbd/GeV << " \n"; output << "newdef " << name() << ":VectorMasscs " << _mVcs/GeV << " \n"; output << "newdef " << name() << ":AxialMasscs " << _mAcs/GeV << " \n"; output << "newdef " << name() << ":VectorMasscu " << _mVcu/GeV << " \n"; output << "newdef " << name() << ":AxialMasscu " << _mAcu/GeV << " \n"; for(unsigned int ix=0;ix describeHerwigSMHiggsGGHiggsPPDecayer("Herwig::SMHiggsGGHiggsPPDecayer", "HwPerturbativeHiggsDecay.so"); bool SMHiggsGGHiggsPPDecayer::accept(tcPDPtr parent, const tPDVector & children) const { int idp = parent->id(); int id0 = children[0]->id(); int id1 = children[1]->id(); if((idp == ParticleID::h0 && id0 == ParticleID::g && id1 == ParticleID::g) || (idp == ParticleID::h0 && id0 == ParticleID::gamma && id1 == ParticleID::gamma)|| (idp == ParticleID::h0 && id0 == ParticleID::Z0 && id1 == ParticleID::gamma)|| (idp == ParticleID::h0 && id0 == ParticleID::gamma && id1 == ParticleID::Z0)) return true; else return false; } ParticleVector SMHiggsGGHiggsPPDecayer::decay(const Particle & parent, const tPDVector & children) const { int imode(2); if(children[0]->id() == ParticleID::gamma && children[1]->id() == ParticleID::gamma) imode = 1; else if(children[0]->id() ==ParticleID::g) imode = 0; ParticleVector out(generate(true,false,imode,parent)); //colour flow if(children[0]->id() == ParticleID::g && children[1]->id() == ParticleID::g) { out[0]->colourNeighbour(out[1]); out[0]->antiColourNeighbour(out[1]); } return out; } void SMHiggsGGHiggsPPDecayer::persistentOutput(PersistentOStream & os) const { os << _hggvertex << _hppvertex << _hzpvertex << _h0wgt << _minloop << _maxloop << _massopt; } void SMHiggsGGHiggsPPDecayer::persistentInput(PersistentIStream & is, int) { is >> _hggvertex >> _hppvertex >> _hzpvertex >> _h0wgt >> _minloop >> _maxloop >> _massopt; } void SMHiggsGGHiggsPPDecayer::Init() { static ClassDocumentation documentation ("This is an implentation of h0->gg or h0->gamma,gamma " "decayer using the SMHGGVertex."); static Reference interfaceSMHGGVertex ("SMHGGVertex", "Pointer to SMHGGVertex", &SMHiggsGGHiggsPPDecayer::_hggvertex, false, false, true, false, false); static Reference interfaceSMHPPVertex ("SMHPPVertex", "Pointer to SMHPPVertex", &SMHiggsGGHiggsPPDecayer::_hppvertex, false, false, true, false, false); static Reference interfaceSMHZPVertex ("SMHZPVertex", "Pointer to SMHZPVertex", &SMHiggsGGHiggsPPDecayer::_hzpvertex, false, false, true, false, false); static ParVector interfaceMaxWeights ("MaxWeights", "Maximum weights for the various decays", &SMHiggsGGHiggsPPDecayer::_h0wgt, 3, 1.0, 0.0, 10.0, false, false, Interface::limited); static Parameter interfaceMinimumInLoop ("MinimumInLoop", "The minimum flavour of the quarks to include in the loops", &SMHiggsGGHiggsPPDecayer::_minloop, 6, 4, 6, false, false, Interface::limited); static Parameter interfaceMaximumInLoop ("MaximumInLoop", "The maximum flavour of the quarks to include in the loops", &SMHiggsGGHiggsPPDecayer::_maxloop, 6, 4, 6, false, false, Interface::limited); static Switch interfaceMassOption ("MassOption", "Option for the treatment of the masses in the loop diagrams", &SMHiggsGGHiggsPPDecayer::_massopt, 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); } void SMHiggsGGHiggsPPDecayer:: constructSpinInfo(const Particle & part, ParticleVector decay) const { ScalarWaveFunction::constructSpinInfo(const_ptr_cast(&part), incoming,true); for(unsigned int ix=0;ix<2;++ix) VectorWaveFunction::constructSpinInfo(_vwave[ix],decay[ix], outgoing,true, decay[ix]->id()!=ParticleID::Z0); } double SMHiggsGGHiggsPPDecayer::me2(const int,const Particle & part, const tPDVector & outgoing, const vector & momenta, MEOption meopt) const { if(!ME()) ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin1,PDT::Spin1))); if(meopt==Initialize) { ScalarWaveFunction:: calculateWaveFunctions(_rho,const_ptr_cast(&part),incoming); _swave = ScalarWaveFunction(part.momentum(),part.dataPtr(),incoming); // fix rho if no correlations fixRho(_rho); } for(unsigned int ix=0;ix<2;++ix) { VectorWaveFunction:: calculateWaveFunctions(_vwave[ix],momenta[ix],outgoing[ix], Helicity::outgoing,outgoing[ix]->id()!=ParticleID::Z0); } //Set up decay matrix Energy2 scale(sqr(part.mass())); unsigned int v1hel,v2hel; AbstractVVSVertexPtr vertex; unsigned int vstep1(2),vstep2(2); double sym(1.); if(outgoing[0]->id() == ParticleID::g && outgoing[1]->id() == ParticleID::g) { vertex = _hggvertex; sym = 2.; } else if(outgoing[0]->id() == ParticleID::gamma && outgoing[1]->id() == ParticleID::gamma) { vertex = _hppvertex; sym = 2.; } else if(outgoing[0]->id() == ParticleID::Z0 && outgoing[1]->id() == ParticleID::gamma) { vertex = _hzpvertex; vstep1 = 1; } else if(outgoing[1]->id() == ParticleID::Z0 && outgoing[0]->id() == ParticleID::gamma) { vertex = _hzpvertex; vstep2 = 1; } else assert(false); // loop over the helicities of the outgoing bosons for(v1hel = 0;v1hel < 3;v1hel+=vstep1) { for(v2hel = 0;v2hel < 3;v2hel+=vstep2) { (*ME())(0,v1hel,v2hel) = vertex->evaluate(scale,_vwave[0][v1hel], _vwave[1][v2hel],_swave); } } //store matrix element double output = ME()->contract(_rho).real()*UnitRemoval::E2/scale; //colour factor (N^2 - 1)/4 if(outgoing[0]->id() == ParticleID::g) output *= 8.; //symmetric final states output /= sym; // return the answer return output; } void SMHiggsGGHiggsPPDecayer::doinit() { PerturbativeDecayer::doinit(); if(_hggvertex) _hggvertex->init(); else { throw InitException() << "SMHiggsGGHiggsPPDecayer::doinit() - " << "_hggvertex is null"; } if(_hppvertex) _hppvertex->init(); else { throw InitException() << "SMHiggsGGHiggsPPDecayer::doinit() - " << "_hppvertex is null"; } if(_hzpvertex) _hzpvertex->init(); //set up decay modes tPDPtr higgs = getParticleData(ParticleID::h0); tPDPtr gluon = getParticleData(ParticleID::g); tPDPtr photon = getParticleData(ParticleID::gamma); tPDPtr Z0 = getParticleData(ParticleID::Z0); // glu,glu mode addMode(new_ptr(PhaseSpaceMode(higgs,{gluon,gluon},_h0wgt[0]))); // gamma,gamma mode addMode(new_ptr(PhaseSpaceMode(higgs,{photon,photon},_h0wgt[1]))); // Z0,gamma mode addMode(new_ptr(PhaseSpaceMode(higgs,{Z0,photon},_h0wgt[2]))); } void SMHiggsGGHiggsPPDecayer::doinitrun() { _hggvertex->initrun(); _hppvertex->initrun(); _hzpvertex->initrun(); PerturbativeDecayer::doinitrun(); if(initialize()) { for(unsigned int ix=0;ixmaxWeight(); } } } void SMHiggsGGHiggsPPDecayer::dataBaseOutput(ofstream & os,bool header) const { if(header) os << "update decayers set parameters=\""; // parameters for the PerturbativeDecayer base class for(unsigned int ix=0;ix<_h0wgt.size();++ix) { os << "newdef " << name() << ":MaxWeights " << ix << " " << _h0wgt[ix] << "\n"; } os << "newdef " << name() << ":SMHGGVertex " << _hggvertex->fullName() << "\n"; os << "newdef " << name() << ":SMHPPVertex " << _hppvertex->fullName() << "\n"; os << "newdef " << name() << ":SMHZPVertex " << _hzpvertex->fullName() << "\n"; PerturbativeDecayer::dataBaseOutput(os,false); if(header) os << "\n\" where BINARY ThePEGName=\"" << fullName() << "\";" << endl; } double SMHiggsGGHiggsPPDecayer::matrixElementRatio(const Particle & inpart, const ParticleVector & decay2, const ParticleVector & decay3, MEOption, +#ifndef NDEBUG ShowerInteraction inter) { +#else + ShowerInteraction ) { +#endif assert(inter==ShowerInteraction::QCD); // extract partons and LO momentas vector partons(1,inpart.dataPtr()); vector lomom(1,inpart.momentum()); for(unsigned int ix=0;ix<2;++ix) { partons.push_back(decay2[ix]->dataPtr()); lomom.push_back(decay2[ix]->momentum()); } vector realmom(1,inpart.momentum()); for(unsigned int ix=0;ix<3;++ix) { if(ix==2) partons.push_back(decay3[ix]->dataPtr()); realmom.push_back(decay3[ix]->momentum()); } Energy2 scale = sqr(inpart.mass()); Energy2 lome = loME(inpart.mass()); double reme = realME(partons,realmom); double ratio = reme/lome*scale; // // analytic value for mt -> infinity // double x1 = 2.*decay3[0]->momentum().t()/inpart.mass(); // double x2 = 2.*decay3[1]->momentum().t()/inpart.mass(); // double x3 = 2.*decay3[2]->momentum().t()/inpart.mass(); // double test = 8.*Constants::pi*3.*(1.+pow(1-x1,4)+pow(1-x2,4)+pow(1-x3,4)) // /(1.-x1)/(1.-x2)/(1.-x3); // generator()->log() << "TESTING RATIO " << test << " " << ratio << " " << ratio/test << "\n"; // remember the symmetry factor return ratio/3.; } double SMHiggsGGHiggsPPDecayer::realME(//const vector & partons, const vector &, const vector & momenta) const { // using std::norm; // ScalarWaveFunction hout(momenta[0],partons[0],outgoing); // LorentzPolarizationVector g[3][2]; // // calculate the polarization vectors for the gluons // for(unsigned int iw=0;iw<3;++iw) { // VectorWaveFunction gwave(momenta[iw+1],partons[iw+1],outgoing); // for(unsigned int ix=0;ix<2;++ix) { // //if(iw==2) gwave.reset(10); // //else // gwave.reset(2*ix); // g[iw][ix] = gwave.wave(); // } // } Energy2 mh2 = momenta[0].mass2(); Energy2 s = (momenta[1]+momenta[2]).m2(); Energy2 t = (momenta[1]+momenta[3]).m2(); Energy2 u = (momenta[2]+momenta[3]).m2(); // calculate the loop functions Complex A4stu(0.),A2stu(0.),A2tsu(0.),A2ust(0.); for(int ix=_minloop;ix<=_maxloop;++ix) { // loop functions if(_massopt==0) { Energy2 mf2=sqr(getParticleData(ix)->mass()); A4stu+=A4(s,t,u,mf2); A2stu+=A2(s,t,u,mf2); A2tsu+=A2(t,s,u,mf2); A2ust+=A2(u,s,t,mf2); } else { A4stu=-1./3.; A2stu=-sqr(s/mh2)/3.; A2tsu=-sqr(t/mh2)/3.; A2ust=-sqr(u/mh2)/3.; } } // Complex A3stu=0.5*(A2stu+A2ust+A2tsu-A4stu); // // compute the dot products for the matrix element // // and polarization vector * momenta // Energy2 pdot[3][3]; // complex eps[3][3][2]; // for(unsigned int ig=0;ig<3;++ig) { // for(unsigned int ip=0;ip<3;++ip) { // pdot[ig][ip]=momenta[ig+1]*momenta[ip+1]; // for(unsigned int ih=0;ih<2;++ih) { // if(ig!=ip) // eps[ig][ip][ih]=g[ig][ih].dot(momenta[ip+1])/pdot[ig][ip]; // else // eps[ig][ip][ih]=ZERO; // } // } // } // prefactors Energy mw(getParticleData(ParticleID::Wplus)->mass()); // Energy3 pre=sqr(mh2)/mw; // // compute the matrix element // double output(0.); // complex wdot[3][3]; // for(unsigned int ghel1=0;ghel1<2;++ghel1) { // for(unsigned int ghel2=0;ghel2<2;++ghel2) { // for(unsigned int ghel3=0;ghel3<2;++ghel3) { // wdot[0][1]=g[0][ghel1].dot(g[1][ghel2])/pdot[0][1]; // wdot[0][2]=g[0][ghel1].dot(g[2][ghel3])/pdot[0][2]; // wdot[1][0]=wdot[0][1]; // wdot[1][2]=g[1][ghel2].dot(g[2][ghel3])/pdot[1][2]; // wdot[2][0]=wdot[0][2]; // wdot[2][1]=wdot[1][2]; // // last piece // Complex diag=pre*A3stu*(eps[0][2][ghel1]*eps[1][0][ghel2]*eps[2][1][ghel3]- // eps[0][1][ghel1]*eps[1][2][ghel2]*eps[2][0][ghel3]+ // (eps[2][0][ghel3]-eps[2][1][ghel3])*wdot[0][1]+ // (eps[1][2][ghel2]-eps[1][0][ghel2])*wdot[0][2]+ // (eps[0][1][ghel1]-eps[0][2][ghel1])*wdot[1][2]); // // first piece // diag+=pre*(+A2stu*(eps[0][1][ghel1]*eps[1][0][ghel2]-wdot[0][1])* // (eps[2][0][ghel3]-eps[2][1][ghel3]) // +A2tsu*(eps[0][2][ghel1]*eps[2][0][ghel3]-wdot[0][2])* // (eps[1][2][ghel2]-eps[1][0][ghel2]) // +A2ust*(eps[1][2][ghel2]*eps[2][1][ghel3]-wdot[1][2])* // (eps[0][1][ghel1]-eps[0][2][ghel1])); // output+=norm(diag); // } // } // } // // colour factor and what's left of the prefactor // output *= 6.; double me=4.*24./s/t/u*pow<4,1>(mh2)/sqr(mw)* (norm(A2stu)+norm(A2ust)+norm(A2tsu)+norm(A4stu)); return me; } Energy2 SMHiggsGGHiggsPPDecayer::loME(Energy mh) const { Complex loop(0.); Energy2 mh2(sqr(mh)); Energy mw(getParticleData(ParticleID::Wplus)->mass()); for(int ix=_minloop;ix<=_maxloop;++ix) { // loop functions if(_massopt==0) { Energy2 mf2=sqr(getParticleData(ix)->mass()); loop += A1(mh2,mf2); } else { loop += 2./3.; } } return 1./Constants::pi*sqr(mh2)/sqr(mw)*norm(loop); } diff --git a/Decay/Perturbative/SMTopDecayer.h b/Decay/Perturbative/SMTopDecayer.h --- a/Decay/Perturbative/SMTopDecayer.h +++ b/Decay/Perturbative/SMTopDecayer.h @@ -1,417 +1,403 @@ // -*- C++ -*- // // SMTopDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2017 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_SMTopDecayer_H #define HERWIG_SMTopDecayer_H // // This is the declaration of the SMTopDecayer class. // #include "Herwig/Decay/PerturbativeDecayer.h" #include "ThePEG/Helicity/Vertex/AbstractFFVVertex.h" #include "ThePEG/Helicity/Vertex/AbstractVVVVertex.h" #include "Herwig/Decay/PhaseSpaceMode.h" #include "Herwig/Models/StandardModel/StandardModel.h" #include "Herwig/Shower/ShowerAlpha.fh" namespace Herwig { using namespace ThePEG; using namespace ThePEG::Helicity; /** * \ingroup Decay * * The SMTopDecayer performs decays of the top quark into * the bottom quark and qqbar pairs or to the bottom quark and lepton * neutrino pairs via W boson exchange. */ class SMTopDecayer: public PerturbativeDecayer { public: /** * The default constructor. */ SMTopDecayer(); public: /** * Virtual members to be overridden by inheriting classes * which implement hard corrections */ //@{ /** * Has an old fashioned ME correction */ virtual bool hasMECorrection() {return true;} /** * Initialize the ME correction */ virtual void initializeMECorrection(RealEmissionProcessPtr , double & , double & ); /** * Apply the soft matrix element correction * @param parent The initial particle in the current branching * @param progenitor The progenitor particle of the jet * @param fs Whether the emission is initial or final-state * @param highestpT The highest pT so far in the shower * @param ids ids of the particles produced in the branching * @param z The momentum fraction of the branching * @param scale the evolution scale of the branching * @param pT The transverse momentum of the branching * @return If true the emission should be vetoed */ virtual bool softMatrixElementVeto(PPtr parent, PPtr progenitor, const bool & fs, const Energy & highestpT, const vector & ids, const double & z, const Energy & scale, const Energy & pT); /** * Has a POWHEG style correction */ virtual POWHEGType hasPOWHEGCorrection() {return FSR;} //@} public: /** * Which of the possible decays is required */ virtual int modeNumber(bool & , tcPDPtr , const tPDVector & ) const {return -1;} /** * Check if this decayer can perfom the decay for a particular mode. * Uses the modeNumber member but can be overridden * @param parent The decaying particle * @param children The decay products */ virtual bool accept(tcPDPtr parent, const tPDVector & children) const; /** * For a given decay mode and a given particle instance, perform the * decay and return the decay products. As this is the base class this * is not implemented. * @return The vector of particles produced in the decay. */ virtual ParticleVector decay(const Particle & parent, const tPDVector & children) const; /** * Return the matrix element squared for a given mode and phase-space channel. * @param ichan The channel we are calculating the matrix element for. * @param part The decaying Particle. * @param outgoing The particles produced in the decay * @param momenta The momenta of the particles produced in the decay * @param meopt Option for the calculation of the matrix element * @return The matrix element squared for the phase-space configuration. */ double me2(const int ichan,const Particle & part, const tPDVector & outgoing, const vector & momenta, MEOption meopt) const; /** * Construct the SpinInfos for the particles produced in the decay */ virtual void constructSpinInfo(const Particle & part, ParticleVector outgoing) const; /** * Method to return an object to calculate the 3 (or higher body) partial width * @param dm The DecayMode * @return A pointer to a WidthCalculatorBase object capable of calculating the width */ virtual WidthCalculatorBasePtr threeBodyMEIntegrator(const DecayMode & dm) const; /** * The differential three body decay rate with one integral performed. * @param imode The mode for which the matrix element is needed. * @param q2 The scale, \e i.e. the mass squared of the decaying particle. * @param s The invariant mass which still needs to be integrate over. * @param m1 The mass of the first outgoing particle. * @param m2 The mass of the second outgoing particle. * @param m3 The mass of the third outgoing particle. * @return The differential rate \f$\frac{d\Gamma}{ds}\f$ */ virtual InvEnergy threeBodydGammads(const int imode, const Energy2 q2, const Energy2 s, const Energy m1, const Energy m2, const Energy m3) const; /** * Output the setup information for the particle database * @param os The stream to output the information to * @param header Whether or not to output the information for MySQL */ virtual void dataBaseOutput(ofstream & os,bool header) const; public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** * The integrand for the integrate partial width */ Energy6 dGammaIntegrand(Energy2 mffb2, Energy2 mbf2, Energy mt, Energy mb, Energy mf, Energy mfb, Energy mw) const; protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const {return new_ptr(*this);} /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const {return new_ptr(*this);} //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving and * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); //@} protected: /** * This function determines the point (\f$x_{g}\f$) where the condition that * \f$x_{a}\f$ be real supersedes that due to the external input * \f$\tilde{\kappa}\f$ where, again, \f$\kappa\f$ pertains to emissions from the * b. */ double xgbcut(double); /** * Full matrix element with a factor of \f$\frac{\alpha_SC_F}{x_g^2\pi}\f$ removed. * @param xw The momentum fraction of the W boson * @param xg The momentum fraction of the gluon. */ double me(double xw, double xg); protected: /** * Calculate matrix element ratio R/B */ virtual double matrixElementRatio(const Particle & inpart, const ParticleVector & decay2, const ParticleVector & decay3, MEOption meopt, ShowerInteraction inter); /** * LO matrix element for \f$t\to b W^\pm\f$ */ double loME(const Particle & inpart, const ParticleVector & decay); /** * LO matrix element for \f$t\to b W^\pm\f$ */ double realME(const Particle & inpart, const ParticleVector & decay, ShowerInteraction inter); private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ SMTopDecayer & operator=(const SMTopDecayer &) = delete; /** * Pointer to the W vertex */ AbstractFFVVertexPtr FFWVertex_; /** * Pointer to the gluon vertex */ AbstractFFVVertexPtr FFGVertex_; /** * Pointer to the photon vertex */ AbstractFFVVertexPtr FFPVertex_; /** * Pointer to the photon vertex */ AbstractVVVVertexPtr WWWVertex_; /** * Max weight for integration */ //@{ /** * Weight \f$W\to q\bar{q}'\f$ */ vector _wquarkwgt; /** * Weight \f$W\to \ell \nu\f$ */ vector _wleptonwgt; //@} /** * Pointer to the \f$W^\pm\f$ */ PDPtr _wplus; /** * Spin density matrix for the decay */ mutable RhoDMatrix _rho; /** * 1st spinor for the decay */ mutable vector _inHalf; /** * 2nd spinor for the decay */ mutable vector _outHalf; /** * 1st barred spinor for the decay */ mutable vector _inHalfBar; /** * 2nd barred spinor for the decay */ mutable vector _outHalfBar; /** * The mass of the W boson */ Energy _ma; /** * The mass of the bottom quark */ Energy _mc; /** * The top mass */ Energy _mt; /** * The gluon mass. */ Energy _mg; /** * The mass ratio for the W. */ double _a; /** * The mass ratio for the bottom. */ double _c; /** * The mass ratio for the gluon. */ double _g; /** * Two times the energy fraction of a. */ double _ktb; /** * Two times the energy fraction of the gluon. */ double _ktc; - /** - * Two times the energy fraction of the gluon. - */ - double _xg; - - /** - * Two times the energy fraction of a. - */ - double _xa; - - /** - * Two times the energy fraction of c. - */ - double _xc; /** * This determines the hard matrix element importance * sampling in _xg. _xg_sampling=2.0 samples as 1/xg^2. */ double _xg_sampling; /** * The enhancement factor for initial-state radiation */ double _initialenhance; /** * The enhancement factor for final-state radiation */ double _finalenhance; }; } #endif /* HERWIG_SMTopDecayer_H */ diff --git a/Decay/Perturbative/SMWDecayer.h b/Decay/Perturbative/SMWDecayer.h --- a/Decay/Perturbative/SMWDecayer.h +++ b/Decay/Perturbative/SMWDecayer.h @@ -1,520 +1,497 @@ // -*- C++ -*- // // SMWDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2017 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_SMWDecayer_H #define HERWIG_SMWDecayer_H // // This is the declaration of the SMWDecayer class. // #include "Herwig/Decay/PerturbativeDecayer.h" #include "ThePEG/Helicity/Vertex/Vector/FFVVertex.h" #include "ThePEG/Helicity/Vertex/AbstractVVVVertex.h" #include "Herwig/Decay/PhaseSpaceMode.h" namespace Herwig { using namespace ThePEG; using namespace ThePEG::Helicity; /** \ingroup Decay * * The SMWDecayer is designed to perform the decay of the * W boson to the Standard Model fermions, including the first order * electroweak corrections. * * @see PerturbativeDecayer * */ class SMWDecayer: public PerturbativeDecayer { public: /** * Default constructor. */ SMWDecayer(); public: /** * Virtual members to be overridden by inheriting classes * which implement hard corrections */ //@{ /** * Has an old fashioned ME correction */ virtual bool hasMECorrection() {return true;} /** * Initialize the ME correction */ virtual void initializeMECorrection(RealEmissionProcessPtr , double & , double & ); /** * Apply the soft matrix element correction * @param parent The initial particle in the current branching * @param progenitor The progenitor particle of the jet * @param fs Whether the emission is initial or final-state * @param highestpT The highest pT so far in the shower * @param ids ids of the particles produced in the branching * @param z The momentum fraction of the branching * @param scale the evolution scale of the branching * @param pT The transverse momentum of the branching * @return If true the emission should be vetoed */ virtual bool softMatrixElementVeto(PPtr parent, PPtr progenitor, const bool & fs, const Energy & highestpT, const vector & ids, const double & z, const Energy & scale, const Energy & pT); /** * Has a POWHEG style correction */ virtual POWHEGType hasPOWHEGCorrection() {return FSR;} public: /** * Which of the possible decays is required * @param cc Is this mode the charge conjugate * @param parent The decaying particle * @param children The decay products */ virtual int modeNumber(bool & cc, tcPDPtr parent, const tPDVector & children) const; /** * For a given decay mode and a given particle instance, perform the * decay and return the decay products. As this is the base class this * is not implemented. * @return The vector of particles produced in the decay. */ virtual ParticleVector decay(const Particle & parent,const tPDVector & children) const; /** * Return the matrix element squared for a given mode and phase-space channel. * @param ichan The channel we are calculating the matrix element for. * @param part The decaying Particle. * @param outgoing The particles produced in the decay * @param momenta The momenta of the particles produced in the decay * @param meopt Option for the calculation of the matrix element * @return The matrix element squared for the phase-space configuration. */ double me2(const int ichan,const Particle & part, const tPDVector & outgoing, const vector & momenta, MEOption meopt) const; /** * Construct the SpinInfos for the particles produced in the decay */ virtual void constructSpinInfo(const Particle & part, ParticleVector outgoing) const; /** * Output the setup information for the particle database * @param os The stream to output the information to * @param header Whether or not to output the information for MySQL */ virtual void dataBaseOutput(ofstream & os,bool header) const; public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * Standard Init function used to initialize the interfaces. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const {return new_ptr(*this);} /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const {return new_ptr(*this);} //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving and * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); //@} protected: /** * Set the \f$\rho\f$ parameter */ void setRho(double); /** * Set the \f$\tilde{\kappa}\f$ parameters symmetrically */ void setKtildeSymm(); /** * Set second \f$\tilde{\kappa}\f$, given the first. */ void setKtilde2(); /** * Translate the variables from \f$x_q,x_{\bar{q}}\f$ to \f$\tilde{\kappa},z\f$ */ //@{ /** * Calculate \f$z\f$. */ double getZfromX(double, double); /** * Calculate \f$\tilde{\kappa}\f$. */ double getKfromX(double, double); //@} /** * Calculate \f$x_{q},x_{\bar{q}}\f$ from \f$\tilde{\kappa},z\f$. * @param kt \f$\tilde{\kappa}\f$ * @param z \f$z\f$ * @param x \f$x_{q}\f$ * @param xbar \f$x_{\bar{q}}\f$ */ void getXXbar(double kt, double z, double & x, double & xbar); /** * Soft weight */ //@{ /** * Soft quark weight calculated from \f$x_{q},x_{\bar{q}}\f$ * @param x \f$x_{q}\f$ * @param xbar \f$x_{\bar{q}}\f$ */ double qWeight(double x, double xbar); /** * Soft antiquark weight calculated from \f$x_{q},x_{\bar{q}}\f$ * @param x \f$x_{q}\f$ * @param xbar \f$x_{\bar{q}}\f$ */ double qbarWeight(double x, double xbar); /** * Soft quark weight calculated from \f$\tilde{q},z\f$ * @param qtilde \f$\tilde{q}\f$ * @param z \f$z\f$ */ double qWeightX(Energy qtilde, double z); /** * Soft antiquark weight calculated from \f$\tilde{q},z\f$ * @param qtilde \f$\tilde{q}\f$ * @param z \f$z\f$ */ double qbarWeightX(Energy qtilde, double z); //@} /** * ???? */ double u(double); /** * Vector and axial vector parts of the matrix element */ //@{ /** * Vector part of the matrix element */ double MEV(double, double); /** * Axial vector part of the matrix element */ double MEA(double, double); /** * The matrix element, given \f$x_1\f$, \f$x_2\f$. * @param x1 \f$x_1\f$ * @param x2 \f$x_2\f$ */ double PS(double x1, double x2); //@} protected: /** * Real emission term, for use in generating the hardest emission */ double calculateRealEmission(double x1, double x2, tcPDVector outgoing, vector momenta, double phi, double muj, double muk, int iemit, bool subtract) const; /** * Calculate the ratio between NLO & LO ME */ double meRatio(tcPDVector partons, vector momenta, unsigned int iemitter,bool subtract) const; /** * Calculate matrix element ratio R/B */ virtual double matrixElementRatio(const Particle & inpart, const ParticleVector & decay2, const ParticleVector & decay3, MEOption meopt, ShowerInteraction inter); /** * Calculate the LO ME */ double loME(const vector & partons, const vector & momenta) const; /** * Calculate the NLO real emission piece of ME */ InvEnergy2 realME(const vector & partons, const vector & momenta, ShowerInteraction inter) const; private: /** * Private and non-existent assignment operator. */ SMWDecayer & operator=(const SMWDecayer &) = delete; private: /** * Pointer to the fermion-antifermion W vertex */ AbstractFFVVertexPtr FFWVertex_; /** * Pointer to the fermion-antifermion G vertex */ AbstractFFVVertexPtr FFGVertex_; /** * Pointer to the fermion-antifermion G vertex */ AbstractFFVVertexPtr FFPVertex_; /** * Pointer to the fermion-antifermion G vertex */ AbstractVVVVertexPtr WWWVertex_; /** * maximum weights for the different integrations */ //@{ /** * Weights for the W to quarks decays. */ vector quarkWeight_; /** * Weights for the W to leptons decays. */ vector leptonWeight_; //@} /** * Spin density matrix for the decay */ mutable RhoDMatrix rho_; /** * Polarization vectors for the decay */ mutable vector vectors_; /** * Spinors for the decay */ mutable vector wave_; /** * Barred spinors for the decay */ mutable vector wavebar_; private: /** * CM energy */ Energy d_Q_; /** * Quark mass */ Energy d_m_; /** * The rho parameter */ double d_rho_; /** * The v parameter */ double d_v_; /** * The initial kappa-tilde values for radiation from the quark */ double d_kt1_; /** * The initial kappa-tilde values for radiation from the antiquark */ double d_kt2_; /** * Cut-off parameter */ static const double EPS_; private: /** * The colour factor */ double CF_; /** * The W mass */ mutable Energy mW_; - // TODO: delete this - mutable double mu_; - - /** - * The reduced mass of particle 1 - */ - mutable double mu1_; - /** - * The reduced mass of particle 1 squared - */ - mutable double mu12_; - - /** - * The reduceed mass of particle 2 - */ - mutable double mu2_; - - /** - * The reduceed mass of particle 2 squared - */ - mutable double mu22_; - - /** * The strong coupling */ mutable double aS_; /** * The scale */ mutable Energy2 scale_; /** * Stuff for the POWHEG correction */ //@{ /** * ParticleData object for the gluon */ tcPDPtr gluon_; /** * The ParticleData objects for the fermions */ vector partons_; /** * The fermion momenta */ vector quark_; /** * The momentum of the radiated gauge boson */ Lorentz5Momentum gauge_; /** * The W boson */ PPtr wboson_; /** * W mass squared */ Energy2 mw2_; //@} /** * Whether ro return the LO or NLO result */ bool NLO_; }; } #endif /* HERWIG_SMWDecayer_H */ diff --git a/Decay/PerturbativeDecayer.cc b/Decay/PerturbativeDecayer.cc --- a/Decay/PerturbativeDecayer.cc +++ b/Decay/PerturbativeDecayer.cc @@ -1,1172 +1,1173 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the PerturbativeDecayer class. // #include "PerturbativeDecayer.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Utilities/EnumIO.h" using namespace Herwig; void PerturbativeDecayer::persistentOutput(PersistentOStream & os) const { os << ounit(pTmin_,GeV) << oenum(inter_) << alphaS_ << alphaEM_ << useMEforT2_ << C_ << ymax_ << phaseOpt_; } void PerturbativeDecayer::persistentInput(PersistentIStream & is, int) { is >> iunit(pTmin_,GeV) >> ienum(inter_) >> alphaS_ >> alphaEM_ >> useMEforT2_ >> C_ >> ymax_ >> phaseOpt_; } // The following static variable is needed for the type // description system in ThePEG. DescribeAbstractClass describeHerwigPerturbativeDecayer("Herwig::PerturbativeDecayer", "Herwig.so HwPerturbativeDecay.so"); void PerturbativeDecayer::Init() { static ClassDocumentation documentation ("The PerturbativeDecayer class is the mase class for " "perturbative decays in Herwig"); static Parameter interfacepTmin ("pTmin", "Minimum transverse momentum from gluon radiation", &PerturbativeDecayer::pTmin_, GeV, 1.0*GeV, 0.0*GeV, 10.0*GeV, false, false, Interface::limited); static Switch interfaceInteractions ("Interactions", "which interactions to include for the hard corrections", &PerturbativeDecayer::inter_, ShowerInteraction::QCD, false, false); static SwitchOption interfaceInteractionsQCD (interfaceInteractions, "QCD", "QCD Only", ShowerInteraction::QCD); static SwitchOption interfaceInteractionsQED (interfaceInteractions, "QED", "QED only", ShowerInteraction::QED); static SwitchOption interfaceInteractionsQCDandQED (interfaceInteractions, "QCDandQED", "Both QCD and QED", ShowerInteraction::Both); static Reference interfaceAlphaS ("AlphaS", "Object for the coupling in the generation of hard QCD radiation", &PerturbativeDecayer::alphaS_, false, false, true, true, false); static Reference interfaceAlphaEM ("AlphaEM", "Object for the coupling in the generation of hard QED radiation", &PerturbativeDecayer::alphaEM_, false, false, true, true, false); static Switch interfaceUseMEForT2 ("UseMEForT2", "Use the matrix element correction, if available to fill the T2" " region for the decay shower and don't fill using the shower", &PerturbativeDecayer::useMEforT2_, true, false, false); static SwitchOption interfaceUseMEForT2Shower (interfaceUseMEForT2, "Shower", "Use the shower to fill the T2 region", false); static SwitchOption interfaceUseMEForT2ME (interfaceUseMEForT2, "ME", "Use the Matrix element to fill the T2 region", true); static Parameter interfacePrefactor ("Prefactor", "The prefactor for the sampling of the powheg Sudakov", &PerturbativeDecayer::C_, 6.3, 0.0, 1e10, false, false, Interface::limited); static Parameter interfaceYMax ("YMax", "The maximum value for the rapidity", &PerturbativeDecayer::ymax_, 10., 0.0, 100., false, false, Interface::limited); static Switch interfacePhaseSpaceOption ("PhaseSpaceOption", "Option for the phase-space sampling", &PerturbativeDecayer::phaseOpt_, 0, false, false); static SwitchOption interfacePhaseSpaceOptionFixedYLimits (interfacePhaseSpaceOption, "FixedYLimits", "Use a fixed limit for the rapidity", 0); static SwitchOption interfacePhaseSpaceOptionVariableYLimits (interfacePhaseSpaceOption, "VariableYLimits", "Change limit for the rapidity with pT", 1); } double PerturbativeDecayer::matrixElementRatio(const Particle & , const ParticleVector & , const ParticleVector & , MEOption , ShowerInteraction ) { throw Exception() << "Base class PerturbativeDecayer::matrixElementRatio() " << "called, should have an implementation in the inheriting class" << Exception::runerror; return 0.; } RealEmissionProcessPtr PerturbativeDecayer::generateHardest(RealEmissionProcessPtr born) { return getHardEvent(born,false,inter_); } RealEmissionProcessPtr PerturbativeDecayer::applyHardMatrixElementCorrection(RealEmissionProcessPtr born) { return getHardEvent(born,true,ShowerInteraction::QCD); } RealEmissionProcessPtr PerturbativeDecayer::getHardEvent(RealEmissionProcessPtr born, bool inDeadZone, ShowerInteraction inter) { // check one incoming assert(born->bornIncoming().size()==1); // check exactly two outgoing particles assert(born->bornOutgoing().size()==2); // search for coloured particles bool colouredParticles=born->bornIncoming()[0]->dataPtr()->coloured(); bool chargedParticles=born->bornIncoming()[0]->dataPtr()->charged(); for(unsigned int ix=0;ixbornOutgoing().size();++ix) { if(born->bornOutgoing()[ix]->dataPtr()->coloured()) colouredParticles=true; if(born->bornOutgoing()[ix]->dataPtr()->charged()) chargedParticles=true; } // if no coloured/charged particles return if ( !colouredParticles && !chargedParticles ) return RealEmissionProcessPtr(); if ( !colouredParticles && inter==ShowerInteraction::QCD ) return RealEmissionProcessPtr(); if ( ! chargedParticles && inter==ShowerInteraction::QED ) return RealEmissionProcessPtr(); // for decay b -> a c // set progenitors PPtr cProgenitor = born->bornOutgoing()[0]; PPtr aProgenitor = born->bornOutgoing()[1]; // get the decaying particle PPtr bProgenitor = born->bornIncoming()[0]; // identify which dipoles are required vector dipoles; if(!identifyDipoles(dipoles,aProgenitor,bProgenitor,cProgenitor,inter)) { return RealEmissionProcessPtr(); } Energy trialpT = pTmin_; LorentzRotation eventFrame; vector momenta; vector trialMomenta(4); PPtr finalEmitter, finalSpectator; PPtr trialEmitter, trialSpectator; DipoleType finalType(FFa,ShowerInteraction::QCD); for (int i=0; imomentum().findBoostToCM()); Lorentz5Momentum pspectator = (trialEventFrame*trialSpectator->momentum()); trialEventFrame.rotateZ( -pspectator.phi() ); trialEventFrame.rotateY( -pspectator.theta() - Constants::pi ); // invert it trialEventFrame.invert(); // try to generate an emission pT_ = pTmin_; vector trialMomenta = hardMomenta(bProgenitor, trialEmitter, trialSpectator, dipoles, i, inDeadZone); // select dipole which gives highest pT emission if(pT_>trialpT) { trialpT = pT_; momenta = trialMomenta; eventFrame = trialEventFrame; finalEmitter = trialEmitter; finalSpectator = trialSpectator; finalType = dipoles[i]; if (dipoles[i].type==FFc || dipoles[i].type==FFa ) { if((momenta[3]+momenta[1]).m2()-momenta[1].m2()> (momenta[3]+momenta[2]).m2()-momenta[2].m2()) { swap(finalEmitter,finalSpectator); swap(momenta[1],momenta[2]); } } } } pT_ = trialpT; // if no emission return if(momenta.empty()) { if(inter==ShowerInteraction::Both || inter==ShowerInteraction::QCD) born->pT()[ShowerInteraction::QCD] = pTmin_; if(inter==ShowerInteraction::Both || inter==ShowerInteraction::QED) born->pT()[ShowerInteraction::QED] = pTmin_; return born; } // rotate momenta back to the lab for(unsigned int ix=0;ixpT()[ShowerInteraction::QCD] = pT_; if(inter==ShowerInteraction::Both || inter==ShowerInteraction::QED) born->pT()[ShowerInteraction::QED] = pT_; // get ParticleData objects tcPDPtr b = bProgenitor ->dataPtr(); tcPDPtr e = finalEmitter ->dataPtr(); tcPDPtr s = finalSpectator->dataPtr(); tcPDPtr boson = getParticleData(finalType.interaction==ShowerInteraction::QCD ? ParticleID::g : ParticleID::gamma); // create new ShowerParticles PPtr emitter = e ->produceParticle(momenta[1]); PPtr spectator = s ->produceParticle(momenta[2]); PPtr gauge = boson->produceParticle(momenta[3]); PPtr incoming = b ->produceParticle(bProgenitor->momentum()); // insert the particles born->incoming().push_back(incoming); unsigned int iemit(0),ispect(0); for(unsigned int ix=0;ixbornOutgoing().size();++ix) { if(born->bornOutgoing()[ix]==finalEmitter) { born->outgoing().push_back(emitter); iemit = born->outgoing().size(); } else if(born->bornOutgoing()[ix]==finalSpectator) { born->outgoing().push_back(spectator); ispect = born->outgoing().size(); } } born->outgoing().push_back(gauge); if(!spectator->dataPtr()->coloured() || (finalType.type != FFa && finalType.type!=FFc) ) ispect = 0; born->emitter(iemit); born->spectator(ispect); born->emitted(3); // boost if being use as ME correction if(inDeadZone) { if(finalType.type==IFa || finalType.type==IFba) { LorentzRotation trans(cProgenitor->momentum().findBoostToCM()); trans.boost(spectator->momentum().boostVector()); born->transformation(trans); } else if(finalType.type==IFc || finalType.type==IFbc) { LorentzRotation trans(bProgenitor->momentum().findBoostToCM()); trans.boost(spectator->momentum().boostVector()); born->transformation(trans); } } // set the interaction born->interaction(finalType.interaction); // set up colour lines getColourLines(born); // return the tree return born; } bool PerturbativeDecayer::identifyDipoles(vector & dipoles, PPtr & aProgenitor, PPtr & bProgenitor, PPtr & cProgenitor, ShowerInteraction inter) const { enhance_ = 1.; // identify any QCD dipoles if(inter==ShowerInteraction::QCD || inter==ShowerInteraction::Both) { PDT::Colour bColour = bProgenitor->dataPtr()->iColour(); PDT::Colour cColour = cProgenitor->dataPtr()->iColour(); PDT::Colour aColour = aProgenitor->dataPtr()->iColour(); // decaying colour singlet if (bColour==PDT::Colour0 ) { if ((cColour==PDT::Colour3 && aColour==PDT::Colour3bar) || (cColour==PDT::Colour3bar && aColour==PDT::Colour3) || (cColour==PDT::Colour8 && aColour==PDT::Colour8)){ dipoles.push_back(DipoleType(FFa,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(FFc,ShowerInteraction::QCD)); if(aProgenitor->id()==ParticleID::g && cProgenitor->id()==ParticleID::g ) { enhance_ = 1.5; dipoles.push_back(DipoleType(FFg,ShowerInteraction::QCD)); } } } // decaying colour triplet else if (bColour==PDT::Colour3 ) { if (cColour==PDT::Colour3 && aColour==PDT::Colour0){ dipoles.push_back(DipoleType(IFbc,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFc ,ShowerInteraction::QCD)); } else if (cColour==PDT::Colour0 && aColour==PDT::Colour3){ dipoles.push_back(DipoleType(IFba,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFa ,ShowerInteraction::QCD)); } else if (cColour==PDT::Colour8 && aColour==PDT::Colour3){ dipoles.push_back(DipoleType(IFbc,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFc ,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(FFc ,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(FFa ,ShowerInteraction::QCD)); } else if (cColour==PDT::Colour3 && aColour==PDT::Colour8){ dipoles.push_back(DipoleType(IFba,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFa ,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(FFc ,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(FFa ,ShowerInteraction::QCD)); } else if(cColour==PDT::Colour3bar && aColour==PDT::Colour3bar) { dipoles.push_back(DipoleType(IFba,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFbc,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFa,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFc,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(FFc ,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(FFa ,ShowerInteraction::QCD)); } } // decaying colour anti-triplet else if (bColour==PDT::Colour3bar) { if ((cColour==PDT::Colour3bar && aColour==PDT::Colour0)){ dipoles.push_back(DipoleType(IFbc,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFc ,ShowerInteraction::QCD)); } else if ((cColour==PDT::Colour0 && aColour==PDT::Colour3bar)){ dipoles.push_back(DipoleType(IFba,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFa ,ShowerInteraction::QCD)); } else if (cColour==PDT::Colour8 && aColour==PDT::Colour3bar){ dipoles.push_back(DipoleType(IFbc,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFc ,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(FFc ,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(FFa ,ShowerInteraction::QCD)); } else if (cColour==PDT::Colour3bar && aColour==PDT::Colour8){ dipoles.push_back(DipoleType(IFba,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFa ,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(FFc ,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(FFa ,ShowerInteraction::QCD)); } else if(cColour==PDT::Colour3 && aColour==PDT::Colour3) { dipoles.push_back(DipoleType(IFba,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFbc,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFa,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFc,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(FFc ,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(FFa ,ShowerInteraction::QCD)); } } // decaying colour octet else if (bColour==PDT::Colour8){ if ((cColour==PDT::Colour3 && aColour==PDT::Colour3bar) || (cColour==PDT::Colour3bar && aColour==PDT::Colour3)){ dipoles.push_back(DipoleType(IFba,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFbc,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFa,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFc,ShowerInteraction::QCD)); } else if (cColour==PDT::Colour8 && aColour==PDT::Colour0){ dipoles.push_back(DipoleType(IFbc,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFc,ShowerInteraction::QCD)); } else if (cColour==PDT::Colour0 && aColour==PDT::Colour8){ dipoles.push_back(DipoleType(IFba,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFa,ShowerInteraction::QCD)); } } // decaying colour sextet else if(bColour==PDT::Colour6) { if (cColour==PDT::Colour3 && aColour==PDT::Colour3) { dipoles.push_back(DipoleType(IFba,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFbc,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFa,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFc,ShowerInteraction::QCD)); } } // decaying colour antisextet else if(bColour==PDT::Colour6bar) { if (cColour==PDT::Colour3bar && aColour==PDT::Colour3bar) { dipoles.push_back(DipoleType(IFba,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFbc,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFa,ShowerInteraction::QCD)); dipoles.push_back(DipoleType(IFc,ShowerInteraction::QCD)); } } } // QED dipoles if(inter==ShowerInteraction::Both || inter==ShowerInteraction::QED) { const bool & bCharged = bProgenitor->dataPtr()->charged(); const bool & cCharged = cProgenitor->dataPtr()->charged(); const bool & aCharged = aProgenitor->dataPtr()->charged(); // initial-final if(bCharged && aCharged) { dipoles.push_back(DipoleType(IFba,ShowerInteraction::QED)); dipoles.push_back(DipoleType(IFa ,ShowerInteraction::QED)); } if(bCharged && cCharged) { dipoles.push_back(DipoleType(IFbc,ShowerInteraction::QED)); dipoles.push_back(DipoleType(IFc ,ShowerInteraction::QED)); } // final-state if(aCharged && cCharged) { dipoles.push_back(DipoleType(FFa,ShowerInteraction::QED)); dipoles.push_back(DipoleType(FFc,ShowerInteraction::QED)); } } // check colour structure is allowed return !dipoles.empty(); } vector PerturbativeDecayer::hardMomenta(PPtr in, PPtr emitter, PPtr spectator, const vector &dipoles, int i, bool inDeadZone) { // get masses of the particles mb_ = in ->momentum().mass(); e_ = emitter ->momentum().mass()/mb_; s_ = spectator->momentum().mass()/mb_; e2_ = sqr(e_); s2_ = sqr(s_); vector particleMomenta; Energy2 lambda = sqr(mb_)*sqrt(1.+sqr(s2_)+sqr(e2_)-2.*s2_-2.*e2_-2.*s2_*e2_); // calculate A double pre = C_; // multiply by the colour factor of the dipole // ISR if (dipoles[i].type==IFba || dipoles[i].type==IFbc) { pre *= colourCoeff(in->dataPtr(),emitter->dataPtr(),spectator->dataPtr(),dipoles[i]); } // radiation from a/c with initial-final connection else if (dipoles[i].type==IFa || dipoles[i].type==IFc) { pre *= colourCoeff(emitter->dataPtr(),in->dataPtr(),spectator->dataPtr(),dipoles[i]); } // radiation from a/c with final-final connection else if (dipoles[i].type==FFa || dipoles[i].type==FFc) { pre *= colourCoeff(emitter->dataPtr(),spectator->dataPtr(),in->dataPtr(),dipoles[i]); } double A = 2.*abs(pre)/Constants::twopi; // factor due sampling choice if(phaseOpt_==0) A *= ymax_; // coupling factor if(dipoles[i].interaction==ShowerInteraction::QCD) A *= alphaS() ->overestimateValue(); else A *= alphaEM()->overestimateValue(); Energy pTmax = 0.5*mb_*(1.-sqr(s_+e_)); // if no possible branching return if ( pTmax < pTmin_ ) return particleMomenta; // loop over the two regions for(unsigned int j=0;j<2;++j) { Energy pT=pTmax; vector momenta(4); while (pT >= pTmin_) { double ymax; // overestimate with flat y limit if(phaseOpt_==0) { pT *= pow(UseRandom::rnd(),(1./A)); ymax=ymax_; } // pT sampling including tighter pT dependent y limit else { pT = 2.*pTmax*exp(-sqrt(-2.*log(UseRandom::rnd())/A+sqr(log(2.*pTmax/pT)))); // choice of limit overestimate ln(2*pTmax/pT) (true limit acosh(pTmax/pT)) ymax = log(2.*pTmax/pT); } if (pT < pTmin_) break; double phi = UseRandom::rnd()*Constants::twopi; double y = ymax*(2.*UseRandom::rnd()-1.); double xs, xe, xe_z, xg; // check if the momenta are physical if (!calcMomenta(j, pT, y, phi, xg, xs, xe, xe_z, momenta)) continue; // check if point lies within phase space if (!psCheck(xg, xs)) continue; // check if point lies within the dead-zone (if required) if(inDeadZone && !inTotalDeadZone(xg,xs,dipoles,i)) continue; // decay products for 3 body decay PPtr inpart = in ->dataPtr()->produceParticle(momenta[0]); ParticleVector decay3; decay3.push_back(emitter ->dataPtr()->produceParticle(momenta[1])); decay3.push_back(spectator->dataPtr()->produceParticle(momenta[2])); if(dipoles[i].interaction==ShowerInteraction::QCD) decay3.push_back(getParticleData(ParticleID::g )->produceParticle(momenta[3])); else decay3.push_back(getParticleData(ParticleID::gamma)->produceParticle(momenta[3])); // decay products for 2 body decay Lorentz5Momentum p1(ZERO,ZERO, lambda/2./mb_,(mb_/2.)*(1.+e2_-s2_),mb_*e_); Lorentz5Momentum p2(ZERO,ZERO,-lambda/2./mb_,(mb_/2.)*(1.+s2_-e2_),mb_*s_); ParticleVector decay2; decay2.push_back(emitter ->dataPtr()->produceParticle(p1)); decay2.push_back(spectator->dataPtr()->produceParticle(p2)); if (dipoles[i].type==FFa || dipoles[i].type==IFa || dipoles[i].type==IFba) { swap(decay2[0],decay2[1]); swap(decay3[0],decay3[1]); } // calculate matrix element ratio R/B double meRatio = matrixElementRatio(*inpart,decay2,decay3,Initialize,dipoles[i].interaction); // calculate dipole factor double dipoleSum(0.),numerator(0.); for (int k=0; k dipole = calculateDipole(dipoles[k],*inpart,decay3); dipoleSum += abs(dipole.first); if (k==i) numerator = abs(dipole.second); } meRatio *= numerator/dipoleSum; // calculate jacobian Energy2 denom = (mb_-momenta[3].e())*momenta[2].vect().mag() - momenta[2].e()*momenta[3].z(); InvEnergy2 J = (momenta[2].vect().mag2())/(lambda*denom); // calculate weight double weight = enhance_*meRatio*fabs(sqr(pT)*J)/pre/Constants::twopi; if(dipoles[i].interaction==ShowerInteraction::QCD) weight *= alphaS() ->ratio(pT*pT); else weight *= alphaEM()->ratio(pT*pT); // accept point if weight > R if (pT > pT_ && weight > UseRandom::rnd()) { particleMomenta=momenta; if (weight > 1.) { generator()->log() << "WEIGHT PROBLEM " << fullName() << " " << weight << "\n"; generator()->log() << xe << " " << xs << " " << xg << "\n"; for(unsigned int ix=0;ixlog() << particleMomenta[ix]/GeV << "\n"; } pT_ = pT; break; } } } return particleMomenta; } bool PerturbativeDecayer::calcMomenta(int j, Energy pT, double y, double phi, double& xg, double& xs, double& xe, double& xe_z, vector& particleMomenta) { // calculate xg xg = 2.*pT*cosh(y) / mb_; if (xg>(1. - sqr(e_ + s_)) || xg<0.) return false; // calculate the two values of zs double xT = 2.*pT / mb_; double zg = 2.*pT*sinh(y) / mb_; double A = (sqr(xT) - 4. * xg + 4.); double B = 2. * zg * (s2_ - e2_ - xg + 1.); double det = -4. * (-sqr(s2_) + (2. * e2_ + sqr(xT) - 2. * xg + 2.) * s2_ - sqr(e2_ + xg - 1.)) * sqr(xg - 2.); if (det<0.) return false; double zs= j==0 ? (-B+sqrt(det))/A : (-B-sqrt(det))/A; // zs must be negative if(zs>0.) return false; xs = sqrt(sqr(zs)+4.*s2_); // check value of xs is physical if (xs>(1.+s2_-e2_) || xs<2.*s_) return false; // calculate xe xe = 2.-xs-xg; // check value of xe is physical if (xe>(1.+e2_-s2_) || xe<2.*e_) return false; // calculate xe_z xe_z = -zg-zs; // calculate 4 momenta particleMomenta[0].setE ( mb_); particleMomenta[0].setX ( ZERO); particleMomenta[0].setY ( ZERO); particleMomenta[0].setZ ( ZERO); particleMomenta[0].setMass( mb_); particleMomenta[1].setE ( mb_*xe/2.); particleMomenta[1].setX (-pT*cos(phi)); particleMomenta[1].setY (-pT*sin(phi)); particleMomenta[1].setZ ( mb_*xe_z/2.); particleMomenta[1].setMass( mb_*e_); particleMomenta[2].setE ( mb_*xs/2.); particleMomenta[2].setX ( ZERO); particleMomenta[2].setY ( ZERO); particleMomenta[2].setZ ( mb_*zs/2.); particleMomenta[2].setMass( mb_*s_); particleMomenta[3].setE ( pT*cosh(y)); particleMomenta[3].setX ( pT*cos(phi)); particleMomenta[3].setY ( pT*sin(phi)); particleMomenta[3].setZ ( pT*sinh(y)); particleMomenta[3].setMass( ZERO); return true; } bool PerturbativeDecayer::psCheck(const double xg, const double xs) { // check is point is in allowed region of phase space double xe_star = (1.-s2_+e2_-xg)/sqrt(1.-xg); double xg_star = xg/sqrt(1.-xg); if ((sqr(xe_star)-4.*e2_) < 1e-10) return false; double xs_max = (4.+4.*s2_-sqr(xe_star+xg_star)+ sqr(sqrt(sqr(xe_star)-4.*e2_)+xg_star))/ 4.; double xs_min = (4.+4.*s2_-sqr(xe_star+xg_star)+ sqr(sqrt(sqr(xe_star)-4.*e2_)-xg_star))/ 4.; if (xs < xs_min || xs > xs_max) return false; return true; } pair PerturbativeDecayer::calculateDipole(const DipoleType & dipoleId, const Particle & inpart, const ParticleVector & decay3) { // calculate dipole for decay b->ac pair dipole = make_pair(0.,0.); double x1 = 2.*decay3[0]->momentum().e()/mb_; double x2 = 2.*decay3[1]->momentum().e()/mb_; double xg = 2.*decay3[2]->momentum().e()/mb_; double mu12 = sqr(decay3[0]->mass()/mb_); double mu22 = sqr(decay3[1]->mass()/mb_); tcPDPtr part[3] = {inpart.dataPtr(),decay3[0]->dataPtr(),decay3[1]->dataPtr()}; if(dipoleId.type==FFa || dipoleId.type == IFa || dipoleId.type == IFba) { swap(part[1],part[2]); swap(x1,x2); swap(mu12,mu22); } // radiation from b with initial-final connection if (dipoleId.type==IFba || dipoleId.type==IFbc) { dipole.first = -2./sqr(xg); dipole.first *= colourCoeff(part[0],part[1],part[2],dipoleId); } // radiation from a/c with initial-final connection else if (dipoleId.type==IFa || dipoleId.type==IFc) { double z = 1. - xg/(1.-mu22+mu12); dipole.first = (-2.*mu12/sqr(1.-x2+mu22-mu12) + (1./(1.-x2+mu22-mu12))* (2./(1.-z)-dipoleSpinFactor(part[1],z))); dipole.first *= colourCoeff(part[1],part[0],part[2],dipoleId); } // radiation from a/c with final-final connection else if (dipoleId.type==FFa || dipoleId.type==FFc) { double z = 1. + ((x1-1.+mu22-mu12)/(x2-2.*mu22)); double y = (1.-x2-mu12+mu22)/(1.-mu12-mu22); double vt = sqrt((1.-sqr(e_+s_))*(1.-sqr(e_-s_)))/(1.-mu12-mu22); double v = sqrt(sqr(2.*mu22+(1.-mu12-mu22)*(1.-y))-4.*mu22) /(1.-y)/(1.-mu12-mu22); if(part[1]->iSpin()!=PDT::Spin1) { dipole.first = (1./(1.-x2+mu22-mu12))* ((2./(1.-z*(1.-y)))-vt/v*(dipoleSpinFactor(part[1],z)+(2.*mu12/(1.+mu22-mu12-x2)))); } else { dipole.first = (1./(1.-x2+mu22-mu12))* (1./(1.-z*(1.-y))+1./(1.-(1.-z)*(1.-y))+(z*(1.-z)-2.)/v-vt/v*(2.*mu12/(1.+mu22-mu12-x2))); dipole.second = (1./(1.-x2+mu22-mu12))* (2./(1.-z*(1.-y))+(z*(1.-z)-2.)/v-vt/v*(2.*mu12/(1.+mu22-mu12-x2))); dipole.second *= colourCoeff(part[1],part[2],part[0],dipoleId); } dipole.first *= colourCoeff(part[1],part[2],part[0],dipoleId); } // special for the case that all particles are gluons else if(dipoleId.type==FFg) { double z = (1.-x2)/xg; double y = 1.-xg; dipole.first = 1./(1.-xg)*(1./(1.-z*(1.-y))+1./(1.-(1.-z)*(1.-y))+(z*(1.-z)-2.)); dipole.first *= colourCoeff(part[1],part[2],part[0],dipoleId); } else assert(false); // coupling prefactors if(dipole.second==0.) dipole.second=dipole.first; dipole.first *= 8.*Constants::pi; dipole.second *= 8.*Constants::pi; // return the answer return dipole; } double PerturbativeDecayer::dipoleSpinFactor(tcPDPtr part, double z){ // calculate the spin dependent component of the dipole if (part->iSpin()==PDT::Spin0) return 2.; else if (part->iSpin()==PDT::Spin1Half) return (1. + z); else if (part->iSpin()==PDT::Spin1) return -(z*(1.-z) - 1./(1.-z) + 1./z -2.); return 0.; } namespace { double colourCharge(PDT::Colour icol) { switch(icol) { case PDT::Colour0 : return 0.; case PDT::Colour3 : case PDT::Colour3bar : return 4./3.; case PDT::Colour8: return 3.; case PDT::Colour6 : case PDT::Colour6bar : return 10./3.; default : assert(false); + return 0.; } } } double PerturbativeDecayer::colourCoeff(tcPDPtr emitter, tcPDPtr spectator, tcPDPtr other, DipoleType dipole) { if(dipole.interaction==ShowerInteraction::QCD) { double emitterColour = colourCharge(emitter ->iColour()); double spectatorColour = colourCharge(spectator->iColour()); double otherColour = colourCharge(other ->iColour()); double val = 0.5*(sqr(emitterColour)+sqr(spectatorColour)-sqr(otherColour))/emitterColour; return val; } else { double val = double(emitter->iCharge()*spectator->iCharge())/9.; // FF dipoles if(dipole.type==FFa || dipole.type == FFc) return -val; // IF dipoles else return val; } } void PerturbativeDecayer::getColourLines(RealEmissionProcessPtr real) { // extract the particles vector branchingPart; branchingPart.push_back(real->incoming()[0]); for(unsigned int ix=0;ixoutgoing().size();++ix) { branchingPart.push_back(real->outgoing()[ix]); } vector sing,trip,atrip,oct,sex,asex; for (size_t ib=0;ibdataPtr()->iColour()==PDT::Colour0 ) sing. push_back(ib); else if(branchingPart[ib]->dataPtr()->iColour()==PDT::Colour3 ) trip. push_back(ib); else if(branchingPart[ib]->dataPtr()->iColour()==PDT::Colour3bar) atrip.push_back(ib); else if(branchingPart[ib]->dataPtr()->iColour()==PDT::Colour8 ) oct. push_back(ib); else if(branchingPart[ib]->dataPtr()->iColour()==PDT::Colour6 ) sex. push_back(ib); else if(branchingPart[ib]->dataPtr()->iColour()==PDT::Colour6bar) asex. push_back(ib); } // decaying colour singlet if (branchingPart[0]->dataPtr()->iColour()==PDT::Colour0) { // 0 -> 3 3bar if (trip.size()==1 && atrip.size()==1) { if(real->interaction()==ShowerInteraction::QCD) { branchingPart[atrip[0]]->colourConnect(branchingPart[ 3 ]); branchingPart[ 3 ]->colourConnect(branchingPart[trip[0]]); } else { branchingPart[atrip[0]]->colourConnect(branchingPart[trip[0]]); } } // 0 -> 8 8 else if (oct.size()==2 ) { if(real->interaction()==ShowerInteraction::QCD) { bool col = UseRandom::rndbool(); branchingPart[oct[0]]->colourConnect(branchingPart[ 3 ],col); branchingPart[ 3 ]->colourConnect(branchingPart[oct[1]],col); branchingPart[oct[1]]->colourConnect(branchingPart[oct[0]],col); } else { branchingPart[oct[0]]->colourConnect(branchingPart[oct[1]]); branchingPart[oct[1]]->colourConnect(branchingPart[oct[0]]); } } else assert(real->interaction()==ShowerInteraction::QED); } // decaying colour triplet else if (branchingPart[0]->dataPtr()->iColour()==PDT::Colour3 ) { // 3 -> 3 0 if (trip.size()==2 && sing.size()==1) { if(real->interaction()==ShowerInteraction::QCD) { branchingPart[3]->incomingColour(branchingPart[trip[0]]); branchingPart[3]-> colourConnect(branchingPart[trip[1]]); } else { branchingPart[trip[1]]->incomingColour(branchingPart[trip[0]]); } } // 3 -> 3 8 else if (trip.size()==2 && oct.size()==1) { if(real->interaction()==ShowerInteraction::QCD) { // 8 emit incoming partner if(real->emitter()==oct[0]&&real->spectator()==0) { branchingPart[ 3 ]->incomingColour(branchingPart[trip[0]]); branchingPart[ 3 ]-> colourConnect(branchingPart[oct[0] ]); branchingPart[oct[0]]-> colourConnect(branchingPart[trip[1]]); } // 8 emit final spectator or vice veras else { branchingPart[oct[0]]->incomingColour(branchingPart[trip[0]]); branchingPart[oct[0]]-> colourConnect(branchingPart[ 3 ]); branchingPart[ 3 ]-> colourConnect(branchingPart[trip[1]]); } } else { branchingPart[oct[0]]->incomingColour(branchingPart[trip[0]]); branchingPart[oct[0]]-> colourConnect(branchingPart[trip[1]]); } } // 3 -> 3bar 3bar else if(trip.size() ==1 && atrip.size()==2) { if(real->interaction()==ShowerInteraction::QCD) { if(real->emitter()==atrip[0]) { branchingPart[3]->colourConnect(branchingPart[atrip[0]],true); tColinePtr col[3] = {ColourLine::create(branchingPart[ trip[0]],false), ColourLine::create(branchingPart[ 3],true ), ColourLine::create(branchingPart[atrip[1]],true)}; col[0]->setSinkNeighbours(col[1],col[2]); } else { branchingPart[3]->colourConnect(branchingPart[atrip[1]],true); tColinePtr col[3] = {ColourLine::create(branchingPart[ trip[0]],false), ColourLine::create(branchingPart[atrip[0]],true ), ColourLine::create(branchingPart[ 3],true)}; col[0]->setSinkNeighbours(col[1],col[2]); } } else { tColinePtr col[3] = {ColourLine::create(branchingPart[ trip[0]],false), ColourLine::create(branchingPart[atrip[0]],true ), ColourLine::create(branchingPart[atrip[1]],true)}; col[0]->setSinkNeighbours(col[1],col[2]); } } else assert(false); } // decaying colour anti-triplet else if (branchingPart[0]->dataPtr()->iColour()==PDT::Colour3bar) { // 3bar -> 3bar 0 if (atrip.size()==2 && sing.size()==1) { if(real->interaction()==ShowerInteraction::QCD) { branchingPart[3]->incomingColour(branchingPart[atrip[0]],true); branchingPart[3]-> colourConnect(branchingPart[atrip[1]],true); } else { branchingPart[atrip[1]]->incomingColour(branchingPart[atrip[0]],true); } } // 3 -> 3 8 else if (atrip.size()==2 && oct.size()==1){ if(real->interaction()==ShowerInteraction::QCD) { // 8 emit incoming partner if(real->emitter()==oct[0]&&real->spectator()==0) { branchingPart[ 3 ]->incomingColour(branchingPart[atrip[0]],true); branchingPart[ 3 ]-> colourConnect(branchingPart[oct[0] ],true); branchingPart[oct[0]]-> colourConnect(branchingPart[atrip[1]],true); } // 8 emit final spectator or vice veras else { if(real->interaction()==ShowerInteraction::QCD) { branchingPart[oct[0]]->incomingColour(branchingPart[atrip[0]],true); branchingPart[oct[0]]-> colourConnect(branchingPart[ 3 ],true); branchingPart[3]-> colourConnect(branchingPart[atrip[1]] ,true); } } } else { branchingPart[oct[0]]->incomingColour(branchingPart[atrip[0]],true); branchingPart[oct[0]]-> colourConnect(branchingPart[atrip[1]],true); } } // 3bar -> 3 3 else if(atrip.size() ==1 && trip.size()==2) { if(real->interaction()==ShowerInteraction::QCD) { if(real->emitter()==trip[0]) { branchingPart[3]->colourConnect(branchingPart[trip[0]],false); tColinePtr col[3] = {ColourLine::create(branchingPart[atrip[0]],true ), ColourLine::create(branchingPart[ 3],false), ColourLine::create(branchingPart[ trip[1]],false)}; col[0]->setSourceNeighbours(col[1],col[2]); } else { branchingPart[3]->colourConnect(branchingPart[trip[1]],false); tColinePtr col[3] = {ColourLine::create(branchingPart[atrip[0]],true ), ColourLine::create(branchingPart[ trip[0]],false), ColourLine::create(branchingPart[ 3],false)}; col[0]->setSourceNeighbours(col[1],col[2]); } } else { tColinePtr col[3] = {ColourLine::create(branchingPart[atrip[0]],true ), ColourLine::create(branchingPart[ trip[0]],false), ColourLine::create(branchingPart[ trip[1]],false)}; col[0]->setSourceNeighbours(col[1],col[2]); } } else assert(false); } // decaying colour octet else if(branchingPart[0]->dataPtr()->iColour()==PDT::Colour8 ) { // 8 -> 3 3bar if (trip.size()==1 && atrip.size()==1) { if(real->interaction()==ShowerInteraction::QCD) { // 3 emits if(trip[0]==real->emitter()) { branchingPart[3] ->incomingColour(branchingPart[oct[0]] ); branchingPart[3] -> colourConnect(branchingPart[trip[0]]); branchingPart[atrip[0]]->incomingColour(branchingPart[oct[0]],true); } // 3bar emits else { branchingPart[3] ->incomingColour(branchingPart[oct[0]] ,true); branchingPart[3] -> colourConnect(branchingPart[atrip[0]],true); branchingPart[trip[0]]->incomingColour(branchingPart[oct[0]] ); } } else { branchingPart[trip[0]]->incomingColour(branchingPart[oct[0]] ); branchingPart[atrip[0]]->incomingColour(branchingPart[oct[0]],true); } } // 8 -> 8 0 else if (sing.size()==1 && oct.size()==2) { if(real->interaction()==ShowerInteraction::QCD) { bool col = UseRandom::rndbool(); branchingPart[ 3 ]->colourConnect (branchingPart[oct[1]], col); branchingPart[ 3 ]->incomingColour(branchingPart[oct[0]], col); branchingPart[oct[1]]->incomingColour(branchingPart[oct[0]],!col); } else { branchingPart[oct[1]]->incomingColour(branchingPart[oct[0]]); branchingPart[oct[1]]->incomingColour(branchingPart[oct[0]],true); } } else assert(false); } // sextet else if(branchingPart[0]->dataPtr()->iColour() == PDT::Colour6) { if(trip.size()==2) { if(real->interaction()==ShowerInteraction::QCD) { Ptr::pointer parentColour = dynamic_ptr_cast::pointer> (branchingPart[0]->colourInfo()); if(trip[0]==real->emitter()) { ColinePtr cline = new_ptr(ColourLine()); parentColour->colourLine(cline); cline->addColoured(branchingPart[3]); branchingPart[3] -> colourConnect(branchingPart[trip[0]]); cline = new_ptr(ColourLine()); parentColour->colourLine(cline); cline->addColoured(branchingPart[trip[1]]); } else { ColinePtr cline = new_ptr(ColourLine()); parentColour->colourLine(cline); cline->addColoured(branchingPart[3]); branchingPart[3] -> colourConnect(branchingPart[trip[1]]); cline = new_ptr(ColourLine()); parentColour->colourLine(cline); cline->addColoured(branchingPart[trip[0]]); } } else { Ptr::pointer parentColour = dynamic_ptr_cast::pointer> (branchingPart[0]->colourInfo()); for(unsigned int ix=0;ix<2;++ix) { ColinePtr cline = new_ptr(ColourLine()); parentColour->colourLine(cline); cline->addColoured(branchingPart[trip[ix]]); } } } else assert(false); } // antisextet else if(branchingPart[0]->dataPtr()->iColour() == PDT::Colour6bar) { if(atrip.size()==2) { if(real->interaction()==ShowerInteraction::QCD) { Ptr::pointer parentColour = dynamic_ptr_cast::pointer> (branchingPart[0]->colourInfo()); if(atrip[0]==real->emitter()) { ColinePtr cline = new_ptr(ColourLine()); parentColour->antiColourLine(cline); cline->addAntiColoured(branchingPart[3]); branchingPart[3]->antiColourConnect(branchingPart[atrip[0]]); cline = new_ptr(ColourLine()); parentColour->antiColourLine(cline); cline->addAntiColoured(branchingPart[atrip[1]]); } else { ColinePtr cline = new_ptr(ColourLine()); parentColour->antiColourLine(cline); cline->addAntiColoured(branchingPart[3]); branchingPart[3]->antiColourConnect(branchingPart[atrip[1]]); cline = new_ptr(ColourLine()); parentColour->antiColourLine(cline); cline->addAntiColoured(branchingPart[trip[0]]); } } else { Ptr::pointer parentColour = dynamic_ptr_cast::pointer> (branchingPart[0]->colourInfo()); for(unsigned int ix=0;ix<2;++ix) { ColinePtr cline = new_ptr(ColourLine()); parentColour->antiColourLine(cline); cline->addColoured(branchingPart[atrip[ix]],true); } } } else assert(false); } else assert(false); } PerturbativeDecayer::phaseSpaceRegion PerturbativeDecayer::inInitialFinalDeadZone(double xg, double xa, double a, double c) const { double lam = sqrt(1.+a*a+c*c-2.*a-2.*c-2.*a*c); double kappab = 1.+0.5*(1.-a+c+lam); double kappac = kappab-1.+c; double kappa(0.); // check whether or not in the region for emission from c double r = 0.5; if(c!=0.) r += 0.5*c/(1.+a-xa); double pa = sqrt(sqr(xa)-4.*a); double z = ((2.-xa)*(1.-r)+r*pa-xg)/pa; if(z<1. && z>0.) { kappa = (1.+a-c-xa)/(z*(1.-z)); if(kappa-1e-10) v= 0.; v = sqrt(v); if(xa<0.5*((u+v)/w+(u-v)/z)) { if(xg0.) { if((1.-b+c-xc)/(z*(1.-z))<0.5*(1.+b-c+lam)) return emissionFromB; } // check whether or not in the region for emission from c r = 0.5; if(c!=0.) r+=0.5*c/(1.+b-xb); double pb = sqrt(sqr(xb)-4.*b); z = -((2.-xb)*r-r*pb-xc)/pb; if(z<1. and z>0.) { if((1.-c+b-xb)/(z*(1.-z))<0.5*(1.-b+c+lam)) return emissionFromC; } return deadZone; } bool PerturbativeDecayer::inTotalDeadZone(double xg, double xs, const vector & dipoles, int i) { double xb,xc,b,c; if(dipoles[i].type==FFa || dipoles[i].type == IFa || dipoles[i].type == IFba) { xc = xs; xb = 2.-xg-xs; b = e2_; c = s2_; } else { xb = xs; xc = 2.-xg-xs; b = s2_; c = e2_; } for(unsigned int ix=0;ix1 if(_cosphot[iphot]>0.0) ombc=ombeta1+beta1*sqr(_sinphot[iphot])/(1.+_cosphot[iphot]); // if cos is less than zero use result accurate as cos->-1 else ombc=1.-beta1*_cosphot[iphot]; return 1.0*sqr(beta1*_sinphot[iphot]/ombc); } /** * The crude YFS form factor for calculating the weight * @param b Velocity of the first charged particle, \f$\beta_1\f$ * @param omb One minus the velocity of the first particle, \f$1-\beta_1\f$ * @return The YFS form factor */ double crudeYFSFormFactor(double b,double omb) { double Y =-_alpha/pi*_chrg1*_chrg2 / b * log((1.+b)/omb) * log(_m[0]/(2.*_emin)); return exp(Y); } /** * The exact YFS form factor for calculating the weight * @param beta1 Velocity of the first charged particle, \f$\beta_1\f$ * @param beta2 Velocity of the second charged particle, \f$\beta_2\f$. * @param ombeta1 One minus the velocity of the first particle, \f$1-\beta_1\f$ * @param ombeta2 One minus the velocity of the second particle, \f$1-\beta_2\f$ * @return The YFS form factor */ double exactYFSFormFactor(double beta1,double ombeta1, double beta2,double ombeta2); /** * Jacobian factor for the weight */ double jacobianWeight(); /** * Matrix element weight */ double meWeight(ParticleVector children); /** * Member which generates the photons * @param boost Boost vector to take the particles produced back from * the decaying particle's rest frame to the lab * @param children The decay products */ double makePhotons(Boost boost,ParticleVector children); /** * Compute a Lorentz transform from p to q * @param p Original momentum * @param q Final momentum */ LorentzRotation solveBoost(const Lorentz5Momentum & q, const Lorentz5Momentum & p ) const; private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ IFDipole & operator=(const IFDipole &) = delete; private: /** * the fine structure constant at $q^2=0$ */ double _alpha; /** * The minimum photon energy */ Energy _emin; /** * The maximum photon energy */ Energy _emax; /** * Photon multiplicity being generated */ unsigned int _multiplicity; /** * Map from arguments of lists such that * _q???[_map[0]] is the charged child and * _q???[_map[1]] is the neutral child. */ vector _map; /** * Masses of the particles involved */ vector _m; /** * charge of the parent particle */ double _chrg1; /** * charge of the (charged) child particle */ double _chrg2; /** * Momentum of the particles in the parent's rest frame */ //@{ /** * Momenta of the charged particles in the parent's rest frame before radiation */ vector _qprf; /** * Momenta of the charged particles in the parent's rest frame after radiation */ vector _qnewprf; /** * Momenta of the photons in the parent rest frame */ vector _lprf; /** * Total momentum of the photons in the parent rest frame */ Lorentz5Momentum _bigLprf; //@} /** * Momentum of the particles in the lab frame */ //@{ /** * Momenta of the charged particles in the lab frame before radiation */ vector _qlab; /** * Momenta of the charged particles in the lab frame after radiation */ vector _qnewlab; /** * Momenta of the photons in the lab frame */ vector _llab; /** * Total momentum of the photons in the lab frame */ Lorentz5Momentum _bigLlab; //@} /** * Reweighting factors due to differences between the true and crude * distributions */ //@{ /** * Reweighting factor for the real emission */ double _dipolewgt; /** * Reweighting factor for the YFS form-factor */ double _yfswgt; /** * Reweighting factor due to phase space */ double _jacobianwgt; /** * Reweighting factor due to matrix element corrections */ double _mewgt; /** * Maximum weight */ double _maxwgt; //@} /** * Angles of the photons with respect to the first charged particle * which are stored for numerical accuracy */ //@{ /** * Cosine of the photon angles */ vector _cosphot; /** * Sine of the photon angles */ vector _sinphot; //@} /** * Type of unweighting to perform */ unsigned int _mode; /** * Maximum number of attempts to generate a result */ unsigned int _maxtry; /** * Option for the energy cut-off */ unsigned int _energyopt; /** * Option for the inclusion of higher order corrections */ unsigned int _betaopt; - /** - * Option for the form of the primary distribution - */ - unsigned int _dipoleopt; }; } #endif /* HERWIG_IFDipole_H */ diff --git a/Decay/WeakCurrents/OmegaPiPiCurrent.cc b/Decay/WeakCurrents/OmegaPiPiCurrent.cc --- a/Decay/WeakCurrents/OmegaPiPiCurrent.cc +++ b/Decay/WeakCurrents/OmegaPiPiCurrent.cc @@ -1,314 +1,314 @@ -+// -*- C++ -*- +// -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the OmegaPiPiCurrent class. // #include "OmegaPiPiCurrent.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; OmegaPiPiCurrent::OmegaPiPiCurrent() { mRes_ = 1.69*GeV; wRes_ = 0.285*GeV; gRes_ = 1.63*GeV; mSigma_ = 0.6*GeV; wSigma_ = 1.0*GeV; mf0_ = 0.98*GeV; gSigma_ = 1.0 *GeV2; gf0_ = 0.883*GeV2; gPiPi_ = 0.165*GeV2; gKK_ = 0.695*GeV2; addDecayMode(1,-1); addDecayMode(1,-1); setInitialModes(2); } IBPtr OmegaPiPiCurrent::clone() const { return new_ptr(*this); } IBPtr OmegaPiPiCurrent::fullclone() const { return new_ptr(*this); } void OmegaPiPiCurrent::persistentOutput(PersistentOStream & os) const { os << ounit(mRes_,GeV) << ounit(wRes_,GeV) << ounit(gRes_,GeV) << ounit(mSigma_,GeV) << ounit(wSigma_,GeV) << ounit(mf0_,GeV) << ounit(gPiPi_,GeV2) << ounit(gKK_,GeV2) << ounit(gSigma_,GeV2) << ounit(gf0_,GeV2); } void OmegaPiPiCurrent::persistentInput(PersistentIStream & is, int) { is >> iunit(mRes_,GeV) >> iunit(wRes_,GeV) >> iunit(gRes_,GeV) >> iunit(mSigma_,GeV) >> iunit(wSigma_,GeV) >> iunit(mf0_,GeV) >> iunit(gPiPi_,GeV2) >> iunit(gKK_,GeV2) >> iunit(gSigma_,GeV2) >> iunit(gf0_,GeV2); } void OmegaPiPiCurrent::doinit() { WeakCurrent::doinit(); } // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeHerwigOmegaPiPiCurrent("Herwig::OmegaPiPiCurrent", "HwWeakCurrents.so"); void OmegaPiPiCurrent::Init() { static ClassDocumentation documentation ("The OmegaPiPiCurrent class provides the current for I=0 omega pi pi"); static Parameter interfacemRes ("mRes", "The mass of the s-channel resonance", &OmegaPiPiCurrent::mRes_, GeV, 1.62*GeV, 0.*GeV, 10.*GeV, false, false, Interface::limited); static Parameter interfacewRes ("wRes", "The width of the s-channel resonance", &OmegaPiPiCurrent::wRes_, GeV, 0.288*GeV, 0.0*GeV, 10.0*GeV, false, false, Interface::limited); static Parameter interfacegRes ("gRes", "The coupling of the s-channel resonance", &OmegaPiPiCurrent::gRes_, GeV, 2.83*GeV, 0.0*GeV, 10.0*GeV, false, false, Interface::limited); static Parameter interfacemSigma ("mSigma", "The mass of the Sigma", &OmegaPiPiCurrent::mSigma_, GeV, 0.6*GeV, 0.0*GeV, 10.0*GeV, false, false, Interface::limited); static Parameter interfacewSigma ("wSigma", "The width of the Sigma", &OmegaPiPiCurrent::wSigma_, GeV, 1.0*GeV, 0.0*GeV, 10.0*GeV, false, false, Interface::limited); static Parameter interfacegSigma ("gSigma", "The coupling of the Sigma resonance", &OmegaPiPiCurrent::gSigma_, GeV2, 1.0*GeV2, 0.0*GeV2, 10.0*GeV2, false, false, Interface::limited); static Parameter interfacemf0 ("mf0", "The mass of the f_0(980)", &OmegaPiPiCurrent::mf0_, GeV, 0.98*GeV, 0.0*GeV, 10.0*GeV, false, false, Interface::limited); static Parameter interfacegf0 ("gf0", "The coupling of the f0(980) resonance", &OmegaPiPiCurrent::gf0_, GeV2, 1.0*GeV2, 0.0*GeV2, 10.0*GeV2, false, false, Interface::limited); static Parameter interfacegPiPi ("gPiPi", "The coupling of the f_0(980) to pipi", &OmegaPiPiCurrent::gPiPi_, GeV2, 0.165*GeV2, 0.0*GeV2, 10.0*GeV2, false, false, Interface::limited); static Parameter interfacegKK ("gKK", "The coupling of the f_0(980) to KK", &OmegaPiPiCurrent::gKK_, GeV2, 0.695*GeV2, 0.0*GeV2, 10.0*GeV2, false, false, Interface::limited); } // complete the construction of the decay mode for integration bool OmegaPiPiCurrent::createMode(int icharge, tcPDPtr resonance, FlavourInfo flavour, unsigned int, PhaseSpaceModePtr mode, unsigned int iloc,int ires, PhaseSpaceChannel phase, Energy upp ) { // check the charge if(icharge!=0) return false; // check the total isospin if(flavour.I!=IsoSpin::IUnknown && flavour.I!=IsoSpin::IZero) return false; // check I_3 if(flavour.I3!=IsoSpin::I3Unknown && flavour.I3!=IsoSpin::I3Zero) return false; // and other flavour if(flavour.strange != Strangeness::Unknown and flavour.strange != Strangeness::Zero) return false; if(flavour.charm != Charm::Unknown and flavour.charm != Charm::Zero ) return false; if(flavour.bottom != Beauty::Unknown and flavour.bottom !=Beauty::Zero ) return false; // check that the mode is are kinematical allowed Energy min = getParticleData(ParticleID::omega)->massMin()+ 2.*getParticleData(ParticleID::pi0)->mass(); if(min>upp) return false; // resonances for the intermediate channels tPDVector res = {getParticleData(30223)}; tPDVector res2 = {getParticleData(9000221),getParticleData(9010221)}; // set up the integration channels; for(unsigned int ix=0;ixaddChannel((PhaseSpaceChannel(phase),ires,res[ix], ires+1,iloc+1,ires+1,res2[iy],ires+2,iloc+2,ires+2,iloc+3)); } } return true; } // the particles produced by the current tPDVector OmegaPiPiCurrent::particles(int icharge, unsigned int imode,int,int) { assert(icharge==0 && imode<=1); if(imode==0) return {getParticleData(ParticleID::omega), getParticleData(ParticleID::piplus), getParticleData(ParticleID::piminus)}; else if(imode==1) return {getParticleData(ParticleID::omega), getParticleData(ParticleID::pi0), getParticleData(ParticleID::pi0)}; else assert(false); } void OmegaPiPiCurrent::constructSpinInfo(ParticleVector decay) const { vector temp(3); for(unsigned int ix=0;ix<3;++ix) { temp[ix] = HelicityFunctions::polarizationVector(-decay[0]->momentum(), ix,Helicity::outgoing); } VectorWaveFunction::constructSpinInfo(temp,decay[0], outgoing,true,true); for(unsigned int ix=1;ix<3;++ix) ScalarWaveFunction::constructSpinInfo(decay[ix],outgoing,true); } // the hadronic currents vector OmegaPiPiCurrent::current(tcPDPtr resonance, FlavourInfo flavour, const int, const int ichan, Energy & scale, const tPDVector & , const vector & momenta, DecayIntegrator::MEOption) const { // no isospin/flavour here if(flavour.I!=IsoSpin::IUnknown && flavour.I!=IsoSpin::IZero) return vector(); if(flavour.I3!=IsoSpin::I3Unknown && flavour.I3!=IsoSpin::I3Zero) return vector(); if(flavour.strange != Strangeness::Unknown and flavour.strange != Strangeness::Zero) return vector(); if(flavour.charm != Charm::Unknown and flavour.charm != Charm::Zero ) return vector(); if(flavour.bottom != Beauty::Unknown and flavour.bottom !=Beauty::Zero ) return vector(); if(resonance and resonance->id()!=30223) return vector(); useMe(); // polarization vectors of the omega vector temp(3); for(unsigned int ix=0;ix<3;++ix) { temp[ix] = HelicityFunctions::polarizationVector(-momenta[0],ix,Helicity::outgoing); } // total momentum of the system Lorentz5Momentum q(momenta[0]+momenta[1]+momenta[2]); // overall hadronic mass q.rescaleMass(); scale=q.mass(); Complex ii(0.,1.); Energy2 q2(q.m2()); // resonance factor for s channel resonance Energy2 mR2=sqr(mRes_); complex pre= mR2*gRes_/(q2-mR2 - ii*scale*wRes_); //cerr << "pre factor " << scale/GeV << " " << q2/GeV2 << " " << pre/GeV << "\n"; // for(auto p : momenta) cerr << p/GeV << " " << p.m()/GeV << "\n"; // virtual mass energy for intermediate f0 channel Energy2 s1 = (momenta[1]+momenta[2]).m2(); Energy sqrs1 = sqrt(s1); //sigma meson Energy2 mSigma2 = sqr(mSigma_); Complex Sigma_form = gSigma_/(mSigma2 -s1 - ii*sqrs1*wSigma_); // compute the form factor Energy2 mf02 = sqr(mf0_); Energy mPi = getParticleData(211)->mass(); Energy2 mPi2 = sqr(mPi); complex mGamma = gPiPi_*sqrt(max(0.,1.-4.*mPi2/s1)); // cerr << "testing pi " << mGamma/GeV2 << " " << gPiPi_/GeV2 << " " << sqrt(max(0.,1.-4.*mPi2/s1))<< "\n"; Energy2 mKp2 = sqr(getParticleData(321)->mass()); double val = 1.-4.*mKp2/s1; if(val>=0.) mGamma += 0.5*gKK_* sqrt( val); else mGamma += 0.5*gKK_*ii*sqrt(-val); Energy2 mK02 = sqr(getParticleData(311)->mass()); val = 1.-4.*mK02/s1; if(val>=0.) mGamma += 0.5*gKK_* sqrt( val); else mGamma += 0.5*gKK_*ii*sqrt(-val); Complex f0_form = gf0_/(mf02-s1-Complex(0.,1.)*mGamma); // cerr << "f0 pieces " << mGamma/GeV2 << "\n"; // cerr << "testing form factor " << s1/GeV2 << " " << f0_form << " " << Sigma_form << "\n"; complex formFactor(ZERO); if(ichan<0) formFactor = (Sigma_form+f0_form)*pre; else if(ichan==0) formFactor = Sigma_form*pre; else if(ichan==1) formFactor = f0_form*pre; // calculate the current vector ret(3); for(unsigned int ix=0;ix<3;++ix) { ret[ix] = formFactor*temp[ix]; } return ret; } bool OmegaPiPiCurrent::accept(vector id) { if(id.size()!=3) return false; unsigned int nomega(0),npip(0),npim(0),npi0(0); for(unsigned int ix=0;ix id) { unsigned int npi0(0); for(unsigned int ix=0;ix #include #include #include #include #include #include #include "Herwig/Utilities/Kinematics.h" #include "CheckId.h" #include "Cluster.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include using namespace Herwig; DescribeClass describeClusterFissioner("Herwig::ClusterFissioner","Herwig.so"); ClusterFissioner::ClusterFissioner() : _clMaxLight(3.35*GeV), _clMaxBottom(3.35*GeV), _clMaxCharm(3.35*GeV), _clMaxExotic(3.35*GeV), _clPowLight(2.0), _clPowBottom(2.0), _clPowCharm(2.0), _clPowExotic(2.0), _pSplitLight(1.0), _pSplitBottom(1.0), _pSplitCharm(1.0), _pSplitExotic(1.0), - _fissionCluster(0), _fissionPwtUquark(1), _fissionPwtDquark(1), _fissionPwtSquark(0.5), + _fissionCluster(0), _btClM(1.0*GeV), _iopRem(1), _kappa(1.0e15*GeV/meter), _enhanceSProb(0), _m0Fission(2.*GeV), _massMeasure(0) {} IBPtr ClusterFissioner::clone() const { return new_ptr(*this); } IBPtr ClusterFissioner::fullclone() const { return new_ptr(*this); } void ClusterFissioner::persistentOutput(PersistentOStream & os) const { os << _hadronsSelector << ounit(_clMaxLight,GeV) << ounit(_clMaxBottom,GeV) << ounit(_clMaxCharm,GeV) << ounit(_clMaxExotic,GeV) << _clPowLight << _clPowBottom << _clPowCharm << _clPowExotic << _pSplitLight << _pSplitBottom << _pSplitCharm << _pSplitExotic << _fissionCluster << _fissionPwtUquark << _fissionPwtDquark << _fissionPwtSquark << ounit(_btClM,GeV) << _iopRem << ounit(_kappa, GeV/meter) << _enhanceSProb << ounit(_m0Fission,GeV) << _massMeasure; } void ClusterFissioner::persistentInput(PersistentIStream & is, int) { is >> _hadronsSelector >> iunit(_clMaxLight,GeV) >> iunit(_clMaxBottom,GeV) >> iunit(_clMaxCharm,GeV) >> iunit(_clMaxExotic,GeV) >> _clPowLight >> _clPowBottom >> _clPowCharm >> _clPowExotic >> _pSplitLight >> _pSplitBottom >> _pSplitCharm >> _pSplitExotic >> _fissionCluster >> _fissionPwtUquark >> _fissionPwtDquark >> _fissionPwtSquark >> iunit(_btClM,GeV) >> _iopRem >> iunit(_kappa, GeV/meter) >> _enhanceSProb >> iunit(_m0Fission,GeV) >> _massMeasure; } void ClusterFissioner::Init() { static ClassDocumentation documentation ("Class responsibles for chopping up the clusters"); static Reference interfaceHadronSelector("HadronSelector", "A reference to the HadronSelector object", &Herwig::ClusterFissioner::_hadronsSelector, false, false, true, false); // ClMax for light, Bottom, Charm and exotic (e.g. Susy) quarks static Parameter interfaceClMaxLight ("ClMaxLight","cluster max mass for light quarks (unit [GeV])", &ClusterFissioner::_clMaxLight, GeV, 3.35*GeV, ZERO, 10.0*GeV, false,false,false); static Parameter interfaceClMaxBottom ("ClMaxBottom","cluster max mass for b quarks (unit [GeV])", &ClusterFissioner::_clMaxBottom, GeV, 3.35*GeV, ZERO, 10.0*GeV, false,false,false); static Parameter interfaceClMaxCharm ("ClMaxCharm","cluster max mass for c quarks (unit [GeV])", &ClusterFissioner::_clMaxCharm, GeV, 3.35*GeV, ZERO, 10.0*GeV, false,false,false); static Parameter interfaceClMaxExotic ("ClMaxExotic","cluster max mass for exotic quarks (unit [GeV])", &ClusterFissioner::_clMaxExotic, GeV, 3.35*GeV, ZERO, 10.0*GeV, false,false,false); // ClPow for light, Bottom, Charm and exotic (e.g. Susy) quarks static Parameter interfaceClPowLight ("ClPowLight","cluster mass exponent for light quarks", &ClusterFissioner::_clPowLight, 0, 2.0, 0.0, 10.0,false,false,false); static Parameter interfaceClPowBottom ("ClPowBottom","cluster mass exponent for b quarks", &ClusterFissioner::_clPowBottom, 0, 2.0, 0.0, 10.0,false,false,false); static Parameter interfaceClPowCharm ("ClPowCharm","cluster mass exponent for c quarks", &ClusterFissioner::_clPowCharm, 0, 2.0, 0.0, 10.0,false,false,false); static Parameter interfaceClPowExotic ("ClPowExotic","cluster mass exponent for exotic quarks", &ClusterFissioner::_clPowExotic, 0, 2.0, 0.0, 10.0,false,false,false); // PSplit for light, Bottom, Charm and exotic (e.g. Susy) quarks static Parameter interfacePSplitLight ("PSplitLight","cluster mass splitting param for light quarks", &ClusterFissioner::_pSplitLight, 0, 1.0, 0.0, 10.0,false,false,false); static Parameter interfacePSplitBottom ("PSplitBottom","cluster mass splitting param for b quarks", &ClusterFissioner::_pSplitBottom, 0, 1.0, 0.0, 10.0,false,false,false); static Parameter interfacePSplitCharm ("PSplitCharm","cluster mass splitting param for c quarks", &ClusterFissioner::_pSplitCharm, 0, 1.0, 0.0, 10.0,false,false,false); static Parameter interfacePSplitExotic ("PSplitExotic","cluster mass splitting param for exotic quarks", &ClusterFissioner::_pSplitExotic, 0, 1.0, 0.0, 10.0,false,false,false); static Switch interfaceFission ("Fission", "Option for different Fission options", &ClusterFissioner::_fissionCluster, 1, false, false); static SwitchOption interfaceFissionDefault (interfaceFission, "default", "Normal cluster fission which depends on the hadron selector class.", 0); static SwitchOption interfaceFissionNew (interfaceFission, "new", "Alternative cluster fission which does not depend on the hadron selector class", 1); static Parameter interfaceFissionPwtUquark ("FissionPwtUquark", "Weight for fission in U quarks", &ClusterFissioner::_fissionPwtUquark, 1, 0.0, 1.0, false, false, Interface::limited); static Parameter interfaceFissionPwtDquark ("FissionPwtDquark", "Weight for fission in D quarks", &ClusterFissioner::_fissionPwtDquark, 1, 0.0, 1.0, false, false, Interface::limited); static Parameter interfaceFissionPwtSquark ("FissionPwtSquark", "Weight for fission in S quarks", &ClusterFissioner::_fissionPwtSquark, 0.5, 0.0, 1.0, false, false, Interface::limited); static Switch interfaceRemnantOption ("RemnantOption", "Option for the treatment of remnant clusters", &ClusterFissioner::_iopRem, 1, false, false); static SwitchOption interfaceRemnantOptionSoft (interfaceRemnantOption, "Soft", "Both clusters produced in the fission of the beam cluster" " are treated as soft clusters.", 0); static SwitchOption interfaceRemnantOptionHard (interfaceRemnantOption, "Hard", "Only the cluster containing the remnant is treated as a soft cluster.", 1); static SwitchOption interfaceRemnantOptionVeryHard (interfaceRemnantOption, "VeryHard", "Even remnant clusters are treated as hard, i.e. all clusters the same", 2); static Parameter interfaceBTCLM ("SoftClusterFactor", "Parameter for the mass spectrum of remnant clusters", &ClusterFissioner::_btClM, GeV, 1.*GeV, 0.1*GeV, 10.0*GeV, false, false, Interface::limited); static Parameter interfaceStringTension ("StringTension", "String tension used in vertex displacement calculation", &ClusterFissioner::_kappa, GeV/meter, 1.0e15*GeV/meter, ZERO, ZERO, false, false, Interface::lowerlim); static Switch interfaceEnhanceSProb ("EnhanceSProb", "Option for enhancing strangeness", &ClusterFissioner::_enhanceSProb, 0, false, false); static SwitchOption interfaceEnhanceSProbNo (interfaceEnhanceSProb, "No", "No strangeness enhancement.", 0); static SwitchOption interfaceEnhanceSProbScaled (interfaceEnhanceSProb, "Scaled", "Scaled strangeness enhancement", 1); static SwitchOption interfaceEnhanceSProbExponential (interfaceEnhanceSProb, "Exponential", "Exponential strangeness enhancement", 2); static Switch interfaceMassMeasure ("MassMeasure", "Option to use different mass measures", &ClusterFissioner::_massMeasure,0,false,false); static SwitchOption interfaceMassMeasureMass (interfaceMassMeasure, "Mass", "Mass Measure", 0); static SwitchOption interfaceMassMeasureLambda (interfaceMassMeasure, "Lambda", "Lambda Measure", 1); static Parameter interfaceFissionMassScale ("FissionMassScale", "Cluster fission mass scale", &ClusterFissioner::_m0Fission, GeV, 2.0*GeV, 0.1*GeV, 50.*GeV, false, false, Interface::limited); } tPVector ClusterFissioner::fission(ClusterVector & clusters, bool softUEisOn) { // return if no clusters if (clusters.empty()) return tPVector(); /***************** * Loop over the (input) collection of cluster pointers, and store in * the vector splitClusters all the clusters that need to be split * (these are beam clusters, if soft underlying event is off, and * heavy non-beam clusters). ********************/ stack splitClusters; for(ClusterVector::iterator it = clusters.begin() ; it != clusters.end() ; ++it) { /************** * Skip 3-component clusters that have been redefined (as 2-component * clusters) or not available clusters. The latter check is indeed * redundant now, but it is used for possible future extensions in which, * for some reasons, some of the clusters found by ClusterFinder are tagged * straight away as not available. **************/ if((*it)->isRedefined() || !(*it)->isAvailable()) continue; // if the cluster is a beam cluster add it to the vector of clusters // to be split or if it is heavy if((*it)->isBeamCluster() || isHeavy(*it)) splitClusters.push(*it); } tPVector finalhadrons; cut(splitClusters, clusters, finalhadrons, softUEisOn); return finalhadrons; } void ClusterFissioner::cut(stack & clusterStack, ClusterVector &clusters, tPVector & finalhadrons, bool softUEisOn) { /************************************************** * This method does the splitting of the cluster pointed by cluPtr * and "recursively" by all of its cluster children, if heavy. All of these * new children clusters are added (indeed the pointers to them) to the * collection of cluster pointers collecCluPtr. The method works as follows. * Initially the vector vecCluPtr contains just the input pointer to the * cluster to be split. Then it will be filled "recursively" by all * of the cluster's children that are heavy enough to require, in their turn, * to be split. In each loop, the last element of the vector vecCluPtr is * considered (only once because it is then removed from the vector). * This approach is conceptually recursive, but avoid the overhead of * a concrete recursive function. Furthermore it requires minimal changes * in the case that the fission of an heavy cluster could produce more * than two cluster children as assumed now. * * Draw the masses: for normal, non-beam clusters a power-like mass dist * is used, whereas for beam clusters a fast-decreasing exponential mass * dist is used instead (to avoid many iterative splitting which could * produce an unphysical large transverse energy from a supposed soft beam * remnant process). ****************************************/ // Here we recursively loop over clusters in the stack and cut them while (!clusterStack.empty()) { // take the last element of the vector ClusterPtr iCluster = clusterStack.top(); clusterStack.pop(); // split it cutType ct = iCluster->numComponents() == 2 ? cutTwo(iCluster, finalhadrons, softUEisOn) : cutThree(iCluster, finalhadrons, softUEisOn); // There are cases when we don't want to split, even if it fails mass test if(!ct.first.first || !ct.second.first) { // if an unsplit beam cluster leave if for the underlying event if(iCluster->isBeamCluster() && softUEisOn) iCluster->isAvailable(false); continue; } // check if clusters ClusterPtr one = dynamic_ptr_cast(ct.first.first); ClusterPtr two = dynamic_ptr_cast(ct.second.first); // is a beam cluster must be split into two clusters if(iCluster->isBeamCluster() && (!one||!two) && softUEisOn) { iCluster->isAvailable(false); continue; } // There should always be a intermediate quark(s) from the splitting assert(ct.first.second && ct.second.second); /// \todo sort out motherless quark pairs here. Watch out for 'quark in final state' errors iCluster->addChild(ct.first.first); // iCluster->addChild(ct.first.second); // ct.first.second->addChild(ct.first.first); iCluster->addChild(ct.second.first); // iCluster->addChild(ct.second.second); // ct.second.second->addChild(ct.second.first); // Sometimes the clusters decay C -> H + C' rather then C -> C' + C'' if(one) { clusters.push_back(one); if(one->isBeamCluster() && softUEisOn) one->isAvailable(false); if(isHeavy(one) && one->isAvailable()) clusterStack.push(one); } if(two) { clusters.push_back(two); if(two->isBeamCluster() && softUEisOn) two->isAvailable(false); if(isHeavy(two) && two->isAvailable()) clusterStack.push(two); } } } namespace { /** * Check if can't make a hadron from the partons */ bool cantMakeHadron(tcPPtr p1, tcPPtr p2) { return ! CheckId::canBeHadron(p1->dataPtr(), p2->dataPtr()); } /** * Check if can't make a diquark from the partons */ bool cantMakeDiQuark(tcPPtr p1, tcPPtr p2) { long id1 = p1->id(), id2 = p2->id(); return ! (QuarkMatcher::Check(id1) && QuarkMatcher::Check(id2) && id1*id2>0); } } ClusterFissioner::cutType ClusterFissioner::cutTwo(ClusterPtr & cluster, tPVector & finalhadrons, bool softUEisOn) { // need to make sure only 2-cpt clusters get here assert(cluster->numComponents() == 2); tPPtr ptrQ1 = cluster->particle(0); tPPtr ptrQ2 = cluster->particle(1); Energy Mc = cluster->mass(); assert(ptrQ1); assert(ptrQ2); // And check if those particles are from a beam remnant bool rem1 = cluster->isBeamRemnant(0); bool rem2 = cluster->isBeamRemnant(1); // workout which distribution to use bool soft1(false),soft2(false); switch (_iopRem) { case 0: soft1 = rem1 || rem2; soft2 = rem2 || rem1; break; case 1: soft1 = rem1; soft2 = rem2; break; } // Initialization for the exponential ("soft") mass distribution. static const int max_loop = 1000; int counter = 0; Energy Mc1 = ZERO, Mc2 = ZERO,m1=ZERO,m2=ZERO,m=ZERO; tcPDPtr toHadron1, toHadron2; PPtr newPtr1 = PPtr (); PPtr newPtr2 = PPtr (); bool succeeded = false; do { succeeded = false; ++counter; if (_enhanceSProb == 0){ drawNewFlavour(newPtr1,newPtr2); } else { Energy2 mass2 = clustermass(cluster); drawNewFlavourEnhanced(newPtr1,newPtr2,mass2); } // check for right ordering assert (ptrQ2); assert (newPtr2); assert (ptrQ2->dataPtr()); assert (newPtr2->dataPtr()); if(cantMakeHadron(ptrQ1, newPtr1) || cantMakeHadron(ptrQ2, newPtr2)) { swap(newPtr1, newPtr2); // check again if(cantMakeHadron(ptrQ1, newPtr1) || cantMakeHadron(ptrQ2, newPtr2)) { throw Exception() << "ClusterFissioner cannot split the cluster (" << ptrQ1->PDGName() << ' ' << ptrQ2->PDGName() << ") into hadrons.\n" << Exception::runerror; } } // Check that new clusters can produce particles and there is enough // phase space to choose the drawn flavour m1 = ptrQ1->data().constituentMass(); m2 = ptrQ2->data().constituentMass(); m = newPtr1->data().constituentMass(); // Do not split in the case there is no phase space available if(Mc < m1+m + m2+m) continue; // power for splitting double exp1=_pSplitLight; double exp2=_pSplitLight; if (CheckId::isExotic(ptrQ1->dataPtr())) exp1 = _pSplitExotic; else if(CheckId::hasBottom(ptrQ1->dataPtr()))exp1 = _pSplitBottom; else if(CheckId::hasCharm(ptrQ1->dataPtr())) exp1 = _pSplitCharm; if (CheckId::isExotic(ptrQ2->dataPtr())) exp2 = _pSplitExotic; else if(CheckId::hasBottom(ptrQ2->dataPtr())) exp2 = _pSplitBottom; else if(CheckId::hasCharm(ptrQ2->dataPtr())) exp2 = _pSplitCharm; // If, during the drawing of candidate masses, too many attempts fail // (because the phase space available is tiny) /// \todo run separate loop here? Mc1 = drawChildMass(Mc,m1,m2,m,exp1,soft1); Mc2 = drawChildMass(Mc,m2,m1,m,exp2,soft2); if(Mc1 < m1+m || Mc2 < m+m2 || Mc1+Mc2 > Mc) continue; /************************** * New (not present in Fortran Herwig): * check whether the fragment masses Mc1 and Mc2 are above the * threshold for the production of the lightest pair of hadrons with the * right flavours. If not, then set by hand the mass to the lightest * single hadron with the right flavours, in order to solve correctly * the kinematics, and (later in this method) create directly such hadron * and add it to the children hadrons of the cluster that undergoes the * fission (i.e. the one pointed by iCluPtr). Notice that in this special * case, the heavy cluster that undergoes the fission has one single * cluster child and one single hadron child. We prefer this approach, * rather than to create a light cluster, with the mass set equal to * the lightest hadron, and let then the class LightClusterDecayer to do * the job to decay it to that single hadron, for two reasons: * First, because the sum of the masses of the two constituents can be, * in this case, greater than the mass of that hadron, hence it would * be impossible to solve the kinematics for such two components, and * therefore we would have a cluster whose components are undefined. * Second, the algorithm is faster, because it avoids the reshuffling * procedure that would be necessary if we used LightClusterDecayer * to decay the light cluster to the lightest hadron. ****************************/ toHadron1 = _hadronsSelector->chooseSingleHadron(ptrQ1->dataPtr(), newPtr1->dataPtr(),Mc1); if(toHadron1) Mc1 = toHadron1->mass(); toHadron2 = _hadronsSelector->chooseSingleHadron(ptrQ2->dataPtr(), newPtr2->dataPtr(),Mc2); if(toHadron2) Mc2 = toHadron2->mass(); // if a beam cluster not allowed to decay to hadrons if(cluster->isBeamCluster() && (toHadron1||toHadron2) && softUEisOn) continue; // Check if the decay kinematics is still possible: if not then // force the one-hadron decay for the other cluster as well. if(Mc1 + Mc2 > Mc) { if(!toHadron1) { toHadron1 = _hadronsSelector->chooseSingleHadron(ptrQ1->dataPtr(), newPtr1->dataPtr(),Mc-Mc2); if(toHadron1) Mc1 = toHadron1->mass(); } else if(!toHadron2) { toHadron2 = _hadronsSelector->chooseSingleHadron(ptrQ2->dataPtr(), newPtr2->dataPtr(),Mc-Mc1); if(toHadron2) Mc2 = toHadron2->mass(); } } succeeded = (Mc >= Mc1+Mc2); } while (!succeeded && counter < max_loop); if(counter >= max_loop) { static const PPtr null = PPtr(); return cutType(PPair(null,null),PPair(null,null)); } // Determined the (5-components) momenta (all in the LAB frame) Lorentz5Momentum pClu = cluster->momentum(); // known Lorentz5Momentum p0Q1 = ptrQ1->momentum(); // known (mom Q1 before fission) Lorentz5Momentum pClu1, pClu2, pQ1, pQone, pQtwo, pQ2; //unknown pClu1.setMass(Mc1); pClu2.setMass(Mc2); pQ1.setMass(m1); pQ2.setMass(m2); pQone.setMass(m); pQtwo.setMass(m); calculateKinematics(pClu,p0Q1,toHadron1,toHadron2, pClu1,pClu2,pQ1,pQone,pQtwo,pQ2); // out /****************** * The previous methods have determined the kinematics and positions * of C -> C1 + C2. * In the case that one of the two product is light, that means either * decayOneHadronClu1 or decayOneHadronClu2 is true, then the momenta * of the components of that light product have not been determined, * and a (light) cluster will not be created: the heavy father cluster * decays, in this case, into a single (not-light) cluster and a * single hadron. In the other, "normal", cases the father cluster * decays into two clusters, each of which has well defined components. * Notice that, in the case of components which point to particles, the * momenta of the components is properly set to the new values, whereas * we do not change the momenta of the pointed particles, because we * want to keep all of the information (that is the new momentum of a * component after the splitting, which is contained in the _momentum * member of the Component class, and the (old) momentum of that component * before the splitting, which is contained in the momentum of the * pointed particle). Please not make confusion of this only apparent * inconsistency! ********************/ LorentzPoint posC,pos1,pos2; posC = cluster->vertex(); calculatePositions(pClu, posC, pClu1, pClu2, pos1, pos2); cutType rval; if(toHadron1) { rval.first = produceHadron(toHadron1, newPtr1, pClu1, pos1); finalhadrons.push_back(rval.first.first); } else { rval.first = produceCluster(ptrQ1, newPtr1, pClu1, pos1, pQ1, pQone, rem1); } if(toHadron2) { rval.second = produceHadron(toHadron2, newPtr2, pClu2, pos2); finalhadrons.push_back(rval.second.first); } else { rval.second = produceCluster(ptrQ2, newPtr2, pClu2, pos2, pQ2, pQtwo, rem2); } return rval; } ClusterFissioner::cutType ClusterFissioner::cutThree(ClusterPtr & cluster, tPVector & finalhadrons, bool softUEisOn) { // need to make sure only 3-cpt clusters get here assert(cluster->numComponents() == 3); // extract quarks tPPtr ptrQ[3] = {cluster->particle(0),cluster->particle(1),cluster->particle(2)}; assert( ptrQ[0] && ptrQ[1] && ptrQ[2] ); // find maximum mass pair Energy mmax(ZERO); Lorentz5Momentum pDiQuark; int iq1(-1),iq2(-1); Lorentz5Momentum psum; for(int q1=0;q1<3;++q1) { psum+= ptrQ[q1]->momentum(); for(int q2=q1+1;q2<3;++q2) { Lorentz5Momentum ptest = ptrQ[q1]->momentum()+ptrQ[q2]->momentum(); ptest.rescaleMass(); Energy mass = ptest.m(); if(mass>mmax) { mmax = mass; pDiQuark = ptest; iq1 = q1; iq2 = q2; } } } // and the spectators int iother(-1); for(int ix=0;ix<3;++ix) if(ix!=iq1&&ix!=iq2) iother=ix; assert(iq1>=0&&iq2>=0&&iother>=0); // And check if those particles are from a beam remnant bool rem1 = cluster->isBeamRemnant(iq1); bool rem2 = cluster->isBeamRemnant(iq2); // workout which distribution to use bool soft1(false),soft2(false); switch (_iopRem) { case 0: soft1 = rem1 || rem2; soft2 = rem2 || rem1; break; case 1: soft1 = rem1; soft2 = rem2; break; } // Initialization for the exponential ("soft") mass distribution. static const int max_loop = 1000; int counter = 0; Energy Mc1 = ZERO, Mc2 = ZERO, m1=ZERO, m2=ZERO, m=ZERO; tcPDPtr toHadron; bool toDiQuark(false); PPtr newPtr1 = PPtr(),newPtr2 = PPtr(); PDPtr diquark; bool succeeded = false; do { succeeded = false; ++counter; if (_enhanceSProb == 0) { drawNewFlavour(newPtr1,newPtr2); } else { Energy2 mass2 = clustermass(cluster); drawNewFlavourEnhanced(newPtr1,newPtr2, mass2); } // randomly pick which will be (anti)diquark and which a mesonic cluster if(UseRandom::rndbool()) { swap(iq1,iq2); swap(rem1,rem2); } // check first order if(cantMakeHadron(ptrQ[iq1], newPtr1) || cantMakeDiQuark(ptrQ[iq2], newPtr2)) { swap(newPtr1,newPtr2); } // check again if(cantMakeHadron(ptrQ[iq1], newPtr1) || cantMakeDiQuark(ptrQ[iq2], newPtr2)) { throw Exception() << "ClusterFissioner cannot split the cluster (" << ptrQ[iq1]->PDGName() << ' ' << ptrQ[iq2]->PDGName() << ") into a hadron and diquark.\n" << Exception::runerror; } // Check that new clusters can produce particles and there is enough // phase space to choose the drawn flavour m1 = ptrQ[iq1]->data().constituentMass(); m2 = ptrQ[iq2]->data().constituentMass(); m = newPtr1->data().constituentMass(); // Do not split in the case there is no phase space available if(mmax < m1+m + m2+m) continue; // power for splitting double exp1(_pSplitLight),exp2(_pSplitLight); if (CheckId::isExotic (ptrQ[iq1]->dataPtr())) exp1 = _pSplitExotic; else if(CheckId::hasBottom(ptrQ[iq1]->dataPtr())) exp1 = _pSplitBottom; else if(CheckId::hasCharm (ptrQ[iq1]->dataPtr())) exp1 = _pSplitCharm; if (CheckId::isExotic (ptrQ[iq2]->dataPtr())) exp2 = _pSplitExotic; else if(CheckId::hasBottom(ptrQ[iq2]->dataPtr())) exp2 = _pSplitBottom; else if(CheckId::hasCharm (ptrQ[iq2]->dataPtr())) exp2 = _pSplitCharm; // If, during the drawing of candidate masses, too many attempts fail // (because the phase space available is tiny) /// \todo run separate loop here? Mc1 = drawChildMass(mmax,m1,m2,m,exp1,soft1); Mc2 = drawChildMass(mmax,m2,m1,m,exp2,soft2); if(Mc1 < m1+m || Mc2 < m+m2 || Mc1+Mc2 > mmax) continue; // check if need to force meson clster to hadron toHadron = _hadronsSelector->chooseSingleHadron(ptrQ[iq1]->dataPtr(), newPtr1->dataPtr(),Mc1); if(toHadron) Mc1 = toHadron->mass(); // check if need to force diquark cluster to be on-shell toDiQuark = false; diquark = CheckId::makeDiquark(ptrQ[iq2]->dataPtr(), newPtr2->dataPtr()); if(Mc2 < diquark->constituentMass()) { Mc2 = diquark->constituentMass(); toDiQuark = true; } // if a beam cluster not allowed to decay to hadrons if(cluster->isBeamCluster() && toHadron && softUEisOn) continue; // Check if the decay kinematics is still possible: if not then // force the one-hadron decay for the other cluster as well. if(Mc1 + Mc2 > mmax) { if(!toHadron) { toHadron = _hadronsSelector->chooseSingleHadron(ptrQ[iq1]->dataPtr(), newPtr1->dataPtr(),mmax-Mc2); if(toHadron) Mc1 = toHadron->mass(); } else if(!toDiQuark) { Mc2 = _hadronsSelector->massLightestHadron(ptrQ[iq2]->dataPtr(), newPtr2->dataPtr()); toDiQuark = true; } } succeeded = (mmax >= Mc1+Mc2); } while (!succeeded && counter < max_loop); // check no of tries if(counter >= max_loop) return cutType(); // Determine the (5-components) momenta (all in the LAB frame) Lorentz5Momentum p0Q1 = ptrQ[iq1]->momentum(); // to be determined Lorentz5Momentum pClu1(Mc1), pClu2(Mc2), pQ1(m1), pQone(m), pQtwo(m), pQ2(m2); calculateKinematics(pDiQuark,p0Q1,toHadron,toDiQuark, pClu1,pClu2,pQ1,pQone,pQtwo,pQ2); // positions of the new clusters LorentzPoint pos1,pos2; Lorentz5Momentum pBaryon = pClu2+ptrQ[iother]->momentum(); calculatePositions(cluster->momentum(), cluster->vertex(), pClu1, pBaryon, pos1, pos2); // first the mesonic cluster/meson cutType rval; if(toHadron) { rval.first = produceHadron(toHadron, newPtr1, pClu1, pos1); finalhadrons.push_back(rval.first.first); } else { rval.first = produceCluster(ptrQ[iq1], newPtr1, pClu1, pos1, pQ1, pQone, rem1); } if(toDiQuark) { rem2 |= cluster->isBeamRemnant(iother); PPtr newDiQuark = diquark->produceParticle(pClu2); rval.second = produceCluster(newDiQuark, ptrQ[iother], pBaryon, pos2, pClu2, ptrQ[iother]->momentum(), rem2); } else { rval.second = produceCluster(ptrQ[iq2], newPtr2, pBaryon, pos2, pQ2, pQtwo, rem2, ptrQ[iother],cluster->isBeamRemnant(iother)); } cluster->isAvailable(false); return rval; } ClusterFissioner::PPair ClusterFissioner::produceHadron(tcPDPtr hadron, tPPtr newPtr, const Lorentz5Momentum &a, const LorentzPoint &b) const { PPair rval; if(hadron->coloured()) { rval.first = (_hadronsSelector->lightestHadron(hadron,newPtr->dataPtr()))->produceParticle(); } else rval.first = hadron->produceParticle(); rval.second = newPtr; rval.first->set5Momentum(a); rval.first->setVertex(b); return rval; } ClusterFissioner::PPair ClusterFissioner::produceCluster(tPPtr ptrQ, tPPtr newPtr, const Lorentz5Momentum & a, const LorentzPoint & b, const Lorentz5Momentum & c, const Lorentz5Momentum & d, bool isRem, tPPtr spect, bool remSpect) const { PPair rval; rval.second = newPtr; ClusterPtr cluster = !spect ? new_ptr(Cluster(ptrQ,rval.second)) : new_ptr(Cluster(ptrQ,rval.second,spect)); rval.first = cluster; cluster->set5Momentum(a); cluster->setVertex(b); assert(cluster->particle(0)->id() == ptrQ->id()); cluster->particle(0)->set5Momentum(c); cluster->particle(1)->set5Momentum(d); cluster->setBeamRemnant(0,isRem); if(remSpect) cluster->setBeamRemnant(2,remSpect); return rval; } void ClusterFissioner::drawNewFlavour(PPtr& newPtrPos,PPtr& newPtrNeg) const { // Flavour is assumed to be only u, d, s, with weights // (which are not normalized probabilities) given // by the same weights as used in HadronsSelector for // the decay of clusters into two hadrons. double prob_d; double prob_u; double prob_s; switch(_fissionCluster){ case 0: prob_d = _hadronsSelector->pwtDquark(); prob_u = _hadronsSelector->pwtUquark(); prob_s = _hadronsSelector->pwtSquark(); break; case 1: prob_d = _fissionPwtDquark; prob_u = _fissionPwtUquark; prob_s = _fissionPwtSquark; break; default : assert(false); } int choice = UseRandom::rnd3(prob_u, prob_d, prob_s); long idNew = 0; switch (choice) { case 0: idNew = ThePEG::ParticleID::u; break; case 1: idNew = ThePEG::ParticleID::d; break; case 2: idNew = ThePEG::ParticleID::s; break; } newPtrPos = getParticle(idNew); newPtrNeg = getParticle(-idNew); assert (newPtrPos); assert(newPtrNeg); assert (newPtrPos->dataPtr()); assert(newPtrNeg->dataPtr()); } void ClusterFissioner::drawNewFlavourEnhanced(PPtr& newPtrPos,PPtr& newPtrNeg, Energy2 mass2) const { // Flavour is assumed to be only u, d, s, with weights // (which are not normalized probabilities) given // by the same weights as used in HadronsSelector for // the decay of clusters into two hadrons. double prob_d; double prob_u; double prob_s = 0.; double scale = abs(double(sqr(_m0Fission)/mass2)); // Choose which splitting weights you wish to use switch(_fissionCluster){ // 0: ClusterFissioner and ClusterDecayer use the same weights case 0: prob_d = _hadronsSelector->pwtDquark(); prob_u = _hadronsSelector->pwtUquark(); /* Strangeness enhancement: Case 1: probability scaling Case 2: Exponential scaling */ if (_enhanceSProb == 1) prob_s = (_maxScale < scale) ? 0. : pow(_hadronsSelector->pwtSquark(),scale); else if (_enhanceSProb == 2) prob_s = (_maxScale < scale) ? 0. : exp(-scale); break; /* 1: ClusterFissioner uses its own unique set of weights, i.e. decoupled from ClusterDecayer */ case 1: prob_d = _fissionPwtDquark; prob_u = _fissionPwtUquark; if (_enhanceSProb == 1) prob_s = (_maxScale < scale) ? 0. : pow(_fissionPwtSquark,scale); else if (_enhanceSProb == 2) prob_s = (_maxScale < scale) ? 0. : exp(-scale); break; } int choice = UseRandom::rnd3(prob_u, prob_d, prob_s); long idNew = 0; switch (choice) { case 0: idNew = ThePEG::ParticleID::u; break; case 1: idNew = ThePEG::ParticleID::d; break; case 2: idNew = ThePEG::ParticleID::s; break; } newPtrPos = getParticle(idNew); newPtrNeg = getParticle(-idNew); assert (newPtrPos); assert(newPtrNeg); assert (newPtrPos->dataPtr()); assert(newPtrNeg->dataPtr()); } Energy2 ClusterFissioner::clustermass(const ClusterPtr & cluster){ Lorentz5Momentum pIn = cluster->momentum(); Energy2 endpointmass2 = sqr(cluster->particle(0)->mass() + cluster->particle(1)->mass()); Energy2 singletm2 = pIn.m2(); // Return either the cluster mass, or the lambda measure return (_massMeasure == 0) ? singletm2 : singletm2 - endpointmass2; } Energy ClusterFissioner::drawChildMass(const Energy M, const Energy m1, const Energy m2, const Energy m, const double expt, const bool soft) const { /*************************** * This method, given in input the cluster mass Mclu of an heavy cluster C, * made of consituents of masses m1 and m2, draws the masses Mclu1 and Mclu2 * of, respectively, the children cluster C1, made of constituent masses m1 * and m, and cluster C2, of mass Mclu2 and made of constituent masses m2 * and m. The mass is extracted from one of the two following mass * distributions: * --- power-like ("normal" distribution) * d(Prob) / d(M^exponent) = const * where the exponent can be different from the two children C1 (exp1) * and C2 (exponent2). * --- exponential ("soft" distribution) * d(Prob) / d(M^2) = exp(-b*M) * where b = 2.0 / average. * Such distributions are limited below by the masses of * the constituents quarks, and above from the mass of decaying cluster C. * The choice of which of the two mass distributions to use for each of the * two cluster children is dictated by iRemnant (see below). * If the number of attempts to extract a pair of mass values that are * kinematically acceptable is above some fixed number (max_loop, see below) * the method gives up and returns false; otherwise, when it succeeds, it * returns true. * * These distributions have been modified from HERWIG: * Before these were: * Mclu1 = m1 + (Mclu - m1 - m2)*pow( rnd(), 1.0/exponent1 ); * The new one coded here is a more efficient version, same density * but taking into account 'in phase space from' beforehand ***************************/ // hard cluster if(!soft) { return pow(UseRandom::rnd(pow((M-m1-m2-m)*UnitRemoval::InvE, expt), pow(m*UnitRemoval::InvE, expt)), 1./expt )*UnitRemoval::E + m1; } // Otherwise it uses a soft mass distribution else { static const InvEnergy b = 2.0 / _btClM; Energy max = M-m1-m2-2.0*m; double rmin = b*max; rmin = ( rmin < 50 ) ? exp(-rmin) : 0.; double r1; do { r1 = UseRandom::rnd(rmin, 1.0) * UseRandom::rnd(rmin, 1.0); } while (r1 < rmin); return m1 + m - log(r1)/b; } } void ClusterFissioner::calculateKinematics(const Lorentz5Momentum & pClu, const Lorentz5Momentum & p0Q1, const bool toHadron1, const bool toHadron2, Lorentz5Momentum & pClu1, Lorentz5Momentum & pClu2, Lorentz5Momentum & pQ1, Lorentz5Momentum & pQbar, Lorentz5Momentum & pQ, Lorentz5Momentum & pQ2bar) const { /****************** * This method solves the kinematics of the two body cluster decay: * C (Q1 Q2bar) ---> C1 (Q1 Qbar) + C2 (Q Q2bar) * In input we receive the momentum of C, pClu, and the momentum * of the quark Q1 (constituent of C), p0Q1, both in the LAB frame. * Furthermore, two boolean variables inform whether the two fission * products (C1, C2) decay immediately into a single hadron (in which * case the cluster itself is identify with that hadron) and we do * not have to solve the kinematics of the components (Q1,Qbar) for * C1 and (Q,Q2bar) for C2. * The output is given by the following momenta (all 5-components, * and all in the LAB frame): * pClu1 , pClu2 respectively of C1 , C2 * pQ1 , pQbar respectively of Q1 , Qbar in C1 * pQ , pQ2bar respectively of Q , Q2 in C2 * The assumption, suggested from the string model, is that, in C frame, * C1 and its constituents Q1 and Qbar are collinear, and collinear to * the direction of Q1 in C (that is before cluster decay); similarly, * (always in the C frame) C2 and its constituents Q and Q2bar are * collinear (and therefore anti-collinear with C1,Q1,Qbar). * The solution is then obtained by using Lorentz boosts, as follows. * The kinematics of C1 and C2 is solved in their parent C frame, * and then boosted back in the LAB. The kinematics of Q1 and Qbar * is solved in their parent C1 frame and then boosted back in the LAB; * similarly, the kinematics of Q and Q2bar is solved in their parent * C2 frame and then boosted back in the LAB. In each of the three * "two-body decay"-like cases, we use the fact that the direction * of the motion of the decay products is known in the rest frame of * their parent. This is obvious for the first case in which the * parent rest frame is C; but it is also true in the other two cases * where the rest frames are C1 and C2. This is because C1 and C2 * are boosted w.r.t. C in the same direction where their components, * respectively (Q1,Qbar) and (Q,Q2bar) move in C1 and C2 rest frame * respectively. * Of course, although the notation used assumed that C = (Q1 Q2bar) * where Q1 is a quark and Q2bar an antiquark, indeed everything remain * unchanged also in all following cases: * Q1 quark, Q2bar antiquark; --> Q quark; * Q1 antiquark , Q2bar quark; --> Q antiquark; * Q1 quark, Q2bar diquark; --> Q quark * Q1 antiquark, Q2bar anti-diquark; --> Q antiquark * Q1 diquark, Q2bar quark --> Q antiquark * Q1 anti-diquark, Q2bar antiquark; --> Q quark **************************/ // Calculate the unit three-vector, in the C frame, along which // all of the constituents and children clusters move. Lorentz5Momentum u(p0Q1); u.boost( -pClu.boostVector() ); // boost from LAB to C // the unit three-vector is then u.vect().unit() // Calculate the momenta of C1 and C2 in the (parent) C frame first, // where the direction of C1 is u.vect().unit(), and then boost back in the // LAB frame. if (pClu.m() < pClu1.mass() + pClu2.mass() ) { throw Exception() << "Impossible Kinematics in ClusterFissioner::calculateKinematics() (A)" << Exception::eventerror; } Kinematics::twoBodyDecay(pClu, pClu1.mass(), pClu2.mass(), u.vect().unit(), pClu1, pClu2); // In the case that cluster1 does not decay immediately into a single hadron, // calculate the momenta of Q1 (as constituent of C1) and Qbar in the // (parent) C1 frame first, where the direction of Q1 is u.vect().unit(), // and then boost back in the LAB frame. if(!toHadron1) { if (pClu1.m() < pQ1.mass() + pQbar.mass() ) { throw Exception() << "Impossible Kinematics in ClusterFissioner::calculateKinematics() (B)" << Exception::eventerror; } Kinematics::twoBodyDecay(pClu1, pQ1.mass(), pQbar.mass(), u.vect().unit(), pQ1, pQbar); } // In the case that cluster2 does not decay immediately into a single hadron, // Calculate the momenta of Q and Q2bar (as constituent of C2) in the // (parent) C2 frame first, where the direction of Q is u.vect().unit(), // and then boost back in the LAB frame. if(!toHadron2) { if (pClu2.m() < pQ.mass() + pQ2bar.mass() ) { throw Exception() << "Impossible Kinematics in ClusterFissioner::calculateKinematics() (C)" << Exception::eventerror; } Kinematics::twoBodyDecay(pClu2, pQ.mass(), pQ2bar.mass(), u.vect().unit(), pQ, pQ2bar); } } void ClusterFissioner::calculatePositions(const Lorentz5Momentum & pClu, const LorentzPoint & positionClu, const Lorentz5Momentum & pClu1, const Lorentz5Momentum & pClu2, LorentzPoint & positionClu1, LorentzPoint & positionClu2) const { // Determine positions of cluster children. // See Marc Smith's thesis, page 127, formulas (4.122) and (4.123). Energy Mclu = pClu.m(); Energy Mclu1 = pClu1.m(); Energy Mclu2 = pClu2.m(); // Calculate the unit three-vector, in the C frame, along which // children clusters move. Lorentz5Momentum u(pClu1); u.boost( -pClu.boostVector() ); // boost from LAB to C frame // the unit three-vector is then u.vect().unit() Energy pstarChild = Kinematics::pstarTwoBodyDecay(Mclu,Mclu1,Mclu2); // First, determine the relative positions of the children clusters // in the parent cluster reference frame. Length x1 = ( 0.25*Mclu + 0.5*( pstarChild + (sqr(Mclu2) - sqr(Mclu1))/(2.0*Mclu)))/_kappa; Length t1 = Mclu/_kappa - x1; LorentzDistance distanceClu1( x1 * u.vect().unit(), t1 ); Length x2 = (-0.25*Mclu + 0.5*(-pstarChild + (sqr(Mclu2) - sqr(Mclu1))/(2.0*Mclu)))/_kappa; Length t2 = Mclu/_kappa + x2; LorentzDistance distanceClu2( x2 * u.vect().unit(), t2 ); // Then, transform such relative positions from the parent cluster // reference frame to the Lab frame. distanceClu1.boost( pClu.boostVector() ); distanceClu2.boost( pClu.boostVector() ); // Finally, determine the absolute positions in the Lab frame. positionClu1 = positionClu + distanceClu1; positionClu2 = positionClu + distanceClu2; } bool ClusterFissioner::isHeavy(tcClusterPtr clu) { // default double clpow = _clPowLight; Energy clmax = _clMaxLight; // particle data for constituents tcPDPtr cptr[3]={tcPDPtr(),tcPDPtr(),tcPDPtr()}; for(int ix=0;ixnumComponents(),3);++ix) { cptr[ix]=clu->particle(ix)->dataPtr(); } // different parameters for exotic, bottom and charm clusters if(CheckId::isExotic(cptr[0],cptr[1],cptr[1])) { clpow = _clPowExotic; clmax = _clMaxExotic; } else if(CheckId::hasBottom(cptr[0],cptr[1],cptr[1])) { clpow = _clPowBottom; clmax = _clMaxBottom; } else if(CheckId::hasCharm(cptr[0],cptr[1],cptr[1])) { clpow = _clPowCharm; clmax = _clMaxCharm; } bool aboveCutoff = ( pow(clu->mass()*UnitRemoval::InvE , clpow) > pow(clmax*UnitRemoval::InvE, clpow) + pow(clu->sumConstituentMasses()*UnitRemoval::InvE, clpow) ); // required test for SUSY clusters, since aboveCutoff alone // cannot guarantee (Mc > m1 + m2 + 2*m) in cut() static const Energy minmass = getParticleData(ParticleID::d)->constituentMass(); bool canSplitMinimally = clu->mass() > clu->sumConstituentMasses() + 2.0 * minmass; return aboveCutoff && canSplitMinimally; } diff --git a/Hadronization/ClusterHadronizationHandler.cc b/Hadronization/ClusterHadronizationHandler.cc --- a/Hadronization/ClusterHadronizationHandler.cc +++ b/Hadronization/ClusterHadronizationHandler.cc @@ -1,307 +1,307 @@ // -*- C++ -*- // // ClusterHadronizationHandler.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2017 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the ClusterHadronizationHandler class. // #include "ClusterHadronizationHandler.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Herwig/Utilities/EnumParticles.h" #include "CluHadConfig.h" #include "Cluster.h" #include using namespace Herwig; ClusterHadronizationHandler * ClusterHadronizationHandler::currentHandler_ = 0; DescribeClass describeClusterHadronizationHandler("Herwig::ClusterHadronizationHandler","Herwig.so"); IBPtr ClusterHadronizationHandler::clone() const { return new_ptr(*this); } IBPtr ClusterHadronizationHandler::fullclone() const { return new_ptr(*this); } void ClusterHadronizationHandler::persistentOutput(PersistentOStream & os) const { os << _partonSplitter << _clusterFinder << _colourReconnector << _clusterFissioner << _lightClusterDecayer << _clusterDecayer << ounit(_minVirtuality2,GeV2) << ounit(_maxDisplacement,mm) << _underlyingEventHandler << _reduceToTwoComponents; } void ClusterHadronizationHandler::persistentInput(PersistentIStream & is, int) { is >> _partonSplitter >> _clusterFinder >> _colourReconnector >> _clusterFissioner >> _lightClusterDecayer >> _clusterDecayer >> iunit(_minVirtuality2,GeV2) >> iunit(_maxDisplacement,mm) >> _underlyingEventHandler >> _reduceToTwoComponents; } void ClusterHadronizationHandler::Init() { static ClassDocumentation documentation ("This is the main handler class for the Cluster Hadronization", "The hadronization was performed using the cluster model of \\cite{Webber:1983if}.", "%\\cite{Webber:1983if}\n" "\\bibitem{Webber:1983if}\n" " B.~R.~Webber,\n" " ``A QCD Model For Jet Fragmentation Including Soft Gluon Interference,''\n" " Nucl.\\ Phys.\\ B {\\bf 238}, 492 (1984).\n" " %%CITATION = NUPHA,B238,492;%%\n" // main manual ); static Reference interfacePartonSplitter("PartonSplitter", "A reference to the PartonSplitter object", &Herwig::ClusterHadronizationHandler::_partonSplitter, false, false, true, false); static Reference interfaceClusterFinder("ClusterFinder", "A reference to the ClusterFinder object", &Herwig::ClusterHadronizationHandler::_clusterFinder, false, false, true, false); static Reference interfaceColourReconnector("ColourReconnector", "A reference to the ColourReconnector object", &Herwig::ClusterHadronizationHandler::_colourReconnector, false, false, true, false); static Reference interfaceClusterFissioner("ClusterFissioner", "A reference to the ClusterFissioner object", &Herwig::ClusterHadronizationHandler::_clusterFissioner, false, false, true, false); static Reference interfaceLightClusterDecayer("LightClusterDecayer", "A reference to the LightClusterDecayer object", &Herwig::ClusterHadronizationHandler::_lightClusterDecayer, false, false, true, false); static Reference interfaceClusterDecayer("ClusterDecayer", "A reference to the ClusterDecayer object", &Herwig::ClusterHadronizationHandler::_clusterDecayer, false, false, true, false); static Parameter interfaceMinVirtuality2 ("MinVirtuality2", "Minimum virtuality^2 of partons to use in calculating distances (unit [GeV2]).", &ClusterHadronizationHandler::_minVirtuality2, GeV2, 0.1*GeV2, ZERO, 10.0*GeV2,false,false,false); static Parameter interfaceMaxDisplacement ("MaxDisplacement", "Maximum displacement that is allowed for a particle (unit [millimeter]).", &ClusterHadronizationHandler::_maxDisplacement, mm, 1.0e-10*mm, 0.0*mm, 1.0e-9*mm,false,false,false); static Reference interfaceUnderlyingEventHandler ("UnderlyingEventHandler", "Pointer to the handler for the Underlying Event. " "Set to NULL to disable.", &ClusterHadronizationHandler::_underlyingEventHandler, false, false, true, true, false); static Switch interfaceReduceToTwoComponents ("ReduceToTwoComponents", "Whether or not to reduce three component baryon-number violating clusters to two components before cluster splitting or leave" " this till after the cluster splitting", &ClusterHadronizationHandler::_reduceToTwoComponents, true, false, false); static SwitchOption interfaceReduceToTwoComponentsYes (interfaceReduceToTwoComponents, "BeforeSplitting", "Reduce to two components", true); static SwitchOption interfaceReduceToTwoComponentsNo (interfaceReduceToTwoComponents, "AfterSplitting", "Treat as three components", false); } namespace { void extractChildren(tPPtr p, set & all) { if (p->children().empty()) return; for (PVector::const_iterator child = p->children().begin(); child != p->children().end(); ++child) { all.insert(*child); extractChildren(*child, all); } } } void ClusterHadronizationHandler:: handle(EventHandler & ch, const tPVector & tagged, const Hint &) { useMe(); currentHandler_ = this; PVector currentlist(tagged.begin(),tagged.end()); // set the scale for coloured particles to just above the gluon mass squared // if less than this so they are classed as perturbative Energy2 Q02 = 1.01*sqr(getParticleData(ParticleID::g)->constituentMass()); for(unsigned int ix=0;ixscale()scale(Q02); } // split the gluons _partonSplitter->split(currentlist); // form the clusters ClusterVector clusters = _clusterFinder->formClusters(currentlist); // reduce BV clusters to two components now if needed if(_reduceToTwoComponents) _clusterFinder->reduceToTwoComponents(clusters); // perform colour reconnection if needed and then // decay the clusters into one hadron bool lightOK = false; short tried = 0; const ClusterVector savedclusters = clusters; tPVector finalHadrons; // only needed for partonic decayer while (!lightOK && tried++ < 10) { // no colour reconnection with baryon-number-violating (BV) clusters ClusterVector CRclusters, BVclusters; CRclusters.reserve( clusters.size() ); BVclusters.reserve( clusters.size() ); for (size_t ic = 0; ic < clusters.size(); ++ic) { ClusterPtr cl = clusters.at(ic); bool hasClusterParent = false; for (unsigned int ix=0; ix < cl->parents().size(); ++ix) { if (cl->parents()[ix]->id() == ParticleID::Cluster) { hasClusterParent = true; break; } } if (cl->numComponents() > 2 || hasClusterParent) BVclusters.push_back(cl); else CRclusters.push_back(cl); } // colour reconnection _colourReconnector->rearrange(CRclusters); // tag new clusters as children of the partons to hadronize _setChildren(CRclusters); // forms diquarks _clusterFinder->reduceToTwoComponents(CRclusters); // recombine vectors of (possibly) reconnected and BV clusters clusters.clear(); clusters.insert( clusters.end(), CRclusters.begin(), CRclusters.end() ); clusters.insert( clusters.end(), BVclusters.begin(), BVclusters.end() ); // fission of heavy clusters // NB: during cluster fission, light hadrons might be produced straight away finalHadrons = _clusterFissioner->fission(clusters,isSoftUnderlyingEventON()); // if clusters not previously reduced to two components do it now if(!_reduceToTwoComponents) _clusterFinder->reduceToTwoComponents(clusters); lightOK = _lightClusterDecayer->decay(clusters,finalHadrons); // if the decay of the light clusters was not successful, undo the cluster // fission and decay steps and revert to the original state of the event // record if (!lightOK) { clusters = savedclusters; for_each(clusters.begin(), clusters.end(), - mem_fun(&Particle::undecay)); + std::mem_fn(&Particle::undecay)); } } if (!lightOK) { throw Exception("CluHad::handle(): tried LightClusterDecayer 10 times!", Exception::eventerror); } // decay the remaining clusters _clusterDecayer->decay(clusters,finalHadrons); // ***************************************** // ***************************************** // ***************************************** StepPtr pstep = newStep(); set allDecendants; for (tPVector::const_iterator it = tagged.begin(); it != tagged.end(); ++it) { extractChildren(*it, allDecendants); } for(set::const_iterator it = allDecendants.begin(); it != allDecendants.end(); ++it) { // this is a workaround because the set sometimes // re-orders parents after their children if ((*it)->children().empty()) pstep->addDecayProduct(*it); else { pstep->addDecayProduct(*it); pstep->addIntermediate(*it); } } // ***************************************** // ***************************************** // ***************************************** // soft underlying event if needed if (isSoftUnderlyingEventON()) { assert(_underlyingEventHandler); ch.performStep(_underlyingEventHandler,Hint::Default()); } } // Sets parent child relationship of all clusters with two components // Relationships for clusters with more than two components are set elsewhere in the Colour Reconnector void ClusterHadronizationHandler::_setChildren(const ClusterVector & clusters) const { // erase existing information about the partons' children tPVector partons; for ( const auto & cl : clusters ) { if ( cl->numComponents() > 2 ) continue; partons.push_back( cl->colParticle() ); partons.push_back( cl->antiColParticle() ); } // erase all previous information about parent child relationship - for_each(partons.begin(), partons.end(), mem_fun(&Particle::undecay)); + for_each(partons.begin(), partons.end(), std::mem_fn(&Particle::undecay)); // give new parents to the clusters: their constituents for ( const auto & cl : clusters ) { if ( cl->numComponents() > 2 ) continue; cl->colParticle()->addChild(cl); cl->antiColParticle()->addChild(cl); } } diff --git a/Hadronization/ColourReconnector.cc b/Hadronization/ColourReconnector.cc --- a/Hadronization/ColourReconnector.cc +++ b/Hadronization/ColourReconnector.cc @@ -1,822 +1,823 @@ // -*- C++ -*- // // ColourReconnector.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 ColourReconnector class. // #include "ColourReconnector.h" #include "Cluster.h" #include #include #include #include #include #include #include #include "Herwig/Utilities/Maths.h" using namespace Herwig; using CluVecIt = ColourReconnector::CluVecIt; using Constants::pi; using Constants::twopi; DescribeClass describeColourReconnector("Herwig::ColourReconnector","Herwig.so"); IBPtr ColourReconnector::clone() const { return new_ptr(*this); } IBPtr ColourReconnector::fullclone() const { return new_ptr(*this); } void ColourReconnector::rearrange(ClusterVector & clusters) { if (_clreco == 0) return; // need at least two clusters if (clusters.size() < 2) return; // do the colour reconnection switch (_algorithm) { case 0: _doRecoPlain(clusters); break; case 1: _doRecoStatistical(clusters); break; case 2: _doRecoBaryonic(clusters); break; } } Energy2 ColourReconnector::_clusterMassSum(const PVector & q, const PVector & aq) const { const size_t nclusters = q.size(); assert (aq.size() == nclusters); Energy2 sum = ZERO; for (size_t i = 0; i < nclusters; i++) sum += ( q[i]->momentum() + aq[i]->momentum() ).m2(); return sum; } bool ColourReconnector::_containsColour8(const ClusterVector & cv, const vector & P) const { assert (P.size() == cv.size()); for (size_t i = 0; i < cv.size(); i++) { tcPPtr p = cv[i]->colParticle(); tcPPtr q = cv[P[i]]->antiColParticle(); if (_isColour8(p, q)) return true; } return false; } void ColourReconnector::_doRecoStatistical(ClusterVector & cv) const { const size_t nclusters = cv.size(); // initially, enumerate (anti)quarks as given in the cluster vector ParticleVector q, aq; for (size_t i = 0; i < nclusters; i++) { q.push_back( cv[i]->colParticle() ); aq.push_back( cv[i]->antiColParticle() ); } // annealing scheme Energy2 t, delta; Energy2 lambda = _clusterMassSum(q,aq); const unsigned _ntries = _triesPerStepFactor * nclusters; // find appropriate starting temperature by measuring the largest lambda // difference in some dry-run random rearrangements { vector typical; for (int i = 0; i < 10; i++) { const pair toswap = _shuffle(q,aq,5); ParticleVector newaq = aq; swap (newaq[toswap.first], newaq[toswap.second]); Energy2 newlambda = _clusterMassSum(q,newaq); typical.push_back( abs(newlambda - lambda) ); } t = _initTemp * Math::median(typical); } // anneal in up to _annealingSteps temperature steps for (unsigned step = 0; step < _annealingSteps; step++) { // For this temperature step, try to reconnect _ntries times. Stop the // algorithm if no successful reconnection happens. unsigned nSuccess = 0; for (unsigned it = 0; it < _ntries; it++) { // make a random rearrangement const unsigned maxtries = 10; const pair toswap = _shuffle(q,aq,maxtries); const int i = toswap.first; const int j = toswap.second; // stop here if we cannot find any allowed reconfiguration if (i == -1) break; // create a new antiquark vector with the two partons swapped ParticleVector newaq = aq; swap (newaq[i], newaq[j]); // Check if lambda would decrease. If yes, accept the reconnection. If no, // accept it only with a probability given by the current Boltzmann // factor. In the latter case we set p = 0 if the temperature is close to // 0, to avoid division by 0. Energy2 newlambda = _clusterMassSum(q,newaq); delta = newlambda - lambda; double prob = 1.0; if (delta > ZERO) prob = ( abs(t) < 1e-8*MeV2 ) ? 0.0 : exp(-delta/t); if (UseRandom::rnd() < prob) { lambda = newlambda; swap (newaq, aq); nSuccess++; } } if (nSuccess == 0) break; // reduce temperature t *= _annealingFactor; } // construct the new cluster vector ClusterVector newclusters; for (size_t i = 0; i < nclusters; i++) { ClusterPtr cl = new_ptr( Cluster( q[i], aq[i] ) ); newclusters.push_back(cl); } swap(newclusters,cv); return; } void ColourReconnector::_doRecoPlain(ClusterVector & cv) const { ClusterVector newcv = cv; // try to avoid systematic errors by randomising the reconnection order long (*p_irnd)(long) = UseRandom::irnd; random_shuffle( newcv.begin(), newcv.end(), p_irnd ); // iterate over all clusters for (CluVecIt cit = newcv.begin(); cit != newcv.end(); cit++) { // find the cluster which, if reconnected with *cit, would result in the // smallest sum of cluster masses // NB this method returns *cit if no reconnection partner can be found CluVecIt candidate = _findRecoPartner(cit, newcv); // skip this cluster if no possible reshuffling partner can be found if (candidate == cit) continue; // accept the reconnection with probability _preco. if (UseRandom::rnd() < _preco) { pair reconnected = _reconnect(*cit, *candidate); // Replace the clusters in the ClusterVector. The order of the // colour-triplet partons in the cluster vector is retained here. // replace *cit by reconnected.first *cit = reconnected.first; // replace candidate by reconnected.second *candidate = reconnected.second; } } swap(cv,newcv); return; } namespace { inline bool hasDiquark(CluVecIt cit) { for(int i = 0; i<(*cit)->numComponents(); i++) { if (DiquarkMatcher::Check(*((*cit)->particle(i)->dataPtr()))) return true; } return false; } } // Implementation of the baryonic reconnection algorithm void ColourReconnector::_doRecoBaryonic(ClusterVector & cv) const { ClusterVector newcv = cv; ClusterVector deleted; deleted.reserve(cv.size()); // try to avoid systematic errors by randomising the reconnection order long (*p_irnd)(long) = UseRandom::irnd; random_shuffle( newcv.begin(), newcv.end(), p_irnd ); // iterate over all clusters for (CluVecIt cit = newcv.begin(); cit != newcv.end(); ++cit) { //avoid clusters already containing diuarks if (hasDiquark(cit)) continue; //skip the cluster to be deleted later 3->2 cluster if (find(deleted.begin(), deleted.end(), *cit) != deleted.end()) continue; // Skip all found baryonic clusters, this biases the algorithm but implementing // something like re-reconnection is ongoing work if ((*cit)->numComponents()==3) continue; // Find a candidate suitable for reconnection CluVecIt baryonic1, baryonic2; bool isBaryonicCandidate = false; CluVecIt candidate = _findPartnerBaryonic(cit, newcv, isBaryonicCandidate, deleted, baryonic1, baryonic2); // skip this cluster if no possible reconnection partner can be found if ( !isBaryonicCandidate && candidate==cit ) continue; if ( isBaryonicCandidate && UseRandom::rnd() < _precoBaryonic ) { deleted.push_back(*baryonic2); // Function that does the reconnection from 3 -> 2 clusters ClusterPtr b1, b2; _makeBaryonicClusters(*cit,*baryonic1,*baryonic2, b1, b2); *cit = b1; *baryonic1 = b2; // Baryonic2 is easily skipped in the next loop } // Normal 2->2 Colour reconnection if ( !isBaryonicCandidate && UseRandom::rnd() < _preco ) { auto reconnected = _reconnectBaryonic(*cit, *candidate); *cit = reconnected.first; *candidate = reconnected.second; } } // create a new vector of clusters except for the ones which are "deleted" during // baryonic reconnection ClusterVector clustervector; for ( const auto & cluster : newcv ) if ( find(deleted.begin(), deleted.end(), cluster) == deleted.end() ) clustervector.push_back(cluster); swap(cv,clustervector); } namespace { double calculateRapidityRF(const Lorentz5Momentum & q1, const Lorentz5Momentum & p2) { //calculate rapidity wrt the direction of q1 //angle between the particles in the RF of cluster of q1 // calculate the z component of p2 w.r.t the direction of q1 + if(q1.rho2()==ZERO) return 0.; const Energy pz = p2.vect() * q1.vect().unit(); if ( pz == ZERO ) return 0.; // Transverse momentum of p2 w.r.t the direction of q1 const Energy pt = sqrt(p2.vect().mag2() - sqr(pz)); // Transverse mass pf p2 w.r.t to the direction of q1 const Energy mtrans = sqrt(p2.mass()*p2.mass() + (pt*pt)); // Correct formula const double y2 = log((p2.t() + abs(pz))/mtrans); return ( pz < ZERO ) ? -y2 : y2; } } CluVecIt ColourReconnector::_findPartnerBaryonic( CluVecIt cl, ClusterVector & cv, bool & baryonicCand, const ClusterVector& deleted, CluVecIt &baryonic1, CluVecIt &baryonic2 ) const { using Constants::pi; using Constants::twopi; // Returns a candidate for possible reconnection CluVecIt candidate = cl; bool bcand = false; double maxrap = 0.0; double minrap = 0.0; double maxrapNormal = 0.0; double minrapNormal = 0.0; double maxsumnormal = 0.0; double maxsum = 0.0; double secondsum = 0.0; // boost into RF of cl Lorentz5Momentum cl1 = (*cl)->momentum(); const Boost boostv(-cl1.boostVector()); cl1.boost(boostv); // boost constituents of cl into RF of cl Lorentz5Momentum p1col = (*cl)->colParticle()->momentum(); Lorentz5Momentum p1anticol = (*cl)->antiColParticle()->momentum(); p1col.boost(boostv); p1anticol.boost(boostv); for (CluVecIt cit=cv.begin(); cit != cv.end(); ++cit) { //avoid looping over clusters containing diquarks if ( hasDiquark(cit) ) continue; if ( (*cit)->numComponents()==3 ) continue; if ( cit==cl ) continue; //skip the cluster to be deleted later 3->2 cluster if ( find(deleted.begin(), deleted.end(), *cit) != deleted.end() ) continue; if ( (*cl)->isBeamCluster() && (*cit)->isBeamCluster() ) continue; // stop it putting far apart clusters together if ( ( (**cl).vertex()-(**cit).vertex() ).m() >_maxDistance ) continue; const bool Colour8 = _isColour8( (*cl)->colParticle(), (*cit)->antiColParticle() ) || _isColour8( (*cit)->colParticle(), (*cl)->antiColParticle() ) ; if ( Colour8 ) continue; // boost constituents of cit into RF of cl Lorentz5Momentum p2col = (*cit)->colParticle()->momentum(); Lorentz5Momentum p2anticol = (*cit)->antiColParticle()->momentum(); p2col.boost(boostv); p2anticol.boost(boostv); // calculate the rapidity of the other constituents of the clusters // w.r.t axis of p1anticol.vect.unit const double rapq = calculateRapidityRF(p1anticol,p2col); const double rapqbar = calculateRapidityRF(p1anticol,p2anticol); // configuration for normal CR if ( rapq > 0.0 && rapqbar < 0.0 && rapq > maxrap && rapqbar < minrap ) { maxrap = rapq; minrap = rapqbar; //sum of rapidities of quarks const double normalsum = abs(rapq) + abs(rapqbar); if ( normalsum > maxsumnormal ) { maxsumnormal = normalsum; maxrapNormal = rapq; minrapNormal = rapqbar; bcand = false; candidate = cit; } } if ( rapq < 0.0 && rapqbar >0.0 && rapqbar > maxrapNormal && rapq < minrapNormal ) { maxrap = rapqbar; minrap = rapq; const double sumrap = abs(rapqbar) + abs(rapq); // first candidate gets here. If second baryonic candidate has higher Ysum than the first // one, the second candidate becomes the first one and the first the second. if (sumrap > maxsum) { if(maxsum != 0){ baryonic2 = baryonic1; baryonic1 = cit; bcand = true; } else { baryonic1 = cit; } maxsum = sumrap; } else { if (sumrap > secondsum && sumrap != maxsum) { secondsum = sumrap; bcand = true; baryonic2 = cit; } } } } if(bcand == true){ baryonicCand = true; } return candidate; } CluVecIt ColourReconnector::_findRecoPartner(CluVecIt cl, ClusterVector & cv) const { CluVecIt candidate = cl; Energy minMass = 1*TeV; for (CluVecIt cit=cv.begin(); cit != cv.end(); ++cit) { // don't even look at original cluster if(cit==cl) continue; // don't allow colour octet clusters if ( _isColour8( (*cl)->colParticle(), (*cit)->antiColParticle() ) || _isColour8( (*cit)->colParticle(), (*cl)->antiColParticle() ) ) { continue; } // stop it putting beam remnants together if((*cl)->isBeamCluster() && (*cit)->isBeamCluster()) continue; // stop it putting far apart clusters together if(((**cl).vertex()-(**cit).vertex()).m()>_maxDistance) continue; // momenta of the old clusters Lorentz5Momentum p1 = (*cl)->colParticle()->momentum() + (*cl)->antiColParticle()->momentum(); Lorentz5Momentum p2 = (*cit)->colParticle()->momentum() + (*cit)->antiColParticle()->momentum(); // momenta of the new clusters Lorentz5Momentum p3 = (*cl)->colParticle()->momentum() + (*cit)->antiColParticle()->momentum(); Lorentz5Momentum p4 = (*cit)->colParticle()->momentum() + (*cl)->antiColParticle()->momentum(); Energy oldMass = abs( p1.m() ) + abs( p2.m() ); Energy newMass = abs( p3.m() ) + abs( p4.m() ); if ( newMass < oldMass && newMass < minMass ) { minMass = newMass; candidate = cit; } } return candidate; } // forms two baryonic clusters from three clusters void ColourReconnector::_makeBaryonicClusters( ClusterPtr &c1, ClusterPtr &c2, ClusterPtr &c3, ClusterPtr &newcluster1, ClusterPtr &newcluster2) const{ //make sure they all have 2 components assert(c1->numComponents()==2); assert(c2->numComponents()==2); assert(c3->numComponents()==2); //abandon children c1->colParticle()->abandonChild(c1); c1->antiColParticle()->abandonChild(c1); c2->colParticle()->abandonChild(c2); c2->antiColParticle()->abandonChild(c2); c3->colParticle()->abandonChild(c3); c3->antiColParticle()->abandonChild(c3); newcluster1 = new_ptr(Cluster(c1->colParticle(),c2->colParticle(), c3->colParticle())); c1->colParticle()->addChild(newcluster1); c2->colParticle()->addChild(newcluster1); c3->colParticle()->addChild(newcluster1); newcluster1->setVertex(LorentzPoint()); newcluster2 = new_ptr(Cluster(c1->antiColParticle(), c2->antiColParticle(), c3->antiColParticle())); c1->antiColParticle()->addChild(newcluster2); c2->antiColParticle()->addChild(newcluster2); c3->antiColParticle()->addChild(newcluster2); newcluster2->setVertex(LorentzPoint()); } pair ColourReconnector::_reconnect(ClusterPtr &c1, ClusterPtr &c2) const { // choose the other possibility to form two clusters from the given // constituents assert(c1->numComponents()==2); assert(c2->numComponents()==2); int c1_col(-1),c1_anti(-1),c2_col(-1),c2_anti(-1); for(unsigned int ix=0;ix<2;++ix) { if (c1->particle(ix)->hasColour(false)) c1_col = ix; else if(c1->particle(ix)->hasColour(true )) c1_anti = ix; if (c2->particle(ix)->hasColour(false)) c2_col = ix; else if(c2->particle(ix)->hasColour(true )) c2_anti = ix; } assert(c1_col>=0&&c2_col>=0&&c1_anti>=0&&c2_anti>=0); ClusterPtr newCluster1 = new_ptr( Cluster( c1->colParticle(), c2->antiColParticle() ) ); newCluster1->setVertex(0.5*( c1->colParticle()->vertex() + c2->antiColParticle()->vertex() )); if(c1->isBeamRemnant(c1_col )) newCluster1->setBeamRemnant(0,true); if(c2->isBeamRemnant(c2_anti)) newCluster1->setBeamRemnant(1,true); ClusterPtr newCluster2 = new_ptr( Cluster( c2->colParticle(), c1->antiColParticle() ) ); newCluster2->setVertex(0.5*( c2->colParticle()->vertex() + c1->antiColParticle()->vertex() )); if(c2->isBeamRemnant(c2_col )) newCluster2->setBeamRemnant(0,true); if(c1->isBeamRemnant(c1_anti)) newCluster2->setBeamRemnant(1,true); return pair (newCluster1, newCluster2); } pair ColourReconnector::_reconnectBaryonic(ClusterPtr &c1, ClusterPtr &c2) const { // choose the other possibility to form two clusters from the given // constituents assert(c1->numComponents()==2); assert(c2->numComponents()==2); int c1_col(-1),c1_anti(-1),c2_col(-1),c2_anti(-1); for(unsigned int ix=0;ix<2;++ix) { if (c1->particle(ix)->hasColour(false)) c1_col = ix; else if(c1->particle(ix)->hasColour(true )) c1_anti = ix; if (c2->particle(ix)->hasColour(false)) c2_col = ix; else if(c2->particle(ix)->hasColour(true )) c2_anti = ix; } assert(c1_col>=0&&c2_col>=0&&c1_anti>=0&&c2_anti>=0); c1->colParticle()->abandonChild(c1); c2->antiColParticle()->abandonChild(c2); ClusterPtr newCluster1 = new_ptr( Cluster( c1->colParticle(), c2->antiColParticle() ) ); c1->colParticle()->addChild(newCluster1); c2->antiColParticle()->addChild(newCluster1); newCluster1->setVertex(0.5*( c1->colParticle()->vertex() + c2->antiColParticle()->vertex() )); if(c1->isBeamRemnant(c1_col )) newCluster1->setBeamRemnant(0,true); if(c2->isBeamRemnant(c2_anti)) newCluster1->setBeamRemnant(1,true); c1->antiColParticle()->abandonChild(c1); c2->colParticle()->abandonChild(c2); ClusterPtr newCluster2 = new_ptr( Cluster( c2->colParticle(), c1->antiColParticle() ) ); c1->antiColParticle()->addChild(newCluster2); c2->colParticle()->addChild(newCluster2); newCluster2->setVertex(0.5*( c2->colParticle()->vertex() + c1->antiColParticle()->vertex() )); if(c2->isBeamRemnant(c2_col )) newCluster2->setBeamRemnant(0,true); if(c1->isBeamRemnant(c1_anti)) newCluster2->setBeamRemnant(1,true); return pair (newCluster1, newCluster2); } pair ColourReconnector::_shuffle (const PVector & q, const PVector & aq, unsigned maxtries) const { const size_t nclusters = q.size(); assert (nclusters > 1); assert (aq.size() == nclusters); int i, j; unsigned tries = 0; bool octet; do { // find two different random integers in the range [0, nclusters) i = UseRandom::irnd( nclusters ); do { j = UseRandom::irnd( nclusters ); } while (i == j); // check if one of the two potential clusters would be a colour octet state octet = _isColour8( q[i], aq[j] ) || _isColour8( q[j], aq[i] ) ; tries++; } while (octet && tries < maxtries); if (octet) i = j = -1; return make_pair(i,j); } bool ColourReconnector::_isColour8(tcPPtr p, tcPPtr q) const { bool octet = false; // make sure we have a triplet and an anti-triplet if ( ( p->hasColour() && q->hasAntiColour() ) || ( p->hasAntiColour() && q->hasColour() ) ) { // true if p and q are originated from a colour octet if ( !p->parents().empty() && !q->parents().empty() ) { octet = ( p->parents()[0] == q->parents()[0] ) && ( p->parents()[0]->data().iColour() == PDT::Colour8 ); } // (Final) option: check if same colour8 parent // or already found an octet. if(_octetOption==0||octet) return octet; // (All) option handling more octets // by browsing particle history/colour lines. tColinePtr cline,aline; // Get colourlines form final states. if(p->hasColour() && q->hasAntiColour()) { cline = p-> colourLine(); aline = q->antiColourLine(); } else { cline = q-> colourLine(); aline = p->antiColourLine(); } // Follow the colourline of p. if ( !p->parents().empty() ) { tPPtr parent = p->parents()[0]; while (parent) { if(parent->data().iColour() == PDT::Colour8) { // Coulour8 particles should have a colour // and an anticolour line. Currently the // remnant has none of those. Since the children // of the remnant are not allowed to emit currently, // the colour octet remnant is handled by the return // statement above. The assert also catches other // colour octets without clines. If the children of // a remnant should be allowed to emit, the remnant // should get appropriate colour lines and // colour states. // See Ticket: #407 // assert(parent->colourLine()&&parent->antiColourLine()); octet = (parent-> colourLine()==cline && parent->antiColourLine()==aline); } if(octet||parent->parents().empty()) break; parent = parent->parents()[0]; } } } return octet; } void ColourReconnector::persistentOutput(PersistentOStream & os) const { os << _clreco << _preco << _precoBaryonic << _algorithm << _initTemp << _annealingFactor << _annealingSteps << _triesPerStepFactor << ounit(_maxDistance,femtometer) << _octetOption; } void ColourReconnector::persistentInput(PersistentIStream & is, int) { is >> _clreco >> _preco >> _precoBaryonic >> _algorithm >> _initTemp >> _annealingFactor >> _annealingSteps >> _triesPerStepFactor >> iunit(_maxDistance,femtometer) >> _octetOption; } void ColourReconnector::Init() { static ClassDocumentation documentation ("This class is responsible of the colour reconnection."); static Switch interfaceColourReconnection ("ColourReconnection", "Colour reconnections", &ColourReconnector::_clreco, 0, true, false); static SwitchOption interfaceColourReconnectionNo (interfaceColourReconnection, "No", "Colour reconnections off", 0); static SwitchOption interfaceColourReconnectionYes (interfaceColourReconnection, "Yes", "Colour reconnections on", 1); static Parameter interfaceMtrpAnnealingFactor ("AnnealingFactor", "The annealing factor is the ratio of the temperatures in two successive " "temperature steps.", &ColourReconnector::_annealingFactor, 0.9, 0.0, 1.0, false, false, Interface::limited); static Parameter interfaceMtrpAnnealingSteps ("AnnealingSteps", "Number of temperature steps in the statistical annealing algorithm", &ColourReconnector::_annealingSteps, 50, 1, 10000, false, false, Interface::limited); static Parameter interfaceMtrpTriesPerStepFactor ("TriesPerStepFactor", "The number of reconnection tries per temperature steps is the number of " "clusters times this factor.", &ColourReconnector::_triesPerStepFactor, 5.0, 0.0, 100.0, false, false, Interface::limited); static Parameter interfaceMtrpInitialTemp ("InitialTemperature", "Factor used to determine the initial temperature from the median of the " "energy change in a few random rearrangements.", &ColourReconnector::_initTemp, 0.1, 0.00001, 100.0, false, false, Interface::limited); static Parameter interfaceRecoProb ("ReconnectionProbability", "Probability that a found reconnection possibility is actually accepted", &ColourReconnector::_preco, 0.5, 0.0, 1.0, false, false, Interface::limited); static Parameter interfaceRecoProbBaryonic ("ReconnectionProbabilityBaryonic", "Probability that a found reconnection possibility is actually accepted", &ColourReconnector::_precoBaryonic, 0.5, 0.0, 1.0, false, false, Interface::limited); static Switch interfaceAlgorithm ("Algorithm", "Specifies the colour reconnection algorithm", &ColourReconnector::_algorithm, 0, true, false); static SwitchOption interfaceAlgorithmPlain (interfaceAlgorithm, "Plain", "Plain colour reconnection as in Herwig 2.5.0", 0); static SwitchOption interfaceAlgorithmStatistical (interfaceAlgorithm, "Statistical", "Statistical colour reconnection using simulated annealing", 1); static SwitchOption interfaceAlgorithmBaryonic (interfaceAlgorithm, "Baryonic", "Baryonic cluster reconnection", 2); static Parameter interfaceMaxDistance ("MaxDistance", "Maximum distance between the clusters at which to consider rearrangement" " to avoid colour reconneections of displaced vertices", &ColourReconnector::_maxDistance, femtometer, 1000.*femtometer, 0.0*femtometer, 1e100*femtometer, false, false, Interface::limited); static Switch interfaceOctetTreatment ("OctetTreatment", "Which octets are not allowed to be reconnected", &ColourReconnector::_octetOption, 0, false, false); static SwitchOption interfaceOctetTreatmentFinal (interfaceOctetTreatment, "Final", "Only prevent for the final (usuaslly non-perturbative) g -> q qbar splitting", 0); static SwitchOption interfaceOctetTreatmentAll (interfaceOctetTreatment, "All", "Prevent for all octets", 1); } diff --git a/Hadronization/HadronSelector.cc b/Hadronization/HadronSelector.cc --- a/Hadronization/HadronSelector.cc +++ b/Hadronization/HadronSelector.cc @@ -1,1003 +1,1013 @@ // -*- C++ -*- // // HadronSelector.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 HadronSelector class. // #include "HadronSelector.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/ParVector.h" #include "ThePEG/Interface/RefVector.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include #include #include #include #include "CheckId.h" #include using namespace Herwig; DescribeAbstractClass describeHadronSelector("Herwig::HadronSelector","Herwig.so"); namespace { // // debug helper // void dumpTable(const HadronSelector::HadronTable & tbl) { // typedef HadronSelector::HadronTable::const_iterator TableIter; // for (TableIter it = tbl.begin(); it != tbl.end(); ++it) { // cerr << it->first.first << ' ' // << it->first.second << '\n'; // for (HadronSelector::KupcoData::const_iterator jt = it->second.begin(); // jt != it->second.end(); ++jt) { // cerr << '\t' << *jt << '\n'; // } // } // } bool weightIsLess (pair a, pair b) { return a.second < b.second; } } ostream & operator<< (ostream & os, const HadronSelector::HadronInfo & hi ) { os << std::scientific << std::showpoint << std::setprecision(4) << setw(2) << hi.id << '\t' // << hi.ptrData << ' ' << hi.swtef << '\t' << hi.wt << '\t' << hi.overallWeight << '\t' << ounit(hi.mass,GeV); return os; } HadronSelector::HadronSelector(unsigned int opt) : _pwtDquark( 1.0 ),_pwtUquark( 1.0 ),_pwtSquark( 1.0 ),_pwtCquark( 0.0 ), _pwtBquark( 0.0 ),_pwtDIquark( 1.0 ), _weight1S0(Nmax,1.),_weight3S1(Nmax,1.),_weight1P1(Nmax,1.),_weight3P0(Nmax,1.), _weight3P1(Nmax,1.),_weight3P2(Nmax,1.),_weight1D2(Nmax,1.),_weight3D1(Nmax,1.), _weight3D2(Nmax,1.),_weight3D3(Nmax,1.), _repwt(Lmax,vector >(Jmax,vector(Nmax))), _sngWt( 1.0 ),_decWt( 1.0 ), _topt(opt),_trial(0), _limBottom(), _limCharm(), _limExotic(), belowThreshold_(0) { // The mixing angles // the ideal mixing angle const double idealAngleMix = atan( sqrt(0.5) ) * 180.0 / Constants::pi; // \eta-\eta' mixing angle _etamix = -23.0; // phi-omega mixing angle _phimix = +36.0; // h_1'-h_1 mixing angle _h1mix = idealAngleMix; // f_0(1710)-f_0(1370) mixing angle _f0mix = idealAngleMix; // f_1(1420)-f_1(1285)\f$ mixing angle _f1mix = idealAngleMix; // f'_2-f_2\f$ mixing angle _f2mix = +26.0; // eta_2(1870)-eta_2(1645) mixing angle _eta2mix = idealAngleMix; // phi(???)-omega(1650) mixing angle _omhmix = idealAngleMix; // phi_3-omega_3 mixing angle _ph3mix = +28.0; // eta(1475)-eta(1295) mixing angle _eta2Smix = idealAngleMix; // phi(1680)-omega(1420) mixing angle _phi2Smix = idealAngleMix; } void HadronSelector::persistentOutput(PersistentOStream & os) const { os << _partons << _pwtDquark << _pwtUquark << _pwtSquark << _pwtCquark << _pwtBquark << _pwtDIquark << _etamix << _phimix << _h1mix << _f0mix << _f1mix << _f2mix << _eta2mix << _omhmix << _ph3mix << _eta2Smix << _phi2Smix << _weight1S0 << _weight3S1 << _weight1P1 << _weight3P0 << _weight3P1 << _weight3P2 << _weight1D2 << _weight3D1 << _weight3D2 << _weight3D3 << _forbidden << _sngWt << _decWt << _repwt << _pwt << _limBottom << _limCharm << _limExotic << belowThreshold_ << _table; } void HadronSelector::persistentInput(PersistentIStream & is, int) { is >> _partons >> _pwtDquark >> _pwtUquark >> _pwtSquark >> _pwtCquark >> _pwtBquark >> _pwtDIquark>> _etamix >> _phimix >> _h1mix >> _f0mix >> _f1mix >> _f2mix >> _eta2mix >> _omhmix >> _ph3mix >> _eta2Smix >> _phi2Smix >> _weight1S0 >> _weight3S1 >> _weight1P1 >> _weight3P0 >> _weight3P1 >> _weight3P2 >> _weight1D2 >> _weight3D1 >> _weight3D2 >> _weight3D3 >> _forbidden >> _sngWt >> _decWt >> _repwt >> _pwt >> _limBottom >> _limCharm >> _limExotic >> belowThreshold_ >> _table; } void HadronSelector::Init() { static ClassDocumentation documentation ("There is no documentation for the HadronSelector class"); static Parameter interfacePwtDquark("PwtDquark","Weight for choosing a quark D", &HadronSelector::_pwtDquark, 0, 1.0, 0.0, 10.0, false,false,false); static Parameter interfacePwtUquark("PwtUquark","Weight for choosing a quark U", &HadronSelector::_pwtUquark, 0, 1.0, 0.0, 10.0, false,false,false); static Parameter interfacePwtSquark("PwtSquark","Weight for choosing a quark S", &HadronSelector::_pwtSquark, 0, 1.0, 0.0, 10.0, false,false,false); static Parameter interfacePwtCquark("PwtCquark","Weight for choosing a quark C", &HadronSelector::_pwtCquark, 0, 0.0, 0.0, 10.0, false,false,false); static Parameter interfacePwtBquark("PwtBquark","Weight for choosing a quark B", &HadronSelector::_pwtBquark, 0, 0.0, 0.0, 10.0, false,false,false); static Parameter interfacePwtDIquark("PwtDIquark","Weight for choosing a DIquark", &HadronSelector::_pwtDIquark, 0, 1.0, 0.0, 100.0, false,false,false); static Parameter interfaceSngWt("SngWt","Weight for singlet baryons", &HadronSelector::_sngWt, 0, 1.0, 0.0, 10.0, false,false,false); static Parameter interfaceDecWt("DecWt","Weight for decuplet baryons", &HadronSelector::_decWt, 0, 1.0, 0.0, 10.0, false,false,false); static RefVector interfacePartons ("Partons", "The partons which are to be considered as the consistuents of the hadrons.", &HadronSelector::_partons, -1, false, false, true, false, false); static RefVector interfaceForbidden ("Forbidden", "The PDG codes of the particles which cannot be produced in the hadronization.", &HadronSelector::_forbidden, -1, false, false, true, false, false); // // mixing angles // // the ideal mixing angle const double idealAngleMix = atan( sqrt(0.5) ) * 180.0 / Constants::pi; static Parameter interface11S0Mixing ("11S0Mixing", "The mixing angle for the I=0 mesons from the 1 1S0 multiplet," " i.e. eta and etaprime.", &HadronSelector::_etamix, -23., -180., 180., false, false, Interface::limited); static Parameter interface13S1Mixing ("13S1Mixing", "The mixing angle for the I=0 mesons from the 1 3S1 multiplet," " i.e. phi and omega.", &HadronSelector::_phimix, +36., -180., 180., false, false, Interface::limited); static Parameter interface11P1Mixing ("11P1Mixing", "The mixing angle for the I=0 mesons from the 1 1P1 multiplet," " i.e. h_1' and h_1.", &HadronSelector::_h1mix, idealAngleMix, -180., 180., false, false, Interface::limited); static Parameter interface13P0Mixing ("13P0Mixing", "The mixing angle for the I=0 mesons from the 1 3P0 multiplet," " i.e. f_0(1710) and f_0(1370).", &HadronSelector::_f0mix, idealAngleMix, -180., 180., false, false, Interface::limited); static Parameter interface13P1Mixing ("13P1Mixing", "The mixing angle for the I=0 mesons from the 1 3P1 multiplet," " i.e. f_1(1420) and f_1(1285).", &HadronSelector::_f1mix, idealAngleMix, -180., 180., false, false, Interface::limited); static Parameter interface13P2Mixing ("13P2Mixing", "The mixing angle for the I=0 mesons from the 1 3P2 multiplet," " i.e. f'_2 and f_2.", &HadronSelector::_f2mix, 26.0, -180., 180., false, false, Interface::limited); static Parameter interface11D2Mixing ("11D2Mixing", "The mixing angle for the I=0 mesons from the 1 1D2 multiplet," " i.e. eta_2(1870) and eta_2(1645).", &HadronSelector::_eta2mix, idealAngleMix, -180., 180., false, false, Interface::limited); static Parameter interface13D0Mixing ("13D0Mixing", "The mixing angle for the I=0 mesons from the 1 3D0 multiplet," " i.e. eta_2(1870) phi(?) and omega(1650).", &HadronSelector::_omhmix, idealAngleMix, -180., 180., false, false, Interface::limited); static Parameter interface13D1Mixing ("13D1Mixing", "The mixing angle for the I=0 mesons from the 1 3D1 multiplet," " i.e. phi_3 and omega_3.", &HadronSelector::_ph3mix, 28.0, -180., 180., false, false, Interface::limited); static Parameter interface21S0Mixing ("21S0Mixing", "The mixing angle for the I=0 mesons from the 2 1S0 multiplet," " i.e. eta(1475) and eta(1295).", &HadronSelector::_eta2Smix, idealAngleMix, -180., 180., false, false, Interface::limited); static Parameter interface23S1Mixing ("23S1Mixing", "The mixing angle for the I=0 mesons from the 1 3S1 multiplet," " i.e. phi(1680) and omega(1420).", &HadronSelector::_phi2Smix, idealAngleMix, -180., 180., false, false, Interface::limited); // // the meson weights // static ParVector interface1S0Weights ("1S0Weights", "The weights for the 1S0 multiplets start with n=1.", &HadronSelector::_weight1S0, Nmax, 1.0, 0.0, 100.0, false, false, Interface::limited); static ParVector interface3S1Weights ("3S1Weights", "The weights for the 3S1 multiplets start with n=1.", &HadronSelector::_weight3S1, Nmax, 1.0, 0.0, 100.0, false, false, Interface::limited); static ParVector interface1P1Weights ("1P1Weights", "The weights for the 1P1 multiplets start with n=1.", &HadronSelector::_weight1P1, Nmax, 1.0, 0.0, 100.0, false, false, Interface::limited); static ParVector interface3P0Weights ("3P0Weights", "The weights for the 3P0 multiplets start with n=1.", &HadronSelector::_weight3P0, Nmax, 1.0, 0.0, 100.0, false, false, Interface::limited); static ParVector interface3P1Weights ("3P1Weights", "The weights for the 3P1 multiplets start with n=1.", &HadronSelector::_weight3P1, Nmax, 1.0, 0.0, 100.0, false, false, Interface::limited); static ParVector interface3P2Weights ("3P2Weights", "The weights for the 3P2 multiplets start with n=1.", &HadronSelector::_weight3P2, Nmax, 1.0, 0.0, 100.0, false, false, Interface::limited); static ParVector interface1D2Weights ("1D2Weights", "The weights for the 1D2 multiplets start with n=1.", &HadronSelector::_weight1D2, Nmax, 1.0, 0.0, 100.0, false, false, Interface::limited); static ParVector interface3D1Weights ("3D1Weights", "The weights for the 3D1 multiplets start with n=1.", &HadronSelector::_weight3D1, Nmax, 1.0, 0.0, 100.0, false, false, Interface::limited); static ParVector interface3D2Weights ("3D2Weights", "The weights for the 3D2 multiplets start with n=1.", &HadronSelector::_weight3D2, Nmax, 1.0, 0.0, 100.0, false, false, Interface::limited); static ParVector interface3D3Weights ("3D3Weights", "The weights for the 3D3 multiplets start with n=1.", &HadronSelector::_weight3D3, Nmax, 1.0, 0.0, 100.0, false, false, Interface::limited); static Switch interfaceTrial ("Trial", "A Debugging option to only produce certain types of hadrons", &HadronSelector::_trial, 0, false, false); static SwitchOption interfaceTrialAll (interfaceTrial, "All", "Produce all the hadrons", 0); static SwitchOption interfaceTrialPions (interfaceTrial, "Pions", "Only produce pions", 1); static SwitchOption interfaceTrialSpin2 (interfaceTrial, "Spin2", "Only mesons with spin less than or equal to two are produced", 2); static SwitchOption interfaceTrialSpin3 (interfaceTrial, "Spin3", "Only hadrons with spin less than or equal to three are produced", 3); static Parameter interfaceSingleHadronLimitBottom ("SingleHadronLimitBottom", "Threshold for one-hadron decay of b-cluster", &HadronSelector::_limBottom, 0, 0.0, 0.0, 100.0,false,false,false); static Parameter interfaceSingleHadronLimitCharm ("SingleHadronLimitCharm", "threshold for one-hadron decay of c-cluster", &HadronSelector::_limCharm, 0, 0.0, 0.0, 100.0,false,false,false); static Parameter interfaceSingleHadronLimitExotic ("SingleHadronLimitExotic", "threshold for one-hadron decay of exotic cluster", &HadronSelector::_limExotic, 0, 0.0, 0.0, 100.0,false,false,false); static Switch interfaceBelowThreshold ("BelowThreshold", "Option fo the selection of the hadrons if the cluster is below the pair threshold", &HadronSelector::belowThreshold_, 0, false, false); static SwitchOption interfaceBelowThresholdLightest (interfaceBelowThreshold, "Lightest", "Force cluster to decay to the lightest hadron with the appropriate flavours", 0); static SwitchOption interfaceBelowThresholdAll (interfaceBelowThreshold, "All", "Select from all the hadrons below the two hadron threshold according to their spin weights", 1); } double HadronSelector::mixingStateWeight(long id) const { switch(id) { case ParticleID::eta: return 0.5*probabilityMixing(_etamix ,1); case ParticleID::etaprime: return 0.5*probabilityMixing(_etamix ,2); case ParticleID::phi: return 0.5*probabilityMixing(_phimix ,1); case ParticleID::omega: return 0.5*probabilityMixing(_phimix ,2); case ParticleID::hprime_1: return 0.5*probabilityMixing(_h1mix ,1); case ParticleID::h_1: return 0.5*probabilityMixing(_h1mix ,2); case 10331: return 0.5*probabilityMixing(_f0mix ,1); case 10221: return 0.5*probabilityMixing(_f0mix ,2); case ParticleID::fprime_1: return 0.5*probabilityMixing(_f1mix ,1); case ParticleID::f_1: return 0.5*probabilityMixing(_f1mix ,2); case ParticleID::fprime_2: return 0.5*probabilityMixing(_f2mix ,1); case ParticleID::f_2: return 0.5*probabilityMixing(_f2mix ,2); case 10335: return 0.5*probabilityMixing(_eta2mix ,1); case 10225: return 0.5*probabilityMixing(_eta2mix ,2); // missing phi member of 13D1 should be here case 30223: return 0.5*probabilityMixing(_omhmix ,2); case 337: return 0.5*probabilityMixing(_ph3mix ,1); case 227: return 0.5*probabilityMixing(_ph3mix ,2); case 100331: return 0.5*probabilityMixing(_eta2mix ,1); case 100221: return 0.5*probabilityMixing(_eta2mix ,2); case 100333: return 0.5*probabilityMixing(_phi2Smix,1); case 100223: return 0.5*probabilityMixing(_phi2Smix,2); default: return 1./3.; } } void HadronSelector::doinit() { Interfaced::doinit(); // the default partons allowed // the quarks for ( int ix=1; ix<=5; ++ix ) { _partons.push_back(getParticleData(ix)); } // the diquarks for(unsigned int ix=1;ix<=5;++ix) { for(unsigned int iy=1; iy<=ix;++iy) { _partons.push_back(getParticleData(CheckId::makeDiquarkID(ix,iy))); } } // set the weights for the various excited mesons // set all to one to start with for (int l = 0; l < Lmax; ++l ) { for (int j = 0; j < Jmax; ++j) { for (int n = 0; n < Nmax; ++n) { _repwt[l][j][n] = 1.0; } } } // set the others from the relevant vectors for( int ix=0;ixid()]=1.; } _pwt[1] = _pwtDquark; _pwt[2] = _pwtUquark; _pwt[3] = _pwtSquark; _pwt[4] = _pwtCquark; _pwt[5] = _pwtBquark; _pwt[1103] = _pwtDIquark * _pwtDquark * _pwtDquark; _pwt[2101] = 0.5 * _pwtDIquark * _pwtUquark * _pwtDquark; _pwt[2203] = _pwtDIquark * _pwtUquark * _pwtUquark; _pwt[3101] = 0.5 * _pwtDIquark * _pwtSquark * _pwtDquark; _pwt[3201] = 0.5 * _pwtDIquark * _pwtSquark * _pwtUquark; _pwt[3303] = _pwtDIquark * _pwtSquark * _pwtSquark; // Commenting out heavy di-quark weights _pwt[4101] = 0.0; _pwt[4201] = 0.0; _pwt[4301] = 0.0; _pwt[4403] = 0.0; _pwt[5101] = 0.0; _pwt[5201] = 0.0; _pwt[5301] = 0.0; _pwt[5401] = 0.0; _pwt[5503] = 0.0; // find the maximum map::iterator pit = max_element(_pwt.begin(),_pwt.end(),weightIsLess); const double pmax = pit->second; for(pit=_pwt.begin(); pit!=_pwt.end(); ++pit) { pit->second/=pmax; } // construct the hadron tables constructHadronTable(); // for debugging // dumpTable(table()); } void HadronSelector::constructHadronTable() { // initialise the table _table.clear(); for(unsigned int ix=0; ix<_partons.size(); ++ix) { for(unsigned int iy=0; iy<_partons.size(); ++iy) { if (!(DiquarkMatcher::Check(_partons[ix]->id()) && DiquarkMatcher::Check(_partons[iy]->id()))) _table[make_pair(_partons[ix]->id(),_partons[iy]->id())] = KupcoData(); } } // get the particles from the event generator ParticleMap particles = generator()->particles(); // loop over the particles double maxdd(0.),maxss(0.),maxrest(0.); for(ParticleMap::iterator it=particles.begin(); it!=particles.end(); ++it) { long pid = it->first; tPDPtr particle = it->second; int pspin = particle->iSpin(); // Don't include hadrons which are explicitly forbidden if(find(_forbidden.begin(),_forbidden.end(),particle)!=_forbidden.end()) continue; // Don't include non-hadrons or antiparticles if(pid < 100) continue; // remove diffractive particles if(pspin == 0) continue; // K_0S and K_0L not made make K0 and Kbar0 if(pid==ParticleID::K_S0||pid==ParticleID::K_L0) continue; // Debugging options // Only include those with 2J+1 less than...5 if(_trial==2 && pspin >= 5) continue; // Only include those with 2J+1 less than...7 if(_trial==3 && pspin >= 7) continue; // Only include pions if(_trial==1 && pid!=111 && pid!=211) continue; // shouldn't be coloured if(particle->coloured()) continue; // Get the flavours const int x4 = (pid/1000)%10; const int x3 = (pid/100 )%10; const int x2 = (pid/10 )%10; const int x7 = (pid/1000000)%10; const bool wantSusy = x7 == 1 || x7 == 2; int flav1; int flav2; // Skip non-hadrons (susy particles, etc...) if(x3 == 0 || x2 == 0) continue; else if(x4 == 0) { // meson flav1 = x2; flav2 = x3; } else { // baryon flav1 = CheckId::makeDiquarkID(x2,x3); flav2 = x4; } if (wantSusy) flav2 += 1000000 * x7; HadronInfo a(pid, particle, specialWeight(pid), particle->mass()); // set the weight to the number of spin states a.overallWeight = pspin; // identical light flavours if(flav1 == flav2 && flav1<=3) { // ddbar> uubar> admixture states if(flav1==1) { if(_topt != 0) a.overallWeight *= 0.5*a.swtef; _table[make_pair(1,1)].insert(a); _table[make_pair(2,2)].insert(a); if(_topt == 0 && a.overallWeight > maxdd) maxdd = a.overallWeight; } // load up ssbar> uubar> ddbar> admixture states else { a.wt = mixingStateWeight(pid); a.overallWeight *= a.wt; if(_topt != 0) a.overallWeight *= a.swtef; _table[make_pair(1,1)].insert(a); _table[make_pair(2,2)].insert(a); if(_topt == 0 && a.overallWeight > maxdd) maxdd = a.overallWeight; a.wt = (_topt != 0) ? 1.- 2.*a.wt : 1 - a.wt; if(a.wt > 0) { a.overallWeight = a.wt * a.swtef * pspin; _table[make_pair(3,3)].insert(a); if(_topt == 0 && a.overallWeight > maxss) maxss = a.overallWeight; } } } // light baryons with all quarks identical else if((flav1 == 1 && flav2 == 1103) || (flav1 == 1103 && flav2 == 1) || (flav1 == 2 && flav2 == 2203) || (flav1 == 2203 && flav2 == 2) || (flav1 == 3 && flav2 == 3303) || (flav1 == 3303 && flav2 == 3)) { if(_topt != 0) a.overallWeight *= 1.5*a.swtef; _table[make_pair(flav1,flav2)].insert(a); _table[make_pair(flav2,flav1)].insert(a); if(_topt == 0 && a.overallWeight > maxrest) maxrest = a.overallWeight; } // all other cases else { if(_topt != 0) a.overallWeight *=a.swtef; _table[make_pair(flav1,flav2)].insert(a); if(flav1 != flav2) _table[make_pair(flav2,flav1)].insert(a); if(_topt == 0 && a.overallWeight > maxrest) maxrest = a.overallWeight; } } // Account for identical combos of diquark/quarks and symmetrical elements // e.g. U UD = D UU HadronTable::iterator tit; for(tit=_table.begin();tit!=_table.end();++tit) { if(tit->first.first>ParticleID::c) continue; if(!DiquarkMatcher::Check(tit->first.second)) continue; long k, l, sub; if(tit->first.second>=ParticleID::bd_0) { k = ParticleID::b; sub = ParticleID::bd_0/100; } else if(tit->first.second>=ParticleID::cd_0) { k = ParticleID::c; sub = ParticleID::cd_0/100; } else if(tit->first.second>=ParticleID::sd_0) { k = ParticleID::s; sub = ParticleID::sd_0/100; } else if(tit->first.second>=ParticleID::ud_0) { k = ParticleID::u; sub = ParticleID::ud_0/100; } else if(tit->first.second==ParticleID::dd_1) { k = ParticleID::d; sub = ParticleID::dd_1/100; } else continue; sub=tit->first.second/100-sub+1; if(sub > tit->first.first) { l = 1000*sub+100*tit->first.first+1; } else if(sub==tit->first.first) { l = 1000*sub+ 100*tit->first.first+3; } else { l = 100*sub +1000*tit->first.first+1; } if(tit->second.empty()) { pair newpair(k,l); tit->second=_table[newpair]; newpair=make_pair(tit->first.second,tit->first.first); _table[newpair]=tit->second; }; } // normalise weights to one for first option if(_topt == 0) { HadronTable::const_iterator tit; KupcoData::iterator it; for(tit=_table.begin();tit!=_table.end();++tit) { double weight; if(tit->first.first==tit->first.second) { if(tit->first.first==1||tit->first.first==2) weight=1./maxdd; else if (tit->first.first==3) weight=1./maxss; else weight=1./maxrest; } else weight=1./maxrest; for(it = tit->second.begin(); it!=tit->second.end(); ++it) { it->rescale(weight); } } } } double HadronSelector::specialWeight(long id) const { const int pspin = id % 10; // Only K0L and K0S have pspin == 0, should // not get them until Decay step assert( pspin != 0 ); // Baryon : J = 1/2 or 3/2 if(pspin == 2) { // Singlet (Lambda-like) baryon if( (id/100)%10 < (id/10 )%10 ) return sqr(_sngWt); // octet else return 1.; } // Decuplet baryon else if (pspin == 4) { return sqr(_decWt); } // Meson else if(pspin % 2 == 1) { // Total angular momentum int j = (pspin - 1) / 2; // related to Orbital angular momentum l int nl = (id/10000 )%10; int l = -999; int n = (id/100000)%10; // Radial excitation if(j == 0) l = nl; else if(nl == 0) l = j - 1; else if(nl == 1 || nl == 2) l = j; else if(nl == 3) l = j + 1; // Angular or Radial excited meson if((l||j||n) && l>=0 && l= 5/2 (ispin >= 6), haven't got those return 1.0; } int HadronSelector::signHadron(tcPDPtr idQ1, tcPDPtr idQ2, tcPDPtr hadron) const { // This method receives in input three PDG ids, whose the // first two have proper signs (corresponding to particles, id > 0, // or antiparticles, id < 0 ), whereas the third one must // be always positive (particle not antiparticle), // corresponding to: // --- quark-antiquark, or antiquark-quark, or // quark-diquark, or diquark-quark, or // antiquark-antidiquark, or antidiquark-antiquark // for the first two input (idQ1, idQ2); // --- meson or baryon for the third input (idHad): // The method returns: // --- + 1 if the two partons (idQ1, idQ2) are exactly // the constituents for the hadron idHad; // --- - 1 if the two partons (idQ1, idQ2) are exactly // the constituents for the anti-hadron -idHad; // --- + 0 otherwise. // The method it is therefore useful to decide the // sign of the id of the produced hadron as appeared // in the vector _vecHad (where only hadron idHad > 0 are present) // given the two constituent partons. int sign = 0; long idHad = hadron->id(); assert(idHad > 0); int chargeIn = idQ1->iCharge() + idQ2->iCharge(); int chargeOut = hadron->iCharge(); // same charge if( chargeIn == chargeOut && chargeIn !=0 ) sign = +1; else if(chargeIn == -chargeOut && chargeIn !=0 ) sign = -1; else if(chargeIn == 0 && chargeOut == 0 ) { // In the case of same null charge, there are four cases: // i) K0-like mesons, B0-like mesons, Bs-like mesons // the PDG convention is to consider them "antiparticle" (idHad < 0) // if the "dominant" (heavier) flavour (respectively, s, b) // is a quark (idQ > 0): for instance, B0s = (b, sbar) has id < 0 // Remember that there is an important exception for K0L (id=130) and // K0S (id=310): they don't have antiparticles, therefore idHad > 0 // always. We use below the fact that K0L and K0S are the unique // hadrons having 0 the first (less significant) digit of their id. // 2) D0-like mesons: the PDG convention is to consider them "particle" // (idHad > 0) if the charm flavour is carried by a c: (c,ubar) has id>0 // 3) the remaining mesons should not have antiparticle, therefore their // sign is always positive. // 4) for baryons, that is when one of idQ1 and idQ2 is a (anti-) quark and // the other one is a (anti-) diquark the sign is negative when both // constituents are "anti", that is both with id < 0; positive otherwise. // meson if(abs(int(idQ1->iColour()))== 3 && abs(int(idQ2->iColour())) == 3 && !DiquarkMatcher::Check(idQ1->id()) && !DiquarkMatcher::Check(idQ2->id())) { int idQa = abs(idQ1->id()); int idQb = abs(idQ2->id()); int dominant = idQ2->id(); if(idQa > idQb) { swap(idQa,idQb); dominant = idQ1->id(); } if((idQa==ParticleID::d && idQb==ParticleID::s) || (idQa==ParticleID::d && idQb==ParticleID::b) || (idQa==ParticleID::s && idQb==ParticleID::b)) { // idHad%10 is zero for K0L,K0S if (dominant < 0 || idHad%10 == 0) sign = +1; else if(dominant > 0) sign = -1; } else if((idQa==ParticleID::u && idQb==ParticleID::c) || (idQa==ParticleID::u && idQb==ParticleID::t) || (idQa==ParticleID::c && idQb==ParticleID::t)) { if (dominant > 0) sign = +1; else if(dominant < 0) sign = -1; } else if(idQa==idQb) sign = +1; // sets sign for Susy particles else sign = (dominant > 0) ? +1 : -1; } // baryon else if(DiquarkMatcher::Check(idQ1->id()) || DiquarkMatcher::Check(idQ2->id())) { if (idQ1->id() > 0 && idQ2->id() > 0) sign = +1; else if(idQ1->id() < 0 && idQ2->id() < 0) sign = -1; } } if (sign == 0) { cerr << "Could not work out sign for " << idQ1->PDGName() << ' ' << idQ2->PDGName() << " => " << hadron->PDGName() << '\n'; assert(false); } return sign; } pair HadronSelector::lightestHadronPair(tcPDPtr ptr1, tcPDPtr ptr2, tcPDPtr ptr3) const { // throw exception of id3!=0 as doesn't work if ( ptr3 ) throw Exception() << "ptr3!=0 not yet implemented in HadronSelector::lightestHadronPair" << Exception::abortnow; // charge int totalcharge = ptr1->iCharge() + ptr2->iCharge(); if ( ptr3 ) totalcharge += ptr3->iCharge(); tcPDPtr vIdHad1[2]={tcPDPtr(),tcPDPtr()},vIdHad2[2]={tcPDPtr(),tcPDPtr()}; bool vOk[2] = {false, false}; Energy vMassPair[2] = { ZERO, ZERO }; for (int i = 0; i < 2; i++) { tcPDPtr idPartner = i==0 ? getParticleData(ParticleID::d) : getParticleData(ParticleID::u); // Change sign to idPartner (transform it into a anti-quark) if it is not // possible to form a meson or a baryon. assert (ptr1 && idPartner); if (!CheckId::canBeHadron(ptr1, idPartner)) idPartner = idPartner->CC(); vIdHad1[i] = lightestHadron(ptr1, idPartner); vIdHad2[i] = lightestHadron(ptr2, idPartner->CC()); if ( vIdHad1[i] && vIdHad2[i] && vIdHad1[i]->iCharge() + vIdHad2[i]->iCharge() == totalcharge ) { vOk[i] = true; vMassPair[i] = vIdHad1[i]->mass() + vIdHad2[i]->mass(); } } // Take the lightest pair compatible with charge conservation. if ( vOk[0] && ( ! vOk[1] || vMassPair[0] <= vMassPair[1] ) ) { return make_pair(vIdHad1[0],vIdHad2[0]); } else if ( vOk[1] && ( ! vOk[0] || vMassPair[1] < vMassPair[0] ) ) { return make_pair(vIdHad1[1],vIdHad2[1]); } else { return make_pair(tcPDPtr(),tcPDPtr()); } } Energy HadronSelector::massLightestBaryonPair(tcPDPtr ptr1, tcPDPtr ptr2) const { // Make sure that we don't have any diquarks as input, return arbitrarily // large value if we do Energy currentSum = Constants::MaxEnergy; for(unsigned int ix=0; ix<_partons.size(); ++ix) { if(!DiquarkMatcher::Check(_partons[ix]->id())) continue; HadronTable::const_iterator tit1=_table.find(make_pair(abs(ptr1->id()),_partons[ix]->id())), tit2=_table.find(make_pair(_partons[ix]->id(),abs(ptr2->id()))); if( tit1==_table.end() || tit2==_table.end()) continue; if(tit1->second.empty()||tit2->second.empty()) continue; Energy s = tit1->second.begin()->mass + tit2->second.begin()->mass; if(currentSum > s) currentSum = s; } return currentSum; } -tcPDPtr HadronSelector::lightestHadron(tcPDPtr ptr1, tcPDPtr ptr2,tcPDPtr ptr3) const { +tcPDPtr HadronSelector::lightestHadron(tcPDPtr ptr1, tcPDPtr ptr2, +#ifndef NDEBUG + tcPDPtr ptr3) const { +#else + tcPDPtr ) const { +#endif // The method assumes ptr3 == 0 rest not implemented assert(ptr1 && ptr2 && !ptr3); // find entry in the table pair ids = make_pair(abs(ptr1->id()),abs(ptr2->id())); HadronTable::const_iterator tit=_table.find(ids); // throw exception if flavours wrong if (tit==_table.end()) throw Exception() << "Could not find " << ids.first << ' ' << ids.second << " in _table. " << "In HadronSelector::lightestHadron()" << Exception::eventerror; if(tit->second.empty()) throw Exception() << "HadronSelector::lightestHadron " << "could not find any hadrons containing " << ptr1->id() << ' ' << ptr2->id() << '\n' << tit->first.first << ' ' << tit->first.second << Exception::eventerror; // find the lightest hadron int sign = signHadron(ptr1,ptr2,tit->second.begin()->ptrData); tcPDPtr candidate = sign > 0 ? tit->second.begin()->ptrData : tit->second.begin()->ptrData->CC(); // \todo 20 GeV limit is temporary fudge to let SM particles go through. // \todo Use isExotic instead? if (candidate->mass() > 20*GeV && candidate->mass() < ptr1->constituentMass() + ptr2->constituentMass()) { generator()->log() << "HadronSelector::lightestHadron: " << "chosen candidate " << candidate->PDGName() << " is lighter than its constituents " << ptr1->PDGName() << ", " << ptr2->PDGName() << '\n' << candidate->mass()/GeV << " < " << ptr1->constituentMass()/GeV << " + " << ptr2->constituentMass()/GeV << '\n' << "Check your particle data tables.\n"; assert(false); } return candidate; } vector > HadronSelector::hadronsBelowThreshold(Energy threshold, tcPDPtr ptr1, - tcPDPtr ptr2, tcPDPtr ptr3) const { + tcPDPtr ptr2, +#ifndef NDEBUG + tcPDPtr ptr3) const { +#else + tcPDPtr ) const { +#endif // The method assumes ptr3 == 0 rest not implemented assert(ptr1 && ptr2 && !ptr3); // find entry in the table pair ids = make_pair(abs(ptr1->id()),abs(ptr2->id())); HadronTable::const_iterator tit=_table.find(ids); // throw exception if flavours wrong if (tit==_table.end()) throw Exception() << "Could not find " << ids.first << ' ' << ids.second << " in _table. " << "In HadronSelector::hadronsBelowThreshold()" << Exception::eventerror; if(tit->second.empty()) throw Exception() << "HadronSelector::hadronsBelowThreshold() " << "could not find any hadrons containing " << ptr1->id() << ' ' << ptr2->id() << '\n' << tit->first.first << ' ' << tit->first.second << Exception::eventerror; vector > candidates; KupcoData::const_iterator hit = tit->second.begin(); // find the hadrons while(hit!=tit->second.end()&&hit->massptrData); tcPDPtr candidate = sign > 0 ? hit->ptrData : hit->ptrData->CC(); // \todo 20 GeV limit is temporary fudge to let SM particles go through. // \todo Use isExotic instead? if (candidate->mass() > 20*GeV && candidate->mass() < ptr1->constituentMass() + ptr2->constituentMass()) { generator()->log() << "HadronSelector::hadronsBelowTheshold: " << "chosen candidate " << candidate->PDGName() << " is lighter than its constituents " << ptr1->PDGName() << ", " << ptr2->PDGName() << '\n' << candidate->mass()/GeV << " < " << ptr1->constituentMass()/GeV << " + " << ptr2->constituentMass()/GeV << '\n' << "Check your particle data tables.\n"; assert(false); } candidates.push_back(make_pair(candidate,hit->overallWeight)); ++hit; } return candidates; } tcPDPtr HadronSelector::chooseSingleHadron(tcPDPtr par1, tcPDPtr par2, Energy mass) const { // Determine the sum of the nominal masses of the two lightest hadrons // with the right flavour numbers as the cluster under consideration. // Notice that we don't need real masses (drawn by a Breit-Wigner // distribution) because the lightest pair of hadrons does not involve // any broad resonance. Energy threshold = massLightestHadronPair(par1,par2); // Special: it allows one-hadron decays also above threshold. if (CheckId::isExotic(par1,par2)) threshold *= (1.0 + UseRandom::rnd()*_limExotic); else if (CheckId::hasBottom(par1,par2)) threshold *= (1.0 + UseRandom::rnd()*_limBottom); else if (CheckId::hasCharm(par1,par2)) threshold *= (1.0 + UseRandom::rnd()*_limCharm); // only do one hadron decay is mass less than the threshold if(mass>=threshold) return tcPDPtr(); // select the hadron tcPDPtr hadron; // old option pick the lightest hadron if(belowThreshold_ == 0) { hadron= lightestHadron(par1,par2); } // new option select from those available else if(belowThreshold_ == 1) { vector > hadrons = hadronsBelowThreshold(threshold,par1,par2); if(hadrons.size()==1) { hadron = hadrons[0].first; } else if(hadrons.empty()) { hadron= lightestHadron(par1,par2); } else { double totalWeight=0.; for(unsigned int ix=0;ix #include "Herwig/Shower/RealEmissionProcess.h" using namespace Herwig; using namespace ThePEG::Helicity; // namespace { // using namespace Herwig; // using namespace ThePEG::Helicity; // // void debuggingMatrixElement(bool BGF,const Lorentz5Momentum & pin, // const Lorentz5Momentum & p1, // const Lorentz5Momentum & p2, // tcPDPtr gluon, // const Lorentz5Momentum & pl1, // const Lorentz5Momentum & pl2, // const Lorentz5Momentum & pq1, // const Lorentz5Momentum & pq2, // tcPDPtr lepton1,tcPDPtr lepton2, // tcPDPtr quark1 ,tcPDPtr quark2, // Energy2 Q2,double phi, double x2, double x3, // double xperp, double zp, double xp, // const vector & azicoeff, // bool normalize) { // tcHwSMPtr hwsm=ThePEG::dynamic_ptr_cast // (CurrentGenerator::current().standardModel()); // assert(hwsm); // vector weakVertex; // vector bosons; // AbstractFFVVertexPtr strongVertex = hwsm->vertexFFG(); // if(lepton1->id()==lepton2->id()) { // weakVertex.push_back(hwsm->vertexFFZ()); // bosons.push_back(hwsm->getParticleData(ParticleID::Z0)); // weakVertex.push_back(hwsm->vertexFFP()); // bosons.push_back(hwsm->getParticleData(ParticleID::gamma)); // } // else { // weakVertex.push_back(hwsm->vertexFFW()); // bosons.push_back(hwsm->getParticleData(ParticleID::Wplus)); // } // if(!BGF) { // SpinorWaveFunction l1,q1,qp1; // SpinorBarWaveFunction l2,q2,qp2; // VectorWaveFunction gl(p2,gluon,outgoing); // if(lepton1->id()>0) { // l1 = SpinorWaveFunction (pl1,lepton1,incoming); // l2 = SpinorBarWaveFunction(pl2,lepton2,outgoing); // } // else { // l1 = SpinorWaveFunction (pl2,lepton2,outgoing); // l2 = SpinorBarWaveFunction(pl1,lepton1,incoming); // } // if(quark1->id()>0) { // q1 = SpinorWaveFunction (pq1,quark1,incoming); // q2 = SpinorBarWaveFunction(pq2,quark2,outgoing); // qp1 = SpinorWaveFunction (pin,quark1,incoming); // qp2 = SpinorBarWaveFunction(p1 ,quark2,outgoing); // } // else { // q1 = SpinorWaveFunction (pq2,quark2,outgoing); // q2 = SpinorBarWaveFunction(pq1,quark1,incoming); // qp1 = SpinorWaveFunction (p1 ,quark2,outgoing); // qp2 = SpinorBarWaveFunction(pin,quark1,incoming); // } // double lome(0.),realme(0.); // for(unsigned int lhel1=0;lhel1<2;++lhel1) { // l1.reset(lhel1); // for(unsigned int lhel2=0;lhel2<2;++lhel2) { // l2.reset(lhel2); // for(unsigned int qhel1=0;qhel1<2;++qhel1) { // q1.reset(qhel1); // qp1.reset(qhel1); // for(unsigned int qhel2=0;qhel2<2;++qhel2) { // q2.reset(qhel2); // qp2.reset(qhel2); // // leading order matrix element // Complex diagLO(0.); // for(unsigned int ix=0;ixevaluate(Q2,3,bosons[ix],l1,l2); // diagLO += weakVertex[ix]->evaluate(Q2,q1,q2,inter); // } // lome += norm(diagLO); // // real emission matrix element // for(unsigned int ghel=0;ghel<2;++ghel) { // gl.reset(2*ghel); // Complex diagReal(0.); // for(unsigned int ix=0;ixevaluate(Q2,3,bosons[ix],l1,l2); // SpinorWaveFunction off1 = // strongVertex->evaluate(Q2,5,qp1.particle(),qp1,gl); // Complex diag1 = weakVertex[ix]->evaluate(Q2,off1,qp2,inter); // SpinorBarWaveFunction off2 = // strongVertex->evaluate(Q2,5,qp2.particle(),qp2,gl); // Complex diag2 = weakVertex[ix]->evaluate(Q2,qp1,off2,inter); // diagReal += diag1+diag2; // } // realme += norm(diagReal); // } // } // } // } // } // double test1 = realme/lome/hwsm->alphaS(Q2)*Q2*UnitRemoval::InvE2; // double cphi(cos(phi)); // double test2; // if(normalize) { // test2 = 8.*Constants::pi/(1.-xp)/(1.-zp)* // (azicoeff[0]+azicoeff[1]*cphi+azicoeff[2]*sqr(cphi))* // (1.+sqr(xp)*(sqr(x2)+1.5*sqr(xperp))); // } // else { // test2 = 8.*Constants::pi/(1.-xp)/(1.-zp)* // (azicoeff[0]+azicoeff[1]*cphi+azicoeff[2]*sqr(cphi)); // } // cerr << "testing RATIO A " << test1/test2 << "\n"; // } // else { // SpinorWaveFunction l1,q1,qp1; // SpinorBarWaveFunction l2,q2,qp2; // VectorWaveFunction gl(pin,gluon,incoming); // if(lepton1->id()>0) { // l1 = SpinorWaveFunction (pl1,lepton1,incoming); // l2 = SpinorBarWaveFunction(pl2,lepton2,outgoing); // } // else { // l1 = SpinorWaveFunction (pl2,lepton2,outgoing); // l2 = SpinorBarWaveFunction(pl1,lepton1,incoming); // } // if(quark1->id()>0) { // q1 = SpinorWaveFunction (pq1,quark1 ,incoming); // q2 = SpinorBarWaveFunction(pq2,quark2 ,outgoing); // qp2 = SpinorBarWaveFunction(p1 ,quark2 ,outgoing); // qp1 = SpinorWaveFunction (p2 ,quark1->CC(),outgoing); // } // else { // q1 = SpinorWaveFunction (pq2,quark2 ,outgoing); // q2 = SpinorBarWaveFunction(pq1,quark1 ,incoming); // qp2 = SpinorBarWaveFunction(p2 ,quark1->CC(),outgoing); // qp1 = SpinorWaveFunction (p1 ,quark2 ,outgoing); // } // double lome(0.),realme(0.); // for(unsigned int lhel1=0;lhel1<2;++lhel1) { // l1.reset(lhel1); // for(unsigned int lhel2=0;lhel2<2;++lhel2) { // l2.reset(lhel2); // for(unsigned int qhel1=0;qhel1<2;++qhel1) { // q1.reset(qhel1); // qp1.reset(qhel1); // for(unsigned int qhel2=0;qhel2<2;++qhel2) { // q2.reset(qhel2); // qp2.reset(qhel2); // // leading order matrix element // Complex diagLO(0.); // for(unsigned int ix=0;ixevaluate(Q2,3,bosons[ix],l1,l2); // diagLO += weakVertex[ix]->evaluate(Q2,q1,q2,inter); // } // lome += norm(diagLO); // // real emission matrix element // for(unsigned int ghel=0;ghel<2;++ghel) { // gl.reset(2*ghel); // Complex diagReal(0.); // for(unsigned int ix=0;ixevaluate(Q2,3,bosons[ix],l1,l2); // SpinorWaveFunction off1 = // strongVertex->evaluate(Q2,5,qp1.particle(),qp1,gl); // Complex diag1 = weakVertex[ix]->evaluate(Q2,off1,qp2,inter); // SpinorBarWaveFunction off2 = // strongVertex->evaluate(Q2,5,qp2.particle(),qp2,gl); // Complex diag2 = weakVertex[ix]->evaluate(Q2,qp1,off2,inter); // diagReal += diag1+diag2; // } // realme += norm(diagReal); // } // } // } // } // } // double test1 = realme/lome/hwsm->alphaS(Q2)*Q2*UnitRemoval::InvE2; // double cphi(cos(phi)); // double test2; // if(normalize) { // test2 = 8.*Constants::pi/zp/(1.-zp)* // (azicoeff[0]+azicoeff[1]*cphi+azicoeff[2]*sqr(cphi))* // sqr(xp)*(sqr(x3)+sqr(x2)+3.*sqr(xperp)); // } // else { // test2 = 8.*Constants::pi/zp/(1.-zp)* // (azicoeff[0]+azicoeff[1]*cphi+azicoeff[2]*sqr(cphi)); // } // cerr << "testing RATIO B " << test1/test2 << "\n"; // } // } // // } DISBase::DISBase() : initial_(6.), final_(3.), procProb_(0.35), comptonInt_(0.), bgfInt_(0.), comptonWeight_(50.), BGFWeight_(150.), pTmin_(0.1*GeV), scaleOpt_(1), muF_(100.*GeV), scaleFact_(1.), contrib_(0), power_(0.1) {} DISBase::~DISBase() {} void DISBase::persistentOutput(PersistentOStream & os) const { os << comptonInt_ << bgfInt_ << procProb_ << initial_ << final_ << alpha_ << ounit(pTmin_,GeV) << comptonWeight_ << BGFWeight_ << gluon_ << ounit(muF_,GeV) << scaleFact_ << scaleOpt_ << contrib_<< power_; } void DISBase::persistentInput(PersistentIStream & is, int) { is >> comptonInt_ >> bgfInt_ >> procProb_ >> initial_ >> final_ >> alpha_ >> iunit(pTmin_,GeV) >> comptonWeight_ >> BGFWeight_ >> gluon_ >> iunit(muF_,GeV) >> scaleFact_ >> scaleOpt_ >> contrib_ >> power_; } // The following static variable is needed for the type // description system in ThePEG. DescribeAbstractClass describeHerwigDISBase("Herwig::DISBase", "HwMEDIS.so"); void DISBase::Init() { static ClassDocumentation documentation ("The DISBase class provides the base class for the " "implementation of DIS type processes including the " "hard corrections in either the old-fashioned matrix " "element correction of POWHEG approaches"); static Parameter interfaceProcessProbability ("ProcessProbability", "The probabilty of the QCD compton process for the process selection", &DISBase::procProb_, 0.3, 0.0, 1., false, false, Interface::limited); static Reference interfaceCoupling ("Coupling", "Pointer to the object to calculate the coupling for the correction", &DISBase::alpha_, false, false, true, false, false); static Parameter interfacepTMin ("pTMin", "The minimum pT", &DISBase::pTmin_, GeV, 1.*GeV, 0.0*GeV, 10.0*GeV, false, false, Interface::limited); static Parameter interfaceComptonWeight ("ComptonWeight", "Weight for the overestimate ofthe compton channel", &DISBase::comptonWeight_, 50.0, 0.0, 100.0, false, false, Interface::limited); static Parameter interfaceBGFWeight ("BGFWeight", "Weight for the overestimate of the BGF channel", &DISBase::BGFWeight_, 100.0, 0.0, 1000.0, false, false, Interface::limited); static Switch interfaceContribution ("Contribution", "Which contributions to the cross section to include", &DISBase::contrib_, 0, false, false); static SwitchOption interfaceContributionLeadingOrder (interfaceContribution, "LeadingOrder", "Just generate the leading order cross section", 0); static SwitchOption interfaceContributionPositiveNLO (interfaceContribution, "PositiveNLO", "Generate the positive contribution to the full NLO cross section", 1); static SwitchOption interfaceContributionNegativeNLO (interfaceContribution, "NegativeNLO", "Generate the negative contribution to the full NLO cross section", 2); static Switch interfaceScaleOption ("ScaleOption", "Option for the choice of factorization (and renormalization) scale", &DISBase::scaleOpt_, 1, false, false); static SwitchOption interfaceDynamic (interfaceScaleOption, "Dynamic", "Dynamic factorization scale equal to the current sqrt(sHat())", 1); static SwitchOption interfaceFixed (interfaceScaleOption, "Fixed", "Use a fixed factorization scale set with FactorizationScaleValue", 2); static Parameter interfaceFactorizationScale ("FactorizationScale", "Value to use in the event of a fixed factorization scale", &DISBase::muF_, GeV, 100.0*GeV, 1.0*GeV, 500.0*GeV, true, false, Interface::limited); static Parameter interfaceScaleFactor ("ScaleFactor", "The factor used before Q2 if using a running scale", &DISBase::scaleFact_, 1.0, 0.0, 10.0, false, false, Interface::limited); static Parameter interfaceSamplingPower ("SamplingPower", "Power for the sampling of xp", &DISBase::power_, 0.6, 0.0, 1., false, false, Interface::limited); } void DISBase::doinit() { HwMEBase::doinit(); // integrals of me over phase space double r5=sqrt(5.),darg((r5-1.)/(r5+1.)),ath(0.5*log((1.+1./r5)/(1.-1./r5))); comptonInt_ = 2.*(-21./20.-6./(5.*r5)*ath+sqr(Constants::pi)/3. -2.*Math::ReLi2(1.-darg)-2.*Math::ReLi2(1.-1./darg)); bgfInt_ = 121./9.-56./r5*ath; // extract the gluon ParticleData objects gluon_ = getParticleData(ParticleID::g); } void DISBase::initializeMECorrection(RealEmissionProcessPtr born, double & initial, double & final) { initial = initial_; final = final_; // incoming particles for(unsigned int ix=0;ixbornIncoming().size();++ix) { if(QuarkMatcher::Check(born->bornIncoming()[ix]->data())) { partons_[0] = born->bornIncoming()[ix]->dataPtr(); pq_[0] = born->bornIncoming()[ix]->momentum(); } else if(LeptonMatcher::Check(born->bornIncoming()[ix]->data())) { leptons_[0] = born->bornIncoming()[ix]->dataPtr(); pl_[0] = born->bornIncoming()[ix]->momentum(); } } // outgoing particles for(unsigned int ix=0;ixbornOutgoing().size();++ix) { if(QuarkMatcher::Check(born->bornOutgoing()[ix]->data())) { partons_[1] = born->bornOutgoing()[ix]->dataPtr(); pq_[1] = born->bornOutgoing()[ix]->momentum(); } else if(LeptonMatcher::Check(born->bornOutgoing()[ix]->data())) { leptons_[1] = born->bornOutgoing()[ix]->dataPtr(); pl_[1] = born->bornOutgoing()[ix]->momentum(); } } // extract the born variables q_ =pl_[0]-pl_[1]; q2_ = -q_.m2(); double yB = (q_*pq_[0])/(pl_[0]*pq_[0]); l_ = 2./yB-1.; // calculate the A coefficient for the correlations acoeff_ = A(leptons_[0],leptons_[1], partons_[0],partons_[1],q2_); } RealEmissionProcessPtr DISBase::applyHardMatrixElementCorrection(RealEmissionProcessPtr born) { static const double eps=1e-6; // find the incoming and outgoing quarks and leptons PPtr quark[2],lepton[2]; PPtr hadron; unsigned int iqIn(0),iqOut(0); // incoming particles for(unsigned int ix=0;ixbornIncoming().size();++ix) { if(QuarkMatcher::Check(born->bornIncoming()[ix]->data())) { iqIn=ix; quark[0] = born->bornIncoming()[ix]; hadron = born->hadrons()[ix]; beam_ = dynamic_ptr_cast(hadron->dataPtr()); xB_ = quark[0]->momentum().rho()/hadron->momentum().rho(); } else if(LeptonMatcher::Check(born->bornIncoming()[ix]->data())) { lepton[0] = born->bornIncoming()[ix]; } } pdf_ = beam_->pdf(); assert(beam_&&pdf_&&quark[0]&&lepton[0]); // outgoing particles for(unsigned int ix=0;ixbornOutgoing().size();++ix) { if(QuarkMatcher::Check(born->bornOutgoing()[ix]->data())) { iqOut=ix; quark [1] = born->bornOutgoing()[ix]; } else if(LeptonMatcher::Check(born->bornOutgoing()[ix]->data())) { lepton[1] = born->bornOutgoing()[ix]; } } // momentum fraction assert(quark[1]&&lepton[1]); // calculate the matrix element vector azicoeff; // select the type of process bool BGF = UseRandom::rnd()>procProb_; double xp,zp,wgt,x1,x2,x3,xperp; // generate a QCD compton process if(!BGF) { wgt = generateComptonPoint(xp,zp); if(xpvalue(scale)/procProb_; // PDF piece wgt *= pdf_->xfx(beam_,quark[0]->dataPtr(),scale,xB_/xp)/ pdf_->xfx(beam_,quark[0]->dataPtr(),q2_ ,xB_); // other bits xperp = sqrt(4.*(1.-xp)*(1.-zp)*zp/xp); x1 = -1./xp; x2 = 1.-(1.-zp)/xp; x3 = 2.+x1-x2; // matrix element pieces azicoeff = ComptonME(xp,x2,xperp,true); } // generate a BGF process else { wgt = generateBGFPoint(xp,zp); if(xpvalue(scale)/(1.-procProb_); // PDF piece wgt *= pdf_->xfx(beam_,gluon_ ,scale,xB_/xp)/ pdf_->xfx(beam_,quark[0]->dataPtr(),q2_ ,xB_); // other bits xperp = sqrt(4.*(1.-xp)*(1.-zp)*zp/xp); x1 = -1./xp; x2 = 1.-(1.-zp)/xp; x3 = 2.+x1-x2; // matrix element pieces azicoeff = BGFME(xp,x2,x3,xperp,true); } // compute the azimuthal average of the weight wgt *= (azicoeff[0]+0.5*azicoeff[2]); // decide whether or not to accept the weight if(UseRandom::rnd()>wgt) return RealEmissionProcessPtr(); // if generate generate phi unsigned int itry(0); double phimax = std::accumulate(azicoeff.begin(),azicoeff.end(),0.); double phiwgt,phi; do { phi = UseRandom::rnd()*Constants::twopi; double cphi(cos(phi)); phiwgt = azicoeff[0]+azicoeff[1]*cphi+azicoeff[2]*sqr(cphi); ++itry; } while (phimax*UseRandom::rnd() > phiwgt && itry<200); if(itry==200) throw Exception() << "Too many tries in DISMECorrection" << "::applyHardMatrixElementCorrection() to" << " generate phi" << Exception::eventerror; // construct lorentz transform from lab to breit frame Lorentz5Momentum phadron = hadron->momentum(); phadron.setMass(0.*GeV); phadron.rescaleEnergy(); Lorentz5Momentum pcmf = phadron+0.5/xB_*q_; pcmf.rescaleMass(); LorentzRotation rot(-pcmf.boostVector()); Lorentz5Momentum pbeam = rot*phadron; Axis axis(pbeam.vect().unit()); double sinth(sqrt(sqr(axis.x())+sqr(axis.y()))); rot.rotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.)); Lorentz5Momentum pl = rot*pl_[0]; rot.rotateZ(-atan2(pl.y(),pl.x())); pl_[0] *= rot; pl_[1] *= rot; pq_[0] *= rot; pq_[1] *= rot; // compute the new incoming and outgoing momenta Energy Q(sqrt(q2_)); Lorentz5Momentum p1 = Lorentz5Momentum( 0.5*Q*xperp*cos(phi), 0.5*Q*xperp*sin(phi), -0.5*Q*x2,0.*GeV,0.*GeV); p1.rescaleEnergy(); Lorentz5Momentum p2 = Lorentz5Momentum(-0.5*Q*xperp*cos(phi),-0.5*Q*xperp*sin(phi), -0.5*Q*x3,0.*GeV,0.*GeV); p2.rescaleEnergy(); Lorentz5Momentum pin(0.*GeV,0.*GeV,-0.5*x1*Q,-0.5*x1*Q,0.*GeV); // debuggingMatrixElement(BGF,pin,p1,p2,gluon_,pl_[0],pl_[1],pq_[0],pq_[1], // lepton[0]->dataPtr(),lepton[1]->dataPtr(), // quark [0]->dataPtr(),quark [1]->dataPtr(), // q2_,phi,x2,x3,xperp,zp,xp,azicoeff,true); // we need the Lorentz transform back to the lab rot.invert(); // transform the momenta to lab frame pin *= rot; p1 *= rot; p2 *= rot; // test to ensure outgoing particles can be put on-shell if(!BGF) { if(p1.e()dataPtr()->constituentMass()) return RealEmissionProcessPtr(); if(p2.e()constituentMass()) return RealEmissionProcessPtr(); } else { if(p1.e()dataPtr() ->constituentMass()) return RealEmissionProcessPtr(); if(p2.e()dataPtr()->CC()->constituentMass()) return RealEmissionProcessPtr(); } // create the new particles and real emission process bool isQuark = quark[0]->colourLine(); bool FSR = false; // incoming lepton if first if(iqIn==1) born->incoming().push_back(born->bornIncoming()[0]->dataPtr()-> produceParticle(born->bornIncoming()[0]->momentum())); // outgoing lepton if first if(iqOut==1) born->outgoing().push_back(born->bornOutgoing()[0]->dataPtr()-> produceParticle(born->bornOutgoing()[0]->momentum())); PPtr newin,newout,emitted; // radiating system if(!BGF) { newin = quark[0]->dataPtr()->produceParticle(pin); emitted = gluon_ ->produceParticle(p2 ); newout = quark[1]->dataPtr()->produceParticle(p1 ); emitted->incomingColour(newin,!isQuark); emitted->colourConnect(newout,!isQuark); FSR = xp>zp; } else { newin = gluon_ ->produceParticle(pin); emitted = quark[0]->dataPtr()->CC()->produceParticle(p2 ); newout = quark[1]->dataPtr() ->produceParticle(p1 ); emitted->incomingColour(newin, isQuark); newout ->incomingColour(newin,!isQuark); FSR = false; } // set x double x(xB_/xp); if(born->incoming().size()==0) born->x(make_pair(x,1.)); else born->x(make_pair(1.,x)); if(FSR) { born->emitter(born->outgoing().size()+2); born->spectator(born->incoming().size()); } else { born->emitter(born->incoming().size()); born->spectator(born->outgoing().size()+2); } born->emitted(4); // radiating particles born->incoming().push_back(newin ); born->outgoing().push_back(newout); // incoming lepton if second if(iqIn==0) born->incoming().push_back(born->bornIncoming()[1]->dataPtr()-> produceParticle(born->bornIncoming()[1]->momentum())); // outgoing lepton if second if(iqOut==0) born->outgoing().push_back(born->bornOutgoing()[1]->dataPtr()-> produceParticle(born->bornOutgoing()[1]->momentum())); // radiated particle born->outgoing().push_back(emitted); born->interaction(ShowerInteraction::QCD); return born; } bool DISBase::softMatrixElementVeto(PPtr parent, PPtr progenitor, const bool & fs, const Energy & highestpT, const vector & ids, const double & z, const Energy & scale, const Energy & pT) { bool veto = !UseRandom::rndbool(fs ? 1./final_ : 1./initial_); // check if me correction should be applied long id[2]={progenitor->id(),parent->id()}; if(id[0]!=id[1]||id[1]==ParticleID::g) return veto; // check if hardest so far if(pT azicoeff = ComptonME(xp,x2,xperp,false); wgt = (azicoeff[0]+0.5*azicoeff[2])*xp/(1.+sqr(z))/final_; if(wgt<.0||wgt>1.) { ostringstream wstring; wstring << "Soft ME correction weight too large or " << "negative for FSR in DISBase::" << "softMatrixElementVeto() soft weight " << " xp = " << xp << " zp = " << zp << " weight = " << wgt << "\n"; generator()->logWarning( Exception(wstring.str(), Exception::warning) ); } } else { double xp = 2.*z/(1.+zk+sqrt(sqr(1.+zk)-4.*z*zk)); double zp = 0.5* (1.-zk+sqrt(sqr(1.+zk)-4.*z*zk)); double xperp = sqrt(4.*(1.-xp)*(1.-zp)*zp/xp); double x1 = -1./xp, x2 = 1.-(1.-zp)/xp, x3 = 2.+x1-x2; // compton if(ids[0]->id()!=ParticleID::g) { vector azicoeff = ComptonME(xp,x2,xperp,false); wgt = (azicoeff[0]+0.5*azicoeff[2])*xp*(1.-z)/(1.-xp)/(1.+sqr(z))/ (1.-zp+xp-2.*xp*(1.-zp)); } // BGF else { vector azicoeff = BGFME(xp,x2,x3,xperp,true); wgt = (azicoeff[0]+0.5*azicoeff[2])*xp/(1.-zp+xp-2.*xp*(1.-zp))/(sqr(z)+sqr(1.-z)); } wgt /=initial_; if(wgt<.0||wgt>1.) { ostringstream wstring; wstring << "Soft ME correction weight too large or " << "negative for ISR in DISBase::" << "softMatrixElementVeto() soft weight " << " xp = " << xp << " zp = " << zp << " weight = " << wgt << "\n"; generator()->logWarning( Exception(wstring.str(), Exception::warning) ); } } // return whether or not vetoed return !UseRandom::rndbool(wgt); } double DISBase::generateComptonPoint(double &xp, double & zp) { static const double maxwgt = 1.; double wgt; do { xp = UseRandom::rnd(); double zpmin = xp, zpmax = 1./(1.+xp*(1.-xp)); zp = 1.-pow((1.-zpmin)/(1.-zpmax),UseRandom::rnd())*(1.-zpmax); wgt = log((1.-zpmin)/(1.-zpmax))*(1.-zp); if(UseRandom::rndbool()) swap(xp,zp); double xperp2 = 4.*(1.-xp)*(1.-zp)*zp/xp,x2=1.-(1.-zp)/xp; wgt *= 2.*(1.+sqr(xp)*(sqr(x2)+1.5*xperp2))/(1.-xp)/(1.-zp); if(wgt>maxwgt) { ostringstream wstring; wstring << "DISBase::generateComptonPoint " << "Weight greater than maximum " << "wgt = " << wgt << " maxwgt = 1\n"; generator()->logWarning( Exception(wstring.str(), Exception::warning) ); } } while(wgtmaxwgt) { ostringstream wstring; wstring << "DISBase::generateBGFPoint " << "Weight greater than maximum " << "wgt = " << wgt << " maxwgt = 1\n"; generator()->logWarning( Exception(wstring.str(), Exception::warning) ); } } while(wgt1.+ac) cerr << "testing violates BGF maxA " << wgt << "\n"; // } // while(wgtmaxwgt*zpwgt) cerr << "testing violates BGF maxB " << wgt/xpwgt << "\n"; // } // while(wgt DISBase::ComptonME(double xp, double x2, double xperp, bool norm) { vector output(3,0.); double cos2 = x2 /sqrt(sqr(x2)+sqr(xperp)); double sin2 = xperp/sqrt(sqr(x2)+sqr(xperp)); double root = sqrt(sqr(l_)-1.); output[0] = sqr(cos2)+acoeff_*cos2*l_+sqr(l_); output[1] = -acoeff_*cos2*root*sin2-2.*l_*root*sin2; output[2] = sqr(root)*sqr(sin2); double lo(1+acoeff_*l_+sqr(l_)); double denom = norm ? 1.+sqr(xp)*(sqr(x2)+1.5*sqr(xperp)) : 1.; double fact = sqr(xp)*(sqr(x2)+sqr(xperp))/lo; for(unsigned int ix=0;ix DISBase::BGFME(double xp, double x2, double x3, double xperp, bool norm) { vector output(3,0.); double cos2 = x2 /sqrt(sqr(x2)+sqr(xperp)); double sin2 = xperp/sqrt(sqr(x2)+sqr(xperp)); double fact2 = sqr(xp)*(sqr(x2)+sqr(xperp)); double cos3 = x3 /sqrt(sqr(x3)+sqr(xperp)); double sin3 = xperp/sqrt(sqr(x3)+sqr(xperp)); double fact3 = sqr(xp)*(sqr(x3)+sqr(xperp)); double root = sqrt(sqr(l_)-1.); output[0] = fact2*(sqr(cos2)+acoeff_*cos2*l_+sqr(l_)) + fact3*(sqr(cos3)-acoeff_*cos3*l_+sqr(l_)); output[1] = - fact2*(acoeff_*cos2*root*sin2+2.*l_*root*sin2) - fact3*(acoeff_*cos3*root*sin3-2.*l_*root*sin3); output[2] = fact2*(sqr(root)*sqr(sin2)) + fact3*(sqr(root)*sqr(sin3)); double lo(1+acoeff_*l_+sqr(l_)); double denom = norm ? sqr(xp)*(sqr(x3)+sqr(x2)+3.*sqr(xperp))*lo : lo; for(unsigned int ix=0;ixbornIncoming().size();++ix) { if(QuarkMatcher::Check(born->bornIncoming()[ix]->data())) { iqIn=ix; hadron = born->hadrons()[ix]; quark [0] = born->bornIncoming()[ix]; beam_ = dynamic_ptr_cast(hadron->dataPtr()); xB_ = quark[0]->momentum().rho()/hadron->momentum().rho(); } else if(LeptonMatcher::Check(born->bornIncoming()[ix]->data())) { lepton[0] = born->bornIncoming()[ix]; leptons_[0] = lepton[0]->dataPtr(); } } pdf_=beam_->pdf(); assert(beam_&&pdf_&&quark[0]&&lepton[0]); // outgoing particles for(unsigned int ix=0;ixbornOutgoing().size();++ix) { if(QuarkMatcher::Check(born->bornOutgoing()[ix]->data())) { iqOut=ix; quark [1] = born->bornOutgoing()[ix]; } else if(LeptonMatcher::Check(born->bornOutgoing()[ix]->data())) { lepton[1] = born->bornOutgoing()[ix]; leptons_[1] = lepton[1]->dataPtr(); } } assert(quark[1]&&lepton[1]); // Particle data objects for(unsigned int ix=0;ix<2;++ix) partons_[ix] = quark[ix]->dataPtr(); // extract the born variables q_ =lepton[0]->momentum()-lepton[1]->momentum(); q2_ = -q_.m2(); double yB = ( q_*quark[0]->momentum())/ (lepton[0]->momentum()*quark[0]->momentum()); l_ = 2./yB-1.; // construct lorentz transform from lab to breit frame Lorentz5Momentum phadron = hadron->momentum(); phadron.setMass(0.*GeV); phadron.rescaleRho(); Lorentz5Momentum pb = quark[0]->momentum(); Axis axis(q_.vect().unit()); double sinth(sqrt(sqr(axis.x())+sqr(axis.y()))); LorentzRotation rot_ = LorentzRotation(); if(axis.perp2()>1e-20) { rot_.setRotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.)); rot_.rotateX(Constants::pi); } if(abs(1.-q_.e()/q_.vect().mag())>1e-6) rot_.boostZ( q_.e()/q_.vect().mag()); pb *= rot_; if(pb.perp2()/GeV2>1e-20) { Boost trans = -1./pb.e()*pb.vect(); trans.setZ(0.); rot_.boost(trans); } Lorentz5Momentum pl = rot_*lepton[0]->momentum(); rot_.rotateZ(-atan2(pl.y(),pl.x())); // momenta of the particles pl_[0]=rot_*lepton[0]->momentum(); pl_[1]=rot_*lepton[1]->momentum(); pq_[0]=rot_* quark[0]->momentum(); pq_[1]=rot_* quark[1]->momentum(); q_ *= rot_; // coefficient for the matrix elements acoeff_ = A(lepton[0]->dataPtr(),lepton[1]->dataPtr(), quark [0]->dataPtr(),quark [1]->dataPtr(),q2_); // generate a compton point generateCompton(); generateBGF(); // no valid emission, return if(pTCompton_pT()[ShowerInteraction::QCD] = pTmin_; return born; } // type of emission, pick highest pT bool isCompton=pTCompton_>pTBGF_; // create the process with real emission bool isQuark = quark[0]->colourLine(); bool FSR = false; // incoming lepton if first if(iqIn==1) born->incoming().push_back(born->bornIncoming()[0]->dataPtr()-> produceParticle(born->bornIncoming()[0]->momentum())); // outgoing lepton if first if(iqOut==1) born->outgoing().push_back(born->bornOutgoing()[0]->dataPtr()-> produceParticle(born->bornOutgoing()[0]->momentum())); PPtr newout,newin,emitted; // compton hardest if(isCompton) { rot_.invert(); for(unsigned int ix=0;ixproduceParticle(ComptonMomenta_[1]); emitted = gluon_ ->produceParticle(ComptonMomenta_[2]); newin = partons_[0]->produceParticle(ComptonMomenta_[0]); emitted->incomingColour(newin,!isQuark); emitted->colourConnect(newout,!isQuark); FSR = !ComptonISFS_; born->pT()[ShowerInteraction::QCD] = pTCompton_; } // BGF hardest else { rot_.invert(); for(unsigned int ix=0;ixproduceParticle(BGFMomenta_[0]); emitted = quark[0]->dataPtr()->CC()->produceParticle(BGFMomenta_[2]); newout = quark[1]->dataPtr() ->produceParticle(BGFMomenta_[1]); emitted->incomingColour(newin, isQuark); newout ->incomingColour(newin,!isQuark); FSR = false; born->pT()[ShowerInteraction::QCD] = pTBGF_; } double x = newin->momentum().rho()/hadron->momentum().rho(); if(born->incoming().size()==0) born->x(make_pair(x,1.)); else born->x(make_pair(1.,x)); if(FSR) { born->emitter(born->outgoing().size()+2); born->spectator(born->incoming().size()); } else { born->emitter(born->incoming().size()); born->spectator(born->outgoing().size()+2); } born->emitted(4); // radiating particles born->incoming().push_back(newin ); born->outgoing().push_back(newout); // incoming lepton if second if(iqIn==0) born->incoming().push_back(born->bornIncoming()[1]->dataPtr()-> produceParticle(born->bornIncoming()[1]->momentum())); // outgoing lepton if second if(iqOut==0) born->outgoing().push_back(born->bornOutgoing()[1]->dataPtr()-> produceParticle(born->bornOutgoing()[1]->momentum())); // radiated particle born->outgoing().push_back(emitted); born->interaction(ShowerInteraction::QCD); return born; } void DISBase::generateCompton() { // maximum value of the xT double xT = sqrt((1.-xB_)/xB_); double xTMin = 2.*pTmin_/sqrt(q2_); double zp; // prefactor double a = alpha_->overestimateValue()*comptonWeight_/Constants::twopi; // loop to generate kinematics double wgt(0.),xp(0.); vector azicoeff; do { wgt = 0.; // intergration variables dxT/xT^3 xT *= 1./sqrt(1.-2.*log(UseRandom::rnd())/a*sqr(xT)); // zp zp = UseRandom::rnd(); xp = 1./(1.+0.25*sqr(xT)/zp/(1.-zp)); // check allowed if(xp1.) continue; // phase-space piece of the weight wgt = 8.*(1.-xp)*zp/comptonWeight_; // PDF piece of the weight Energy2 scale = q2_*((1.-xp)*(1-zp)*zp/xp+1.); wgt *= pdf_->xfx(beam_,partons_[0],scale,xB_/xp)/ pdf_->xfx(beam_,partons_[0],q2_ ,xB_); // me piece of the weight double x2 = 1.-(1.-zp)/xp; azicoeff = ComptonME(xp,x2,xT,false); wgt *= 4./3.*alpha_->ratio(0.25*q2_*sqr(xT))*(azicoeff[0]+0.5*azicoeff[2]); if(wgt>1.||wgt<0.) { ostringstream wstring; wstring << "DISBase::generateCompton() " << "Weight greater than one or less than zero" << "wgt = " << wgt << "\n"; generator()->logWarning( Exception(wstring.str(), Exception::warning) ); } } while(xT>xTMin&&UseRandom::rnd()>wgt); if(xT<=xTMin) { pTCompton_=-GeV; return; } // generate phi unsigned int itry(0); double phimax = std::accumulate(azicoeff.begin(),azicoeff.end(),0.); double phiwgt,phi; do { phi = UseRandom::rnd()*Constants::twopi; double cphi(cos(phi)); phiwgt = azicoeff[0]+azicoeff[1]*cphi+azicoeff[2]*sqr(cphi); ++itry; } while (phimax*UseRandom::rnd() > phiwgt && itry<200); if(itry==200) throw Exception() << "Too many tries in DISMECorrection" << "::generateCompton() to" << " generate phi" << Exception::eventerror; // momenta for the configuration Energy Q(sqrt(q2_)); double x1 = -1./xp; double x2 = 1.-(1.-zp)/xp; double x3 = 2.+x1-x2; Lorentz5Momentum p1( 0.5*Q*xT*cos(phi), 0.5*Q*xT*sin(phi), -0.5*Q*x2, 0.5*Q*sqrt(sqr(xT)+sqr(x2))); Lorentz5Momentum p2(-0.5*Q*xT*cos(phi), -0.5*Q*xT*sin(phi), -0.5*Q*x3, 0.5*Q*sqrt(sqr(xT)+sqr(x3))); Lorentz5Momentum p0(ZERO,ZERO,-0.5*Q*x1,-0.5*Q*x1); pTCompton_ = 0.5*Q*xT; ComptonMomenta_.resize(3); ComptonMomenta_[0] = p0; ComptonMomenta_[1] = p1; ComptonMomenta_[2] = p2; ComptonISFS_ = zp>xp; // debuggingMatrixElement(false,p0,p1,p2,gluon_,pl_[0],pl_[1],pq_[0],pq_[1], // leptons_[0],leptons_[1], // partons_[0],partons_[1], // q2_,phi,x2,x3,xT,zp,xp,azicoeff,false); } void DISBase::generateBGF() { // maximum value of the xT double xT = (1.-xB_)/xB_; double xTMin = 2.*max(pTmin_,pTCompton_)/sqrt(q2_); double zp; // prefactor double a = alpha_->overestimateValue()*BGFWeight_/Constants::twopi; // loop to generate kinematics double wgt(0.),xp(0.); vector azicoeff; do { wgt = 0.; // intergration variables dxT/xT^3 xT *= 1./sqrt(1.-2.*log(UseRandom::rnd())/a*sqr(xT)); // zp zp = UseRandom::rnd(); xp = 1./(1.+0.25*sqr(xT)/zp/(1.-zp)); // check allowed if(xp1.) continue; // phase-space piece of the weight wgt = 8.*sqr(1.-xp)*zp/BGFWeight_; // PDF piece of the weight Energy2 scale = q2_*((1.-xp)*(1-zp)*zp/xp+1.); wgt *= pdf_->xfx(beam_,gluon_ ,scale,xB_/xp)/ pdf_->xfx(beam_,partons_[0],q2_ ,xB_); // me piece of the weight double x1 = -1./xp; double x2 = 1.-(1.-zp)/xp; double x3 = 2.+x1-x2; azicoeff = BGFME(xp,x2,x3,xT,false); wgt *= 0.5*alpha_->ratio(0.25*q2_*sqr(xT))* (azicoeff[0]+0.5*azicoeff[2]); if(wgt>1.||wgt<0.) { ostringstream wstring; wstring << "DISBase::generateBGF() " << "Weight greater than one or less than zero" << "wgt = " << wgt << "\n"; generator()->logWarning( Exception(wstring.str(), Exception::warning) ); } } while(xT>xTMin&&UseRandom::rnd()>wgt); if(xT<=xTMin) { pTBGF_=-GeV; return; } // generate phi unsigned int itry(0); double phimax = std::accumulate(azicoeff.begin(),azicoeff.end(),0.); double phiwgt,phi; do { phi = UseRandom::rnd()*Constants::twopi; double cphi(cos(phi)); phiwgt = azicoeff[0]+azicoeff[1]*cphi+azicoeff[2]*sqr(cphi); ++itry; } while (phimax*UseRandom::rnd() > phiwgt && itry<200); if(itry==200) throw Exception() << "Too many tries in DISMECorrection" << "::generateBGF() to" << " generate phi" << Exception::eventerror; // momenta for the configuration Energy Q(sqrt(q2_)); double x1 = -1./xp; double x2 = 1.-(1.-zp)/xp; double x3 = 2.+x1-x2; Lorentz5Momentum p1( 0.5*Q*xT*cos(phi), 0.5*Q*xT*sin(phi), -0.5*Q*x2, 0.5*Q*sqrt(sqr(xT)+sqr(x2))); Lorentz5Momentum p2(-0.5*Q*xT*cos(phi), -0.5*Q*xT*sin(phi), -0.5*Q*x3, 0.5*Q*sqrt(sqr(xT)+sqr(x3))); Lorentz5Momentum p0(ZERO,ZERO,-0.5*Q*x1,-0.5*Q*x1); pTBGF_=0.5*Q*xT; BGFMomenta_.resize(3); BGFMomenta_[0]=p0; BGFMomenta_[1]=p1; BGFMomenta_[2]=p2; // debuggingMatrixElement(true,p0,p1,p2,gluon_,pl_[0],pl_[1],pq_[0],pq_[1], // leptons_[0],leptons_[1], // partons_[0],partons_[1], // q2_,phi,x2,x3,xT,zp,xp,azicoeff,false); } int DISBase::nDim() const { return HwMEBase::nDim() + (contrib_>0 ? 1 : 0 ); } bool DISBase::generateKinematics(const double * r) { // Born kinematics if(!HwMEBase::generateKinematics(r)) return false; if(contrib_!=0) { // hadron and momentum fraction if(HadronMatcher::Check(*lastParticles().first->dataPtr())) { hadron_ = dynamic_ptr_cast(lastParticles().first->dataPtr()); xB_ = lastX1(); } else { hadron_ = dynamic_ptr_cast(lastParticles().second->dataPtr()); xB_ = lastX2(); } // Q2 q2_ = -(meMomenta()[0]-meMomenta()[2]).m2(); // xp int ndim=nDim(); double rhomin = pow(1.-xB_,1.-power_); double rho = r[ndim-1]*rhomin; xp_ = 1.-pow(rho,1./(1.-power_)); jac_ = rhomin/(1.-power_)*pow(1.-xp_,power_); jacobian(jacobian()*jac_); } return true; } Energy2 DISBase::scale() const { return scaleOpt_ == 1 ? -sqr(scaleFact_)*tHat() : sqr(scaleFact_*muF_); } CrossSection DISBase::dSigHatDR() const { return NLOWeight()*HwMEBase::dSigHatDR(); } double DISBase::NLOWeight() const { // If only leading order is required return 1: if(contrib_==0) return 1.; // scale and prefactors Energy2 mu2(scale()); double aS = SM().alphaS(mu2); double CFfact = 4./3.*aS/Constants::twopi; double TRfact = 1./2.*aS/Constants::twopi; // LO + dipole subtracted virtual + collinear quark bit with LO pdf double virt = 1.+CFfact*(-4.5-1./3.*sqr(Constants::pi)+1.5*log(q2_/mu2/(1.-xB_)) +2.*log(1.-xB_)*log(q2_/mu2)+sqr(log(1.-xB_))); virt /= jac_; // PDF from leading-order double loPDF = hadron_->pdf()->xfx(hadron_,mePartonData()[1],mu2,xB_)/xB_; + if(loPDF==0.) return 0.; // NLO gluon PDF tcPDPtr gluon = getParticleData(ParticleID::g); double gPDF = hadron_->pdf()->xfx(hadron_,gluon,mu2,xB_/xp_)*xp_/xB_; // NLO quark PDF double qPDF = hadron_->pdf()->xfx(hadron_,mePartonData()[1],mu2,xB_/xp_)*xp_/xB_; // collinear counterterms // gluon double collg = TRfact/xp_*gPDF*(2.*xp_*(1.-xp_)+(sqr(xp_)+sqr(1.-xp_))*log((1.-xp_)*q2_/xp_/mu2)); // quark double collq = CFfact/xp_*qPDF*(1-xp_-2./(1.-xp_)*log(xp_)-(1.+xp_)*log((1.-xp_)/xp_*q2_/mu2))+ CFfact/xp_*(qPDF-xp_*loPDF)*(2./(1.-xp_)*log(q2_*(1.-xp_)/mu2)-1.5/(1.-xp_)); // calculate the A coefficient for the real pieces double a(A(mePartonData()[0],mePartonData()[2], mePartonData()[1],mePartonData()[3],q2_)); // cacluate lepton kinematic variables Lorentz5Momentum q = meMomenta()[0]-meMomenta()[2]; double yB = (q*meMomenta()[1])/(meMomenta()[0]*meMomenta()[1]); double l = 2./yB-1.; // q -> qg term double realq = CFfact/xp_/(1.+a*l+sqr(l))*qPDF/loPDF* (2.+2.*sqr(l)-xp_+3.*xp_*sqr(l)+a*l*(2.*xp_+1.)); // g -> q qbar term double realg =-TRfact/xp_/(1.+a*l+sqr(l))*gPDF/loPDF* ((1.+sqr(l)+2.*(1.-3.*sqr(l))*xp_*(1.-xp_)) +2.*a*l*(1.-2.*xp_*(1.-xp_))); // return the full result double wgt = virt+((collq+collg)/loPDF+realq+realg); // double f2g = gPDF/xp_*TRfact*((sqr(1-xp_)+sqr(xp_))*log((1-xp_)/xp_)+ // 8*xp_*(1.-xp_)-1.); // double f2q = // loPDF/jac_*(1.+CFfact*(-1.5*log(1.-xB_)+sqr(log(1.-xB_)) // -sqr(Constants::pi)/3.-4.5)) // +qPDF *CFfact/xp_*(3.+2.*xp_-(1.+xp_)*log(1.-xp_) // -(1.+sqr(xp_))/(1.-xp_)*log(xp_)) // +(qPDF-xp_*loPDF)*CFfact/xp_*(2.*log(1.-xp_)/(1.-xp_)-1.5/(1.-xp_)); // double wgt = (f2g+f2q)/loPDF; return contrib_ == 1 ? max(0.,wgt) : max(0.,-wgt); } diff --git a/MatrixElement/General/GeneralHardME.h b/MatrixElement/General/GeneralHardME.h --- a/MatrixElement/General/GeneralHardME.h +++ b/MatrixElement/General/GeneralHardME.h @@ -1,494 +1,497 @@ // -*- C++ -*- // // GeneralHardME.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_GeneralHardME_H #define HERWIG_GeneralHardME_H // // This is the declaration of the GeneralHardME class. // #include "Herwig/MatrixElement/HwMEBase.h" #include "ThePEG/Utilities/Exception.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/Models/General/HPDiagram.h" #include "Herwig/MatrixElement/ProductionMatrixElement.h" #include "Herwig/MatrixElement/HardVertex.h" #include "ThePEG/EventRecord/SpinInfo.h" #include "ThePEG/PDF/PolarizedBeamParticleData.h" #include "GeneralHardME.fh" namespace Herwig { using namespace ThePEG; using Helicity::VertexBasePtr; /** * This defines the GeneralHardME class that is designed to serve as a * base class for matrix elements of specific spin structures when those * structures are created by a a general model, i.e. a SUSY production * ME. It stores a vector of diagram structures that contain the required * to calculate the matrix element. * * @see HwMEBase */ class GeneralHardME: public HwMEBase { public: /** * Convenient typedef for size_type of HPDiagram vector */ typedef vector::size_type HPCount; /** * Enum for the possible colour structures */ enum ColourStructure {UNDEFINED, Colour11to11,Colour11to33bar,Colour11to88, Colour33to33,Colour33barto11,Colour33barto33bar, Colour33barto66bar, Colour33barto6bar6, Colour33to61, Colour3bar3barto6bar1, Colour33to16, Colour3bar3barto16bar, Colour38to3bar6, Colour38to63bar, Colour33barto18,Colour33barto81,Colour33barto88, Colour38to13,Colour38to31, Colour38to83,Colour38to38, Colour3bar3barto3bar3bar, Colour3bar8to13bar,Colour3bar8to3bar1, Colour3bar8to83bar,Colour3bar8to3bar8, Colour88to11,Colour88to33bar, Colour88to66bar,Colour88to88, Colour88to18,Colour88to81, Colour33to13bar,Colour33to3bar1, Colour33to83bar,Colour33to3bar8, Colour3bar3barto13,Colour3bar3barto31, Colour3bar3barto83,Colour3bar3barto38, Colour38to3bar3bar,Colour3bar8to33}; public: /** * The default constructor. */ GeneralHardME(); public: /** @name Virtual functions required by the MEBase class. */ //@{ /** * Return the order in \f$\alpha_S\f$ in which this matrix * element is given. */ virtual unsigned int orderInAlphaS() const; /** * Return the order in \f$\alpha_{EW}\f$ in which this matrix * element is given. */ virtual unsigned int orderInAlphaEW() const; /** * The matrix element for the kinematical configuration * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. * @return the matrix element scaled with sHat() to give a * dimensionless number. */ virtual double me2() const = 0; /** * Return the scale associated with the last set phase space point. */ virtual Energy2 scale() const { if(scaleChoice_==0) { return scaleFactor_*sHat(); } else if(scaleChoice_==1) { Energy2 mbar = 0.5*(meMomenta()[2].mass2()+meMomenta()[3].mass2()); Energy2 t = 0.5*(tHat()-mbar); Energy2 u = 0.5*(uHat()-mbar); Energy2 s = 0.5*sHat(); return scaleFactor_*4.*s*t*u/(s*s+t*t+u*u); } else if(scaleChoice_ ==2) { Energy2 scale1 = meMomenta()[2].mass2()+meMomenta()[2].perp2(); Energy2 scale2 = meMomenta()[3].mass2()+meMomenta()[3].perp2(); return scaleFactor_*max(scale1,scale2); } - else assert(false); + else { + assert(false); + return ZERO; + } } /** * Add all possible diagrams with the add() function. */ virtual void getDiagrams() const; /** * Get diagram selector. With the information previously supplied with the * setKinematics method, a derived class may optionally * override this method to weight the given diagrams with their * (although certainly not physical) relative probabilities. * @param dv the diagrams to be weighted. * @return a Selector relating the given diagrams to their weights. */ virtual Selector diagrams(const DiagramVector & dv) const; /** * Return a Selector with possible colour geometries for the selected * diagram weighted by their relative probabilities. * @param diag the diagram chosen. * @return the possible colour geometries weighted by their * relative probabilities. */ virtual Selector colourGeometries(tcDiagPtr diag) const; //@} /** * Set the diagrams and matrix of colour factors. * @param process vector of MEDiagram with information that * will allow the diagrams to be created in the specific matrix element * @param colour The colour structure for the process * @param debug Whether to compare the numerical answer to an analytical * formula (This is only stored for certain processes. It is intended * for quick checks of the matrix elements). * @param scaleOption The option of what scale to use * @param scaleFactor The prefactor for the scale */ void setProcessInfo(const vector & process, ColourStructure colour, bool debug, unsigned int scaleOption, double scaleFactor); 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 Standard Interfaced functions. */ //@{ /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); //@} protected: /** * A debugging function to test the value of me2 against an * analytic function. This is to be overidden in an inheriting class. */ virtual void debug(double ) const {} protected: /** * Access the HPDiagrams that store the required information * to create the diagrams */ const vector & getProcessInfo() const { return diagrams_; } /** * Return the incoming pair * @return Pair of particle ids for the incoming particles */ pair getIncoming() const { return incoming_; } /** * Return the outgoing pair * @return Pair of particle ids for the outgoing particles */ pair getOutgoing() const { return outgoing_; } /** * Return the matrix of colour factors */ const vector & getColourFactors() const { return colour_; } /** * Get the number of diagrams in this process */ HPCount numberOfDiags() const { return numberOfDiagrams_; } /** * Access number of colour flows */ size_t numberOfFlows() const { return numberOfFlows_; } /** * Whether to print the debug information */ bool debugME() const { return debug_; } /** * Set/Get Info on the selected diagram and colour flow */ //@{ /** * Colour flow */ unsigned int colourFlow() const {return flow_;} /** * Colour flow */ void colourFlow(unsigned int flow) const {flow_=flow;} /** * Diagram */ unsigned int diagram() const {return diagram_;} /** * Diagram */ void diagram(unsigned int diag) const {diagram_=diag;} //@} /** * Calculate weight and select colour flow */ double selectColourFlow(vector & flow, vector & me,double average) const; /** * Access to the colour flow matrix element */ vector & flowME() const { return flowME_; } /** * Access to the diagram matrix element */ vector & diagramME() const { return diagramME_; } /** * Access to the colour structure */ ColourStructure colour() const {return colourStructure_;} /** * Extract the paricles from the subprocess */ ParticleVector hardParticles(tSubProPtr subp) { ParticleVector output(4); output[0] = subp->incoming().first; output[1] = subp->incoming().second; output[2] = subp->outgoing()[0]; output[3] = subp->outgoing()[1]; //ensure particle ordering is the same as it was when //the diagrams were created if( output[0]->id() != getIncoming().first ) swap(output[0], output[1]); if( output[2]->id() != getOutgoing().first ) swap(output[2], output[3]); // return answer return output; } /** * Set the rescaled momenta */ void setRescaledMomenta(const ParticleVector & external) { cPDVector data(4); vector momenta(4); for( size_t i = 0; i < 4; ++i ) { data[i] = external[i]->dataPtr(); momenta[i] = external[i]->momentum(); } rescaleMomenta(momenta, data); } /** * Create the vertes */ void createVertex(ProductionMatrixElement & me, ParticleVector & external) { HardVertexPtr hardvertex = new_ptr(HardVertex()); hardvertex->ME(me); for(ParticleVector::size_type i = 0; i < 4; ++i) { tSpinPtr spin = external[i]->spinInfo(); if(i<2) { tcPolarizedBeamPDPtr beam = dynamic_ptr_cast(external[i]->dataPtr()); if(beam) spin->rhoMatrix() = beam->rhoMatrix(); } spin->productionVertex(hardvertex); } } /** * Initialize the storage of the helicity matrix elements */ void initializeMatrixElements(PDT::Spin in1, PDT::Spin in2, PDT::Spin out1, PDT::Spin out2) { flowME().resize(numberOfFlows(), ProductionMatrixElement(in1,in2,out1,out2)); diagramME().resize(numberOfDiags(), ProductionMatrixElement(in1,in2,out1,out2)); } private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ GeneralHardME & operator=(const GeneralHardME &) = delete; private: /** * External particles */ //@{ /** * Store incoming particles */ pair incoming_; /** * Store the outgoing particles */ pair outgoing_; //@} /** * Diagrams */ //@{ /** * Store all diagrams as a vector of structures */ vector diagrams_; /** * Store the number of diagrams for fast retrieval */ HPCount numberOfDiagrams_; //@} /** * Colour information */ //@{ /** * The colour structure */ ColourStructure colourStructure_; /** * Store colour factors for ME calc. */ vector colour_; /** * The number of colourflows. */ unsigned int numberOfFlows_; //@} /** * Whether to test the value of me2 against the analytical function */ bool debug_; /** * The scale chocie */ unsigned int scaleChoice_; /** * The scale factor */ double scaleFactor_; /** * Info on the selected diagram and colour flow */ //@{ /** * Colour flow */ mutable unsigned int flow_; /** * Diagram */ mutable unsigned int diagram_; //@} /** * Storage of the matrix elements */ //@{ /** * Matrix elements for the different colour flows */ mutable vector flowME_; /** * Matrix elements for the different Feynman diagrams */ mutable vector diagramME_; //@} }; /** Exception class to indicate a problem has occurred with setting up to matrix element.*/ class MEException : public Exception {}; } #endif /* HERWIG_GeneralHardME_H */ diff --git a/MatrixElement/Hadron/MEMinBias.cc b/MatrixElement/Hadron/MEMinBias.cc --- a/MatrixElement/Hadron/MEMinBias.cc +++ b/MatrixElement/Hadron/MEMinBias.cc @@ -1,279 +1,280 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the MEMinBias class. // #include "MEMinBias.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/SimplePhaseSpace.h" //#include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Handlers/StandardXComb.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Handlers/SamplerBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" inline bool checkValence(int i,int side,Ptr::tptr eh){ // Inline function to check for valence quarks of the beam. // i: pdgid of quark // side: beam side // eh: pointer to the eventhandler int beam= ( side == 0 ) ? eh->incoming().first->id() : eh->incoming().second->id(); vector val; if( beam == ParticleID::pplus || beam == ParticleID::n0 ) val = {1,2}; if( beam == ParticleID::pbarminus || beam == ParticleID::nbar0 ) val = { -1 , -2 }; - if( val.size() == 0 ) assert(false && ("MEMinBias: Valence Quarks not defined for pid "+beam)); + if( val.size() == 0 ) + {cerr<<"\n\n MEMinBias: Valence Quarks not defined for pid "<::tptr eh = dynamic_ptr_cast::tptr>(generator()->eventHandler()); for ( int i = 1; i <= maxflav; ++i ) { for( int j=1; j <= i; ++j){ tcPDPtr q1 = getParticleData(i); tcPDPtr q1b = q1->CC(); tcPDPtr q2 = getParticleData(j); tcPDPtr q2b = q2->CC(); // For each flavour we add: //qq -> qq if(!onlyValQuarks_) add(new_ptr((Tree2toNDiagram(3), q1, pom, q2, 1, q1, 2, q2, -1))); else if(checkValence(i,0,eh) && checkValence(j,1,eh) ) add(new_ptr((Tree2toNDiagram(3), q1, pom, q2, 1, q1, 2, q2, -1))); //qqb -> qqb if(!onlyValQuarks_) add(new_ptr((Tree2toNDiagram(3), q1, pom, q2b, 1, q1, 2, q2b, -2))); else if(checkValence(i,0,eh) && checkValence(-j,1,eh) ) add(new_ptr((Tree2toNDiagram(3), q1, pom, q2b, 1, q1, 2, q2b, -2))); //qbqb -> qbqb if(!onlyValQuarks_) add(new_ptr((Tree2toNDiagram(3), q1b, pom, q2b, 1, q1b, 2, q2b, -3))); else if(checkValence(-i,0,eh) && checkValence(-j,1,eh) ) add(new_ptr((Tree2toNDiagram(3), q1b, pom, q2b, 1, q1b, 2, q2b, -3))); } } } Energy2 MEMinBias::scale() const { return sqr(Scale_); } int MEMinBias::nDim() const { return 0; } void MEMinBias::setKinematics() { HwMEBase::setKinematics(); // Always call the base class method first. } bool MEMinBias::generateKinematics(const double *) { // generate the masses of the particles for ( int i = 2, N = meMomenta().size(); i < N; ++i ) { meMomenta()[i] = Lorentz5Momentum(mePartonData()[i]->generateMass()); } Energy q = ZERO; try { q = SimplePhaseSpace:: getMagnitude(sHat(), meMomenta()[2].mass(), meMomenta()[3].mass()); } catch ( ImpossibleKinematics & e ) { return false; } Energy pt = ZERO; meMomenta()[2].setVect(Momentum3( pt, pt, q)); meMomenta()[3].setVect(Momentum3(-pt, -pt, -q)); meMomenta()[2].rescaleEnergy(); meMomenta()[3].rescaleEnergy(); jacobian(1.0); return true; } double MEMinBias::correctionweight() const { // Here we calculate the weight to restore the inelastic-diffractiveXSec // given by the MPIHandler. // First get the eventhandler to get the current cross sections. static Ptr::tptr eh = dynamic_ptr_cast::tptr>(generator()->eventHandler()); // All diffractive processes make use of this ME. // The static map can be used to collect all the sumOfWeights. static map weightsmap; weightsmap[lastXCombPtr()]=lastXComb().stats().sumWeights(); // Define static variable to keep trac of reweighting static double rew_=1.; static int countUpdateWeight=50; static double sumRew=0.; static double countN=0; // if we produce events we count if(eh->integratedXSec()>ZERO)sumRew+=rew_; if(eh->integratedXSec()>ZERO)countN+=1.; if(countUpdateWeightsampler()->maxXSec()/eh->sampler()->attempts()*sum; - CrossSection XS_wanted=MPIHandler_->inelasticXSec()-MPIHandler_->diffractiveXSec(); + CrossSection XS_wanted=MPIHandler_->nonDiffractiveXSec(); double deltaN=50; // Cross section without reweighting: XS_norew // XS_have = avcsNorm2*XS_norew (for large N) // We want to determine the rew that allows to get the wanted XS. // In deltaN points we want (left) and we get (right): // XS_wanted*(countN+deltaN) = XS_have*countN + rew*deltaN*XS_norew // Solve for rew: rew_=avRew*(XS_wanted*(countN+deltaN)-XS_have*countN)/(XS_have*deltaN); countUpdateWeight+=deltaN; } //Make sure we dont produce negative weights. // TODO: write finalize method that checks if reweighting was performed correctly. rew_=max(rew_,0.000001); rew_=min(rew_,10000.0); return rew_; } double MEMinBias::me2() const { //tuned so it gives the correct normalization for xmin = 0.11 return csNorm_*(sqr(generator()->maximumCMEnergy())/GeV2); } CrossSection MEMinBias::dSigHatDR() const { return me2()*jacobian()/sHat()*sqr(hbarc)*correctionweight(); } unsigned int MEMinBias::orderInAlphaS() const { return 2; } unsigned int MEMinBias::orderInAlphaEW() const { return 0; } Selector MEMinBias::diagrams(const DiagramVector & diags) const { Selector sel; for ( DiagramIndex i = 0; i < diags.size(); ++i ) sel.insert(1.0, i); return sel; } Selector MEMinBias::colourGeometries(tcDiagPtr diag) const { static ColourLines qq("1 4, 3 5"); static ColourLines qqb("1 4, -3 -5"); static ColourLines qbqb("-1 -4, -3 -5"); Selector sel; switch(diag->id()){ case -1: sel.insert(1.0, &qq); break; case -2: sel.insert(1.0, &qqb); break; case -3: sel.insert(1.0, &qbqb); break; } return sel; } IBPtr MEMinBias::clone() const { return new_ptr(*this); } IBPtr MEMinBias::fullclone() const { return new_ptr(*this); } // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeHerwigMEMinBias("Herwig::MEMinBias", "HwMEHadron.so"); void MEMinBias::persistentOutput(PersistentOStream & os) const { os << csNorm_ << ounit(Scale_,GeV) << MPIHandler_; } void MEMinBias::persistentInput(PersistentIStream & is, int) { is >> csNorm_ >> iunit(Scale_,GeV) >> MPIHandler_; } void MEMinBias::Init() { static ClassDocumentation documentation ("There is no documentation for the MEMinBias class"); static Parameter interfacecsNorm ("csNorm", "Normalization of the min-bias cross section.", &MEMinBias::csNorm_, 1.0, 0.0, 100.0, false, false, Interface::limited); static Parameter interfaceScale ("Scale", "Scale for the Min Bias matrix element.", &MEMinBias::Scale_,GeV, 2.0*GeV, 0.0*GeV, 100.0*GeV, false, false, Interface::limited); static Reference interfaceMPIHandler ("MPIHandler", "The object that administers all additional scatterings.", &MEMinBias::MPIHandler_, false, false, true, true); static Switch interfaceOnlyVal ("OnlyValence" , "Allow the dummy process to only extract valence quarks." , &MEMinBias::onlyValQuarks_ , false , false , false ); static SwitchOption interfaceOnlyValYes ( interfaceOnlyVal , "Yes" , "" , true ); static SwitchOption interfaceOnlyValNo ( interfaceOnlyVal , "No" , "" , false ); } diff --git a/MatrixElement/Hadron/MEMinBias.h b/MatrixElement/Hadron/MEMinBias.h --- a/MatrixElement/Hadron/MEMinBias.h +++ b/MatrixElement/Hadron/MEMinBias.h @@ -1,217 +1,217 @@ // -*- C++ -*- #ifndef HERWIG_MEMinBias_H #define HERWIG_MEMinBias_H // // This is the declaration of the MEMinBias class. // #include "Herwig/MatrixElement/HwMEBase.h" #include "Herwig/Shower/UEBase.h" namespace Herwig { using namespace ThePEG; /** * The MEMinBias class provides a simple colour singlet exchange matrix element * to be used in the soft component of the multiple scattering model of the * underlying event * * @see \ref MEMinBiasInterfaces "The interfaces" * defined for MEMinBias. */ class MEMinBias: public HwMEBase { public: /** * The default constructor. */ MEMinBias() : csNorm_(1.), Scale_(2.*GeV) {} public: /** @name Virtual functions required by the MEBase class. */ //@{ /** * Return the order in \f$\alpha_S\f$ in which this matrix * element is given. */ virtual unsigned int orderInAlphaS() const; /** * Return the order in \f$\alpha_{EW}\f$ in which this matrix * element is given. */ virtual unsigned int orderInAlphaEW() const; /** * The matrix element for the kinematical configuration * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. * @return the matrix element scaled with sHat() to give a * dimensionless number. */ virtual double me2() const; /** * Correction weight to reweight the cross section to the inelastic cross * section subtracted by the diffractive cross section. */ double correctionweight() const; /** * Return the scale associated with the last set phase space point. */ virtual Energy2 scale() const; /** * Set the typed and momenta of the incoming and outgoing partons to * be used in subsequent calls to me() and colourGeometries() * according to the associated XComb object. If the function is * overridden in a sub class the new function must call the base * class one first. */ virtual void setKinematics(); /** * The number of internal degrees of freedom used in the matrix * element. */ virtual int nDim() const; /** * Generate internal degrees of freedom given nDim() uniform * random numbers in the interval \f$ ]0,1[ \f$. To help the phase space * generator, the dSigHatDR should be a smooth function of these * numbers, although this is not strictly necessary. * @param r a pointer to the first of nDim() consecutive random numbers. * @return true if the generation succeeded, otherwise false. */ virtual bool generateKinematics(const double * r); /** * Return the matrix element squared differential in the variables * given by the last call to generateKinematics(). */ virtual CrossSection dSigHatDR() const; /** * Add all possible diagrams with the add() function. */ virtual void getDiagrams() const; /** * Get diagram selector. With the information previously supplied with the * setKinematics method, a derived class may optionally * override this method to weight the given diagrams with their * (although certainly not physical) relative probabilities. * @param dv the diagrams to be weighted. * @return a Selector relating the given diagrams to their weights. */ virtual Selector diagrams(const DiagramVector & dv) const; /** * Return a Selector with possible colour geometries for the selected * diagram weighted by their relative probabilities. * @param diag the diagram chosen. * @return the possible colour geometries weighted by their * relative probabilities. */ virtual Selector colourGeometries(tcDiagPtr diag) const; //@} 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. */ /** * 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: /** * Normalization of the min-bias cross section. * Note that the cross section is reweighted in addition to produce the * non-diffractive cross section given by the MPIHandler * csNorm can be modified to improve the unweighting effiency. */ double csNorm_; /** * Scale for the Min Bias matrix element */ Energy Scale_; /** * Allow only valence quark extraction. */ - bool onlyValQuarks_=false; + bool onlyValQuarks_=true; /** * a MPIHandler to administer the creation of several (semihard) * partonic interactions. * Needed to comunicate the non-diffractive cross section. */ UEBasePtr MPIHandler_; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ MEMinBias & operator=(const MEMinBias &) = delete; }; } #endif /* HERWIG_MEMinBias_H */ diff --git a/MatrixElement/Hadron/MEPP2Higgs.cc b/MatrixElement/Hadron/MEPP2Higgs.cc --- a/MatrixElement/Hadron/MEPP2Higgs.cc +++ b/MatrixElement/Hadron/MEPP2Higgs.cc @@ -1,1441 +1,1442 @@ // -*- C++ -*- // // MEPP2Higgs.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2017 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the MEPP2Higgs class. // #include "MEPP2Higgs.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/Handlers/StandardXComb.h" #include "ThePEG/Cuts/Cuts.h" #include "Herwig/MatrixElement/HardVertex.h" #include "Herwig/Models/StandardModel/StandardModel.h" #include "Herwig/Utilities/Maths.h" #include "Herwig/Shower/RealEmissionProcess.h" using namespace Herwig; const complex MEPP2Higgs::epsi_ = complex(ZERO,-1.e-10*GeV2); MEPP2Higgs::MEPP2Higgs() : scaleopt_(1), mu_F_(100.*GeV), shapeOption_(2), processOption_(1), minFlavour_(4), maxFlavour_(5), mh_(ZERO), wh_(ZERO), minLoop_(6),maxLoop_(6),massOption_(0), mu_R_opt_(1),mu_F_opt_(1), channelwgtA_(0.45),channelwgtB_(0.15), ggPow_(1.6), qgPow_(1.6), enhance_(1.1), nover_(0), ntry_(0), ngen_(0), maxwgt_(0.), power_(2.0), pregg_(7.), preqg_(3.), pregqbar_(3.), minpT_(2.*GeV), spinCorrelations_(true) {} // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeHerwigMEPP2Higgs("Herwig::MEPP2Higgs", "HwMEHadron.so"); void MEPP2Higgs::persistentOutput(PersistentOStream & os) const { os << HGGVertex_ << HFFVertex_ << shapeOption_ << processOption_ << minFlavour_ << maxFlavour_ << hmass_ << ounit(mh_,GeV) << ounit(wh_,GeV) << minLoop_ << maxLoop_ << massOption_ << alpha_ << prefactor_ << power_ << pregg_ << preqg_ << pregqbar_ << ounit( minpT_, GeV ) << ggPow_ << qgPow_ << enhance_ << channelwgtA_ << channelwgtB_ << channelWeights_ << mu_R_opt_ << mu_F_opt_ << spinCorrelations_; } void MEPP2Higgs::persistentInput(PersistentIStream & is, int) { is >> HGGVertex_ >> HFFVertex_ >> shapeOption_ >> processOption_ >> minFlavour_ >> maxFlavour_ >> hmass_ >> iunit(mh_,GeV) >> iunit(wh_,GeV) >> minLoop_ >> maxLoop_ >> massOption_ >> alpha_ >> prefactor_ >> power_ >> pregg_ >> preqg_ >> pregqbar_ >> iunit( minpT_, GeV ) >> ggPow_ >> qgPow_ >> enhance_ >> channelwgtA_ >> channelwgtB_ >> channelWeights_ >> mu_R_opt_ >> mu_F_opt_ >> spinCorrelations_; } void MEPP2Higgs::Init() { static ClassDocumentation documentation ("The MEPP2Higgs class implements the matrix elements for" " Higgs production (with decay H->W-W+) in hadron-hadron collisions" " including the generation of additional hard QCD radiation in " "gg to h0 processes in the POWHEG scheme", "Hard QCD radiation for $gg\\to h^0$ processes in the" " POWHEG scheme \\cite{Hamilton:2009za}.", "%\\cite{Hamilton:2009za}\n" "\\bibitem{Hamilton:2009za}\n" " K.~Hamilton, P.~Richardson and J.~Tully,\n" " ``A Positive-Weight Next-to-Leading Order Monte Carlo Simulation for Higgs\n" " Boson Production,''\n" " JHEP {\\bf 0904}, 116 (2009)\n" " [arXiv:0903.4345 [hep-ph]].\n" " %%CITATION = JHEPA,0904,116;%%\n"); static Switch interfaceFactorizationScaleOption ("FactorizationScaleOption", "Option for the choice of factorization scale", &MEPP2Higgs::scaleopt_, 1, false, false); static SwitchOption interfaceDynamic (interfaceFactorizationScaleOption, "Dynamic", "Dynamic factorization scale equal to the current sqrt(sHat())", 1); static SwitchOption interfaceFixed (interfaceFactorizationScaleOption, "Fixed", "Use a fixed factorization scale set with FactorizationScaleValue", 2); static Parameter interfaceFactorizationScaleValue ("FactorizationScaleValue", "Value to use in the event of a fixed factorization scale", &MEPP2Higgs::mu_F_, GeV, 100.0*GeV, 50.0*GeV, 500.0*GeV, true, false, Interface::limited); static Reference interfaceCoupling ("Coupling", "Pointer to the object to calculate the coupling for the correction", &MEPP2Higgs::alpha_, false, false, true, false, false); static Switch interfaceShapeOption ("ShapeScheme", "Option for the treatment of the Higgs resonance shape", &MEPP2Higgs::shapeOption_, 1, false, false); static SwitchOption interfaceStandardShapeFixed (interfaceShapeOption, "FixedBreitWigner", "Breit-Wigner s-channel resonanse", 1); static SwitchOption interfaceStandardShapeRunning (interfaceShapeOption, "MassGenerator", "Use the mass generator to give the shape", 2); static Switch interfaceProcess ("Process", "Which subprocesses to include", &MEPP2Higgs::processOption_, 1, false, false); static SwitchOption interfaceProcessAll (interfaceProcess, "All", "Include all subprocesses", 1); static SwitchOption interfaceProcess1 (interfaceProcess, "qqbar", "Only include the incoming q qbar subprocess", 2); static SwitchOption interfaceProcessgg (interfaceProcess, "gg", "Only include the incoming gg subprocess", 3); static Parameter interfaceMinimumInLoop ("MinimumInLoop", "The minimum flavour of the quarks to include in the loops", &MEPP2Higgs::minLoop_, 6, 5, 6, false, false, Interface::limited); static Parameter interfaceMaximumInLoop ("MaximumInLoop", "The maximum flavour of the quarks to include in the loops", &MEPP2Higgs::maxLoop_, 6, 5, 6, false, false, Interface::limited); static Switch interfaceMassOption ("MassOption", "Option for the treatment of the masses in the loop diagrams", &MEPP2Higgs::massOption_, 0, false, false); static SwitchOption interfaceMassOptionFull (interfaceMassOption, "Full", "Include the full mass dependence", 0); static SwitchOption interfaceMassOptionLarge (interfaceMassOption, "Large", "Use the heavy mass limit", 1); static Parameter interfaceMinimumFlavour ("MinimumFlavour", "The minimum flavour of the incoming quarks in the hard process", &MEPP2Higgs::minFlavour_, 4, 3, 5, false, false, Interface::limited); static Parameter interfaceMaximumFlavour ("MaximumFlavour", "The maximum flavour of the incoming quarks in the hard process", &MEPP2Higgs::maxFlavour_, 5, 3, 5, false, false, Interface::limited); static Parameter interfaceQGChannelWeight ("QGChannelWeight", "The relative weights of the g g and q g channels for selection." " This is a technical parameter for the phase-space generation and " "should not affect the results only the efficiency and fraction" " of events with weight > 1.", &MEPP2Higgs::channelwgtA_, 0.45, 0., 1.e10, false, false, Interface::limited); static Parameter interfaceQbarGChannelWeight ("QbarGChannelWeight", "The relative weights of the g g abd qbar g channels for selection." " This is a technical parameter for the phase-space generation and " "should not affect the results only the efficiency and fraction", &MEPP2Higgs::channelwgtB_, 0.15, 0., 1.e10, false, false, Interface::limited); static Parameter interfaceGGPower ("GGPower", "Power for the phase-space sampling of the gg channel", &MEPP2Higgs::ggPow_, 1.6, 1.0, 3.0, false, false, Interface::limited); static Parameter interfaceQGPower ("QGPower", "Power for the phase-space sampling of the qg and qbarg channels", &MEPP2Higgs::qgPow_, 1.6, 1.0, 3.0, false, false, Interface::limited); static Parameter interfaceEnhancementFactor ("InitialEnhancementFactor", "The enhancement factor for initial-state radiation in the shower to ensure" " the weight for the matrix element correction is less than one.", &MEPP2Higgs::enhance_, 1.1, 1.0, 10.0, false, false, Interface::limited); static Parameter interfacePower ("Power", "The power for the sampling of the matrix elements", &MEPP2Higgs::power_, 2.0, 1.0, 10.0, false, false, Interface::limited); static Parameter interfacePrefactorgg ("Prefactorgg", "The prefactor for the sampling of the q qbar channel", &MEPP2Higgs::pregg_, 7.0, 0.0, 1000.0, false, false, Interface::limited); static Parameter interfacePrefactorqg ("Prefactorqg", "The prefactor for the sampling of the q g channel", &MEPP2Higgs::preqg_, 3.0, 0.0, 1000.0, false, false, Interface::limited); static Parameter interfacePrefactorgqbar ("Prefactorgqbar", "The prefactor for the sampling of the g qbar channel", &MEPP2Higgs::pregqbar_, 3.0, 0.0, 1000.0, false, false, Interface::limited); static Parameter interfacePtMin ("minPt", "The pt cut on hardest emision generation" "2*(1-Beta)*exp(-sqr(intrinsicpT/RMS))/sqr(RMS)", &MEPP2Higgs::minpT_, GeV, 2.*GeV, ZERO, 100000.0*GeV, false, false, Interface::limited); static Switch interface_mu_R_Option ("mu_R_Option", "Option to use pT or mT as the scale in alphaS", &MEPP2Higgs::mu_R_opt_, 1, false, false); static SwitchOption interface_mu_R_Option_mT (interface_mu_R_Option, "mT", "Use mT as the scale in alpha_S", 0); static SwitchOption interface_mu_R_Option_pT (interface_mu_R_Option, "pT", "Use pT as the scale in alpha_S", 1); static Switch interface_mu_F_Option ("mu_F_Option", "Option to use pT or mT as the factorization scale in the PDFs", &MEPP2Higgs::mu_F_opt_, 1, false, false); static SwitchOption interface_mu_F_Option_mT (interface_mu_F_Option, "mT", "Use mT as the scale in the PDFs", 0); static SwitchOption interface_mu_F_Option_pT (interface_mu_F_Option, "pT", "Use pT as the scale in the PDFs", 1); static Switch interfaceSpinCorrelations ("SpinCorrelations", "Which on/off spin correlations in the hard process", &MEPP2Higgs::spinCorrelations_, true, false, false); static SwitchOption interfaceSpinCorrelationsYes (interfaceSpinCorrelations, "Yes", "Switch correlations on", true); static SwitchOption interfaceSpinCorrelationsNo (interfaceSpinCorrelations, "No", "Switch correlations off", false); } void MEPP2Higgs::doinit() { HwMEBase::doinit(); // get the vertex pointers from the SM object tcHwSMPtr theSM = dynamic_ptr_cast(standardModel()); // do the initialisation if(!theSM) { throw InitException() << "Wrong type of StandardModel object in MEPP2Higgs::doinit()," << " the Herwig version must be used" << Exception::runerror; } HGGVertex_ = theSM->vertexHGG(); HFFVertex_ = theSM->vertexFFH(); // get the mass generator for the higgs PDPtr h0 = getParticleData(ParticleID::h0); mh_ = h0->mass(); wh_ = h0->generateWidth(mh_); if(h0->massGenerator()) { hmass_=dynamic_ptr_cast(h0->massGenerator()); } if(shapeOption_==2&&!hmass_) throw InitException() << "If using the mass generator for the line shape in MEPP2Higgs::doinit()" << "the mass generator must be an instance of the GenericMassGenerator class" << Exception::runerror; // stuff for the ME correction double total = 1.+channelwgtA_+channelwgtB_; channelWeights_.push_back(1./total); channelWeights_.push_back(channelWeights_.back()+channelwgtA_/total); channelWeights_.push_back(channelWeights_.back()+channelwgtB_/total); // insert the different prefactors in the vector for easy look up prefactor_.push_back(pregg_); prefactor_.push_back(preqg_); prefactor_.push_back(preqg_); prefactor_.push_back(pregqbar_); prefactor_.push_back(pregqbar_); } void MEPP2Higgs::dofinish() { HwMEBase::dofinish(); if(ntry_==0) return; generator()->log() << "MEPP2Higgs when applying the hard correction " << "generated " << ntry_ << " trial emissions of which " << ngen_ << " were accepted\n"; if(nover_==0) return; generator()->log() << "MEPP2Higgs when applying the hard correction " << nover_ << " weights larger than one were generated of which" << " the largest was " << maxwgt_ << "\n"; } unsigned int MEPP2Higgs::orderInAlphaS() const { return 2; } unsigned int MEPP2Higgs::orderInAlphaEW() const { return 1; } Energy2 MEPP2Higgs::scale() const { return scaleopt_ == 1 ? sHat() : sqr(mu_F_); } int MEPP2Higgs::nDim() const { return 0; } bool MEPP2Higgs::generateKinematics(const double *) { Lorentz5Momentum pout = meMomenta()[0] + meMomenta()[1]; pout.rescaleMass(); meMomenta()[2].setMass(pout.mass()); meMomenta()[2] = LorentzMomentum(pout.x(),pout.y(),pout.z(),pout.t()); jacobian(1.0); // check whether it passes all the cuts: returns true if it does vector out(1,meMomenta()[2]); tcPDVector tout(1,mePartonData()[2]); return lastCuts().passCuts(tout, out, mePartonData()[0], mePartonData()[1]); } void MEPP2Higgs::getDiagrams() const { tcPDPtr h0=getParticleData(ParticleID::h0); // gg -> H process if(processOption_==1||processOption_==3) { tcPDPtr g=getParticleData(ParticleID::g); add(new_ptr((Tree2toNDiagram(2), g, g, 1, h0, -1))); } // q qbar -> H processes if(processOption_==1||processOption_==2) { for ( int i = minFlavour_; i <= maxFlavour_; ++i ) { tcPDPtr q = getParticleData(i); tcPDPtr qb = q->CC(); add(new_ptr((Tree2toNDiagram(2), q, qb, 1, h0, -2))); } } } CrossSection MEPP2Higgs::dSigHatDR() const { using Constants::pi; InvEnergy2 bwfact; if(shapeOption_==1) { bwfact = mePartonData()[2]->generateWidth(sqrt(sHat()))*sqrt(sHat())/pi/ (sqr(sHat()-sqr(mh_))+sqr(mh_*wh_)); } else { bwfact = hmass_->BreitWignerWeight(sqrt(sHat())); } double cs = me2() * jacobian() * pi * double(UnitRemoval::E4 * bwfact/sHat()); return UnitRemoval::InvE2 * sqr(hbarc) * cs; } double MEPP2Higgs::me2() const { double output(0.0); ScalarWaveFunction hout(meMomenta()[2],mePartonData()[2],outgoing); // Safety code to garantee the reliable behaviour of Higgs shape limits // (important for heavy and broad Higgs resonance). Energy hmass = meMomenta()[2].m(); tcPDPtr h0 = mePartonData()[2]; Energy mass = h0->mass(); Energy halfmass = .5*mass; if (.0*GeV > hmass) return 0.0; // stricly speaking the condition is applicable if // h0->widthUpCut() == h0->widthLoCut()... if (h0->widthLoCut() > halfmass) { if ( mass + h0->widthUpCut() < hmass || mass - h0->widthLoCut() > hmass ) return 0.0; } else { if (mass + halfmass < hmass || halfmass > hmass) return 0.0; } if (mePartonData()[0]->id() == ParticleID::g && mePartonData()[1]->id() == ParticleID::g) { VectorWaveFunction gin1(meMomenta()[0],mePartonData()[0],incoming); VectorWaveFunction gin2(meMomenta()[1],mePartonData()[1],incoming); vector g1,g2; for(unsigned int i = 0; i < 2; ++i) { gin1.reset(2*i); g1.push_back(gin1); gin2.reset(2*i); g2.push_back(gin2); } output = ggME(g1,g2,hout,false); } else { if (mePartonData()[0]->id() == -mePartonData()[1]->id()) { SpinorWaveFunction qin (meMomenta()[0],mePartonData()[0],incoming); SpinorBarWaveFunction qbin(meMomenta()[1],mePartonData()[1],incoming); vector fin; vector ain; for (unsigned int i = 0; i < 2; ++i) { qin.reset(i); fin.push_back(qin); qbin.reset(i); ain.push_back(qbin); } output = qqME(fin,ain,hout,false); } else assert(false); } return output; } Selector MEPP2Higgs::diagrams(const DiagramVector & diags) const { Selector sel; for (DiagramIndex i = 0; i < diags.size(); ++i) sel.insert(1.0, i); return sel; } Selector MEPP2Higgs::colourGeometries(tcDiagPtr diag) const { // colour lines static const ColourLines line1("1 -2,2 -1"); static const ColourLines line2("1 -2"); // select the colour flow Selector sel; if (diag->id() == -1) { sel.insert(1.0, &line1); } else { sel.insert(1.0, &line2); } // return the answer return sel; } void MEPP2Higgs::constructVertex(tSubProPtr sub) { if(!spinCorrelations_) return; // extract the particles in the hard process ParticleVector hard; hard.push_back(sub->incoming().first); hard.push_back(sub->incoming().second); hard.push_back(sub->outgoing()[0]); if(hard[0]->id() < hard[1]->id()) { swap(hard[0],hard[1]); } // identify the process and calculate the matrix element if(hard[0]->id() == ParticleID::g && hard[1]->id() == ParticleID::g) { vector g1,g2; vector q; vector qbar; VectorWaveFunction (g1,hard[0],incoming,false,true,true); VectorWaveFunction (g2,hard[1],incoming,false,true,true); ScalarWaveFunction hout(hard[2],outgoing,true); g1[1] = g1[2]; g2[1] = g2[2]; ggME(g1,g2,hout,true); } else { vector q1; vector q2; SpinorWaveFunction (q1,hard[0],incoming,false,true); SpinorBarWaveFunction (q2,hard[1],incoming,false,true); ScalarWaveFunction hout(hard[2],outgoing,true); qqME(q1,q2,hout,true); } // construct the vertex HardVertexPtr hardvertex = new_ptr(HardVertex()); // set the matrix element for the vertex hardvertex->ME(me_); // set the pointers and to and from the vertex for(unsigned int i = 0; i < 3; ++i) hard[i]->spinInfo()->productionVertex(hardvertex); } double MEPP2Higgs::ggME(vector g1, vector g2, ScalarWaveFunction & in, bool calc) const { ProductionMatrixElement newme(PDT::Spin1,PDT::Spin1,PDT::Spin0); Energy2 s(sHat()); double me2(0.0); for(int i = 0; i < 2; ++i) { for(int j = 0; j < 2; ++j) { Complex diag = HGGVertex_->evaluate(s,g1[i],g2[j],in); me2 += norm(diag); if(calc) newme(2*i, 2*j, 0) = diag; } } if(calc) me_.reset(newme); // initial colour and spin factors: colour -> (8/64) and spin -> (1/4) return me2/32.; } double MEPP2Higgs::qqME(vector & fin, vector & ain, ScalarWaveFunction & in, bool calc) const { ProductionMatrixElement newme(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin0); Energy2 s(scale()); double me2(0.0); for(int i = 0; i < 2; ++i) { for(int j = 0; j < 2; ++j) { Complex diag = HFFVertex_->evaluate(s,fin[i],ain[j],in); me2+=norm(diag); if(calc) newme(i, j, 0) = diag; } } if(calc) me_.reset(newme); // final colour/spin factors return me2/12.; } RealEmissionProcessPtr MEPP2Higgs::applyHardMatrixElementCorrection(RealEmissionProcessPtr born) { useMe(); assert(born->bornOutgoing().size()==1); if(born->bornIncoming()[0]->id()!=ParticleID::g) return RealEmissionProcessPtr(); // get gluons and Higgs // get the gluons ParticleVector incoming; vector beams; for(unsigned int ix=0;ixbornIncoming().size();++ix) { incoming.push_back(born->bornIncoming()[ix]); beams.push_back(dynamic_ptr_cast(born->hadrons()[ix]->dataPtr())); } pair xnew=born->x(); if(incoming[0]->momentum().z()bornOutgoing()[0]; // calculate the momenta unsigned int iemit,itype; vector pnew; // if not accepted return tPDPtr out; if(!applyHard(incoming,beams,higgs,iemit,itype,pnew,xnew,out)) return RealEmissionProcessPtr(); // fix the momentum of the higgs Boost boostv=born->bornOutgoing()[0]->momentum().findBoostToCM(); LorentzRotation trans(pnew[3].boostVector()); trans *=LorentzRotation(boostv); born->transformation(trans); born->outgoing().push_back(born->bornOutgoing()[0]->dataPtr()->produceParticle(pnew[3])); born->emitted(3); // if applying ME correction create the new particles if(itype==0) { // ensure gluon can be put on shell Lorentz5Momentum ptest(pnew[2]); if(ptest.boost(-(pnew[0]+pnew[1]).boostVector()).e() < getParticleData(ParticleID::g)->constituentMass()) return RealEmissionProcessPtr(); // create the new gluon PPtr newg= getParticleData(ParticleID::g)->produceParticle(pnew[2]); PPtr newg1 = incoming[0]->dataPtr()->produceParticle(pnew[0]); PPtr newg2 = incoming[1]->dataPtr()->produceParticle(pnew[1]); // set emitter and spectator if(born->bornIncoming()[0]->momentum().z()>ZERO) { born->incoming().push_back(newg1); born->incoming().push_back(newg2); if(iemit==0) { born->emitter(0); born->spectator(1); } else { born->emitter(1); born->spectator(0); } } else { born->incoming().push_back(newg2); born->incoming().push_back(newg1); if(iemit==0) { born->emitter(1); born->spectator(0); } else { born->emitter(0); born->spectator(1); } } bool colour = UseRandom::rndbool(); newg ->incomingColour(newg1,!colour); newg ->incomingColour(newg2, colour); newg1->colourConnect(newg2,!colour); born->outgoing().push_back(newg); } else if(itype==1) { // ensure outgoing quark can be put on-shell Lorentz5Momentum ptest(pnew[2]); if(ptest.boost(-(pnew[0]+pnew[1]).boostVector()).e() < out->constituentMass()) return RealEmissionProcessPtr(); // create the new particles PPtr newqout = out->produceParticle(pnew[2]); PPtr newqin,newg; if(iemit==0) { newqin = out ->produceParticle(pnew[0]); newg = incoming[1]->dataPtr()->produceParticle(pnew[1]); } else { newg = incoming[0]->dataPtr()->produceParticle(pnew[0]); newqin = out ->produceParticle(pnew[1]); } newqout->incomingColour(newg); newg->colourConnect(newqin); if((born->bornIncoming()[0]->momentum().z()>ZERO && iemit==0) || (born->bornIncoming()[0]->momentum().z()incoming().push_back(newqin); born->incoming().push_back(newg ); born->emitter(0); born->spectator(1); } else { born->incoming().push_back(newg ); born->incoming().push_back(newqin); born->emitter(1); born->spectator(0); } born->outgoing().push_back(newqout); } else if(itype==2) { // ensure outgoing antiquark can be put on-shell Lorentz5Momentum ptest(pnew[2]); if(ptest.boost(-(pnew[0]+pnew[1]).boostVector()).e() < incoming[0]->dataPtr()->constituentMass()) return RealEmissionProcessPtr(); // create the new particles PPtr newqout = out->produceParticle(pnew[2]); PPtr newqin,newg; if(iemit==0) { newqin = out ->produceParticle(pnew[0]); newg = incoming[1]->dataPtr()->produceParticle(pnew[1]); } else { newg = incoming[0]->dataPtr()->produceParticle(pnew[0]); newqin = out ->produceParticle(pnew[1]); } newqout->incomingAntiColour(newg); newg->colourConnect(newqin,true); if((born->bornIncoming()[0]->momentum().z()>ZERO && iemit==0) || (born->bornIncoming()[0]->momentum().z()incoming().push_back(newqin); born->incoming().push_back(newg ); born->emitter(0); born->spectator(1); } else { born->incoming().push_back(newg ); born->incoming().push_back(newqin); born->emitter(1); born->spectator(0); } born->outgoing().push_back(newqout); } if(born->bornIncoming()[0]->momentum().z()x(xnew); born->interaction(ShowerInteraction::QCD); return born; } bool MEPP2Higgs::softMatrixElementVeto(PPtr parent, PPtr progenitor, const bool & fs, const Energy & highestpT, const vector & ids, const double & z, const Energy & scale, const Energy & pT) { if(fs) return false; // check if me correction should be applied long id[2]={progenitor->id(),parent->id()}; // must have started as a gluon if(id[0]!=ParticleID::g) return false; // must be a gluon going into the hard process if(ids[1]->id()!=ParticleID::g) return false; // check if hardest so far if(pTid()==ParticleID::g&&ids[2]->id()==ParticleID::g) { double split = 6.*(z/(1.-z)+(1.-z)/z+z*(1.-z)); me = ggME(shat,that,uhat)/split; } // q g else if(ids[0]->id() >= 1 && ids[0]->id() <= 5 && ids[2]->id()==ids[0]->id()) { double split = 4./3./z*(1.+sqr(1.-z)); me = qgME(shat,uhat,that)/split; } // qbar g else if(ids[0]->id() <= -1 && ids[0]->id() >= -5 && ids[2]->id()==ids[0]->id()) { double split = 4./3./z*(1.+sqr(1.-z)); me = qbargME(shat,uhat,that)/split; } else { return false; } InvEnergy2 pre = 0.125/Constants::pi/loME()*sqr(mh2_)*that/shat/(shat+uhat); double wgt = -pre*me/enhance_; if(wgt<.0||wgt>1.) generator()->log() << "Soft ME correction weight too large or " << "negative in MEPP2Higgs::" << "softMatrixElementVeto()\n soft weight " << " sbar = " << shat/mh2_ << " tbar = " << that/mh2_ << "weight = " << wgt << " for " << ids[0]->id() << " " << ids[1]->id() << " " << ids[2]->id() << "\n"; // return whether or not vetoed return !UseRandom::rndbool(wgt); } RealEmissionProcessPtr MEPP2Higgs::generateHardest(RealEmissionProcessPtr born, ShowerInteraction inter) { if(inter==ShowerInteraction::QED) return RealEmissionProcessPtr(); useMe(); // get the particles to be showered beams_.clear(); partons_.clear(); // find the incoming particles ParticleVector incoming; ParticleVector particlesToShower; for(unsigned int ix=0;ixbornIncoming().size();++ix) { incoming.push_back( born->bornIncoming()[ix] ); beams_.push_back( dynamic_ptr_cast(born->hadrons()[ix]->dataPtr())); partons_.push_back( born->bornIncoming()[ix]->dataPtr() ); particlesToShower.push_back( born->bornIncoming()[ix] ); } // find the higgs boson assert(born->bornOutgoing().size()==1); PPtr higgs = born->bornOutgoing()[0]; // calculate the rapidity of the higgs yh_ = 0.5 * log((higgs->momentum().e()+higgs->momentum().z())/ (higgs->momentum().e()-higgs->momentum().z())); mass_=higgs->mass(); mh2_ = sqr(mass_); vector pnew; int emission_type(-1); // generate the hard emission and return if no emission if(!getEvent(pnew,emission_type)) { born->pT()[ShowerInteraction::QCD] = minpT_; return born; } // construct the HardTree object needed to perform the showers ParticleVector newparticles(4); // create the partons int iemit=-1; // create the jet newparticles[3] = out_->produceParticle(pnew[3]); // g g -> h g if(emission_type==0) { newparticles[0] = partons_[0]->produceParticle(pnew[0]); newparticles[1] = partons_[1]->produceParticle(pnew[1]); iemit = pnew[0].z()/pnew[3].z()>0. ? 0 : 1; bool colour = UseRandom::rndbool(); newparticles[3]->incomingColour(newparticles[0],!colour); newparticles[3]->incomingColour(newparticles[1], colour); newparticles[0]-> colourConnect(newparticles[1],!colour); } // g q -> H q else if(emission_type==1) { newparticles[0] = partons_[0]->produceParticle(pnew[0]); newparticles[1] = out_ ->produceParticle(pnew[1]); iemit = 1; newparticles[3]->incomingColour(newparticles[0]); newparticles[0]->colourConnect (newparticles[1]); } // q g -> H q else if(emission_type==2) { newparticles[0] = out_ ->produceParticle(pnew[0]); newparticles[1] = partons_[1]->produceParticle(pnew[1]); iemit = 0; newparticles[3]->incomingColour(newparticles[1]); newparticles[1]->colourConnect (newparticles[0]); } // g qbar -> H qbar else if(emission_type==3) { newparticles[0] = partons_[0]->produceParticle(pnew[0]); newparticles[1] = out_ ->produceParticle(pnew[1]); iemit = 1; newparticles[3]->incomingAntiColour(newparticles[0]); newparticles[0]->colourConnect(newparticles[1],true); } // qbar g -> H qbar else if(emission_type==4) { newparticles[0] = out_ ->produceParticle(pnew[0]); newparticles[1] = partons_[1]->produceParticle(pnew[1]); iemit = 0; newparticles[3]->incomingAntiColour(newparticles[1]); newparticles[1]->colourConnect(newparticles[0],true); } unsigned int ispect = iemit==0 ? 1 : 0; // create the boson newparticles[2] = higgs->dataPtr()->produceParticle(pnew[2]); born->emitter (iemit); born->spectator(ispect); born->emitted(3); born->pT()[ShowerInteraction::QCD] = pt_; pair xnew; for(unsigned int ix=0;ix<2;++ix) { born->incoming().push_back(newparticles[ix]); if(ix==0) xnew.first = newparticles[ix]->momentum().rho()/born->hadrons()[ix]->momentum().rho(); else xnew.second = newparticles[ix]->momentum().rho()/born->hadrons()[ix]->momentum().rho(); } born->x(xnew); for(unsigned int ix=0;ix<2;++ix) born->outgoing().push_back(newparticles[ix+2]); // return the answer born->interaction(ShowerInteraction::QCD); return born; } bool MEPP2Higgs::applyHard(ParticleVector gluons, vector beams,PPtr higgs, unsigned int & iemit, unsigned int & itype, vector & pnew, pair & xout, tPDPtr & out) { ++ntry_; // calculate the limits on s Energy mh(higgs->mass()); mh2_=sqr(mh); Energy2 smin=mh2_; Energy2 s= (generator()->currentEvent()->incoming().first->momentum()+ generator()->currentEvent()->incoming().second->momentum()).m2(); Energy2 smax(s); // calculate the rapidity of the higgs double yH = 0.5*log((higgs->momentum().e()+higgs->momentum().z())/ (higgs->momentum().e()-higgs->momentum().z())); // if no phase-space return if(smaxpdf(); assert(pdf[ix]); fx[ix]=pdf[ix]->xfx(beams[ix],gluons[ix]->dataPtr(),mh2_,x[ix]); } // leading order ME Energy4 lome = loME(); // select the type of process and generate the kinematics double rn(UseRandom::rnd()); Energy2 shat(ZERO),uhat(ZERO),that(ZERO); double weight(0.),xnew[2]={1.,1.}; // gg -> H g if(rn=1.||xnew[1]<=0.||xnew[1]>=1.) return false; for(unsigned int ix=0;ix<2;++ix) fxnew[ix]=pdf[ix]->xfx(beams[ix],gluons[ix]->dataPtr(),scale,xnew[ix]); // jacobian and me parts of the weight weight = jacobian2*ggME(shat,uhat,that)/lome*mh2_/sqr(shat); // pdf part of the weight weight *=fxnew[0]*fxnew[1]*x[0]*x[1]/(fx[0]*fx[1]*xnew[0]*xnew[1]); // finally coupling and different channel pieces weight *= 1./16./sqr(Constants::pi)*alpha_->value(scale)/channelWeights_[0]; itype=0; iemit = that>uhat ? 0 : 1; out = getParticleData(ParticleID::g); } // incoming quark or antiquark else { // generate the value of s according to 1/s^n double rhomax(pow(smin/mh2_,1.-qgPow_)),rhomin(pow(smax/mh2_,1.-qgPow_)); double rho = rhomin+UseRandom::rnd()*(rhomax-rhomin); shat = mh2_*pow(rho,1./(1.-qgPow_)); Energy2 jacobian = mh2_/(qgPow_-1.)*(rhomax-rhomin)*pow(shat/mh2_,qgPow_); double sbar=shat/mh2_; // calculate limits on that Energy2 tmax=mh2_*kappa[0]*(1.-sbar)/(kappa[0]+sbar); Energy2 tmin=shat*(1.-sbar)/(kappa[1]+sbar); // calculate the limits on uhat Energy2 umax(mh2_-shat-tmin),umin(mh2_-shat-tmax); // check inside phase space if(tmax=1.||xnew[1]<=0.||xnew[1]>=1.) return false; if(rn H q if(!order) { out = quarkFlavour(pdf[0],scale,xnew[0],beams[0],fxnew[0],false); fxnew[1]=pdf[1]->xfx(beams[1],gluons[1]->dataPtr(),scale,xnew[1]); iemit = 0; mewgt = out ? qgME(shat,uhat,that)/lome*mh2_/sqr(shat) : ZERO; } // g q -> H q else { fxnew[0]=pdf[0]->xfx(beams[0],gluons[0]->dataPtr(),scale,xnew[0]); out = quarkFlavour(pdf[1],scale,xnew[1],beams[1],fxnew[1],false); iemit = 1; mewgt = out ? qgME(shat,that,uhat)/lome*mh2_/sqr(shat) : ZERO; } jacobian2 /= (channelWeights_[1]-channelWeights_[0]); } else { itype=2; // qbar g -> H qbar if(!order) { out = quarkFlavour(pdf[0],scale,xnew[0],beams[0],fxnew[0],true); fxnew[1]=pdf[1]->xfx(beams[1],gluons[1]->dataPtr(),scale,xnew[1]); iemit = 0; mewgt = out ? qbargME(shat,uhat,that)/lome*mh2_/sqr(shat) : ZERO; } // g qbar -> H qbar else { fxnew[0]=pdf[0]->xfx(beams[0],gluons[0]->dataPtr(),scale,xnew[0]); out = quarkFlavour(pdf[1],scale,xnew[1],beams[1],fxnew[1],true); iemit = 1; mewgt = out ? qbargME(shat,that,uhat)/lome*mh2_/sqr(shat) : ZERO; } jacobian2/=(channelWeights_[2]-channelWeights_[1]); } // weight (factor of 2 as pick q(bar)g or gq(bar) weight = 2.*jacobian2*mewgt; // pdf part of the weight weight *=fxnew[0]*fxnew[1]*x[0]*x[1]/(fx[0]*fx[1]*xnew[0]*xnew[1]); // finally coupling and different channel pieces weight *= 1./16./sqr(Constants::pi)*alpha_->value(scale); } // if me correction should be applied if(weight>1.) { ++nover_; maxwgt_ = max( maxwgt_ , weight); weight=1.; } if(UseRandom::rnd()>weight) return false; ++ngen_; // construct the momenta Energy roots = 0.5*sqrt(s); Energy pt = sqrt(uhat*that/shat); Energy mt = sqrt(uhat*that/shat+mh2_); Lorentz5Momentum pin[2]={Lorentz5Momentum(ZERO,ZERO, xnew[0]*roots,xnew[0]*roots), Lorentz5Momentum(ZERO,ZERO,-xnew[1]*roots,xnew[1]*roots)}; double phi = Constants::twopi*UseRandom::rnd(); Lorentz5Momentum pH(pt*cos(phi),pt*sin(phi),mt*sinh(yH),mt*cosh(yH)); Lorentz5Momentum pJ(pin[0]+pin[1]-pH); // momenta to be returned pnew.push_back(pin[0]); pnew.push_back(pin[1]); pnew.push_back(pJ); pnew.push_back(pH); xout.first = xnew[0]; xout.second = xnew[1]; return true; } Energy2 MEPP2Higgs::ggME(Energy2 s, Energy2 t, Energy2 u) { Energy2 output; if(massOption_==0) { complex me[2][2][2]; me[1][1][1] = ZERO; me[1][1][0] = ZERO; me[0][1][0] = ZERO; me[0][1][1] = ZERO; for(unsigned int ix=minLoop_; ix<=maxLoop_; ++ix ) { Energy2 mf2=sqr(getParticleData(long(ix))->mass()); bi_[1]=B(s,mf2); bi_[2]=B(u,mf2); bi_[3]=B(t,mf2); bi_[4]=B(mh2_,mf2); bi_[1]=bi_[1]-bi_[4]; bi_[2]=bi_[2]-bi_[4]; bi_[3]=bi_[3]-bi_[4]; ci_[1]=C(s,mf2); ci_[2]=C(u,mf2); ci_[3]=C(t,mf2); ci_[7]=C(mh2_,mf2); ci_[4]=(s*ci_[1]-mh2_*ci_[7])/(s-mh2_); ci_[5]=(u*ci_[2]-mh2_*ci_[7])/(u-mh2_); ci_[6]=(t*ci_[3]-mh2_*ci_[7])/(t-mh2_); di_[1]=D(t,u,s,mf2); di_[2]=D(s,t,u,mf2); di_[3]=D(s,u,t,mf2); me[1][1][1]+=me1(s,u,t,mf2,1,2,3,4,5,6); me[1][1][0]+=me2(s,u,t,mf2); me[0][1][0]+=me1(u,s,t,mf2,2,1,3,5,4,6); me[0][1][1]+=me1(t,u,s,mf2,3,2,1,6,5,4); } me[0][0][0]=-me[1][1][1]; me[0][0][1]=-me[1][1][0]; me[1][0][1]=-me[0][1][0]; me[1][0][0]=-me[0][1][1]; output = real(me[0][0][0]*conj(me[0][0][0])+ me[0][0][1]*conj(me[0][0][1])+ me[0][1][0]*conj(me[0][1][0])+ me[0][1][1]*conj(me[0][1][1])+ me[1][0][0]*conj(me[1][0][0])+ me[1][0][1]*conj(me[1][0][1])+ me[1][1][0]*conj(me[1][1][0])+ me[1][1][1]*conj(me[1][1][1])); output *= 3./8.; } else { output=32./3.* (pow<4,1>(s)+pow<4,1>(t)+pow<4,1>(u)+pow<4,1>(mh2_))/s/t/u; } // spin and colour factors return output/4./64.; } Energy2 MEPP2Higgs::qgME(Energy2 s, Energy2 t, Energy2 u) { Energy2 output; if(massOption_==0) { complex A(ZERO); Energy2 si(u-mh2_); for(unsigned int ix=minLoop_;ix<=maxLoop_;++ix) { Energy2 mf2=sqr(getParticleData(long(ix))->mass()); A += mf2*(2.+2.*double(u/si)*(B(u,mf2)-B(mh2_,mf2)) +double((4.*mf2-s-t)/si)*Complex(u*C(u,mf2)-mh2_*C(mh2_,mf2))); } output =-4.*(sqr(s)+sqr(t))/sqr(si)/u*real(A*conj(A)); } else{ output =-4.*(sqr(s)+sqr(t))/u/9.; } // final colour/spin factors return output/24.; } Energy2 MEPP2Higgs::qbargME(Energy2 s, Energy2 t, Energy2 u) { Energy2 output; if(massOption_==0) { complex A(ZERO); Energy2 si(u-mh2_); for(unsigned int ix=minLoop_;ix<=maxLoop_;++ix) { Energy2 mf2=sqr(getParticleData(long(ix))->mass()); A+=mf2*(2.+2.*double(u/si)*(B(u,mf2)-B(mh2_,mf2)) +double((4.*mf2-s-t)/si)*Complex(u*C(u,mf2)-mh2_*C(mh2_,mf2))); } output =-4.*(sqr(s)+sqr(t))/sqr(si)/u*real(A*conj(A)); } else { output =-4.*(sqr(s)+sqr(t))/u/9.; } // final colour/spin factors return output/24.; } Energy4 MEPP2Higgs::loME() const { Complex I(0); if(massOption_==0) { for(unsigned int ix=minLoop_;ix<=maxLoop_;++ix) { double x = sqr(getParticleData(long(ix))->mass())/mh2_; I += 3.*x*(2.+(4.*x-1.)*F(x)); } } else { I = 1.; } return sqr(mh2_)/576./Constants::pi*norm(I); } tPDPtr MEPP2Higgs::quarkFlavour(tcPDFPtr pdf, Energy2 scale, double x, tcBeamPtr beam, double & pdfweight, bool anti) { vector weights; vector partons; pdfweight = 0.; if(!anti) { for(unsigned int ix=1;ix<=5;++ix) { partons.push_back(getParticleData(long(ix))); weights.push_back(max(0.,pdf->xfx(beam,partons.back(),scale,x))); pdfweight += weights.back(); } } else { for(unsigned int ix=1;ix<=5;++ix) { partons.push_back(getParticleData(-long(ix))); weights.push_back(max(0.,pdf->xfx(beam,partons.back(),scale,x))); pdfweight += weights.back(); } } if(pdfweight==0.) return tPDPtr(); double wgt=UseRandom::rnd()*pdfweight; for(unsigned int ix=0;ix=ZERO&&rat<1.) output=2.-2.*sqrt(1./rat-1.)*asin(sqrt(rat)); else output=2.-sqrt(1.-1./rat)*(2.*log(sqrt(rat)+sqrt(rat-1.))-pii); return output; } complex MEPP2Higgs::C(Energy2 s,Energy2 mf2) const { complex output; - Complex pii(0.,Constants::pi); + const Complex pii(0.,Constants::pi); double rat=s/(4.*mf2); if(s=ZERO&&rat<1.) output=-2.*sqr(asin(sqrt(rat)))/s; else { double cosh=log(sqrt(rat)+sqrt(rat-1.)); output=2.*(sqr(cosh)-sqr(Constants::pi)/4.-pii*cosh)/s; } return output; } Complex MEPP2Higgs::dIntegral(Energy2 a, Energy2 b, double y0) const { Complex output; if(b==ZERO) output=0.; else { Complex y1=0.5*(1.+sqrt(1.-4.*(a+epsi_)/b)); Complex y2=1.-y1; Complex z1=y0/(y0-y1); Complex z2=(y0-1.)/(y0-y1); Complex z3=y0/(y0-y2); Complex z4=(y0-1.)/(y0-y2); output=Math::Li2(z1)-Math::Li2(z2)+Math::Li2(z3)-Math::Li2(z4); } return output; } complex MEPP2Higgs::D(Energy2 s,Energy2 t, Energy2, Energy2 mf2) const { - Complex output,pii(0.,Constants::pi); + Complex output; Energy4 st=s*t; Energy4 root=sqrt(sqr(st)-4.*st*mf2*(s+t-mh2_)); double xp=0.5*(st+root)/st,xm=1-xp; output = 2.*(-dIntegral(mf2,s,xp)-dIntegral(mf2,t,xp) +dIntegral(mf2,mh2_,xp)+log(-xm/xp) *(log((mf2+epsi_)/GeV2)-log((mf2+epsi_-s*xp*xm)/GeV2) +log((mf2+epsi_-mh2_*xp*xm)/GeV2)-log((mf2+epsi_-t*xp*xm)/GeV2))); return output/root; } complex MEPP2Higgs::me1(Energy2 s,Energy2 t,Energy2 u, Energy2 mf2, unsigned int i ,unsigned int j ,unsigned int k , unsigned int i1,unsigned int j1,unsigned int k1) const { Energy2 s1(s-mh2_),t1(t-mh2_),u1(u-mh2_); return mf2*4.*sqrt(2.*s*t*u)* (-4.*(1./(u*t)+1./(u*u1)+1./(t*t1)) -4.*((2.*s+t)*bi_[k]/sqr(u1)+(2.*s+u)*bi_[j]/sqr(t1))/s -(s-4.*mf2)*(s1*ci_[i1]+(u-s)*ci_[j1]+(t-s)*ci_[k1])/(s*t*u) -8.*mf2*(ci_[j1]/(t*t1)+ci_[k1]/(u*u1)) +0.5*(s-4.*mf2)*(s*t*di_[k]+u*s*di_[j]-u*t*di_[i])/(s*t*u) +4.*mf2*di_[i]/s -2.*Complex(u*ci_[k]+t*ci_[j]+u1*ci_[k1]+t1*ci_[j1]-u*t*di_[i])/sqr(s)); } complex MEPP2Higgs::me2(Energy2 s,Energy2 t,Energy2 u, Energy2 mf2) const { Energy2 s1(s-mh2_),t1(t-mh2_),u1(u-mh2_); return mf2*4.*sqrt(2.*s*t*u)*(4.*mh2_+(mh2_-4.*mf2)*(s1*ci_[4]+t1*ci_[5]+u1*ci_[6]) -0.5*(mh2_-4.*mf2)*(s*t*di_[3]+u*s*di_[2]+u*t*di_[1]) )/ (s*t*u); } Complex MEPP2Higgs::F(double x) const { if(x<.25) { double root = sqrt(1.-4.*x); - Complex pii(0.,Constants::pi); + const Complex pii(0.,Constants::pi); return 0.5*sqr(log((1.+root)/(1.-root))-pii); } else { return -2.*sqr(asin(0.5/sqrt(x))); } } bool MEPP2Higgs::getEvent(vector & pnew, int & emis_type){ // maximum pt (half of centre-of-mass energy) Energy maxp = 0.5*generator()->maximumCMEnergy(); // set pt of emission to zero pt_=ZERO; //Working Variables Energy pt; double yj; // limits on the rapidity of the jet double minyj = -8.0,maxyj = 8.0; bool reject; double wgt; emis_type=-1; tcPDPtr outParton; for(int j=0;j<5;++j) { pt = maxp; do { double a = alpha_->overestimateValue()*prefactor_[j]*(maxyj-minyj)/(power_-1.); // generate next pt pt=GeV/pow(pow(GeV/pt,power_-1)-log(UseRandom::rnd())/a,1./(power_-1.)); // generate rapidity of the jet yj=UseRandom::rnd()*(maxyj-minyj)+ minyj; // calculate rejection weight wgt=getResult(j,pt,yj,outParton); wgt/= prefactor_[j]*pow(GeV/pt,power_); reject = UseRandom::rnd()>wgt; //no emission event if p goes past p min - basically set to outside //of the histogram bounds (hopefully hist object just ignores it) if(pt1.0) { ostringstream s; s << "MEPP2Higgs::getEvent weight for channel " << j << "is " << wgt << " which is greater than 1"; generator()->logWarning( Exception(s.str(), Exception::warning) ); } } while(reject); // set pt of emission etc if(pt>pt_){ emis_type = j; pt_=pt; yj_=yj; out_ = outParton; } } //was this an (overall) no emission event? if(pt_maximumCMEnergy()); // transverse energy Energy et=sqrt(mh2_+sqr(pt_)); // first calculate all the kinematic variables // longitudinal real correction fractions double x = pt_*exp( yj_)/sqrt(s)+et*exp( yh_)/sqrt(s); double y = pt_*exp(-yj_)/sqrt(s)+et*exp(-yh_)/sqrt(s); // that and uhat // Energy2 th = -sqrt(s)*x*pt_*exp(-yj_); // Energy2 uh = -sqrt(s)*y*pt_*exp( yj_); // Energy2 sh = x*y*s; // reconstruct the momenta // incoming momenta pnew.push_back(Lorentz5Momentum(ZERO,ZERO, x*0.5*sqrt(s), x*0.5*sqrt(s),ZERO)); pnew.push_back(Lorentz5Momentum(ZERO,ZERO, -y*0.5*sqrt(s), y*0.5*sqrt(s),ZERO)); // outgoing momenta double phi(Constants::twopi*UseRandom::rnd()); double sphi(sin(phi)),cphi(cos(phi)); pnew.push_back(Lorentz5Momentum( cphi*pt_, sphi*pt_, et*sinh(yh_), et*cosh(yh_), mass_)); pnew.push_back(Lorentz5Momentum(-cphi*pt_,-sphi*pt_,pt_*sinh(yj_), pt_*cosh(yj_),ZERO)); return true; } double MEPP2Higgs::getResult(int emis_type, Energy pt, double yj, tcPDPtr & outParton) { Energy2 s=sqr(generator()->maximumCMEnergy()); Energy2 scale = mh2_+sqr(pt); Energy et=sqrt(scale); scale = mu_F_opt_==0 ? mh2_+sqr(pt) : sqr(pt) ; // longitudinal real correction fractions double x = pt*exp( yj)/sqrt(s)+et*exp( yh_)/sqrt(s); double y = pt*exp(-yj)/sqrt(s)+et*exp(-yh_)/sqrt(s); // reject if outside region if(x<0.||x>1.||y<0.||y>1.||x*ypdf()->xfx(beams_[0],partons_[0],mh2_,x1); pdf[1]=beams_[1]->pdf()->xfx(beams_[1],partons_[1],mh2_,y1); } else { // As in Nason and Ridolfi paper ... pdf[0]=beams_[0]->pdf()->xfx(beams_[0],partons_[0],scale,x1); pdf[1]=beams_[1]->pdf()->xfx(beams_[1],partons_[1],scale,y1); } // g g -> H g if(emis_type==0) { outParton = partons_[1]; pdf[2]=beams_[0]->pdf()->xfx(beams_[0],partons_[0],scale,x); pdf[3]=beams_[1]->pdf()->xfx(beams_[1],partons_[1],scale,y); res = ggME(sh,uh,th)/loME(); } // q g -> H q else if(emis_type==1) { outParton = quarkFlavour(beams_[0]->pdf(),scale,x,beams_[0],pdf[2],false); pdf[3]=beams_[1]->pdf()->xfx(beams_[1],partons_[1],scale,y); res = outParton ? qgME(sh,uh,th)/loME() : ZERO; } // g q -> H q else if(emis_type==2) { pdf[2]=beams_[0]->pdf()->xfx(beams_[0],partons_[0],scale,x); outParton = quarkFlavour(beams_[1]->pdf(),scale,y,beams_[1],pdf[3],false); res = outParton ? qgME(sh,th,uh)/loME() : ZERO; } // qbar g -> H qbar else if(emis_type==3) { outParton = quarkFlavour(beams_[0]->pdf(),scale,x,beams_[0],pdf[2],true); pdf[3]=beams_[1]->pdf()->xfx(beams_[1],partons_[1],scale,y); res = outParton ? qbargME(sh,uh,th)/loME() : ZERO; } // g qbar -> H qbar else if(emis_type==4) { pdf[2]=beams_[0]->pdf()->xfx(beams_[0],partons_[0],scale,x); outParton = quarkFlavour(beams_[1]->pdf(),scale,y,beams_[1],pdf[3],true); res = outParton ? qbargME(sh,th,uh)/loME() : ZERO; } //deals with pdf zero issue at large x if(pdf[0]<=0.||pdf[1]<=0.||pdf[2]<=0.||pdf[3]<=0.) { res = ZERO; } else { res *= pdf[2]*pdf[3]/pdf[0]/pdf[1]*mh2_/sh; } scale = mu_R_opt_==0 ? mh2_+sqr(pt) : sqr(pt) ; return alpha_->ratio(scale)/8./sqr(Constants::pi)*mh2_/sh*GeV*pt*res; } void MEPP2Higgs::initializeMECorrection(RealEmissionProcessPtr born, double & initial, double & final) { final = 1.; initial = born->bornIncoming()[0]->id()==ParticleID::g ? enhance_ : 1.; } diff --git a/MatrixElement/Hadron/MEPP2ZH.h b/MatrixElement/Hadron/MEPP2ZH.h --- a/MatrixElement/Hadron/MEPP2ZH.h +++ b/MatrixElement/Hadron/MEPP2ZH.h @@ -1,111 +1,105 @@ // -*- C++ -*- #ifndef HERWIG_MEPP2ZH_H #define HERWIG_MEPP2ZH_H // // This is the declaration of the MEPP2ZH class. // #include "Herwig/MatrixElement/MEfftoVH.h" namespace Herwig { using namespace ThePEG; /** * The MEPP2ZH class implements the matrix element * for \f$q\bar{q}\to Z^0h^0\f$. * * @see \ref MEPP2ZHInterfaces "The interfaces" * defined for MEPP2ZH. */ class MEPP2ZH: public MEfftoVH { public: /** * The default constructor. */ MEPP2ZH(); /** @name Virtual functions required by the MEBase class. */ //@{ /** * Add all possible diagrams with the add() function. */ virtual void getDiagrams() const; //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const { return new_ptr(*this); } /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const { return new_ptr(*this); } //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); //@} private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ MEPP2ZH & operator=(const MEPP2ZH &) = delete; -private: - - /** - * The allowed flavours of the incoming quarks - */ - int _maxflavour; }; } #endif /* HERWIG_MEPP2ZH_H */ diff --git a/MatrixElement/Lepton/MEee2VectorMeson.cc b/MatrixElement/Lepton/MEee2VectorMeson.cc --- a/MatrixElement/Lepton/MEee2VectorMeson.cc +++ b/MatrixElement/Lepton/MEee2VectorMeson.cc @@ -1,228 +1,227 @@ // -*- C++ -*- // // MEee2VectorMeson.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2017 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the MEee2VectorMeson class. // #include "MEee2VectorMeson.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/Cuts/Cuts.h" #include "Herwig/PDT/GenericMassGenerator.h" #include "ThePEG/Handlers/StandardXComb.h" #include "Herwig/Models/StandardModel/StandardModel.h" #include "Herwig/MatrixElement/HardVertex.h" using namespace Herwig; using namespace ThePEG; using namespace ThePEG::Helicity; void MEee2VectorMeson::getDiagrams() const { tcPDPtr em = getParticleData(ParticleID::eminus); tcPDPtr ep = getParticleData(ParticleID::eplus); add(new_ptr((Tree2toNDiagram(2), em, ep, 1, vector_,-1))); } Energy2 MEee2VectorMeson::scale() const { return sHat(); } int MEee2VectorMeson::nDim() const { return 0; } void MEee2VectorMeson::setKinematics() { MEBase::setKinematics(); } bool MEee2VectorMeson::generateKinematics(const double *) { Lorentz5Momentum pout=meMomenta()[0]+meMomenta()[1]; pout.rescaleMass(); meMomenta()[2] = pout; jacobian(1.0); // check passes all the cuts vector out(1,meMomenta()[2]); tcPDVector tout(1,mePartonData()[2]); return lastCuts().passCuts(tout, out, mePartonData()[0], mePartonData()[1]); } unsigned int MEee2VectorMeson::orderInAlphaS() const { return 0; } unsigned int MEee2VectorMeson::orderInAlphaEW() const { return 2; } Selector MEee2VectorMeson::colourGeometries(tcDiagPtr) const { static ColourLines neutral ( " " ); Selector sel;sel.insert(1.,&neutral); return sel; } void MEee2VectorMeson::persistentOutput(PersistentOStream & os) const { os << coupling_ << vector_ << massGen_ << lineShape_; } void MEee2VectorMeson::persistentInput(PersistentIStream & is, int) { is >> coupling_ >> vector_ >> massGen_ >> lineShape_; } // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeHerwigMEee2VectorMeson("Herwig::MEee2VectorMeson", "HwMELepton.so"); void MEee2VectorMeson::Init() { static ClassDocumentation documentation ("The MEee2VectorMeson class implements the production of a vector meson" " in e+e- collisions and is primilarly intended to test the hadron decay package"); static Switch interfaceLineShape ("LineShape", "Option for the vector meson lineshape", &MEee2VectorMeson::lineShape_, false, false, false); static SwitchOption interfaceLineShapeMassGenerator (interfaceLineShape, "MassGenerator", "Use the mass generator if available", true); static SwitchOption interfaceLineShapeBreitWigner (interfaceLineShape, "BreitWigner", "Use a Breit-Wigner with the naive running width", false); static Reference interfaceVectorMeson ("VectorMeson", "The vector meson produced", &MEee2VectorMeson::vector_, false, false, true, false, false); static Parameter interfaceCoupling ("Coupling", "The leptonic coupling of the vector meson", &MEee2VectorMeson::coupling_, 0., 0.0, 100.0, false, false, Interface::limited); } Selector MEee2VectorMeson::diagrams(const DiagramVector &) const { Selector sel;sel.insert(1.0, 0); return sel; } CrossSection MEee2VectorMeson::dSigHatDR() const { InvEnergy2 wgt; Energy M(vector_->mass()),G(vector_->width()); - Energy2 M2(sqr(M)),GM(G*M); + Energy2 M2(sqr(M)); if(massGen_&&lineShape_) wgt = Constants::pi*massGen_->BreitWignerWeight(sqrt(sHat())); else wgt = sHat()*G/M/(sqr(sHat()-M2)+sqr(sHat()*G/M)); return sqr(4.*Constants::pi*SM().alphaEM(sHat()))*me2()*jacobian()*wgt*sqr(hbarc)*sqr(M2/sHat()); } void MEee2VectorMeson::doinit() { MEBase::doinit(); // mass generator tMassGenPtr mass=vector_->massGenerator(); if(mass) { massGen_=dynamic_ptr_cast(mass); } } double MEee2VectorMeson::me2() const { double aver=0.; // get the order right int ielectron(0),ipositron(1); if(mePartonData()[0]->id()!=11) swap(ielectron,ipositron); // the vectors for the wavefunction to be passed to the matrix element vector fin; vector ain; vector vout; for(unsigned int ihel=0;ihel<2;++ihel) { fin.push_back(SpinorWaveFunction(meMomenta()[ielectron], mePartonData()[ielectron],ihel,incoming)); ain.push_back(SpinorBarWaveFunction(meMomenta()[ipositron], mePartonData()[ipositron],ihel,incoming)); } for(unsigned int ihel=0;ihel<3;++ihel) { vout.push_back(VectorWaveFunction(meMomenta()[2],mePartonData()[2],ihel,outgoing)); } ProductionMatrixElement temp=HelicityME(fin,ain,vout,aver); return aver; } // the helicity amplitude matrix element ProductionMatrixElement MEee2VectorMeson::HelicityME(vector fin, vector ain, vector vout, double & aver) const { ProductionMatrixElement output(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1); Complex product; // sum over helicities to get the matrix element unsigned int inhel1,inhel2,outhel1; aver = 0.; LorentzPolarizationVectorE vec; - Complex ii(0.,1.); Energy ecms = sqrt(sHat()); for(inhel1=0;inhel1<2;++inhel1) { for(inhel2=0;inhel2<2;++inhel2) { vec = fin[inhel1].dimensionedWave().vectorCurrent(ain[inhel2].dimensionedWave()); vec /= coupling_; for(outhel1=0;outhel1<3;++outhel1) { product = vec.dot(vout[outhel1].wave())/ecms; output(inhel1,inhel2,outhel1)=product; aver += norm(product); } } } aver *= 0.25; return output; } void MEee2VectorMeson::constructVertex(tSubProPtr sub) { // extract the particles in the hard process ParticleVector hard; hard.push_back(sub->incoming().first);hard.push_back(sub->incoming().second); hard.push_back(sub->outgoing()[0]); if(hard[0]->id()id()) swap(hard[0],hard[1]); vector fin; vector ain; vector vout; SpinorWaveFunction( fin ,hard[0],incoming,false,true); SpinorBarWaveFunction(ain ,hard[1],incoming,false,true); VectorWaveFunction(vout ,hard[2],outgoing,true,false,true); double dummy; ProductionMatrixElement prodme=HelicityME(fin,ain,vout,dummy); // construct the vertex HardVertexPtr hardvertex=new_ptr(HardVertex()); // set the matrix element for the vertex hardvertex->ME(prodme); // set the pointers and to and from the vertex for(unsigned int ix=0;ix<3;++ix) { (hard[ix]->spinInfo())->productionVertex(hardvertex); } } diff --git a/MatrixElement/Lepton/MEee2gZ2ll.h b/MatrixElement/Lepton/MEee2gZ2ll.h --- a/MatrixElement/Lepton/MEee2gZ2ll.h +++ b/MatrixElement/Lepton/MEee2gZ2ll.h @@ -1,366 +1,363 @@ // -*- C++ -*- // // MEee2gZ2ll.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2017 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_MEee2gZ2ll_H #define HERWIG_MEee2gZ2ll_H // // This is the declaration of the MEee2gZ2ll class. // #include "Herwig/MatrixElement/HwMEBase.h" #include "Herwig/Models/StandardModel/StandardModel.h" #include "ThePEG/PDT/EnumParticles.h" #include "Herwig/MatrixElement/ProductionMatrixElement.h" #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h" #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h" #include "Herwig/Shower/ShowerAlpha.h" namespace Herwig { using namespace ThePEG; /** * The MEee2gZ2ll class provides the matrix element for * \f$e^+e^-\to\ell^+\ell^-\f$. N.B. for the production of \f$e^+e^-\f$ * only the \f$s\f$-channel Z and photon diagrams are included. * * @see \ref MEee2gZ2llInterfaces "The interfaces" * defined for MEee2gZ2ll. */ class MEee2gZ2ll: public HwMEBase { public: /** * The default constructor. */ MEee2gZ2ll() : allowed_(0), pTmin_(GeV), preFactor_(6.) { massOption(vector(2,1)); } /** * Members for hard corrections to the emission of QCD radiation */ //@{ /** * Has a POWHEG style correction */ virtual POWHEGType hasPOWHEGCorrection() {return FSR;} /** * Has an old fashioned ME correction */ virtual bool hasMECorrection() {return false;} /** * Apply the POWHEG style correction */ virtual RealEmissionProcessPtr generateHardest(RealEmissionProcessPtr, ShowerInteraction); //@} public: /** @name Virtual functions required by the MEBase class. */ //@{ /** * Return the order in \f$\alpha_S\f$ in which this matrix * element is given. */ virtual unsigned int orderInAlphaS() const; /** * Return the order in \f$\alpha_{EW}\f$ in which this matrix * element is given. */ virtual unsigned int orderInAlphaEW() const; /** * The matrix element for the kinematical configuration * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. * @return the matrix element scaled with sHat() to give a * dimensionless number. */ virtual double me2() const; /** * Return the scale associated with the last set phase space point. */ virtual Energy2 scale() const; /** * Add all possible diagrams with the add() function. */ virtual void getDiagrams() const; /** * Get diagram selector. With the information previously supplied with the * setKinematics method, a derived class may optionally * override this method to weight the given diagrams with their * (although certainly not physical) relative probabilities. * @param dv the diagrams to be weighted. * @return a Selector relating the given diagrams to their weights. */ virtual Selector diagrams(const DiagramVector & dv) const; /** * Return a Selector with possible colour geometries for the selected * diagram weighted by their relative probabilities. * @param diag the diagram chosen. * @return the possible colour geometries weighted by their * relative probabilities. */ virtual Selector colourGeometries(tcDiagPtr diag) const; /** * Construct the vertex of spin correlations. */ virtual void constructVertex(tSubProPtr); //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const {return new_ptr(*this);} /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const {return new_ptr(*this);} //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); /** * Rebind pointer to other Interfaced objects. Called in the setup phase * after all objects used in an EventGenerator has been cloned so that * the pointers will refer to the cloned objects afterwards. * @param trans a TranslationMap relating the original objects to * their respective clones. * @throws RebindException if no cloned object was found for a given * pointer. */ virtual void rebind(const TranslationMap & trans) ; /** * Return a vector of all pointers to Interfaced objects used in this * object. * @return a vector of pointers. */ virtual IVector getReferences(); //@} protected: /** * Calculate the matrix element for \f$e^+e^-\to \ell^+ \ell^-\f$. * @param partons The incoming and outgoing particles * @param momenta The momenta of the incoming and outgoing particles */ double loME(const vector & partons, const vector & momenta, bool first) const; /** * Member to calculate the matrix element * @param fin Spinors for incoming fermion * @param ain Spinors for incoming antifermion * @param fout Spinors for outgoing fermion * @param aout Spinors for outgong antifermion * @param me Spin summed Matrix element * @param cont The continuum piece of the matrix element * @param BW The Z piece of the matrix element */ ProductionMatrixElement HelicityME(vector & fin, vector & ain, vector & fout, vector & aout, double & me, double & cont, double & BW ) const; /** * The ratio of the matrix element for one additional jet over the * leading order result. In practice * \[\frac{\hat{s}|\overline{\mathcal{M}}|^2_2|D_{\rm emit}|}{4\pi C_F\alpha_S|\overline{\mathcal{M}}|^2_3\left(|D_{\rm emit}|+|D_{\rm spect}\right)}}\] * is returned where \f$\|\overline{\mathcal{M}}|^2\f$ is * the spin and colour summed/averaged matrix element. * @param partons The incoming and outgoing particles * @param momenta The momenta of the incoming and outgoing particles * @param iemitter Whether the quark or antiquark is regardede as the emitter * @param inter The type of interaction */ double meRatio(vector partons, vector momenta, unsigned int iemittor, bool subtract=false) const; /** * Calculate the matrix element for \f$e^-e^-\to q \bar q g$. * @param partons The incoming and outgoing particles * @param momenta The momenta of the incoming and outgoing particles * @param inter The type of interaction */ InvEnergy2 realME(const vector & partons, const vector & momenta) const; /** * Generate the momenta for a hard configuration */ Energy generateHard(RealEmissionProcessPtr tree, vector & emission, unsigned int & iemit, unsigned int & ispect, bool applyVeto); protected: /** * Pointer to the fermion-antifermion Z vertex */ AbstractFFVVertexPtr FFZVertex() const {return FFZVertex_;} /** * Pointer to the fermion-antifermion photon vertex */ AbstractFFVVertexPtr FFPVertex() const {return FFPVertex_;} /** * Pointer to the particle data object for the Z */ PDPtr Z0() const {return Z0_;} /** * Pointer to the particle data object for the photon */ PDPtr gamma() const {return gamma_;} private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ MEee2gZ2ll & operator=(const MEee2gZ2ll &) = delete; private: /** * Pointers to the vertices */ //@{ /** * Pointer to the fermion-antifermion Z vertex */ AbstractFFVVertexPtr FFZVertex_; /** * Pointer to the fermion-antifermion photon vertex */ AbstractFFVVertexPtr FFPVertex_; //@} /** * Pointer to the particle data object for the Z */ PDPtr Z0_; /** * Pointer to the particle data object for the photon */ PDPtr gamma_; /** * The allowed outgoing */ int allowed_; - /** - * The initial kappa-tilde values for radiation from the quark - */ - double d_kt1_; + /** * Pointer to the EM coupling */ ShowerAlphaPtr alphaQED_; /** * Variables for the POWHEG style corrections */ //@{ /** * The cut off on pt, assuming massless quarks. */ Energy pTmin_; /** * Overestimate for the prefactor */ double preFactor_; /** * ParticleData objects for the partons */ vector partons_; /** * Momenta of the leading-order partons */ vector loMomenta_; //@} }; } #endif /* HERWIG_MEee2gZ2ll_H */ diff --git a/MatrixElement/Matchbox/CVolver/ColourFlowBasis.cc b/MatrixElement/Matchbox/CVolver/ColourFlowBasis.cc --- a/MatrixElement/Matchbox/CVolver/ColourFlowBasis.cc +++ b/MatrixElement/Matchbox/CVolver/ColourFlowBasis.cc @@ -1,276 +1,280 @@ // -*- C++ -*- // // ColourFlowBasis.cc is a part of CVolver // Copyright (C) 2013-2017 Simon Platzer, The Herwig Collaboration // // CVolver 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 ColourFlowBasis class. // #include "ColourFlowBasis.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 "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace CVolver; ColourFlowBasis::ColourFlowBasis() {} ColourFlowBasis::~ColourFlowBasis() {} IBPtr ColourFlowBasis::clone() const { return new_ptr(*this); } IBPtr ColourFlowBasis::fullclone() const { return new_ptr(*this); } void ColourFlowBasis::clear() { ColourBasis::clear(); } map > > ColourFlowBasis::basisList(const vector& basisId) const { assert(theCrossings.find(basisId) != theCrossings.end()); const ColourFlowCrossing& crossing = theCrossings.find(basisId)->second; size_t n = crossing.nFlows(); assert(theFlows.find(n) != theFlows.end()); map > > res; const vector& flows = theFlows.find(n)->second; for ( size_t n = 0; n < flows.size(); ++n ) { vector fundamental; vector antiFundamental; for ( size_t k = 0; k < flows[n].nLegs(); ++k ) { fundamental.push_back(crossing.colourLeg(k)); size_t ac = flows[n].antiColour(k); antiFundamental.push_back(crossing.antiColourLeg(ac)); } res[n].push_back(fundamental); res[n].push_back(antiFundamental); } return res; } size_t ColourFlowBasis::prepareBasis(const vector& sub) { useMe(); map,ColourFlowCrossing>::const_iterator cross = theCrossings.find(sub); if ( cross != theCrossings.end() ) return cross->second.nFlows(); ColourFlowCrossing newCrossing(sub,false); theCrossings[sub] = newCrossing; if ( theFlows.find(newCrossing.nFlows()) != theFlows.end() ) return newCrossing.nFlows(); set flows = ColourFlow::allFlows(newCrossing.nFlows()); copy(flows.begin(),flows.end(), back_inserter(theFlows[newCrossing.nFlows()])); return newCrossing.nFlows(); } void ColourFlowBasis::readBasisDetails(const vector& sub) { prepareBasis(sub); } double ColourFlowBasis::scalarProduct(size_t i, size_t j, const vector& abBasis) const { if ( largeN() && i != j ) return 0.; assert(theCrossings.find(abBasis) != theCrossings.end()); size_t n = theCrossings.find(abBasis)->second.nFlows(); assert(theFlows.find(n) != theFlows.end()); const ColourFlow& iflow = theFlows.find(n)->second[i]; const ColourFlow& jflow = theFlows.find(n)->second[j]; return pow(3.,(double)(iflow.scalarProduct(jflow))); } double ColourFlowBasis::tMatrixElement(size_t m, size_t a, size_t b, const vector& aBasis, const vector& bBasis, +#ifndef NDEBUG size_t k, size_t l, +#else + size_t , size_t , +#endif const map& dict ) const { // Check indices k and l assert( k == m ); assert( l == bBasis.size() ); // Check that dict is the standardMap assert( dict.size()+1 == bBasis.size() ); map::const_iterator tmp; for ( size_t ii = 0; ii < bBasis.size(); ii++ ) if ( ii != m ) { tmp = dict.find(ii); assert( tmp != dict.end() ); assert( tmp->second == ii ); } assert(theCrossings.find(bBasis) != theCrossings.end()); const ColourFlowCrossing& bcrossing = theCrossings.find(bBasis)->second; assert(theFlows.find(bcrossing.nFlows()) != theFlows.end()); const ColourFlow& bflow = theFlows.find(bcrossing.nFlows())->second[b]; assert(theCrossings.find(aBasis) != theCrossings.end()); const ColourFlowCrossing& acrossing = theCrossings.find(aBasis)->second; assert(theFlows.find(acrossing.nFlows()) != theFlows.end()); const ColourFlow& aflow = theFlows.find(acrossing.nFlows())->second[a]; size_t bEmitterLine = bBasis[m] == PDT::Colour3 || bBasis[m] == PDT::Colour8 ? bcrossing.colourLine(m) : bcrossing.antiColourLine(m); size_t bSpectatorLine = bBasis[m] == PDT::Colour3 || bBasis[m] == PDT::Colour8 ? bflow.antiColour(bEmitterLine) : bflow.colour(bEmitterLine); size_t aEmitterLine = bBasis[m] == PDT::Colour3 || bBasis[m] == PDT::Colour8 ? acrossing.colourLine(m) : acrossing.antiColourLine(m); size_t aSpectatorLine = bBasis[m] == PDT::Colour3 || bBasis[m] == PDT::Colour8 ? aflow.antiColour(aEmitterLine) : aflow.colour(aEmitterLine); assert(aEmitterLine == bEmitterLine); if ( bBasis[m] == PDT::Colour3 ) { if ( bSpectatorLine != aSpectatorLine ) { return 1./2.; } else { return -1./2./3.; } } if ( bBasis[m] == PDT::Colour3bar ) { if ( bSpectatorLine != aSpectatorLine ) { return -1./2.; } else { return 1./2./3.; } } if ( bBasis[m] == PDT::Colour8 ) { if ( bSpectatorLine != aSpectatorLine ) { return 1.; } else { return -1.; } } return 0.0; } double ColourFlowBasis::sMatrixElement(size_t, size_t, size_t, const vector&, const vector&, size_t, size_t, const map&) const { throw Exception() << "ATTENTION this is missing on the CVolver API" << Exception::runerror; return 0.; } bool ColourFlowBasis::colourConnected(const cPDVector& sub, const vector& basisId, const pair& first, const pair& second, size_t tensor) const { assert(theCrossings.find(basisId) != theCrossings.end()); const ColourFlowCrossing& crossing = theCrossings.find(basisId)->second; // translate process to basis ids map >::const_iterator trans = indexMap().find(sub); assert(trans != indexMap().end()); size_t idColoured = first.second ? second.first : first.first; idColoured = trans->second.find(idColoured)->second; size_t idAntiColoured = first.second ? first.first : second.first; idAntiColoured = trans->second.find(idAntiColoured)->second; size_t colourLine = crossing.colourLine(idColoured); size_t antiColourLine = crossing.antiColourLine(idAntiColoured); size_t n = crossing.nFlows(); assert(theFlows.find(n) != theFlows.end()); const ColourFlow& iflow = theFlows.find(n)->second[tensor]; return antiColourLine == iflow.antiColour(colourLine); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void ColourFlowBasis::persistentOutput(PersistentOStream &) const {} void ColourFlowBasis::persistentInput(PersistentIStream & , int) {} // *** Attention *** The following static variable is needed for the type // description system in ThePEG. Please check that the template arguments // are correct (the class and its base class), and that the constructor // arguments are correct (the class name and the name of the dynamically // loadable library where the class implementation can be found). DescribeClass describeColourFlowBasis("CVolver::ColourFlowBasis", "HwCVolver.so"); void ColourFlowBasis::Init() { static ClassDocumentation documentation ("ColourFlowBasis implements the colour flow basis.", "The colour algebra has been performed using CVolver \\cite{Platzer:2013fha}", "%\\cite{Platzer:2013fha}\n" "\\bibitem{Platzer:2013fha}\n" "S.~Platzer,\n" "``Summming Large-N Towers in Colour Flow Evolution,''\n" "arXiv:1312.2448 [hep-ph].\n" "%%CITATION = ARXIV:1312.2448;%%"); } diff --git a/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h --- a/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h +++ b/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h @@ -1,183 +1,179 @@ // -*- C++ -*- // // FFMassiveInvertedTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2017 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FFMassiveInvertedTildeKinematics_H #define HERWIG_FFMassiveInvertedTildeKinematics_H // // This is the declaration of the FFMassiveInvertedTildeKinematics class. // #include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer, Stephen Webster * * \brief FFMassiveInvertedTildeKinematics inverts the final-final tilde * kinematics. * */ class FFMassiveInvertedTildeKinematics: public Herwig::InvertedTildeKinematics { public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ FFMassiveInvertedTildeKinematics(); /** * The destructor. */ virtual ~FFMassiveInvertedTildeKinematics(); //@} public: /** * Perform the mapping of the tilde kinematics for the * last selected process and store all dimensionless * variables in the subtractionParameters() vector. * Return false, if the calculation of the real * kinematics was impossible for the selected configuration * and true on success. */ virtual bool doMap(const double *); /** * Return the pt associated to the last generated splitting. */ virtual Energy lastPt() const; /** * Return the momentum fraction associated to the last splitting. */ virtual double lastZ() const; /** * Return the upper bound on pt */ virtual Energy ptMax() const; /** * Given a pt, return the boundaries on z * Note that allowing parton masses these bounds may be too loose */ virtual pair zBounds(Energy pt, Energy hardPt = ZERO) const; /** * For generated pt and z, check if this point is * kinematically allowed */ /*virtual*/ bool ptzAllowed(pair ptz, vector* values ) const; /** * Generate pt and z */ virtual pair generatePtZ(double& jac, const double * r, vector* values) const; public: /** * Triangular / Kallen function */ template inline T rootOfKallen (T a, T b, T c) const { return sqrt( a*a + b*b + c*c - 2.*( a*b+a*c+b*c ) ); } // TODO: remove in both /** * stolen from FFMassiveKinematics.h * Perform a rotation on both momenta such that the first one will * point along the (positive) z axis. Rotate back to the original * reference frame by applying rotateUz(returnedVector) to each momentum. */ ThreeVector rotateToZ (Lorentz5Momentum& pTarget, Lorentz5Momentum& p1) { ThreeVector oldAxis = pTarget.vect().unit(); double ct = oldAxis.z(); double st = sqrt( 1.-sqr(ct) ); // cos,sin(theta) double cp = oldAxis.x()/st; double sp = oldAxis.y()/st; // cos,sin(phi) pTarget.setZ( pTarget.vect().mag() ); pTarget.setX( 0.*GeV ); pTarget.setY( 0.*GeV ); Lorentz5Momentum p1old = p1; p1.setX( sp*p1old.x() - cp*p1old.y() ); p1.setY( ct*cp*p1old.x() + ct*sp*p1old.y() - st*p1old.z() ); p1.setZ( st*cp*p1old.x() + st*sp*p1old.y() + ct*p1old.z() ); return oldAxis; } public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ FFMassiveInvertedTildeKinematics & operator=(const FFMassiveInvertedTildeKinematics &) = delete; - /** - * Option to use the full jacobian, including the z->zprime jacobian. - **/ - bool theFullJacobian; }; } #endif /* HERWIG_FFMassiveInvertedTildeKinematics_H */ diff --git a/MatrixElement/Matchbox/Phasespace/PhasespaceHelpers.cc b/MatrixElement/Matchbox/Phasespace/PhasespaceHelpers.cc --- a/MatrixElement/Matchbox/Phasespace/PhasespaceHelpers.cc +++ b/MatrixElement/Matchbox/Phasespace/PhasespaceHelpers.cc @@ -1,571 +1,572 @@ // -*- C++ -*- // // PhasespaceHelpers.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 "PhasespaceHelpers.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/RandomHelpers.h" using namespace Herwig; using namespace Herwig::PhasespaceHelpers; using namespace Herwig::RandomHelpers; Energy PhasespaceInfo::generateMass(tcPDPtr data, const pair& range) { double xlow = sqr(range.first)/sHat; if ( range.first < ZERO ) xlow = -xlow; double xup = sqr(range.second)/sHat; if ( range.second < ZERO ) xup = -xup; double mu = sqr(data->hardProcessMass())/sHat; double gamma = sqr(data->hardProcessWidth())/sHat; if ( gamma < 1e-14 ) gamma = 0.0; if ( M0 != ZERO ) x0 = M0/sqrtSHat; if ( Mc != ZERO ) xc = Mc/sqrtSHat; double r = rnd(); pair event; if ( gamma == 0. ) { if ( mu < xlow || mu > xup ) { if ( abs(xlow-mu) < xc ) xlow = mu; if ( abs(xup-mu) < xc ) xup = mu; } if ( mu < xlow || mu > xup ) { event = generate(inverse(mu,xlow,xup),r); } else { pair pLeft(xlow,xlow < mu-x0 ? mu-x0 : xlow); pair pRight(xup > mu+x0 ? mu+x0 : xup,xup); pair fLeft(pLeft.second < mu-x0 ? mu-x0 : pLeft.second,mu-xc); if ( fLeft.first >= fLeft.second ) fLeft.first = fLeft.second; pair fRight(mu+xc,pRight.first > mu+x0 ? mu+x0 : pRight.first); if ( fRight.first >= fRight.second ) fRight.second = fRight.first; const bool pL= abs( pLeft.first - pLeft.second ) < 1e-14; const bool fL= abs( fLeft.first - fLeft.second ) < 1e-14; const bool fR= abs( fRight.first - fRight.second ) < 1e-14; const bool pR= abs( pRight.first - pRight.second ) < 1e-14; if ( !pL && !fL && !fR && !pR ) { event = generate((piecewise(), inverse(mu,pLeft.first,pLeft.second), match(flat(fLeft.first,fLeft.second))) + match((piecewise(), flat(fRight.first,fRight.second), match(inverse(mu,pRight.first,pRight.second)))), r); } else if ( pL && !fL && !fR && !pR ) { event = generate(flat(fLeft.first,fLeft.second) + match((piecewise(), flat(fRight.first,fRight.second), match(inverse(mu,pRight.first,pRight.second)))), r); } else if ( !pL && !fL && !fR && pR ) { event = generate((piecewise(), inverse(mu,pLeft.first,pLeft.second), match(flat(fLeft.first,fLeft.second))) + match(flat(fRight.first,fRight.second)), r); } else if ( pL && fL && !fR && !pR ) { event = generate((piecewise(),flat(fRight.first,fRight.second), match(inverse(mu,pRight.first,pRight.second))), r); } else if ( !pL && !fL && fR && pR ) { event = generate((piecewise(), inverse(mu,pLeft.first,pLeft.second), match(flat(fLeft.first,fLeft.second))),r); } else if ( pL && !fL && !fR && pR ) { event = generate(flat(fLeft.first,fLeft.second) + match(flat(fRight.first,fRight.second)),r); } else if ( pL && fL && !fR && pR ) { event = generate(flat(fRight.first,fRight.second),r); } else if ( pL && !fL && fR && pR ) { event = generate(flat(fLeft.first,fLeft.second),r); } else if ( pL && fL && fR && pR ) { throw Veto(); } else assert(false); } } else { event = generate(breitWigner(mu,gamma,xlow,xup),r); } if ( abs(event.first) < xc ) throw Veto(); weight *= event.second; Energy res = sqrt(abs(event.first)*sHat); if ( event.first < 0. ) res = -res; return res; } Lorentz5Momentum PhasespaceInfo::generateKt(const Lorentz5Momentum& p1, const Lorentz5Momentum& p2, Energy pt) { double phi = 2.*Constants::pi*rnd(); weight *= 2.*Constants::pi; Lorentz5Momentum P = p1 + p2; Energy2 Q2 = abs(P.m2()); Lorentz5Momentum Q = Lorentz5Momentum(ZERO,ZERO,ZERO,sqrt(Q2),sqrt(Q2)); bool boost = abs((P-Q).vect().mag2()/GeV2) > 1e-8 || abs((P-Q).t()/GeV) > 1e-4; boost &= (P*Q-Q.mass2())/GeV2 > 1e-8; Lorentz5Momentum inFrame1; if ( boost ) inFrame1 = p1 + ((P*p1-Q*p1)/(P*Q-Q.mass2()))*(P-Q); else inFrame1 = p1; Energy ptx = inFrame1.x(); Energy pty = inFrame1.y(); Energy q = 2.*inFrame1.z(); Energy Qp = sqrt(4.*(sqr(ptx)+sqr(pty))+sqr(q)); Energy Qy = sqrt(4.*sqr(pty)+sqr(q)); double cPhi = cos(phi); double sPhi = sqrt(1.-sqr(cPhi)); if ( phi > Constants::pi ) sPhi = -sPhi; Lorentz5Momentum kt; kt.setT(ZERO); kt.setX(pt*Qy*cPhi/Qp); kt.setY(-pt*(4*ptx*pty*cPhi/Qp+q*sPhi)/Qy); kt.setZ(2.*pt*(-ptx*q*cPhi/Qp + pty*sPhi)/Qy); if ( boost ) kt = kt + ((P*kt-Q*kt)/(P*Q-Q.mass2()))*(P-Q); kt.setMass(-pt); kt.rescaleRho(); return kt; } void PhasespaceTree::setup(const Tree2toNDiagram& diag, int pos) { doMirror = false; pair dchildren = diag.children(pos); data = diag.allPartons()[pos]; spacelike = pos < diag.nSpace(); if ( pos == 0 ) externalId = 0; if ( dchildren.first == -1 ) { externalId = diag.externalId(pos); leafs.insert(externalId); return; } children.push_back(PhasespaceTree()); children.back().setup(diag,dchildren.first); children.push_back(PhasespaceTree()); children.back().setup(diag,dchildren.second); if ( !children[0].children.empty() && children[1].children.empty() && !spacelike ) swap(children[0],children[1]); if ( spacelike && !children[0].spacelike ) swap(children[0],children[1]); copy(children[0].leafs.begin(),children[0].leafs.end(), inserter(leafs,leafs.begin())); copy(children[1].leafs.begin(),children[1].leafs.end(), inserter(leafs,leafs.begin())); } void PhasespaceTree::setupMirrored(const Tree2toNDiagram& diag, int pos) { doMirror = true; spacelike = pos < diag.nSpace(); pair dchildren; if (pos != 0 && spacelike) dchildren = {diag.parent(pos), diag.children(diag.parent(pos)).second}; else if ( !spacelike ) dchildren = diag.children(pos); else dchildren = {-1,-1}; data = diag.allPartons()[pos]; if ( pos == diag.nSpace() - 1 ) externalId = 1; if ( dchildren.first == -1 ) { externalId = diag.externalId(pos); leafs.insert(externalId); return; } children.push_back(PhasespaceTree()); children.back().setupMirrored(diag,dchildren.first); children.push_back(PhasespaceTree()); children.back().setupMirrored(diag,dchildren.second); if ( !children[0].children.empty() && children[1].children.empty() && !spacelike ) swap(children[0],children[1]); if ( spacelike && !children[0].spacelike ) { assert (false); } copy(children[0].leafs.begin(),children[0].leafs.end(), inserter(leafs,leafs.begin())); copy(children[1].leafs.begin(),children[1].leafs.end(), inserter(leafs,leafs.begin())); } void PhasespaceTree::print(int in) { for (int i = 0; i != in; i++) cerr << " "; cerr << " |- " << data->PDGName() << " " << externalId << "\n" << flush; if ( !children.empty() ) { children[1].print(in+1); children[0].print(in+int(!spacelike)); } else { cerr << "\n"; } } void PhasespaceTree::init(const vector& meMomenta) { if ( children.empty() ) { massRange.first = meMomenta[externalId].mass(); massRange.second = massRange.first; if ( !doMirror && externalId == 1 ) momentum = meMomenta[1]; if ( doMirror && externalId == 0 ) momentum = meMomenta[0]; momentum.setMass(meMomenta[externalId].mass()); return; } children[0].init(meMomenta); children[1].init(meMomenta); if ( !children[0].spacelike && !children[1].spacelike ) { massRange.first = children[0].massRange.first + children[1].massRange.first; } } void PhasespaceTree::generateKinematics(PhasespaceInfo& info, vector& meMomenta) { if ( !doMirror && externalId == 0 ) { init(meMomenta); Energy2 s = (meMomenta[0]+meMomenta[1]).m2(); double sign = meMomenta[0].z() >= ZERO ? 1. : -1; momentum = Lorentz5Momentum(ZERO,ZERO,sign*sqrt(s)/2.,sqrt(s)/2.,ZERO); backwardMomentum = Lorentz5Momentum(ZERO,ZERO,-sign*sqrt(s)/2.,sqrt(s)/2.,ZERO); } else if ( doMirror && externalId == 1) { init(meMomenta); Energy2 s = (meMomenta[0]+meMomenta[1]).m2(); double sign = meMomenta[0].z() >= ZERO ? 1. : -1; momentum = Lorentz5Momentum(ZERO,ZERO,-sign*sqrt(s)/2.,sqrt(s)/2.,ZERO); backwardMomentum = Lorentz5Momentum(ZERO,ZERO,sign*sqrt(s)/2.,sqrt(s)/2.,ZERO); } if ( children.empty() ) { if ( ( !doMirror && externalId != 1 ) || ( doMirror && externalId !=0 ) ) meMomenta[externalId] = momentum; return; } // s-channel if ( ( !doMirror && externalId == 0 && children[0].externalId == 1 ) || ( doMirror && externalId == 1 && children[0].externalId == 0 ) ) { children[1].momentum = meMomenta[0] + meMomenta[1]; children[1].momentum.setMass(info.sqrtSHat); children[1].momentum.rescaleEnergy(); children[1].generateKinematics(info,meMomenta); return; } if ( !spacelike ) { Energy mij = momentum.mass(); Energy mi,mj; // work out the mass for the first child if ( !children[0].children.empty() ) { Energy sumOthers = ZERO; for ( size_t k = 2; k < meMomenta.size(); ++k ) if ( children[1].leafs.find(k) != children[1].leafs.end() ) sumOthers += meMomenta[k].mass(); children[0].massRange.second = momentum.mass() - sumOthers; if ( children[0].massRange.second < children[0].massRange.first ) throw Veto(); if ( children[0].massRange.second > momentum.mass() ) throw Veto(); mi = info.generateMass(children[0].data,children[0].massRange); children[0].momentum.setMass(mi); } else { mi = children[0].momentum.mass(); } // work out the mass for the second child if ( !children[1].children.empty() ) { children[1].massRange.second = momentum.mass()-children[0].momentum.mass(); if ( children[1].massRange.second < children[1].massRange.first ) throw Veto(); mj = info.generateMass(children[1].data,children[1].massRange); children[1].momentum.setMass(mj); } else { mj = children[1].momentum.mass(); } Energy2 mij2 = sqr(mij); Energy2 mi2 = sqr(mi); Energy2 mj2 = sqr(mj); // perform the decay Energy4 lambda2 = sqr(mij2-mi2-mj2)-4.*mi2*mj2; if ( lambda2 <= ZERO ) throw Veto(); Energy2 lambda = sqrt(lambda2); double phi = 2.*Constants::pi*info.rnd(); double cosPhi = cos(phi); double sinPhi = sqrt(1.-sqr(cosPhi)); if ( phi > Constants::pi ) sinPhi = -sinPhi; info.weight *= Constants::pi*lambda/(2.*mij2); double cosTheta = 2.*info.rnd() - 1.; double sinTheta = sqrt(1.-sqr(cosTheta)); Energy p = lambda/(2.*mij); children[0].momentum.setX(p*cosPhi*sinTheta); children[0].momentum.setY(p*sinPhi*sinTheta); children[0].momentum.setZ(p*cosTheta); children[0].momentum.rescaleEnergy(); if ( momentum.m2() <= ZERO ) throw Veto(); Boost out = momentum.boostVector(); if ( out.mag2() > Constants::epsilon ) { children[0].momentum.boost(out); } children[1].momentum = momentum - children[0].momentum; children[1].momentum.setMass(mj); children[1].momentum.rescaleEnergy(); // go on with next branchings children[0].generateKinematics(info,meMomenta); children[1].generateKinematics(info,meMomenta); return; } // get the minimum mass of the `W' system Energy Wmin = ZERO; PhasespaceTree* current = &children[0]; while ( !(current->children.empty()) ) { Wmin += current->children[1].massRange.first; current = &(current->children[0]); } // get the CM energy avaialble Energy2 s = (momentum+backwardMomentum).m2(); if ( s <= ZERO ) throw Veto(); // generate a mass for the timelike child Energy mi; if ( !children[1].children.empty() ) { children[1].massRange.second = sqrt(s)-Wmin; if ( children[1].massRange.second < children[1].massRange.first ) throw Veto(); mi = info.generateMass(children[1].data,children[1].massRange); children[1].momentum.setMass(mi); } else { mi = children[1].momentum.mass(); } Energy2 mi2 = sqr(mi); // wether or not this is the last 2->2 scatter bool lastScatter = children[0].children[0].children.empty(); // `W' mass relevant for the other boundaries Energy MW = Wmin; // generate a mass for second outgoing leg, if needed if ( lastScatter ) if ( !children[0].children[1].children.empty() ) { // get the maximum `W' mass Energy Wmax = sqrt(s)-children[1].momentum.mass(); children[0].children[1].massRange.second = Wmax; if ( children[0].children[1].massRange.second < children[0].children[1].massRange.first ) throw Veto(); MW = info.generateMass(children[0].children[1].data, children[0].children[1].massRange); children[0].children[1].momentum.setMass(MW); } Energy2 MW2 = sqr(MW); Energy ma = momentum.mass(); Energy2 ma2 = sqr(ma); if ( ma < ZERO ) ma2 = -ma2; Energy mb = backwardMomentum.mass(); Energy2 mb2 = sqr(mb); if ( mb < ZERO ) mb2 = -mb2; // pick the ys variable Energy2 ys = ZERO; if ( !lastScatter ) { ys = info.rnd()*(sqr(sqrt(s)-mi)-MW2); info.weight *= (sqr(sqrt(s)-mi)-MW2)/info.sHat; } Energy4 lambda2 = sqr(s-ma2-mb2)-4.*ma2*mb2; if ( lambda2 <= ZERO ) { throw Veto(); } Energy2 lambda = sqrt(lambda2); info.weight *= info.sHat/(4.*lambda); // get the boundaries on the momentum transfer Energy4 rho2 = sqr(s-ys-MW2-mi2)-4.*mi2*(ys+MW2); if ( rho2 < ZERO ) throw Veto(); Energy2 rho = sqrt(rho2); Energy4 tau2 = ys*(ma2-mb2+s) - sqr(s)+s*(ma2+mb2+mi2+MW2)-(mi2-MW2)*(ma2-mb2); pair tBounds ((tau2-rho*lambda)/(2.*s),(tau2+rho*lambda)/(2.*s)); children[0].massRange.first = sqrt(abs(tBounds.first)); if ( tBounds.first < ZERO ) children[0].massRange.first = -children[0].massRange.first; children[0].massRange.second = sqrt(abs(tBounds.second)); if ( tBounds.second < ZERO ) children[0].massRange.second = -children[0].massRange.second; // generate a momentum transfer Energy mai = info.generateMass(children[0].data,children[0].massRange); children[0].momentum.setMass(mai); Energy2 t = sqr(mai); if ( mai < ZERO ) t = -t; Energy2 u = -s -t + ys + ma2 + mb2 + mi2 + MW2; Energy2 st = s - ma2 - mb2; Energy2 tt = t - mi2 - ma2; Energy2 ut = u - mi2 - mb2; // get the timelike momentum double xa = (-st*ut+2.*mb2*tt)/lambda2; double xb = (-st*tt+2.*ma2*ut)/lambda2; Energy2 pt2 = (st*tt*ut-ma2*sqr(ut)-mb2*sqr(tt)-mi2*sqr(st)+4.*ma2*mb2*mi2)/lambda2; if ( pt2 < ZERO ) throw Veto(); Energy pt = sqrt(pt2); children[1].momentum = xa*momentum + xb*backwardMomentum + info.generateKt(momentum,backwardMomentum,pt); children[1].momentum.setMass(mi); children[1].momentum.rescaleEnergy(); children[0].momentum = momentum - children[1].momentum; children[0].momentum.setMass(mai); bool changeSign = false; if ( children[0].momentum.t() < ZERO && mai > ZERO ) changeSign = true; if ( mai < ZERO ) children[0].momentum.rescaleRho(); else children[0].momentum.rescaleEnergy(); if ( changeSign ) children[0].momentum.setT(-children[0].momentum.t()); children[1].generateKinematics(info,meMomenta); if ( !lastScatter ) { + children[0].backwardMomentum = backwardMomentum; children[0].generateKinematics(info,meMomenta); } else { children[0].children[1].momentum = backwardMomentum + children[0].momentum; children[0].children[1].momentum.setMass(MW); children[0].children[1].momentum.rescaleEnergy(); children[0].children[1].generateKinematics(info,meMomenta); } } void PhasespaceTree::put(PersistentOStream& os) const { os << children.size(); if ( !children.empty() ) { children[0].put(os); children[1].put(os); } os << data << externalId << leafs << spacelike << doMirror; } void PhasespaceTree::get(PersistentIStream& is) { size_t nc; is >> nc; assert(nc == 0 || nc == 2); if ( nc == 2 ) { children.resize(2,PhasespaceTree()); children[0].get(is); children[1].get(is); } is >> data >> externalId >> leafs >> spacelike >> doMirror; } diff --git a/MatrixElement/Matchbox/Utility/DensityOperator.cc b/MatrixElement/Matchbox/Utility/DensityOperator.cc --- a/MatrixElement/Matchbox/Utility/DensityOperator.cc +++ b/MatrixElement/Matchbox/Utility/DensityOperator.cc @@ -1,479 +1,479 @@ // -*- C++ -*- // // DensityOperator.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2007 The Herwig Collaboration // // Herwig is licenced under version 2 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the DensityOperator class. // #include "DensityOperator.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "Herwig/MatrixElement/Matchbox/Utility/MatchboxXCombData.h" #include "Herwig/MatrixElement/Matchbox/Base/MatchboxMEBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; DensityOperator::DensityOperator() : Nc(3.0), TR(0.5) { } DensityOperator::~DensityOperator() {} void DensityOperator::clear() { theCorrelatorMap.clear(); } // Prepare density operator if not done before void DensityOperator::prepare(const cPDVector& mePartonData) { // Take parton data and create key of type 33bar888 to use as key for basis vector mePartonDataColoured = theColourBasis->normalOrderMap(mePartonData); if( theDensityOperatorMap.count( mePartonDataColoured ) == 0 ){ // Get basis dimension size_t dim = theColourBasis->prepare( mePartonData, false ); // Allocate space for density matrix theDensityOperatorMap.insert(make_pair(mePartonDataColoured,matrix (dim,dim))); } } // Fill the density matrix for the first time void DensityOperator::fill(const Ptr::ptr MBXCombPtr, const cPDVector& partons, const vector& momenta){ // Map from helicity structure to amplitude vector in the color basis const map,CVector>& amplitudeMap = MBXCombPtr->lastAmplitudes(); const cPDVector& mePartonData = MBXCombPtr->mePartonData(); // Get the dimension of the basis for the indexChange method size_t dim = theColourBasis->prepare(mePartonData,false); // Normal order partons according to ColourBasis const vector mePartonDataColoured = theColourBasis->normalOrderMap(mePartonData); // Get the colour basis to colour basis map for this hard subprocess map >::iterator cb2cbit = theColourBasisToColourBasisMap.find(mePartonData); // Fill the map with this hard subprocess if it doesn't have it yet if ( cb2cbit == theColourBasisToColourBasisMap.end() ) { // Get the index map for the partons as they are ordered in the MatchboxXComb // object const map& mbIndexMap = theColourBasis->indexMap().at(mePartonData); // Get the index map for the partons as they are ordered // in the shower. // Use prepare, as it might not have been done for this order of the partons theColourBasis->prepare(partons,false); const map& showerIndexMap = theColourBasis->indexMap().at(partons); // ensure the maps are of the same size assert( mbIndexMap.size() == showerIndexMap.size() ); // Loop over both sets of partons to determine how the order between them // differs, then translate the index to the colour basis and put the // key-value pair into the map map cb2cbMap; // Get the momenta for comparison const vector& meMomenta = MBXCombPtr->matchboxME()->lastMEMomenta(); // Make sure there's the same number of momenta in both vectors assert( momenta.size() == meMomenta.size() ); bool done; // Boost the momenta to the same frame const vector momentaCM = boostToRestFrame(momenta); for ( size_t i = 0; i < momentaCM.size(); i++ ) { // The cb2cb map is intended to translate how the indices // are different in the colour basis due to the different // orderings of the partons, so it should only bother // with coloured particles. if ( partons[i]->coloured() ) { done = false; for ( size_t j = 0; j < meMomenta.size(); j++ ) { if ( !done ) { if ( compareMomentum(momentaCM[i],meMomenta[j]) ) { cb2cbMap[mbIndexMap.at(i)] = showerIndexMap.at(j); done = true; } } } } } // Make sure all momenta have been identified assert( cb2cbMap.size() == mePartonDataColoured.size() ); // Add the map to the cache theColourBasisToColourBasisMap[mePartonData] = cb2cbMap; // Get the iterator cb2cbit = theColourBasisToColourBasisMap.find(mePartonData); } // With the cb2cb index map we can create the basis vector index map const map vectorMap = theColourBasis->indexChange(mePartonDataColoured, dim,cb2cbit->second); // Prepare density operator (allocate) for set of particles prepare(mePartonData); // Check that density operator (place holder for) exist in density operator map map,matrix >::iterator dOit = theDensityOperatorMap.find(mePartonDataColoured); assert(dOit != theDensityOperatorMap.end()); // Initialize the density operator matrix& densOp = dOit->second; for(unsigned int i = 0; i < (amplitudeMap.begin()->second).size(); i++){ for(unsigned int j = 0; j < (amplitudeMap.begin()->second).size(); j++){ densOp (i,j) = 0; } } // Fill the density operator, ok to sum over helicities since the density operator // exist at the probability level CVector amplitude; for ( map,CVector>::const_iterator itHel = amplitudeMap.begin(); itHel != amplitudeMap.end(); itHel++ ) { amplitude = itHel->second; for ( unsigned int i = 0; i < amplitude.size(); i++ ) { for ( unsigned int j = 0; j < amplitude.size(); j++ ) { // vectorMap is used such that densOp is filled according to the // basis order defined by the input cPDVector partons. densOp (vectorMap.at(i),vectorMap.at(j)) += amplitude(i)*std::conj(amplitude(j)); } } } // Colour conservation check colourConservation(mePartonData); } // Update density matrix after emitting or splitting a gluon // The emissionsMap argument contains the relation of the indices in the smaller (before) // and larger basis (after). the first 3-tuple contains the indices // (emitter before, emitter after, emitted parton) // The map contains the old and new indices of all other partons (not involved) void DensityOperator::evolve(const map,Complex>& Vijk, const cPDVector& before, const cPDVector& after, const map,map >& emissionsMap, const bool splitAGluon, const bool initialGluonSplitting) { size_t dimBefore = theColourBasis->prepare( before, false ); size_t dimAfter = theColourBasis->prepare( after, false ); vector beforeColoured = theColourBasis->normalOrderMap(before); vector afterColoured = theColourBasis->normalOrderMap(after); const map,matrix >::iterator dOit = theDensityOperatorMap.find(beforeColoured); assert(dOit != theDensityOperatorMap.end()); const matrix& densOpBefore = dOit->second; prepare(after); matrix& densOpAfter = theDensityOperatorMap[afterColoured]; for(size_t i = 0; i < densOpAfter.size1(); i++){ for(size_t j = 0; j < densOpAfter.size2(); j++){ densOpAfter(i,j) = 0; } } compressed_matrix Tij; matrix TijMn (dimAfter,dimBefore); compressed_matrix Tk; matrix TijMnTkdagger (dimAfter,dimAfter); Complex V; // Compensate for sign from updated density matrix // TODO Check signs again double sign = -1.0; if ( splitAGluon ) sign = 1.0; // Loop over emitter legs ij and recoil legs k and add the contribution, // for Vijk is assumed to contain the factor 4*pi*\alpha_s/pi.pj typedef map,map > dictMap; int ij,k; // Loop over emitters for(dictMap::const_iterator ijit = emissionsMap.begin(); ijit != emissionsMap.end(); ijit++) { // get first element in 3-tuple, i.e., emitter before ij = std::get<0>(ijit->first); assert(before[ij]->coloured()); // Get rectangular matrices T_{ij} or S_{ij} taking us from the // smaller to the larger basis depending on // the involved particles before and after, the emitter index before ij, // the emitter after and the emitted parton index int i=std::get<1>(ijit->first); // emitter after int j=std::get<2>(ijit->first);// emitted parton Tij = theColourBasis->charge(before,after, ij,i,j,ijit->second).first; TijMn = prodSparseDense(Tij,densOpBefore); // Loop over spectators for(dictMap::const_iterator kit = emissionsMap.begin(); kit != emissionsMap.end(); kit++) { k = std::get<0>(kit->first); assert(before[k]->coloured()); // Standard case of gluon radiation if ( ijit != kit || splitAGluon || initialGluonSplitting ) { int k_after=std::get<1>(kit->first); // For color structure k now has role of emitter int k_emission= std::get<2>(kit->first); // Emitted parton index Tk = theColourBasis->charge(before,after, k, k_after, k_emission, kit->second).first; TijMnTkdagger = prodDenseSparse(TijMn,Tk); // sign == -1.0 if it isn't a gluon splitting into a qqbar pair V = sign*(1.0/colourNorm(before[ij]))* Vijk.at(make_pair(ij,k)); densOpAfter += V*TijMnTkdagger; } } } // Check that the density operator does not vanish assert( theColourBasis->me2(after,densOpAfter) != 0.0 ); colourConservation(after); } // The 3-tuple contains (emitter index, spectator index, emission pid) double DensityOperator::colourMatrixElementCorrection(const std::tuple& ikemission, const cPDVector& particles) { const int i = std::get<0>(ikemission); const int k = std::get<1>(ikemission); - const long emissionID = std::get<2>(ikemission); + //const long emissionID = std::get<2>(ikemission); // Get the density operator // normal order particles as in ColourBasis vector particlesColoured = theColourBasis->normalOrderMap(particles); // ... and find corresponding density operator const map,matrix >::iterator particlesit = theDensityOperatorMap.find(particlesColoured); assert(particlesit != theDensityOperatorMap.end()); const matrix& densOp = particlesit->second; double Ti2 = colourNorm(particles[i]); // Emitter-spectator pair const pair ik = make_pair(i,k); // Create key for color matrix element correction map pair,pair > particlesAndLegs = make_pair(particlesColoured,ik); // Result double res = 0; // Check if it has already been calculated // TODO: move this check earlier (we only need particlesColoured to check if it has been // calculated). // Check for color matrix element associated with key, and calculate if not done const map,pair >,double >::const_iterator corrit = theCorrelatorMap.find(particlesAndLegs); if ( corrit == theCorrelatorMap.end() ) { double corrME2 = theColourBasis->colourCorrelatedME2(ik,particles,densOp); double me2 = theColourBasis->me2(particles,densOp); res = -(1/Ti2)*corrME2/me2; if ( particles[i]->id() == ParticleID::g ) res *= 2.; theCorrelatorMap.insert(make_pair(particlesAndLegs,res)); } else { res = corrit->second; } return res; } double DensityOperator::colourNorm(const cPDPtr particle) { if ( particle->id() == ParticleID::g ) { return Nc; //is 3.0 for Nc = 3, TR = 1/2 } else if ( particle->iColour() == PDT::Colour3 || particle->iColour() == PDT::Colour3bar ) { return TR*(Nc*Nc-1.)/Nc; // is 4.0/3.0 for Nc = 3, TR = 1/2 } else { throw Exception() << "Colour matrix element corrections only work " << "on quark and gluon legs. " << Exception::runerror; } } void DensityOperator::colourConservation(const cPDVector& particles) { // To contain (emitter, spectator, emission pid) std::tuple ikemission; // Normal order particles as defined in ColourBasis const vector particlesColoured = theColourBasis->normalOrderMap(particles); vector sum(particlesColoured.size(),0.0); size_t iterm = 0; // To compensate for the CMEC having a 1/(1+\delta(i is gluon)) factor // in the splitting kernel double gluonFactor = 1.0; // Loop over "emitters" to check color conservation for for ( size_t i = 0; i < particles.size(); i++ ) { if ( particles[i]->coloured() ) { for ( size_t k = 0; k < particles.size(); k++ ) { if ( particles[k]->coloured() && i != k ) { ikemission = std::make_tuple(i,k,ParticleID::g); if ( particles[i]->id() != ParticleID::g ) { gluonFactor = 1.0; } else { gluonFactor = 1./2.; } sum[iterm] += gluonFactor*colourMatrixElementCorrection(ikemission,particles); } } iterm++; } } for ( size_t i = 0; i < sum.size(); i++ ) assert( std::abs(sum[i]-1.0) < pow(10.0,-10.0)); } matrix DensityOperator::prodSparseDense(const compressed_matrix& Tij, const matrix& Mn){ // Dimension before emission size_t dimBefore = Tij.size2(); // Dimension after emission size_t dimAfter = Tij.size1(); //Check matrix dimensions assert( dimBefore == Mn.size1() ); // Allocate memory for the matrix matrix TijMn (dimAfter,dimBefore,0); // Use iterators for the compressed matrix to iterate only over the non-zero // elements. size_t ii; size_t jj; for ( compressed_matrix::const_iterator1 it1 = Tij.begin1(); it1 != Tij.end1(); it1++ ) { for ( compressed_matrix::const_iterator2 it2 = it1.begin(); it2 != it1.end(); it2++ ) { ii = it2.index1(); jj = it2.index2(); for ( size_t kk = 0; kk < dimBefore; kk++ ) { // *it2 is Tij(ii,jj) TijMn(ii,kk) += (*it2)*Mn(jj,kk); } } } return TijMn; } matrix DensityOperator::prodDenseSparse(const matrix& TijMn, const compressed_matrix& Tk){ // The compressed matrix comes from the charge method, do not transpose yet // Dimension after emission size_t dimAfter = Tk.size1();//Since this method returns TijMn*Tk^\dagger //Check matrix dimensions assert( TijMn.size2() == Tk.size2() ); // Allocate memory for the matrix matrix TijMnTkdagger (dimAfter,dimAfter,0); size_t jj; size_t kk; for ( compressed_matrix::const_iterator1 it1 = Tk.begin1(); it1 != Tk.end1(); it1++ ) { for ( compressed_matrix::const_iterator2 it2 = it1.begin(); it2 != it1.end(); it2++ ) { jj = it2.index2();//transposing Tk jj is index2(), not index1() kk = it2.index1();//transposing Tk for ( size_t ii = 0; ii < dimAfter; ii++ ) { // *it2 is Tk(kk,jj) = trans(Tk)(jj,kk) TijMnTkdagger(ii,kk) += TijMn(ii,jj)*(*it2); } } } return TijMnTkdagger; } vector DensityOperator::boostToRestFrame(const vector& momenta) { // We need 2 initial particles assert(momenta.size() >= 2); // The boosted vectors vector vboosted = momenta; // The boost should be to the rest frame of the initial particles Boost b = (momenta[0] + momenta[1]).findBoostToCM(); // Boost all of the vectors for ( size_t i = 0; i < momenta.size(); i++ ) { vboosted[i].boost(b); } return vboosted; } bool DensityOperator::compareMomentum(const Lorentz5Momentum& p, const Lorentz5Momentum& q) { bool equal = true; // Compares two momentum vectors p and q, if they are close enough (defined by the // double eps below) it returns true. This is sufficient to distinguish particles // in the matrix element as we are not interested in the matrix element for extremely // collinear radiation (better described by the parton shower). // Create the difference of the two vectors const Lorentz5Momentum l = p - q; // A relevant size that is guaranteed to be larger than 0 const Energy2 e2 = p.t()*p.t(); // Size of the difference that would be considered equal const double eps = pow(10.,-15.); if ( l.x()*l.x()/e2 > eps ) equal = false; if ( l.y()*l.y()/e2 > eps ) equal = false; if ( l.z()*l.z()/e2 > eps ) equal = false; if ( l.t()*l.t()/e2 > eps ) equal = false; return equal; } IBPtr DensityOperator::clone() const { return new_ptr(*this); } IBPtr DensityOperator::fullclone() const { return new_ptr(*this); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void DensityOperator::persistentOutput(PersistentOStream &) const { // *** ATTENTION *** os << ; // Add all member variable which should be written persistently here. } void DensityOperator::persistentInput(PersistentIStream &, int) { // *** ATTENTION *** is >> ; // Add all member variable which should be read persistently here. } // *** Attention *** The following static variable is needed for the type // description system in ThePEG. Please check that the template arguments // are correct (the class and its base class), and that the constructor // arguments are correct (the class name and the name of the dynamically // loadable library where the class implementation can be found). DescribeClass describeHerwigDensityOperator("Herwig::DensityOperator", "DensityOperator.so"); void DensityOperator::Init() { static ClassDocumentation documentation ("There is no documentation for the DensityOperator class"); } diff --git a/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc b/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc --- a/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc +++ b/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc @@ -1,410 +1,414 @@ // -*- C++ -*- // // SimpleColourBasis.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. // // // This is the implementation of the non-inlined, non-templated member // functions of the SimpleColourBasis class. // #include "SimpleColourBasis.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; SimpleColourBasis::SimpleColourBasis() {} SimpleColourBasis::~SimpleColourBasis() {} IBPtr SimpleColourBasis::clone() const { return new_ptr(*this); } IBPtr SimpleColourBasis::fullclone() const { return new_ptr(*this); } size_t SimpleColourBasis::prepareBasis(const vector& basis) { if ( id33bar.empty() ) makeIds(); if ( basis == id88 || basis == id33bar || basis == id33bar8 ) return 1; if ( basis == id888 || basis == id33bar88 || basis == id33bar33bar ) return 2; if ( basis == id8888 ) return 6; throw Exception() << "SimpleColourBasis::prepareBasis(): Cannot handle colour configuration" << Exception::runerror; return 0; } double SimpleColourBasis::scalarProduct(size_t a, size_t b, const vector& abBasis) const { if ( id33bar.empty() ) makeIds(); double Nc = SM().Nc(); double Nc2 = sqr(Nc); double Nc3 = Nc*Nc2; double Nc4 = sqr(Nc2); double Nc6 = Nc2*Nc4; if ( a > b ) swap(a,b); if ( !largeN() ) { if ( abBasis == id88 ) { return ( Nc2 - 1. )/4.; } if ( abBasis == id33bar ) { return Nc; } if ( abBasis == id888 ) { if ( a == b ) return ( Nc4 - 3.*Nc2 + 2. )/(8.*Nc); return -( Nc2 - 1. )/(4.*Nc); } if ( abBasis == id33bar8 ) { return ( Nc2 - 1. )/2.; } if ( abBasis == id8888 ) { if ( a == b ) return ( Nc6 - 4.*Nc4 + 6.*Nc2 - 3. )/(16.*Nc2); if ( ( a == 0 && b == 1 ) || ( a == 2 && b == 3 ) || ( a == 4 && b == 5 ) ) return ( Nc4 + 2.*Nc2 - 3. )/(16.*Nc2); return -( Nc2 - 4. + 3./Nc2 )/16.; } if ( abBasis == id33bar88 ) { if ( a == b ) return ( Nc4 - 2.*Nc2 + 1 )/(4.*Nc); return -( Nc2 - 1. )/(4.*Nc); } if ( abBasis == id33bar33bar ) { if ( a == b ) return Nc2; return Nc; } } else { if ( a != b ) return 0.; if ( abBasis == id88 ) { return Nc2/4.; } if ( abBasis == id33bar ) { return Nc; } if ( abBasis == id888 ) { return Nc3/8.; } if ( abBasis == id33bar8 ) { return Nc2/2.; } if ( abBasis == id8888 ) { return Nc4/16.; } if ( abBasis == id33bar88 ) { return Nc3/4.; } if ( abBasis == id33bar33bar ) { return Nc2; } } throw Exception() << "SimpleColourBasis::scalarProduct(): Cannot handle colour configuration" << Exception::runerror; } double SimpleColourBasis::tMatrixElement(size_t i, size_t a, size_t b, const vector&, const vector& bBasis, +#ifndef NDEBUG size_t k, size_t l, +#else + size_t , size_t , +#endif const map& dict) const { // Check indices k and l assert( k == i ); assert( l == bBasis.size() ); // Check that dict is the standardMap assert( dict.size()+1 == bBasis.size() ); map::const_iterator tmp; for ( size_t ii = 0; ii < bBasis.size(); ii++ ) if ( ii != i ) { tmp = dict.find(ii); assert( tmp != dict.end() ); assert( tmp->second == ii ); } if ( id33bar.empty() ) makeIds(); if ( bBasis == id88 ) { if ( i == 0 ) return a == 0 ? -1. : 1.; else return a == 0 ? 1. : -1.; } if ( bBasis == id33bar ) { return i == 0 ? 1. : -1.; } if ( bBasis == id888 ) { if ( i == 0 ) { if ( a == 3 && b == 0 ) return 1.; if ( a == 0 && b == 0 ) return -1.; if ( a == 1 && b == 1 ) return 1.; if ( a == 2 && b == 1 ) return -1.; } if ( i == 1 ) { if ( a == 4 && b == 0 ) return 1.; if ( a == 3 && b == 0 ) return -1.; if ( a == 2 && b == 1 ) return 1.; if ( a == 5 && b == 1 ) return -1.; } if ( i == 2 ) { if ( a == 0 && b == 0 ) return 1.; if ( a == 4 && b == 0 ) return -1.; if ( a == 5 && b == 1 ) return 1.; if ( a == 1 && b == 1 ) return -1.; } return 0.; } if ( bBasis == id33bar8 ) { if ( i == 0 ) return a == 1 ? 1. : 0.; if ( i == 1 ) return a == 0 ? -1. : 0.; if ( i == 2 ) return a == 0 ? 1. : -1.; } throw Exception() << "SimpleColourBasis::tMatrixElement(): Cannot handle colour configuration" << Exception::runerror; return 0.; } bool SimpleColourBasis::colourConnected(const cPDVector& sub, const vector& basis, const pair& i, const pair& j, size_t a) const { if ( id33bar.empty() ) makeIds(); // translate process to basis ids map >::const_iterator trans = indexMap().find(sub); assert(trans != indexMap().end()); int idColoured = i.second ? j.first : i.first; idColoured = trans->second.find(idColoured)->second; int idAntiColoured = i.second ? i.first : j.first; idAntiColoured = trans->second.find(idAntiColoured)->second; if ( basis == id88 ) { return ( idColoured == 0 && idAntiColoured == 1 ) || ( idColoured == 1 && idAntiColoured == 0 ); } if ( basis == id33bar ) { return idColoured == 0 && idAntiColoured == 1; } if ( basis == id888 ) { if ( a == 0 ) return ( idColoured == 0 && idAntiColoured == 1 ) || ( idColoured == 1 && idAntiColoured == 2 ) || ( idColoured == 2 && idAntiColoured == 0 ); if ( a == 1 ) return ( idColoured == 0 && idAntiColoured == 2 ) || ( idColoured == 2 && idAntiColoured == 1 ) || ( idColoured == 1 && idAntiColoured == 0 ); } if ( basis == id33bar8 ) { return ( idColoured == 0 && idAntiColoured == 2 ) || ( idColoured == 2 && idAntiColoured == 1 ); } if ( basis == id8888 ) { if ( a == 0 ) return ( idColoured == 0 && idAntiColoured == 1 ) || ( idColoured == 1 && idAntiColoured == 2 ) || ( idColoured == 2 && idAntiColoured == 3 ) || ( idColoured == 3 && idAntiColoured == 0 ); if ( a == 1 ) return ( idColoured == 0 && idAntiColoured == 3 ) || ( idColoured == 3 && idAntiColoured == 2 ) || ( idColoured == 2 && idAntiColoured == 1 ) || ( idColoured == 1 && idAntiColoured == 0 ); if ( a == 2 ) return ( idColoured == 0 && idAntiColoured == 2 ) || ( idColoured == 2 && idAntiColoured == 1 ) || ( idColoured == 1 && idAntiColoured == 3 ) || ( idColoured == 3 && idAntiColoured == 0 ); if ( a == 3 ) return ( idColoured == 0 && idAntiColoured == 3 ) || ( idColoured == 3 && idAntiColoured == 1 ) || ( idColoured == 1 && idAntiColoured == 2 ) || ( idColoured == 2 && idAntiColoured == 0 ); if ( a == 4 ) return ( idColoured == 0 && idAntiColoured == 1 ) || ( idColoured == 1 && idAntiColoured == 3 ) || ( idColoured == 3 && idAntiColoured == 2 ) || ( idColoured == 2 && idAntiColoured == 0 ); if ( a == 5 ) return ( idColoured == 0 && idAntiColoured == 2 ) || ( idColoured == 2 && idAntiColoured == 3 ) || ( idColoured == 3 && idAntiColoured == 1 ) || ( idColoured == 1 && idAntiColoured == 0 ); } if ( basis == id33bar88 ) { if ( a == 0 ) return ( idColoured == 0 && idAntiColoured == 2 ) || ( idColoured == 2 && idAntiColoured == 3 ) || ( idColoured == 3 && idAntiColoured == 1 ); if ( a == 1 ) return ( idColoured == 0 && idAntiColoured == 3 ) || ( idColoured == 3 && idAntiColoured == 2 ) || ( idColoured == 2 && idAntiColoured == 1 ); } if ( basis == id33bar33bar ) { if ( a == 0 ) return ( idColoured == 0 && idAntiColoured == 1 ) || ( idColoured == 2 && idAntiColoured == 3 ); if ( a == 1 ) return ( idColoured == 0 && idAntiColoured == 3 ) || ( idColoured == 2 && idAntiColoured == 1 ); } return false; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void SimpleColourBasis::makeIds() const { id88.push_back(PDT::Colour8); id88.push_back(PDT::Colour8); id33bar.push_back(PDT::Colour3); id33bar.push_back(PDT::Colour3bar); id888.push_back(PDT::Colour8); id888.push_back(PDT::Colour8); id888.push_back(PDT::Colour8); id33bar8.push_back(PDT::Colour3); id33bar8.push_back(PDT::Colour3bar); id33bar8.push_back(PDT::Colour8); id8888.push_back(PDT::Colour8); id8888.push_back(PDT::Colour8); id8888.push_back(PDT::Colour8); id8888.push_back(PDT::Colour8); id33bar88.push_back(PDT::Colour3); id33bar88.push_back(PDT::Colour3bar); id33bar88.push_back(PDT::Colour8); id33bar88.push_back(PDT::Colour8); id33bar33bar.push_back(PDT::Colour3); id33bar33bar.push_back(PDT::Colour3bar); id33bar33bar.push_back(PDT::Colour3); id33bar33bar.push_back(PDT::Colour3bar); } void SimpleColourBasis::persistentOutput(PersistentOStream &) const {} void SimpleColourBasis::persistentInput(PersistentIStream &, int) {} // *** Attention *** The following static variable is needed for the type // description system in ThePEG. Please check that the template arguments // are correct (the class and its base class), and that the constructor // arguments are correct (the class name and the name of the dynamically // loadable library where the class implementation can be found). DescribeClass describeHerwigSimpleColourBasis("Herwig::SimpleColourBasis", "Herwig.so"); void SimpleColourBasis::Init() { static ClassDocumentation documentation ("SimpleColourBasis implements the colour algebra needed for " "electroweak boson and electroweak boson + jet production at NLO. It mainly " "serves as an example for the general ColourBasis interface."); } diff --git a/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc b/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc --- a/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc +++ b/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc @@ -1,2878 +1,2882 @@ // -*- C++ -*- // // SimpleColourBasis2.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. // // // This is the implementation of the non-inlined, non-templated member // functions of the SimpleColourBasis2 class. // #include "SimpleColourBasis2.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; SimpleColourBasis2::SimpleColourBasis2() {} SimpleColourBasis2::~SimpleColourBasis2() {} IBPtr SimpleColourBasis2::clone() const { return new_ptr(*this); } IBPtr SimpleColourBasis2::fullclone() const { return new_ptr(*this); } size_t SimpleColourBasis2::prepareBasis(const vector& basis) { if ( id33bar.empty() ) makeIds(); if ( basis == id88 ) { return 1; } if ( basis == id33bar ) { return 1; } if ( basis == id888 ) { return 2; } if ( basis == id33bar8 ) { return 1; } if ( basis == id8888 ) { return 9; } if ( basis == id33bar88 ) { return 3; } if ( basis == id33bar33bar ) { return 2; } if ( basis == id88888 ) { return 44; } if ( basis == id33bar888 ) { return 11; } if ( basis == id33bar33bar8 ) { return 4; } throw Exception() << "SimpleColourBasis2::prepareBasis(): Cannot handle colour configuration" << Exception::runerror; return 0; } double SimpleColourBasis2::scalarProduct(size_t a, size_t b, const vector& basis) const { if ( id33bar.empty() ) makeIds(); double Nc = SM().Nc(); double Nc2 = sqr(Nc); double Nc3 = Nc*Nc2; double Nc4 = sqr(Nc2); double Nc5 = Nc*Nc4; double Nc6 = Nc2*Nc4; double Nc8 = Nc2*Nc6; if ( a > b ) swap(a,b); if ( !largeN() ) { if ( basis == id88 ) { if( a == 0 && b == 0 ) return (-1 + Nc2)/4.; } if ( basis == id33bar ) { if( a == 0 && b == 0 ) return Nc; } if ( basis == id888 ) { if( ( a == 0 && b == 0 ) || ( a == 1 && b == 1 ) ) return (2 - 3*Nc2 + Nc4)/(8.*Nc); if( ( a == 0 ) && ( b == 1 ) ) return -(-1 + Nc2)/(4.*Nc); } if ( basis == id33bar8 ) { if( a == 0 && b == 0 ) return (-1 + Nc2)/2.; } if ( basis == id8888 ) { if( ( a == 0 && b == 0 ) || ( a == 1 && b == 1 ) || ( a == 2 && b == 2 ) ) return sqr(-1 + Nc2)/16.; if( ( a == 0 && b == 1 ) || ( a == 0 && b == 2 ) || ( a == 1 && b == 2 ) ) return (-1 + Nc2)/16.; if( ( a == 0 && b == 3 ) || ( a == 0 && b == 5 ) || ( a == 0 && b == 7 ) || ( a == 0 && b == 8 ) || ( a == 1 && b == 4 ) || ( a == 1 && b == 5 ) || ( a == 1 && b == 6 ) || ( a == 1 && b == 7 ) || ( a == 2 && b == 3 ) || ( a == 2 && b == 4 ) || ( a == 2 && b == 6 ) || ( a == 2 && b == 8 ) ) return sqr(-1 + Nc2)/(16.*Nc); if( ( a == 0 && b == 4 ) || ( a == 0 && b == 6 ) || ( a == 1 && b == 3 ) || ( a == 1 && b == 8 ) || ( a == 2 && b == 5 ) || ( a == 2 && b == 7 ) ) return -(-1 + Nc2)/(16.*Nc); if( ( a == 3 && b == 3 ) || ( a == 4 && b == 4 ) || ( a == 5 && b == 5 ) || ( a == 6 && b == 6 ) || ( a == 7 && b == 7 ) || ( a == 8 && b == 8 ) ) return (-3 + 6*Nc2 - 4*Nc4 + Nc6)/(16.*Nc2); if( ( a == 3 && b == 4 ) || ( a == 3 && b == 5 ) || ( a == 3 && b == 6 ) || ( a == 3 && b == 7 ) || ( a == 4 && b == 5 ) || ( a == 4 && b == 7 ) || ( a == 4 && b == 8 ) || ( a == 5 && b == 6 ) || ( a == 5 && b == 8 ) || ( a == 6 && b == 7 ) || ( a == 6 && b == 8 ) || ( a == 7 && b == 8 ) ) return (4 - 3/Nc2 - Nc2)/16.; if( ( a == 3 && b == 8 ) || ( a == 4 && b == 6 ) || ( a == 5 && b == 7 ) ) return (-3 + 2*Nc2 + Nc4)/(16.*Nc2); } if ( basis == id33bar88 ) { if( a == 0 && b == 0 ) return (Nc*(-1 + Nc2))/4.; if( ( a == 0 && b == 1 ) || ( a == 0 && b == 2 ) ) return (-1 + Nc2)/4.; if( ( a == 1 && b == 1 ) || ( a == 2 && b == 2 ) ) return sqr(-1 + Nc2)/(4.*Nc); if( a == 1 && b == 2 ) return -(-1 + Nc2)/(4.*Nc); } if ( basis == id33bar33bar ) { if( ( a == 0 && b == 0 ) || ( a == 1 && b == 1 ) ) return Nc2; if( a == 0 && b == 1 ) return Nc; } if ( basis == id88888 ) { if( ( a == 0 && b == 0 ) || ( a == 1 && b == 1 ) || ( a == 2 && b == 2 ) || ( a == 3 && b == 3 ) || ( a == 4 && b == 4 ) || ( a == 5 && b == 5 ) || ( a == 6 && b == 6 ) || ( a == 7 && b == 7 ) || ( a == 8 && b == 8 ) || ( a == 9 && b == 9 ) || ( a == 10 && b == 10 ) || ( a == 11 && b == 11 ) || ( a == 12 && b == 12 ) || ( a == 13 && b == 13 ) || ( a == 14 && b == 14 ) || ( a == 15 && b == 15 ) || ( a == 16 && b == 16 ) || ( a == 17 && b == 17 ) || ( a == 18 && b == 18 ) || ( a == 19 && b == 19 ) ) return ((-2 + Nc2)*sqr(-1 + Nc2))/(32.*Nc); if( ( a == 0 && b == 1 ) || ( a == 0 && b == 2 ) || ( a == 0 && b == 7 ) || ( a == 0 && b == 10 ) || ( a == 0 && b == 12 ) || ( a == 0 && b == 13 ) || ( a == 1 && b == 2 ) || ( a == 1 && b == 4 ) || ( a == 1 && b == 11 ) || ( a == 1 && b == 14 ) || ( a == 1 && b == 15 ) || ( a == 2 && b == 5 ) || ( a == 2 && b == 8 ) || ( a == 2 && b == 16 ) || ( a == 2 && b == 17 ) || ( a == 3 && b == 4 ) || ( a == 3 && b == 5 ) || ( a == 3 && b == 6 ) || ( a == 3 && b == 9 ) || ( a == 3 && b == 14 ) || ( a == 3 && b == 16 ) || ( a == 4 && b == 5 ) || ( a == 4 && b == 11 ) || ( a == 4 && b == 12 ) || ( a == 4 && b == 18 ) || ( a == 5 && b == 8 ) || ( a == 5 && b == 13 ) || ( a == 5 && b == 19 ) || ( a == 6 && b == 7 ) || ( a == 6 && b == 8 ) || ( a == 6 && b == 9 ) || ( a == 6 && b == 12 ) || ( a == 6 && b == 17 ) || ( a == 7 && b == 8 ) || ( a == 7 && b == 10 ) || ( a == 7 && b == 14 ) || ( a == 7 && b == 19 ) || ( a == 8 && b == 15 ) || ( a == 8 && b == 18 ) || ( a == 9 && b == 10 ) || ( a == 9 && b == 11 ) || ( a == 9 && b == 13 ) || ( a == 9 && b == 15 ) || ( a == 10 && b == 11 ) || ( a == 10 && b == 16 ) || ( a == 10 && b == 18 ) || ( a == 11 && b == 17 ) || ( a == 11 && b == 19 ) || ( a == 12 && b == 13 ) || ( a == 12 && b == 17 ) || ( a == 12 && b == 18 ) || ( a == 13 && b == 15 ) || ( a == 13 && b == 19 ) || ( a == 14 && b == 15 ) || ( a == 14 && b == 16 ) || ( a == 14 && b == 19 ) || ( a == 15 && b == 18 ) || ( a == 16 && b == 17 ) || ( a == 16 && b == 18 ) || ( a == 17 && b == 19 ) ) return (2 - 3*Nc2 + Nc4)/(32.*Nc); if( ( a == 0 && b == 3 ) || ( a == 1 && b == 6 ) || ( a == 2 && b == 9 ) || ( a == 4 && b == 7 ) || ( a == 5 && b == 10 ) || ( a == 8 && b == 11 ) || ( a == 12 && b == 14 ) || ( a == 13 && b == 16 ) || ( a == 15 && b == 17 ) || ( a == 18 && b == 19 ) ) return -sqr(-1 + Nc2)/(16.*Nc); if( ( a == 0 && b == 4 ) || ( a == 0 && b == 5 ) || ( a == 0 && b == 6 ) || ( a == 0 && b == 9 ) || ( a == 0 && b == 14 ) || ( a == 0 && b == 16 ) || ( a == 1 && b == 3 ) || ( a == 1 && b == 7 ) || ( a == 1 && b == 8 ) || ( a == 1 && b == 9 ) || ( a == 1 && b == 12 ) || ( a == 1 && b == 17 ) || ( a == 2 && b == 3 ) || ( a == 2 && b == 6 ) || ( a == 2 && b == 10 ) || ( a == 2 && b == 11 ) || ( a == 2 && b == 13 ) || ( a == 2 && b == 15 ) || ( a == 3 && b == 7 ) || ( a == 3 && b == 10 ) || ( a == 3 && b == 12 ) || ( a == 3 && b == 13 ) || ( a == 4 && b == 6 ) || ( a == 4 && b == 8 ) || ( a == 4 && b == 10 ) || ( a == 4 && b == 14 ) || ( a == 4 && b == 19 ) || ( a == 5 && b == 7 ) || ( a == 5 && b == 9 ) || ( a == 5 && b == 11 ) || ( a == 5 && b == 16 ) || ( a == 5 && b == 18 ) || ( a == 6 && b == 11 ) || ( a == 6 && b == 14 ) || ( a == 6 && b == 15 ) || ( a == 7 && b == 11 ) || ( a == 7 && b == 12 ) || ( a == 7 && b == 18 ) || ( a == 8 && b == 9 ) || ( a == 8 && b == 10 ) || ( a == 8 && b == 17 ) || ( a == 8 && b == 19 ) || ( a == 9 && b == 16 ) || ( a == 9 && b == 17 ) || ( a == 10 && b == 13 ) || ( a == 10 && b == 19 ) || ( a == 11 && b == 15 ) || ( a == 11 && b == 18 ) || ( a == 12 && b == 15 ) || ( a == 12 && b == 16 ) || ( a == 12 && b == 19 ) || ( a == 13 && b == 14 ) || ( a == 13 && b == 17 ) || ( a == 13 && b == 18 ) || ( a == 14 && b == 17 ) || ( a == 14 && b == 18 ) || ( a == 15 && b == 16 ) || ( a == 15 && b == 19 ) || ( a == 16 && b == 19 ) || ( a == 17 && b == 18 ) ) return -(-1 + Nc2)/(16.*Nc); if( ( a == 0 && b == 8 ) || ( a == 0 && b == 11 ) || ( a == 0 && b == 15 ) || ( a == 0 && b == 17 ) || ( a == 0 && b == 18 ) || ( a == 0 && b == 19 ) || ( a == 1 && b == 5 ) || ( a == 1 && b == 10 ) || ( a == 1 && b == 13 ) || ( a == 1 && b == 16 ) || ( a == 1 && b == 18 ) || ( a == 1 && b == 19 ) || ( a == 2 && b == 4 ) || ( a == 2 && b == 7 ) || ( a == 2 && b == 12 ) || ( a == 2 && b == 14 ) || ( a == 2 && b == 18 ) || ( a == 2 && b == 19 ) || ( a == 3 && b == 8 ) || ( a == 3 && b == 11 ) || ( a == 3 && b == 15 ) || ( a == 3 && b == 17 ) || ( a == 3 && b == 18 ) || ( a == 3 && b == 19 ) || ( a == 4 && b == 9 ) || ( a == 4 && b == 13 ) || ( a == 4 && b == 15 ) || ( a == 4 && b == 16 ) || ( a == 4 && b == 17 ) || ( a == 5 && b == 6 ) || ( a == 5 && b == 12 ) || ( a == 5 && b == 14 ) || ( a == 5 && b == 15 ) || ( a == 5 && b == 17 ) || ( a == 6 && b == 10 ) || ( a == 6 && b == 13 ) || ( a == 6 && b == 16 ) || ( a == 6 && b == 18 ) || ( a == 6 && b == 19 ) || ( a == 7 && b == 9 ) || ( a == 7 && b == 13 ) || ( a == 7 && b == 15 ) || ( a == 7 && b == 16 ) || ( a == 7 && b == 17 ) || ( a == 8 && b == 12 ) || ( a == 8 && b == 13 ) || ( a == 8 && b == 14 ) || ( a == 8 && b == 16 ) || ( a == 9 && b == 12 ) || ( a == 9 && b == 14 ) || ( a == 9 && b == 18 ) || ( a == 9 && b == 19 ) || ( a == 10 && b == 12 ) || ( a == 10 && b == 14 ) || ( a == 10 && b == 15 ) || ( a == 10 && b == 17 ) || ( a == 11 && b == 12 ) || ( a == 11 && b == 13 ) || ( a == 11 && b == 14 ) || ( a == 11 && b == 16 ) ) return 0; if( ( a == 0 && b == 20 ) || ( a == 0 && b == 21 ) || ( a == 0 && b == 23 ) || ( a == 0 && b == 25 ) || ( a == 0 && b == 36 ) || ( a == 0 && b == 42 ) || ( a == 1 && b == 21 ) || ( a == 1 && b == 22 ) || ( a == 1 && b == 23 ) || ( a == 1 && b == 24 ) || ( a == 1 && b == 30 ) || ( a == 1 && b == 40 ) || ( a == 2 && b == 20 ) || ( a == 2 && b == 22 ) || ( a == 2 && b == 24 ) || ( a == 2 && b == 25 ) || ( a == 2 && b == 28 ) || ( a == 2 && b == 34 ) || ( a == 3 && b == 26 ) || ( a == 3 && b == 27 ) || ( a == 3 && b == 29 ) || ( a == 3 && b == 31 ) || ( a == 3 && b == 37 ) || ( a == 3 && b == 43 ) || ( a == 4 && b == 24 ) || ( a == 4 && b == 27 ) || ( a == 4 && b == 28 ) || ( a == 4 && b == 29 ) || ( a == 4 && b == 30 ) || ( a == 4 && b == 38 ) || ( a == 5 && b == 22 ) || ( a == 5 && b == 26 ) || ( a == 5 && b == 28 ) || ( a == 5 && b == 30 ) || ( a == 5 && b == 31 ) || ( a == 5 && b == 32 ) || ( a == 6 && b == 31 ) || ( a == 6 && b == 32 ) || ( a == 6 && b == 33 ) || ( a == 6 && b == 35 ) || ( a == 6 && b == 37 ) || ( a == 6 && b == 41 ) || ( a == 7 && b == 25 ) || ( a == 7 && b == 33 ) || ( a == 7 && b == 34 ) || ( a == 7 && b == 35 ) || ( a == 7 && b == 36 ) || ( a == 7 && b == 39 ) || ( a == 8 && b == 20 ) || ( a == 8 && b == 26 ) || ( a == 8 && b == 32 ) || ( a == 8 && b == 34 ) || ( a == 8 && b == 36 ) || ( a == 8 && b == 37 ) || ( a == 9 && b == 29 ) || ( a == 9 && b == 35 ) || ( a == 9 && b == 38 ) || ( a == 9 && b == 39 ) || ( a == 9 && b == 41 ) || ( a == 9 && b == 43 ) || ( a == 10 && b == 23 ) || ( a == 10 && b == 33 ) || ( a == 10 && b == 39 ) || ( a == 10 && b == 40 ) || ( a == 10 && b == 41 ) || ( a == 10 && b == 42 ) || ( a == 11 && b == 21 ) || ( a == 11 && b == 27 ) || ( a == 11 && b == 38 ) || ( a == 11 && b == 40 ) || ( a == 11 && b == 42 ) || ( a == 11 && b == 43 ) || ( a == 12 && b == 20 ) || ( a == 12 && b == 28 ) || ( a == 12 && b == 32 ) || ( a == 12 && b == 38 ) || ( a == 12 && b == 41 ) || ( a == 12 && b == 42 ) || ( a == 13 && b == 21 ) || ( a == 13 && b == 30 ) || ( a == 13 && b == 32 ) || ( a == 13 && b == 35 ) || ( a == 13 && b == 36 ) || ( a == 13 && b == 38 ) || ( a == 14 && b == 22 ) || ( a == 14 && b == 26 ) || ( a == 14 && b == 34 ) || ( a == 14 && b == 39 ) || ( a == 14 && b == 40 ) || ( a == 14 && b == 43 ) || ( a == 15 && b == 23 ) || ( a == 15 && b == 26 ) || ( a == 15 && b == 29 ) || ( a == 15 && b == 30 ) || ( a == 15 && b == 36 ) || ( a == 15 && b == 39 ) || ( a == 16 && b == 24 ) || ( a == 16 && b == 27 ) || ( a == 16 && b == 33 ) || ( a == 16 && b == 34 ) || ( a == 16 && b == 37 ) || ( a == 16 && b == 40 ) || ( a == 17 && b == 25 ) || ( a == 17 && b == 27 ) || ( a == 17 && b == 28 ) || ( a == 17 && b == 31 ) || ( a == 17 && b == 33 ) || ( a == 17 && b == 42 ) || ( a == 18 && b == 20 ) || ( a == 18 && b == 23 ) || ( a == 18 && b == 24 ) || ( a == 18 && b == 29 ) || ( a == 18 && b == 37 ) || ( a == 18 && b == 41 ) || ( a == 19 && b == 21 ) || ( a == 19 && b == 22 ) || ( a == 19 && b == 25 ) || ( a == 19 && b == 31 ) || ( a == 19 && b == 35 ) || ( a == 19 && b == 43 ) ) return ((-2 + Nc2)*sqr(-1 + Nc2))/(32.*Nc2); if( ( a == 0 && b == 22 ) || ( a == 0 && b == 24 ) || ( a == 0 && b == 32 ) || ( a == 0 && b == 33 ) || ( a == 0 && b == 38 ) || ( a == 0 && b == 39 ) || ( a == 1 && b == 20 ) || ( a == 1 && b == 25 ) || ( a == 1 && b == 26 ) || ( a == 1 && b == 27 ) || ( a == 1 && b == 38 ) || ( a == 1 && b == 39 ) || ( a == 2 && b == 21 ) || ( a == 2 && b == 23 ) || ( a == 2 && b == 26 ) || ( a == 2 && b == 27 ) || ( a == 2 && b == 32 ) || ( a == 2 && b == 33 ) || ( a == 3 && b == 28 ) || ( a == 3 && b == 30 ) || ( a == 3 && b == 34 ) || ( a == 3 && b == 35 ) || ( a == 3 && b == 40 ) || ( a == 3 && b == 41 ) || ( a == 4 && b == 20 ) || ( a == 4 && b == 21 ) || ( a == 4 && b == 26 ) || ( a == 4 && b == 31 ) || ( a == 4 && b == 40 ) || ( a == 4 && b == 41 ) || ( a == 5 && b == 20 ) || ( a == 5 && b == 21 ) || ( a == 5 && b == 27 ) || ( a == 5 && b == 29 ) || ( a == 5 && b == 34 ) || ( a == 5 && b == 35 ) || ( a == 6 && b == 28 ) || ( a == 6 && b == 29 ) || ( a == 6 && b == 34 ) || ( a == 6 && b == 36 ) || ( a == 6 && b == 42 ) || ( a == 6 && b == 43 ) || ( a == 7 && b == 22 ) || ( a == 7 && b == 23 ) || ( a == 7 && b == 32 ) || ( a == 7 && b == 37 ) || ( a == 7 && b == 42 ) || ( a == 7 && b == 43 ) || ( a == 8 && b == 22 ) || ( a == 8 && b == 23 ) || ( a == 8 && b == 28 ) || ( a == 8 && b == 29 ) || ( a == 8 && b == 33 ) || ( a == 8 && b == 35 ) || ( a == 9 && b == 30 ) || ( a == 9 && b == 31 ) || ( a == 9 && b == 36 ) || ( a == 9 && b == 37 ) || ( a == 9 && b == 40 ) || ( a == 9 && b == 42 ) || ( a == 10 && b == 24 ) || ( a == 10 && b == 25 ) || ( a == 10 && b == 36 ) || ( a == 10 && b == 37 ) || ( a == 10 && b == 38 ) || ( a == 10 && b == 43 ) || ( a == 11 && b == 24 ) || ( a == 11 && b == 25 ) || ( a == 11 && b == 30 ) || ( a == 11 && b == 31 ) || ( a == 11 && b == 39 ) || ( a == 11 && b == 41 ) || ( a == 12 && b == 21 ) || ( a == 12 && b == 24 ) || ( a == 12 && b == 29 ) || ( a == 12 && b == 31 ) || ( a == 12 && b == 33 ) || ( a == 12 && b == 36 ) || ( a == 13 && b == 20 ) || ( a == 13 && b == 22 ) || ( a == 13 && b == 29 ) || ( a == 13 && b == 31 ) || ( a == 13 && b == 39 ) || ( a == 13 && b == 42 ) || ( a == 14 && b == 23 ) || ( a == 14 && b == 25 ) || ( a == 14 && b == 27 ) || ( a == 14 && b == 30 ) || ( a == 14 && b == 35 ) || ( a == 14 && b == 37 ) || ( a == 15 && b == 20 ) || ( a == 15 && b == 22 ) || ( a == 15 && b == 35 ) || ( a == 15 && b == 37 ) || ( a == 15 && b == 38 ) || ( a == 15 && b == 40 ) || ( a == 16 && b == 23 ) || ( a == 16 && b == 25 ) || ( a == 16 && b == 26 ) || ( a == 16 && b == 28 ) || ( a == 16 && b == 41 ) || ( a == 16 && b == 43 ) || ( a == 17 && b == 21 ) || ( a == 17 && b == 24 ) || ( a == 17 && b == 32 ) || ( a == 17 && b == 34 ) || ( a == 17 && b == 41 ) || ( a == 17 && b == 43 ) || ( a == 18 && b == 26 ) || ( a == 18 && b == 28 ) || ( a == 18 && b == 33 ) || ( a == 18 && b == 36 ) || ( a == 18 && b == 38 ) || ( a == 18 && b == 40 ) || ( a == 19 && b == 27 ) || ( a == 19 && b == 30 ) || ( a == 19 && b == 32 ) || ( a == 19 && b == 34 ) || ( a == 19 && b == 39 ) || ( a == 19 && b == 42 ) ) return -(2 - 3*Nc2 + Nc4)/(32.*Nc2); if( ( a == 0 && b == 26 ) || ( a == 0 && b == 27 ) || ( a == 0 && b == 29 ) || ( a == 0 && b == 31 ) || ( a == 0 && b == 37 ) || ( a == 0 && b == 43 ) || ( a == 1 && b == 31 ) || ( a == 1 && b == 32 ) || ( a == 1 && b == 33 ) || ( a == 1 && b == 35 ) || ( a == 1 && b == 37 ) || ( a == 1 && b == 41 ) || ( a == 2 && b == 29 ) || ( a == 2 && b == 35 ) || ( a == 2 && b == 38 ) || ( a == 2 && b == 39 ) || ( a == 2 && b == 41 ) || ( a == 2 && b == 43 ) || ( a == 3 && b == 20 ) || ( a == 3 && b == 21 ) || ( a == 3 && b == 23 ) || ( a == 3 && b == 25 ) || ( a == 3 && b == 36 ) || ( a == 3 && b == 42 ) || ( a == 4 && b == 25 ) || ( a == 4 && b == 33 ) || ( a == 4 && b == 34 ) || ( a == 4 && b == 35 ) || ( a == 4 && b == 36 ) || ( a == 4 && b == 39 ) || ( a == 5 && b == 23 ) || ( a == 5 && b == 33 ) || ( a == 5 && b == 39 ) || ( a == 5 && b == 40 ) || ( a == 5 && b == 41 ) || ( a == 5 && b == 42 ) || ( a == 6 && b == 21 ) || ( a == 6 && b == 22 ) || ( a == 6 && b == 23 ) || ( a == 6 && b == 24 ) || ( a == 6 && b == 30 ) || ( a == 6 && b == 40 ) || ( a == 7 && b == 24 ) || ( a == 7 && b == 27 ) || ( a == 7 && b == 28 ) || ( a == 7 && b == 29 ) || ( a == 7 && b == 30 ) || ( a == 7 && b == 38 ) || ( a == 8 && b == 21 ) || ( a == 8 && b == 27 ) || ( a == 8 && b == 38 ) || ( a == 8 && b == 40 ) || ( a == 8 && b == 42 ) || ( a == 8 && b == 43 ) || ( a == 9 && b == 20 ) || ( a == 9 && b == 22 ) || ( a == 9 && b == 24 ) || ( a == 9 && b == 25 ) || ( a == 9 && b == 28 ) || ( a == 9 && b == 34 ) || ( a == 10 && b == 22 ) || ( a == 10 && b == 26 ) || ( a == 10 && b == 28 ) || ( a == 10 && b == 30 ) || ( a == 10 && b == 31 ) || ( a == 10 && b == 32 ) || ( a == 11 && b == 20 ) || ( a == 11 && b == 26 ) || ( a == 11 && b == 32 ) || ( a == 11 && b == 34 ) || ( a == 11 && b == 36 ) || ( a == 11 && b == 37 ) || ( a == 12 && b == 22 ) || ( a == 12 && b == 26 ) || ( a == 12 && b == 34 ) || ( a == 12 && b == 39 ) || ( a == 12 && b == 40 ) || ( a == 12 && b == 43 ) || ( a == 13 && b == 24 ) || ( a == 13 && b == 27 ) || ( a == 13 && b == 33 ) || ( a == 13 && b == 34 ) || ( a == 13 && b == 37 ) || ( a == 13 && b == 40 ) || ( a == 14 && b == 20 ) || ( a == 14 && b == 28 ) || ( a == 14 && b == 32 ) || ( a == 14 && b == 38 ) || ( a == 14 && b == 41 ) || ( a == 14 && b == 42 ) || ( a == 15 && b == 25 ) || ( a == 15 && b == 27 ) || ( a == 15 && b == 28 ) || ( a == 15 && b == 31 ) || ( a == 15 && b == 33 ) || ( a == 15 && b == 42 ) || ( a == 16 && b == 21 ) || ( a == 16 && b == 30 ) || ( a == 16 && b == 32 ) || ( a == 16 && b == 35 ) || ( a == 16 && b == 36 ) || ( a == 16 && b == 38 ) || ( a == 17 && b == 23 ) || ( a == 17 && b == 26 ) || ( a == 17 && b == 29 ) || ( a == 17 && b == 30 ) || ( a == 17 && b == 36 ) || ( a == 17 && b == 39 ) || ( a == 18 && b == 21 ) || ( a == 18 && b == 22 ) || ( a == 18 && b == 25 ) || ( a == 18 && b == 31 ) || ( a == 18 && b == 35 ) || ( a == 18 && b == 43 ) || ( a == 19 && b == 20 ) || ( a == 19 && b == 23 ) || ( a == 19 && b == 24 ) || ( a == 19 && b == 29 ) || ( a == 19 && b == 37 ) || ( a == 19 && b == 41 ) ) return -sqr(-1 + Nc2)/(16.*Nc2); if( ( a == 0 && b == 28 ) || ( a == 0 && b == 30 ) || ( a == 0 && b == 34 ) || ( a == 0 && b == 35 ) || ( a == 0 && b == 40 ) || ( a == 0 && b == 41 ) || ( a == 1 && b == 28 ) || ( a == 1 && b == 29 ) || ( a == 1 && b == 34 ) || ( a == 1 && b == 36 ) || ( a == 1 && b == 42 ) || ( a == 1 && b == 43 ) || ( a == 2 && b == 30 ) || ( a == 2 && b == 31 ) || ( a == 2 && b == 36 ) || ( a == 2 && b == 37 ) || ( a == 2 && b == 40 ) || ( a == 2 && b == 42 ) || ( a == 3 && b == 22 ) || ( a == 3 && b == 24 ) || ( a == 3 && b == 32 ) || ( a == 3 && b == 33 ) || ( a == 3 && b == 38 ) || ( a == 3 && b == 39 ) || ( a == 4 && b == 22 ) || ( a == 4 && b == 23 ) || ( a == 4 && b == 32 ) || ( a == 4 && b == 37 ) || ( a == 4 && b == 42 ) || ( a == 4 && b == 43 ) || ( a == 5 && b == 24 ) || ( a == 5 && b == 25 ) || ( a == 5 && b == 36 ) || ( a == 5 && b == 37 ) || ( a == 5 && b == 38 ) || ( a == 5 && b == 43 ) || ( a == 6 && b == 20 ) || ( a == 6 && b == 25 ) || ( a == 6 && b == 26 ) || ( a == 6 && b == 27 ) || ( a == 6 && b == 38 ) || ( a == 6 && b == 39 ) || ( a == 7 && b == 20 ) || ( a == 7 && b == 21 ) || ( a == 7 && b == 26 ) || ( a == 7 && b == 31 ) || ( a == 7 && b == 40 ) || ( a == 7 && b == 41 ) || ( a == 8 && b == 24 ) || ( a == 8 && b == 25 ) || ( a == 8 && b == 30 ) || ( a == 8 && b == 31 ) || ( a == 8 && b == 39 ) || ( a == 8 && b == 41 ) || ( a == 9 && b == 21 ) || ( a == 9 && b == 23 ) || ( a == 9 && b == 26 ) || ( a == 9 && b == 27 ) || ( a == 9 && b == 32 ) || ( a == 9 && b == 33 ) || ( a == 10 && b == 20 ) || ( a == 10 && b == 21 ) || ( a == 10 && b == 27 ) || ( a == 10 && b == 29 ) || ( a == 10 && b == 34 ) || ( a == 10 && b == 35 ) || ( a == 11 && b == 22 ) || ( a == 11 && b == 23 ) || ( a == 11 && b == 28 ) || ( a == 11 && b == 29 ) || ( a == 11 && b == 33 ) || ( a == 11 && b == 35 ) || ( a == 12 && b == 23 ) || ( a == 12 && b == 25 ) || ( a == 12 && b == 27 ) || ( a == 12 && b == 30 ) || ( a == 12 && b == 35 ) || ( a == 12 && b == 37 ) || ( a == 13 && b == 23 ) || ( a == 13 && b == 25 ) || ( a == 13 && b == 26 ) || ( a == 13 && b == 28 ) || ( a == 13 && b == 41 ) || ( a == 13 && b == 43 ) || ( a == 14 && b == 21 ) || ( a == 14 && b == 24 ) || ( a == 14 && b == 29 ) || ( a == 14 && b == 31 ) || ( a == 14 && b == 33 ) || ( a == 14 && b == 36 ) || ( a == 15 && b == 21 ) || ( a == 15 && b == 24 ) || ( a == 15 && b == 32 ) || ( a == 15 && b == 34 ) || ( a == 15 && b == 41 ) || ( a == 15 && b == 43 ) || ( a == 16 && b == 20 ) || ( a == 16 && b == 22 ) || ( a == 16 && b == 29 ) || ( a == 16 && b == 31 ) || ( a == 16 && b == 39 ) || ( a == 16 && b == 42 ) || ( a == 17 && b == 20 ) || ( a == 17 && b == 22 ) || ( a == 17 && b == 35 ) || ( a == 17 && b == 37 ) || ( a == 17 && b == 38 ) || ( a == 17 && b == 40 ) || ( a == 18 && b == 27 ) || ( a == 18 && b == 30 ) || ( a == 18 && b == 32 ) || ( a == 18 && b == 34 ) || ( a == 18 && b == 39 ) || ( a == 18 && b == 42 ) || ( a == 19 && b == 26 ) || ( a == 19 && b == 28 ) || ( a == 19 && b == 33 ) || ( a == 19 && b == 36 ) || ( a == 19 && b == 38 ) || ( a == 19 && b == 40 ) ) return (1 - 1/Nc2)/16.; if( ( a == 20 && b == 20 ) || ( a == 21 && b == 21 ) || ( a == 22 && b == 22 ) || ( a == 23 && b == 23 ) || ( a == 24 && b == 24 ) || ( a == 25 && b == 25 ) || ( a == 26 && b == 26 ) || ( a == 27 && b == 27 ) || ( a == 28 && b == 28 ) || ( a == 29 && b == 29 ) || ( a == 30 && b == 30 ) || ( a == 31 && b == 31 ) || ( a == 32 && b == 32 ) || ( a == 33 && b == 33 ) || ( a == 34 && b == 34 ) || ( a == 35 && b == 35 ) || ( a == 36 && b == 36 ) || ( a == 37 && b == 37 ) || ( a == 38 && b == 38 ) || ( a == 39 && b == 39 ) || ( a == 40 && b == 40 ) || ( a == 41 && b == 41 ) || ( a == 42 && b == 42 ) || ( a == 43 && b == 43 ) ) return (4 - 10*Nc2 + 10*Nc4 - 5*Nc6 + Nc8)/(32.*Nc3); if( ( a == 20 && b == 21 ) || ( a == 20 && b == 22 ) || ( a == 20 && b == 26 ) || ( a == 20 && b == 29 ) || ( a == 20 && b == 38 ) || ( a == 21 && b == 24 ) || ( a == 21 && b == 27 ) || ( a == 21 && b == 31 ) || ( a == 21 && b == 32 ) || ( a == 22 && b == 23 ) || ( a == 22 && b == 32 ) || ( a == 22 && b == 35 ) || ( a == 22 && b == 39 ) || ( a == 23 && b == 25 ) || ( a == 23 && b == 26 ) || ( a == 23 && b == 33 ) || ( a == 23 && b == 37 ) || ( a == 24 && b == 25 ) || ( a == 24 && b == 33 ) || ( a == 24 && b == 38 ) || ( a == 24 && b == 41 ) || ( a == 25 && b == 27 ) || ( a == 25 && b == 39 ) || ( a == 25 && b == 43 ) || ( a == 26 && b == 27 ) || ( a == 26 && b == 28 ) || ( a == 26 && b == 40 ) || ( a == 27 && b == 30 ) || ( a == 27 && b == 34 ) || ( a == 28 && b == 29 ) || ( a == 28 && b == 33 ) || ( a == 28 && b == 34 ) || ( a == 28 && b == 41 ) || ( a == 29 && b == 31 ) || ( a == 29 && b == 35 ) || ( a == 29 && b == 36 ) || ( a == 30 && b == 31 ) || ( a == 30 && b == 35 ) || ( a == 30 && b == 39 ) || ( a == 30 && b == 40 ) || ( a == 31 && b == 41 ) || ( a == 31 && b == 42 ) || ( a == 32 && b == 33 ) || ( a == 32 && b == 34 ) || ( a == 32 && b == 42 ) || ( a == 33 && b == 36 ) || ( a == 34 && b == 35 ) || ( a == 34 && b == 43 ) || ( a == 35 && b == 37 ) || ( a == 36 && b == 37 ) || ( a == 36 && b == 38 ) || ( a == 36 && b == 42 ) || ( a == 37 && b == 40 ) || ( a == 37 && b == 43 ) || ( a == 38 && b == 39 ) || ( a == 38 && b == 40 ) || ( a == 39 && b == 42 ) || ( a == 40 && b == 41 ) || ( a == 41 && b == 43 ) || ( a == 42 && b == 43 ) ) return -(-4 + 7*Nc2 - 4*Nc4 + Nc6)/(32.*Nc3); if( ( a == 20 && b == 23 ) || ( a == 20 && b == 24 ) || ( a == 20 && b == 28 ) || ( a == 20 && b == 32 ) || ( a == 20 && b == 36 ) || ( a == 21 && b == 22 ) || ( a == 21 && b == 25 ) || ( a == 21 && b == 30 ) || ( a == 21 && b == 38 ) || ( a == 21 && b == 42 ) || ( a == 22 && b == 25 ) || ( a == 22 && b == 26 ) || ( a == 22 && b == 30 ) || ( a == 22 && b == 34 ) || ( a == 23 && b == 24 ) || ( a == 23 && b == 36 ) || ( a == 23 && b == 39 ) || ( a == 23 && b == 40 ) || ( a == 24 && b == 27 ) || ( a == 24 && b == 28 ) || ( a == 24 && b == 40 ) || ( a == 25 && b == 33 ) || ( a == 25 && b == 34 ) || ( a == 25 && b == 42 ) || ( a == 26 && b == 29 ) || ( a == 26 && b == 30 ) || ( a == 26 && b == 34 ) || ( a == 26 && b == 37 ) || ( a == 27 && b == 28 ) || ( a == 27 && b == 31 ) || ( a == 27 && b == 40 ) || ( a == 27 && b == 43 ) || ( a == 28 && b == 31 ) || ( a == 28 && b == 32 ) || ( a == 29 && b == 30 ) || ( a == 29 && b == 37 ) || ( a == 29 && b == 38 ) || ( a == 29 && b == 41 ) || ( a == 30 && b == 38 ) || ( a == 31 && b == 32 ) || ( a == 31 && b == 35 ) || ( a == 31 && b == 43 ) || ( a == 32 && b == 35 ) || ( a == 32 && b == 36 ) || ( a == 33 && b == 34 ) || ( a == 33 && b == 37 ) || ( a == 33 && b == 41 ) || ( a == 33 && b == 42 ) || ( a == 34 && b == 37 ) || ( a == 35 && b == 36 ) || ( a == 35 && b == 39 ) || ( a == 35 && b == 43 ) || ( a == 36 && b == 39 ) || ( a == 37 && b == 41 ) || ( a == 38 && b == 41 ) || ( a == 38 && b == 42 ) || ( a == 39 && b == 40 ) || ( a == 39 && b == 43 ) || ( a == 40 && b == 43 ) || ( a == 41 && b == 42 ) ) return (2 - 3*Nc2 + Nc4)/(16.*Nc3); if( ( a == 20 && b == 25 ) || ( a == 20 && b == 34 ) || ( a == 20 && b == 37 ) || ( a == 20 && b == 41 ) || ( a == 20 && b == 42 ) || ( a == 21 && b == 23 ) || ( a == 21 && b == 35 ) || ( a == 21 && b == 36 ) || ( a == 21 && b == 40 ) || ( a == 21 && b == 43 ) || ( a == 22 && b == 24 ) || ( a == 22 && b == 28 ) || ( a == 22 && b == 31 ) || ( a == 22 && b == 40 ) || ( a == 22 && b == 43 ) || ( a == 23 && b == 29 ) || ( a == 23 && b == 30 ) || ( a == 23 && b == 41 ) || ( a == 23 && b == 42 ) || ( a == 24 && b == 29 ) || ( a == 24 && b == 30 ) || ( a == 24 && b == 34 ) || ( a == 24 && b == 37 ) || ( a == 25 && b == 28 ) || ( a == 25 && b == 31 ) || ( a == 25 && b == 35 ) || ( a == 25 && b == 36 ) || ( a == 26 && b == 31 ) || ( a == 26 && b == 32 ) || ( a == 26 && b == 36 ) || ( a == 26 && b == 39 ) || ( a == 26 && b == 43 ) || ( a == 27 && b == 29 ) || ( a == 27 && b == 33 ) || ( a == 27 && b == 37 ) || ( a == 27 && b == 38 ) || ( a == 27 && b == 42 ) || ( a == 28 && b == 30 ) || ( a == 28 && b == 38 ) || ( a == 28 && b == 42 ) || ( a == 29 && b == 39 ) || ( a == 29 && b == 43 ) || ( a == 30 && b == 32 ) || ( a == 30 && b == 36 ) || ( a == 31 && b == 33 ) || ( a == 31 && b == 37 ) || ( a == 32 && b == 37 ) || ( a == 32 && b == 38 ) || ( a == 32 && b == 41 ) || ( a == 33 && b == 35 ) || ( a == 33 && b == 39 ) || ( a == 33 && b == 40 ) || ( a == 34 && b == 36 ) || ( a == 34 && b == 39 ) || ( a == 34 && b == 40 ) || ( a == 35 && b == 38 ) || ( a == 35 && b == 41 ) || ( a == 38 && b == 43 ) || ( a == 39 && b == 41 ) || ( a == 40 && b == 42 ) ) return (4 - 3*Nc2 - 2*Nc4 + Nc6)/(32.*Nc3); if( ( a == 20 && b == 27 ) || ( a == 20 && b == 31 ) || ( a == 20 && b == 35 ) || ( a == 20 && b == 39 ) || ( a == 20 && b == 40 ) || ( a == 21 && b == 26 ) || ( a == 21 && b == 29 ) || ( a == 21 && b == 33 ) || ( a == 21 && b == 34 ) || ( a == 21 && b == 41 ) || ( a == 22 && b == 29 ) || ( a == 22 && b == 33 ) || ( a == 22 && b == 37 ) || ( a == 22 && b == 38 ) || ( a == 22 && b == 42 ) || ( a == 23 && b == 27 ) || ( a == 23 && b == 28 ) || ( a == 23 && b == 32 ) || ( a == 23 && b == 35 ) || ( a == 23 && b == 43 ) || ( a == 24 && b == 31 ) || ( a == 24 && b == 32 ) || ( a == 24 && b == 36 ) || ( a == 24 && b == 39 ) || ( a == 24 && b == 43 ) || ( a == 25 && b == 26 ) || ( a == 25 && b == 30 ) || ( a == 25 && b == 37 ) || ( a == 25 && b == 38 ) || ( a == 25 && b == 41 ) || ( a == 26 && b == 33 ) || ( a == 26 && b == 38 ) || ( a == 26 && b == 41 ) || ( a == 27 && b == 32 ) || ( a == 27 && b == 35 ) || ( a == 27 && b == 39 ) || ( a == 28 && b == 35 ) || ( a == 28 && b == 36 ) || ( a == 28 && b == 40 ) || ( a == 28 && b == 43 ) || ( a == 29 && b == 33 ) || ( a == 29 && b == 34 ) || ( a == 29 && b == 42 ) || ( a == 30 && b == 34 ) || ( a == 30 && b == 37 ) || ( a == 30 && b == 41 ) || ( a == 30 && b == 42 ) || ( a == 31 && b == 36 ) || ( a == 31 && b == 39 ) || ( a == 31 && b == 40 ) || ( a == 32 && b == 39 ) || ( a == 32 && b == 43 ) || ( a == 33 && b == 38 ) || ( a == 34 && b == 41 ) || ( a == 34 && b == 42 ) || ( a == 35 && b == 40 ) || ( a == 36 && b == 40 ) || ( a == 36 && b == 43 ) || ( a == 37 && b == 38 ) || ( a == 37 && b == 42 ) ) return -(-1 + Nc2)/(8.*Nc3); if( ( a == 20 && b == 30 ) || ( a == 20 && b == 33 ) || ( a == 21 && b == 28 ) || ( a == 21 && b == 39 ) || ( a == 22 && b == 27 ) || ( a == 22 && b == 36 ) || ( a == 23 && b == 34 ) || ( a == 23 && b == 38 ) || ( a == 24 && b == 26 ) || ( a == 24 && b == 42 ) || ( a == 25 && b == 32 ) || ( a == 25 && b == 40 ) || ( a == 26 && b == 35 ) || ( a == 27 && b == 41 ) || ( a == 28 && b == 37 ) || ( a == 29 && b == 32 ) || ( a == 29 && b == 40 ) || ( a == 30 && b == 43 ) || ( a == 31 && b == 34 ) || ( a == 31 && b == 38 ) || ( a == 33 && b == 43 ) || ( a == 35 && b == 42 ) || ( a == 36 && b == 41 ) || ( a == 37 && b == 39 ) ) return (4 - 5*Nc2 + Nc4)/(32.*Nc3); if( ( a == 20 && b == 43 ) || ( a == 21 && b == 37 ) || ( a == 22 && b == 41 ) || ( a == 23 && b == 31 ) || ( a == 24 && b == 35 ) || ( a == 25 && b == 29 ) || ( a == 26 && b == 42 ) || ( a == 27 && b == 36 ) || ( a == 28 && b == 39 ) || ( a == 30 && b == 33 ) || ( a == 32 && b == 40 ) || ( a == 34 && b == 38 ) ) return -(-1 + Nc4)/(8.*Nc3); } if ( basis == id33bar888 ) { if( ( a == 0 && b == 0 ) || ( a == 1 && b == 1 ) ) return (2 - 3*Nc2 + Nc4)/8.; if( a == 0 && b == 1 ) return (1 - Nc2)/4.; if( ( a == 0 && b == 2 ) || ( a == 0 && b == 3 ) || ( a == 0 && b == 4 ) || ( a == 1 && b == 2 ) || ( a == 1 && b == 3 ) || ( a == 1 && b == 4 ) ) return 0; if( ( a == 0 && b == 5 ) || ( a == 0 && b == 8 ) || ( a == 0 && b == 9 ) || ( a == 1 && b == 6 ) || ( a == 1 && b == 7 ) || ( a == 1 && b == 10 ) ) return (2 - 3*Nc2 + Nc4)/(8.*Nc); if( ( a == 0 && b == 6 ) || ( a == 0 && b == 7 ) || ( a == 0 && b == 10 ) || ( a == 1 && b == 5 ) || ( a == 1 && b == 8 ) || ( a == 1 && b == 9 ) ) return -(-1 + Nc2)/(4.*Nc); if( ( a == 2 && b == 2 ) || ( a == 3 && b == 3 ) || ( a == 4 && b == 4 ) ) return sqr(-1 + Nc2)/8.; if( ( a == 2 && b == 3 ) || ( a == 2 && b == 4 ) || ( a == 3 && b == 4 ) ) return (-1 + Nc2)/8.; if( ( a == 2 && b == 5 ) || ( a == 2 && b == 6 ) || ( a == 2 && b == 8 ) || ( a == 2 && b == 10 ) || ( a == 3 && b == 6 ) || ( a == 3 && b == 7 ) || ( a == 3 && b == 8 ) || ( a == 3 && b == 9 ) || ( a == 4 && b == 5 ) || ( a == 4 && b == 7 ) || ( a == 4 && b == 9 ) || ( a == 4 && b == 10 ) ) return sqr(-1 + Nc2)/(8.*Nc); if( ( a == 2 && b == 7 ) || ( a == 2 && b == 9 ) || ( a == 3 && b == 5 ) || ( a == 3 && b == 10 ) || ( a == 4 && b == 6 ) || ( a == 4 && b == 8 ) ) return -(-1 + Nc2)/(8.*Nc); if( ( a == 5 && b == 5 ) || ( a == 6 && b == 6 ) || ( a == 7 && b == 7 ) || ( a == 8 && b == 8 ) || ( a == 9 && b == 9 ) || ( a == 10 && b == 10 ) ) return pow(-1 + Nc2,3.)/(8.*Nc2); if( ( a == 5 && b == 6 ) || ( a == 5 && b == 7 ) || ( a == 6 && b == 9 ) || ( a == 7 && b == 8 ) || ( a == 8 && b == 10 ) || ( a == 9 && b == 10 ) ) return -sqr(-1 + Nc2)/(8.*Nc2); if( ( a == 5 && b == 8 ) || ( a == 5 && b == 9 ) || ( a == 6 && b == 7 ) || ( a == 6 && b == 10 ) || ( a == 7 && b == 10 ) || ( a == 8 && b == 9 ) ) return 0.125 - 1/(8.*Nc2); if( ( a == 5 && b == 10 ) || ( a == 6 && b == 8 ) || ( a == 7 && b == 9 ) ) return (-1 + Nc4)/(8.*Nc2); } if ( basis == id33bar33bar8 ) { if( ( a == 0 && b == 0 ) || ( a == 1 && b == 1 ) || ( a == 2 && b == 2 ) || ( a == 3 && b == 3 ) ) return (Nc*(-1 + Nc2))/2.; if( ( a == 0 && b == 1 ) || ( a == 0 && b == 3 ) || ( a == 1 && b == 2 ) || ( a == 2 && b == 3 ) ) return (-1 + Nc2)/2.; if( ( a == 0 && b == 2 ) || ( a == 1 && b == 3 ) ) return 0; } } else { if ( a != b ) return 0.; if ( basis == id88 ) { return Nc2/4.; } if ( basis == id33bar ) { return Nc; } if ( basis == id888 ) { return Nc3/8.; } if ( basis == id33bar8 ) { return Nc2/2.; } if ( basis == id8888 ) { return Nc4/16.; } if ( basis == id33bar88 ) { return Nc3/4.; } if ( basis == id33bar33bar ) { return Nc2; } if ( basis == id88888 ) { return Nc5/32.; } if ( basis == id33bar888 ) { return Nc4/8.; } if ( basis == id33bar33bar8 ) { return Nc3/2.; } } throw Exception() << "SimpleColourBasis2::scalarProduct(): Cannot handle colour configuration" << Exception::runerror; } double SimpleColourBasis2::tMatrixElement(size_t i, size_t a, - size_t b, - const vector&, - const vector& basis, - size_t k, size_t l, - const map& dict) const { + size_t b, + const vector&, + const vector& basis, +#ifndef NDEBUG + size_t k, size_t l, +#else + size_t , size_t , +#endif + const map& dict) const { // Check indices k and l assert( k == i ); assert( l == basis.size() ); // Check that dict is the standardMap assert( dict.size()+1 == basis.size() ); map::const_iterator tmp; for ( size_t ii = 0; ii < basis.size(); ii++ ) if ( ii != i ) { tmp = dict.find(ii); assert( tmp != dict.end() ); assert( tmp->second == ii ); } if ( id33bar.empty() ) makeIds(); if ( basis == id88 ) { if(i == 0 && a == 0 && b == 0) return -1; if(i == 0 && a == 1 && b == 0) return 1; if(i == 1 && a == 0 && b == 0) return 1; if(i == 1 && a == 1 && b == 0) return -1; return 0.; } if ( basis == id33bar ) { if(i == 0 && a == 0 && b == 0) return 1; if(i == 1 && a == 0 && b == 0) return -1; return 0.; } if ( basis == id888 ) { if(i == 0 && a == 3 && b == 0) return -1; if(i == 0 && a == 5 && b == 1) return -1; if(i == 0 && a == 7 && b == 0) return 1; if(i == 0 && a == 8 && b == 1) return 1; if(i == 1 && a == 4 && b == 0) return 1; if(i == 1 && a == 5 && b == 1) return 1; if(i == 1 && a == 6 && b == 1) return -1; if(i == 1 && a == 7 && b == 0) return -1; if(i == 2 && a == 3 && b == 0) return 1; if(i == 2 && a == 4 && b == 0) return -1; if(i == 2 && a == 6 && b == 1) return 1; if(i == 2 && a == 8 && b == 1) return -1; return 0.; } if ( basis == id33bar8 ) { if(i == 0 && a == 2 && b == 0) return 1; if(i == 1 && a == 1 && b == 0) return -1; if(i == 2 && a == 1 && b == 0) return 1; if(i == 2 && a == 2 && b == 0) return -1; return 0.; } if ( basis == id8888 ) { if(i == 0 && a == 2 && b == 2) return -1; if(i == 0 && a == 5 && b == 1) return -1; if(i == 0 && a == 8 && b == 0) return -1; if(i == 0 && a == 9 && b == 2) return 1; if(i == 0 && a == 10 && b == 1) return 1; if(i == 0 && a == 11 && b == 0) return 1; if(i == 0 && a == 20 && b == 3) return -1; if(i == 0 && a == 22 && b == 4) return -1; if(i == 0 && a == 26 && b == 5) return -1; if(i == 0 && a == 28 && b == 6) return -1; if(i == 0 && a == 32 && b == 7) return -1; if(i == 0 && a == 34 && b == 8) return -1; if(i == 0 && a == 38 && b == 3) return 1; if(i == 0 && a == 39 && b == 4) return 1; if(i == 0 && a == 40 && b == 5) return 1; if(i == 0 && a == 41 && b == 6) return 1; if(i == 0 && a == 42 && b == 7) return 1; if(i == 0 && a == 43 && b == 8) return 1; if(i == 1 && a == 2 && b == 2) return 1; if(i == 1 && a == 9 && b == 2) return -1; if(i == 1 && a == 13 && b == 0) return -1; if(i == 1 && a == 15 && b == 1) return -1; if(i == 1 && a == 16 && b == 0) return 1; if(i == 1 && a == 17 && b == 1) return 1; if(i == 1 && a == 24 && b == 3) return 1; if(i == 1 && a == 25 && b == 4) return 1; if(i == 1 && a == 27 && b == 5) return 1; if(i == 1 && a == 28 && b == 6) return 1; if(i == 1 && a == 29 && b == 6) return -1; if(i == 1 && a == 30 && b == 5) return -1; if(i == 1 && a == 33 && b == 7) return 1; if(i == 1 && a == 34 && b == 8) return 1; if(i == 1 && a == 35 && b == 8) return -1; if(i == 1 && a == 36 && b == 7) return -1; if(i == 1 && a == 38 && b == 3) return -1; if(i == 1 && a == 39 && b == 4) return -1; if(i == 2 && a == 5 && b == 1) return 1; if(i == 2 && a == 10 && b == 1) return -1; if(i == 2 && a == 13 && b == 0) return 1; if(i == 2 && a == 16 && b == 0) return -1; if(i == 2 && a == 18 && b == 2) return -1; if(i == 2 && a == 19 && b == 2) return 1; if(i == 2 && a == 21 && b == 3) return 1; if(i == 2 && a == 22 && b == 4) return 1; if(i == 2 && a == 23 && b == 4) return -1; if(i == 2 && a == 24 && b == 3) return -1; if(i == 2 && a == 30 && b == 5) return 1; if(i == 2 && a == 31 && b == 6) return 1; if(i == 2 && a == 32 && b == 7) return 1; if(i == 2 && a == 33 && b == 7) return -1; if(i == 2 && a == 35 && b == 8) return 1; if(i == 2 && a == 37 && b == 8) return -1; if(i == 2 && a == 40 && b == 5) return -1; if(i == 2 && a == 41 && b == 6) return -1; if(i == 3 && a == 8 && b == 0) return 1; if(i == 3 && a == 11 && b == 0) return -1; if(i == 3 && a == 15 && b == 1) return 1; if(i == 3 && a == 17 && b == 1) return -1; if(i == 3 && a == 18 && b == 2) return 1; if(i == 3 && a == 19 && b == 2) return -1; if(i == 3 && a == 20 && b == 3) return 1; if(i == 3 && a == 21 && b == 3) return -1; if(i == 3 && a == 23 && b == 4) return 1; if(i == 3 && a == 25 && b == 4) return -1; if(i == 3 && a == 26 && b == 5) return 1; if(i == 3 && a == 27 && b == 5) return -1; if(i == 3 && a == 29 && b == 6) return 1; if(i == 3 && a == 31 && b == 6) return -1; if(i == 3 && a == 36 && b == 7) return 1; if(i == 3 && a == 37 && b == 8) return 1; if(i == 3 && a == 42 && b == 7) return -1; if(i == 3 && a == 43 && b == 8) return -1; return 0.; } if ( basis == id33bar88 ) { if(i == 0 && a == 4 && b == 0) return 1; if(i == 0 && a == 9 && b == 1) return 1; if(i == 0 && a == 10 && b == 2) return 1; if(i == 1 && a == 4 && b == 0) return -1; if(i == 1 && a == 5 && b == 1) return -1; if(i == 1 && a == 7 && b == 2) return -1; if(i == 2 && a == 0 && b == 0) return -1; if(i == 2 && a == 1 && b == 0) return 1; if(i == 2 && a == 6 && b == 1) return 1; if(i == 2 && a == 7 && b == 2) return 1; if(i == 2 && a == 8 && b == 2) return -1; if(i == 2 && a == 9 && b == 1) return -1; if(i == 3 && a == 0 && b == 0) return 1; if(i == 3 && a == 1 && b == 0) return -1; if(i == 3 && a == 5 && b == 1) return 1; if(i == 3 && a == 6 && b == 1) return -1; if(i == 3 && a == 8 && b == 2) return 1; if(i == 3 && a == 10 && b == 2) return -1; return 0.; } if ( basis == id33bar33bar ) { if(i == 0 && a == 0 && b == 0) return 1; if(i == 0 && a == 1 && b == 1) return 1; if(i == 1 && a == 1 && b == 1) return -1; if(i == 1 && a == 2 && b == 0) return -1; if(i == 2 && a == 2 && b == 0) return 1; if(i == 2 && a == 3 && b == 1) return 1; if(i == 3 && a == 0 && b == 0) return -1; if(i == 3 && a == 3 && b == 1) return -1; return 0.; } throw Exception() << "SimpleColourBasis2::tMatrixElement(): Cannot handle colour configuration" << Exception::runerror; return 0.; } bool SimpleColourBasis2::colourConnected(const cPDVector& sub, const vector& basis, const pair& i, const pair& j, size_t a) const { if ( id33bar.empty() ) makeIds(); // translate process to basis ids map >::const_iterator trans = indexMap().find(sub); assert(trans != indexMap().end()); int idColoured = i.second ? j.first : i.first; idColoured = trans->second.find(idColoured)->second; int idAntiColoured = i.second ? i.first : j.first; idAntiColoured = trans->second.find(idAntiColoured)->second; if ( basis == id88 ) { return a == 0 && ((idColoured == 0 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 0)); } if ( basis == id33bar ) { return a == 0 && (idColoured == 0 && idAntiColoured == 1); } if ( basis == id888 ) { return (a == 0 && ((idColoured == 0 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 0))) || (a == 1 && ((idColoured == 0 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 0))); } if ( basis == id33bar8 ) { return a == 0 && ((idColoured == 0 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 1)); } if ( basis == id8888 ) { return (a == 0 && ((idColoured == 0 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 0) || (idColoured == 1 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 1))) || (a == 1 && ((idColoured == 0 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 0) || (idColoured == 1 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 1))) || (a == 2 && ((idColoured == 0 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 0) || (idColoured == 2 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 2))) || (a == 3 && ((idColoured == 0 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 0))) || (a == 4 && ((idColoured == 0 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 0))) || (a == 5 && ((idColoured == 0 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 0))) || (a == 6 && ((idColoured == 0 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 0))) || (a == 7 && ((idColoured == 0 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 0))) || (a == 8 && ((idColoured == 0 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 0))); } if ( basis == id33bar88 ) { return (a == 0 && ((idColoured == 2 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 2) || (idColoured == 0 && idAntiColoured == 1))) || (a == 1 && ((idColoured == 0 && idAntiColoured == 2) || (idColoured == 3 && idAntiColoured == 1) || (idColoured == 2 && idAntiColoured == 3))) || (a == 2 && ((idColoured == 0 && idAntiColoured == 3) || (idColoured == 2 && idAntiColoured == 1) || (idColoured == 3 && idAntiColoured == 2))); } if ( basis == id33bar33bar ) { return (a == 0 && ((idColoured == 0 && idAntiColoured == 3) || (idColoured == 2 && idAntiColoured == 1))) || (a == 1 && ((idColoured == 0 && idAntiColoured == 1) || (idColoured == 2 && idAntiColoured == 3))); } if ( basis == id88888 ) { return (a == 0 && ((idColoured == 3 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 3) || (idColoured == 0 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 0))) || (a == 1 && ((idColoured == 2 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 2) || (idColoured == 0 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 0))) || (a == 2 && ((idColoured == 2 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 2) || (idColoured == 0 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 0))) || (a == 3 && ((idColoured == 3 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 3) || (idColoured == 0 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 0))) || (a == 4 && ((idColoured == 1 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 1) || (idColoured == 0 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 0))) || (a == 5 && ((idColoured == 1 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 1) || (idColoured == 0 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 0))) || (a == 6 && ((idColoured == 2 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 2) || (idColoured == 0 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 0))) || (a == 7 && ((idColoured == 1 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 1) || (idColoured == 0 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 0))) || (a == 8 && ((idColoured == 1 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 1) || (idColoured == 0 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 0))) || (a == 9 && ((idColoured == 2 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 2) || (idColoured == 0 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 0))) || (a == 10 && ((idColoured == 1 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 1) || (idColoured == 0 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 0))) || (a == 11 && ((idColoured == 1 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 1) || (idColoured == 0 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 0))) || (a == 12 && ((idColoured == 0 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 0) || (idColoured == 1 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 1))) || (a == 13 && ((idColoured == 0 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 0) || (idColoured == 1 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 1))) || (a == 14 && ((idColoured == 0 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 0) || (idColoured == 1 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 1))) || (a == 15 && ((idColoured == 0 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 0) || (idColoured == 1 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 1))) || (a == 16 && ((idColoured == 0 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 0) || (idColoured == 1 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 1))) || (a == 17 && ((idColoured == 0 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 0) || (idColoured == 1 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 1))) || (a == 18 && ((idColoured == 0 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 0) || (idColoured == 2 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 2))) || (a == 19 && ((idColoured == 0 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 0) || (idColoured == 2 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 2))) || (a == 20 && ((idColoured == 0 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 0))) || (a == 21 && ((idColoured == 0 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 0))) || (a == 22 && ((idColoured == 0 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 0))) || (a == 23 && ((idColoured == 0 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 0))) || (a == 24 && ((idColoured == 0 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 0))) || (a == 25 && ((idColoured == 0 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 0))) || (a == 26 && ((idColoured == 0 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 0))) || (a == 27 && ((idColoured == 0 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 0))) || (a == 28 && ((idColoured == 0 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 0))) || (a == 29 && ((idColoured == 0 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 0))) || (a == 30 && ((idColoured == 0 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 0))) || (a == 31 && ((idColoured == 0 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 0))) || (a == 32 && ((idColoured == 0 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 0))) || (a == 33 && ((idColoured == 0 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 0))) || (a == 34 && ((idColoured == 0 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 0))) || (a == 35 && ((idColoured == 0 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 0))) || (a == 36 && ((idColoured == 0 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 0))) || (a == 37 && ((idColoured == 0 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 0))) || (a == 38 && ((idColoured == 0 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 0))) || (a == 39 && ((idColoured == 0 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 0))) || (a == 40 && ((idColoured == 0 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 0))) || (a == 41 && ((idColoured == 0 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 0))) || (a == 42 && ((idColoured == 0 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 0))) || (a == 43 && ((idColoured == 0 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 1) || (idColoured == 1 && idAntiColoured == 0))); } if ( basis == id33bar888 ) { return (a == 0 && ((idColoured == 2 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 2) || (idColoured == 0 && idAntiColoured == 1))) || (a == 1 && ((idColoured == 2 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 2) || (idColoured == 0 && idAntiColoured == 1))) || (a == 2 && ((idColoured == 3 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 3) || (idColoured == 0 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 1))) || (a == 3 && ((idColoured == 2 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 2) || (idColoured == 0 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 1))) || (a == 4 && ((idColoured == 2 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 2) || (idColoured == 0 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 1))) || (a == 5 && ((idColoured == 0 && idAntiColoured == 2) || (idColoured == 4 && idAntiColoured == 1) || (idColoured == 2 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 4))) || (a == 6 && ((idColoured == 0 && idAntiColoured == 2) || (idColoured == 3 && idAntiColoured == 1) || (idColoured == 2 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 3))) || (a == 7 && ((idColoured == 0 && idAntiColoured == 3) || (idColoured == 4 && idAntiColoured == 1) || (idColoured == 3 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 4))) || (a == 8 && ((idColoured == 0 && idAntiColoured == 3) || (idColoured == 2 && idAntiColoured == 1) || (idColoured == 3 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 2))) || (a == 9 && ((idColoured == 0 && idAntiColoured == 4) || (idColoured == 3 && idAntiColoured == 1) || (idColoured == 4 && idAntiColoured == 2) || (idColoured == 2 && idAntiColoured == 3))) || (a == 10 && ((idColoured == 0 && idAntiColoured == 4) || (idColoured == 2 && idAntiColoured == 1) || (idColoured == 4 && idAntiColoured == 3) || (idColoured == 3 && idAntiColoured == 2))); } if ( basis == id33bar33bar8 ) { return (a == 0 && ((idColoured == 0 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 3) || (idColoured == 2 && idAntiColoured == 1))) || (a == 1 && ((idColoured == 0 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 1) || (idColoured == 2 && idAntiColoured == 3))) || (a == 2 && ((idColoured == 0 && idAntiColoured == 3) || (idColoured == 2 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 1))) || (a == 3 && ((idColoured == 0 && idAntiColoured == 1) || (idColoured == 2 && idAntiColoured == 4) || (idColoured == 4 && idAntiColoured == 3))); } throw Exception() << "SimpleColourBasis2::colourConnected(): Cannot handle colour configuration" << Exception::runerror; return false; } map > > SimpleColourBasis2::basisList(const vector& basis) const { if ( id33bar.empty() ) makeIds(); map > > blist; vector > structures; vector structure; if ( basis == id88 ) { structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(1); structures.push_back(structure); blist[0] = structures; return blist; } if ( basis == id33bar ) { structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(1); structures.push_back(structure); blist[0] = structures; return blist; } if ( basis == id888 ) { structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(1); structure.push_back(2); structures.push_back(structure); blist[0] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(2); structure.push_back(1); structures.push_back(structure); blist[1] = structures; return blist; } if ( basis == id33bar8 ) { structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(2); structure.push_back(1); structures.push_back(structure); blist[0] = structures; return blist; } if ( basis == id8888 ) { structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(3); structures.push_back(structure); structure.clear(); structure.push_back(1); structure.push_back(2); structures.push_back(structure); blist[0] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(2); structures.push_back(structure); structure.clear(); structure.push_back(1); structure.push_back(3); structures.push_back(structure); blist[1] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(1); structures.push_back(structure); structure.clear(); structure.push_back(2); structure.push_back(3); structures.push_back(structure); blist[2] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(1); structure.push_back(2); structure.push_back(3); structures.push_back(structure); blist[3] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(1); structure.push_back(3); structure.push_back(2); structures.push_back(structure); blist[4] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(2); structure.push_back(1); structure.push_back(3); structures.push_back(structure); blist[5] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(2); structure.push_back(3); structure.push_back(1); structures.push_back(structure); blist[6] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(3); structure.push_back(1); structure.push_back(2); structures.push_back(structure); blist[7] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(3); structure.push_back(2); structure.push_back(1); structures.push_back(structure); blist[8] = structures; return blist; } if ( basis == id33bar88 ) { structures.clear(); structure.clear(); structure.push_back(2); structure.push_back(3); structures.push_back(structure); structure.clear(); structure.push_back(0); structure.push_back(1); structures.push_back(structure); blist[0] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(2); structure.push_back(3); structure.push_back(1); structures.push_back(structure); blist[1] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(3); structure.push_back(2); structure.push_back(1); structures.push_back(structure); blist[2] = structures; return blist; } if ( basis == id33bar33bar ) { structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(3); structures.push_back(structure); structure.clear(); structure.push_back(2); structure.push_back(1); structures.push_back(structure); blist[0] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(1); structures.push_back(structure); structure.clear(); structure.push_back(2); structure.push_back(3); structures.push_back(structure); blist[1] = structures; return blist; } if ( basis == id88888 ) { structures.clear(); structure.clear(); structure.push_back(3); structure.push_back(4); structures.push_back(structure); structure.clear(); structure.push_back(0); structure.push_back(1); structure.push_back(2); structures.push_back(structure); blist[0] = structures; structures.clear(); structure.clear(); structure.push_back(2); structure.push_back(4); structures.push_back(structure); structure.clear(); structure.push_back(0); structure.push_back(1); structure.push_back(3); structures.push_back(structure); blist[1] = structures; structures.clear(); structure.clear(); structure.push_back(2); structure.push_back(3); structures.push_back(structure); structure.clear(); structure.push_back(0); structure.push_back(1); structure.push_back(4); structures.push_back(structure); blist[2] = structures; structures.clear(); structure.clear(); structure.push_back(3); structure.push_back(4); structures.push_back(structure); structure.clear(); structure.push_back(0); structure.push_back(2); structure.push_back(1); structures.push_back(structure); blist[3] = structures; structures.clear(); structure.clear(); structure.push_back(1); structure.push_back(4); structures.push_back(structure); structure.clear(); structure.push_back(0); structure.push_back(2); structure.push_back(3); structures.push_back(structure); blist[4] = structures; structures.clear(); structure.clear(); structure.push_back(1); structure.push_back(3); structures.push_back(structure); structure.clear(); structure.push_back(0); structure.push_back(2); structure.push_back(4); structures.push_back(structure); blist[5] = structures; structures.clear(); structure.clear(); structure.push_back(2); structure.push_back(4); structures.push_back(structure); structure.clear(); structure.push_back(0); structure.push_back(3); structure.push_back(1); structures.push_back(structure); blist[6] = structures; structures.clear(); structure.clear(); structure.push_back(1); structure.push_back(4); structures.push_back(structure); structure.clear(); structure.push_back(0); structure.push_back(3); structure.push_back(2); structures.push_back(structure); blist[7] = structures; structures.clear(); structure.clear(); structure.push_back(1); structure.push_back(2); structures.push_back(structure); structure.clear(); structure.push_back(0); structure.push_back(3); structure.push_back(4); structures.push_back(structure); blist[8] = structures; structures.clear(); structure.clear(); structure.push_back(2); structure.push_back(3); structures.push_back(structure); structure.clear(); structure.push_back(0); structure.push_back(4); structure.push_back(1); structures.push_back(structure); blist[9] = structures; structures.clear(); structure.clear(); structure.push_back(1); structure.push_back(3); structures.push_back(structure); structure.clear(); structure.push_back(0); structure.push_back(4); structure.push_back(2); structures.push_back(structure); blist[10] = structures; structures.clear(); structure.clear(); structure.push_back(1); structure.push_back(2); structures.push_back(structure); structure.clear(); structure.push_back(0); structure.push_back(4); structure.push_back(3); structures.push_back(structure); blist[11] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(4); structures.push_back(structure); structure.clear(); structure.push_back(1); structure.push_back(2); structure.push_back(3); structures.push_back(structure); blist[12] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(3); structures.push_back(structure); structure.clear(); structure.push_back(1); structure.push_back(2); structure.push_back(4); structures.push_back(structure); blist[13] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(4); structures.push_back(structure); structure.clear(); structure.push_back(1); structure.push_back(3); structure.push_back(2); structures.push_back(structure); blist[14] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(2); structures.push_back(structure); structure.clear(); structure.push_back(1); structure.push_back(3); structure.push_back(4); structures.push_back(structure); blist[15] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(3); structures.push_back(structure); structure.clear(); structure.push_back(1); structure.push_back(4); structure.push_back(2); structures.push_back(structure); blist[16] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(2); structures.push_back(structure); structure.clear(); structure.push_back(1); structure.push_back(4); structure.push_back(3); structures.push_back(structure); blist[17] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(1); structures.push_back(structure); structure.clear(); structure.push_back(2); structure.push_back(3); structure.push_back(4); structures.push_back(structure); blist[18] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(1); structures.push_back(structure); structure.clear(); structure.push_back(2); structure.push_back(4); structure.push_back(3); structures.push_back(structure); blist[19] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(1); structure.push_back(2); structure.push_back(3); structure.push_back(4); structures.push_back(structure); blist[20] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(1); structure.push_back(2); structure.push_back(4); structure.push_back(3); structures.push_back(structure); blist[21] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(1); structure.push_back(3); structure.push_back(2); structure.push_back(4); structures.push_back(structure); blist[22] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(1); structure.push_back(3); structure.push_back(4); structure.push_back(2); structures.push_back(structure); blist[23] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(1); structure.push_back(4); structure.push_back(2); structure.push_back(3); structures.push_back(structure); blist[24] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(1); structure.push_back(4); structure.push_back(3); structure.push_back(2); structures.push_back(structure); blist[25] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(2); structure.push_back(1); structure.push_back(3); structure.push_back(4); structures.push_back(structure); blist[26] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(2); structure.push_back(1); structure.push_back(4); structure.push_back(3); structures.push_back(structure); blist[27] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(2); structure.push_back(3); structure.push_back(1); structure.push_back(4); structures.push_back(structure); blist[28] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(2); structure.push_back(3); structure.push_back(4); structure.push_back(1); structures.push_back(structure); blist[29] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(2); structure.push_back(4); structure.push_back(1); structure.push_back(3); structures.push_back(structure); blist[30] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(2); structure.push_back(4); structure.push_back(3); structure.push_back(1); structures.push_back(structure); blist[31] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(3); structure.push_back(1); structure.push_back(2); structure.push_back(4); structures.push_back(structure); blist[32] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(3); structure.push_back(1); structure.push_back(4); structure.push_back(2); structures.push_back(structure); blist[33] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(3); structure.push_back(2); structure.push_back(1); structure.push_back(4); structures.push_back(structure); blist[34] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(3); structure.push_back(2); structure.push_back(4); structure.push_back(1); structures.push_back(structure); blist[35] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(3); structure.push_back(4); structure.push_back(1); structure.push_back(2); structures.push_back(structure); blist[36] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(3); structure.push_back(4); structure.push_back(2); structure.push_back(1); structures.push_back(structure); blist[37] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(4); structure.push_back(1); structure.push_back(2); structure.push_back(3); structures.push_back(structure); blist[38] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(4); structure.push_back(1); structure.push_back(3); structure.push_back(2); structures.push_back(structure); blist[39] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(4); structure.push_back(2); structure.push_back(1); structure.push_back(3); structures.push_back(structure); blist[40] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(4); structure.push_back(2); structure.push_back(3); structure.push_back(1); structures.push_back(structure); blist[41] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(4); structure.push_back(3); structure.push_back(1); structure.push_back(2); structures.push_back(structure); blist[42] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(4); structure.push_back(3); structure.push_back(2); structure.push_back(1); structures.push_back(structure); blist[43] = structures; return blist; } if ( basis == id33bar888 ) { structures.clear(); structure.clear(); structure.push_back(2); structure.push_back(3); structure.push_back(4); structures.push_back(structure); structure.clear(); structure.push_back(0); structure.push_back(1); structures.push_back(structure); blist[0] = structures; structures.clear(); structure.clear(); structure.push_back(2); structure.push_back(4); structure.push_back(3); structures.push_back(structure); structure.clear(); structure.push_back(0); structure.push_back(1); structures.push_back(structure); blist[1] = structures; structures.clear(); structure.clear(); structure.push_back(3); structure.push_back(4); structures.push_back(structure); structure.clear(); structure.push_back(0); structure.push_back(2); structure.push_back(1); structures.push_back(structure); blist[2] = structures; structures.clear(); structure.clear(); structure.push_back(2); structure.push_back(4); structures.push_back(structure); structure.clear(); structure.push_back(0); structure.push_back(3); structure.push_back(1); structures.push_back(structure); blist[3] = structures; structures.clear(); structure.clear(); structure.push_back(2); structure.push_back(3); structures.push_back(structure); structure.clear(); structure.push_back(0); structure.push_back(4); structure.push_back(1); structures.push_back(structure); blist[4] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(2); structure.push_back(3); structure.push_back(4); structure.push_back(1); structures.push_back(structure); blist[5] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(2); structure.push_back(4); structure.push_back(3); structure.push_back(1); structures.push_back(structure); blist[6] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(3); structure.push_back(2); structure.push_back(4); structure.push_back(1); structures.push_back(structure); blist[7] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(3); structure.push_back(4); structure.push_back(2); structure.push_back(1); structures.push_back(structure); blist[8] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(4); structure.push_back(2); structure.push_back(3); structure.push_back(1); structures.push_back(structure); blist[9] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(4); structure.push_back(3); structure.push_back(2); structure.push_back(1); structures.push_back(structure); blist[10] = structures; return blist; } if ( basis == id33bar33bar8 ) { structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(4); structure.push_back(3); structures.push_back(structure); structure.clear(); structure.push_back(2); structure.push_back(1); structures.push_back(structure); blist[0] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(4); structure.push_back(1); structures.push_back(structure); structure.clear(); structure.push_back(2); structure.push_back(3); structures.push_back(structure); blist[1] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(3); structures.push_back(structure); structure.clear(); structure.push_back(2); structure.push_back(4); structure.push_back(1); structures.push_back(structure); blist[2] = structures; structures.clear(); structure.clear(); structure.push_back(0); structure.push_back(1); structures.push_back(structure); structure.clear(); structure.push_back(2); structure.push_back(4); structure.push_back(3); structures.push_back(structure); blist[3] = structures; return blist; } throw Exception() << "SimpleColourBasis2::basisList(): Cannot handle colour configuration" << Exception::runerror; return blist; } void SimpleColourBasis2::makeIds() const { id88 = vector(2,PDT::Colour8); id33bar.push_back(PDT::Colour3); id33bar.push_back(PDT::Colour3bar); id888 = vector(3,PDT::Colour8); id33bar8 = id33bar; id33bar8.push_back(PDT::Colour8); id8888 = vector(4,PDT::Colour8); id33bar88 = id33bar8; id33bar88.push_back(PDT::Colour8); id33bar33bar = id33bar; id33bar33bar.push_back(PDT::Colour3); id33bar33bar.push_back(PDT::Colour3bar); id88888 = vector(5,PDT::Colour8); id33bar888 = id33bar88; id33bar888.push_back(PDT::Colour8); id33bar33bar8 = id33bar33bar; id33bar33bar8.push_back(PDT::Colour8); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void SimpleColourBasis2::persistentOutput(PersistentOStream &) const {} void SimpleColourBasis2::persistentInput(PersistentIStream &, int) {} // *** Attention *** The following static variable is needed for the type // description system in ThePEG. Please check that the template arguments // are correct (the class and its base class), and that the constructor // arguments are correct (the class name and the name of the dynamically // loadable library where the class implementation can be found). DescribeClass describeHerwigSimpleColourBasis2("Herwig::SimpleColourBasis2", "Herwig.so"); void SimpleColourBasis2::Init() { static ClassDocumentation documentation ("SimpleColourBasis2 implements the colour algebra needed for " "processes with four coloured legs at NLO. It mainly " "serves as an example for the general ColourBasis interface."); } diff --git a/MatrixElement/Matchbox/Utility/Tree2toNGenerator.cc b/MatrixElement/Matchbox/Utility/Tree2toNGenerator.cc --- a/MatrixElement/Matchbox/Utility/Tree2toNGenerator.cc +++ b/MatrixElement/Matchbox/Utility/Tree2toNGenerator.cc @@ -1,490 +1,490 @@ // -*- C++ -*- // // Tree2toNGenerator.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2017 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the Tree2toNGenerator class. // #include "Tree2toNGenerator.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/RefVector.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/Command.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Utilities/StringUtils.h" using namespace Herwig; Tree2toNGenerator::Tree2toNGenerator() : maxOrderGs(0), maxOrderGem(0), prepared(false) {} Tree2toNGenerator::~Tree2toNGenerator() {} IBPtr Tree2toNGenerator::clone() const { return new_ptr(*this); } IBPtr Tree2toNGenerator::fullclone() const { return new_ptr(*this); } vector::ptr> Tree2toNGenerator:: generate(const PDVector& legs, unsigned int orderInGs, unsigned int orderInGem) { vector::ptr> res; list > prog = clusterAll(legs,orderInGs,orderInGem); int count = 1; for ( auto & d : prog ) { assert(d.size() == 1); Tree2toNDiagram diag = d.front().generate(count); if ( !spaceLikeAllowed.empty() ) { map counts; for ( int k = 1; k < diag.nSpace()-1; ++k ) counts[diag.allPartons()[k]] += 1; for ( auto & m : spaceLikeAllowed ) { m.reset(); for ( auto const & c : counts ) m.add(c.first,c.second); } bool failed = false; for ( auto const & m : spaceLikeAllowed) { if ( !m.check() ) { failed = true; break; } } if ( failed ) continue; } if ( !timeLikeAllowed.empty() ) { map counts; int all = diag.allPartons().size(); for ( int k = diag.nSpace(); k < all; ++k ) { if ( diag.children(k).first < 0 ) continue; counts[diag.allPartons()[k]] += 1; } for ( auto & m : timeLikeAllowed ) { m.reset(); for ( auto const & c : counts ) m.add(c.first,c.second); } bool failed = false; for ( auto const & m : timeLikeAllowed ) { if ( !m.check() ) { failed = true; break; } } if ( failed ) continue; } bool internalVeto = false; set external; int nex = diag.partons().size(); for ( int i = 0; i < nex; ++i ) { external.insert(diag.diagramId(i)); } int n = diag.allPartons().size(); for ( int i = 0; i < n; ++i ) { if ( external.find(i) != external.end() ) continue; if ( find(excludeInternal().begin(), excludeInternal().end(), diag.allPartons()[i]) != excludeInternal().end() ) { internalVeto = true; break; } } if ( internalVeto ) continue; bool gotit = false; for ( auto const & d : res) { map checkPermutation; if ( diag.isSame(d,checkPermutation) ) { gotit = true; for ( auto const & p : checkPermutation ) if ( p.first != p.second ) gotit = false; if ( gotit ) break; } } if ( !gotit ) { res.push_back(new_ptr(diag)); ++count; } } return res; } list > Tree2toNGenerator:: cluster(const vector& children, unsigned int orderInGs, unsigned int orderInGem) const { list > res; bool externalCluster = children[1].externalId != -1; if ( children.size() == 3 ) { for ( auto const & v : theVertices ) { if ( v->getNpoint() != 3 ) continue; if ( find(theExcludeVertices.begin(), theExcludeVertices.end(), v) != theExcludeVertices.end() ) continue; bool noMatch = - v->orderInGs() != orderInGs || - v->orderInGem() != orderInGem || + v->orderInGs() != int(orderInGs) || + v->orderInGem() != int(orderInGem) || !v->isIncoming(children[0].parent); long idij = children[0].parent->id(); long idi = children[2].parent->id(); long idj = children[1].parent->id(); if ( externalCluster && children[1].parent->CC() ) idj = -idj; if ( children[0].parent->CC() ) idij = -idij; if ( !externalCluster ) noMatch |= !v->isOutgoing(children[1].parent) || !v->isOutgoing(children[2].parent); else noMatch |= !v->isIncoming(children[1].parent) || !v->isOutgoing(children[2].parent); noMatch |= !( v->allowed(idij,idi,idj) || v->allowed(idj,idij,idi) || v->allowed(idi,idj,idij) || v->allowed(idij,idj,idi) || v->allowed(idi,idij,idj) || v->allowed(idj,idi,idij) ); if ( noMatch ) continue; Vertex last; last.spacelike = true; last.parent = children[0].parent; last.externalId = 0; last.children.push_back(children[1]); last.children.push_back(children[2]); res.push_back(vector(1,last)); // only one possible break; } return res; } // spacelike clusterings (cluster on second one) for ( size_t i = 2; i < children.size(); ++i ) { for ( auto const & v : theVertices ) { if ( v->getNpoint() != 3 ) continue; if ( find(theExcludeVertices.begin(), theExcludeVertices.end(), v) != theExcludeVertices.end() ) continue; bool noMatch = false; noMatch |= - v->orderInGs() != orderInGs || - v->orderInGem() != orderInGem; + v->orderInGs() != int(orderInGs) || + v->orderInGem() != int(orderInGem); if ( !externalCluster ) noMatch |= !v->isOutgoing(children[1].parent) || !v->isOutgoing(children[i].parent); else noMatch |= !v->isIncoming(children[1].parent) || !v->isOutgoing(children[i].parent); if ( noMatch ) continue; long idi = children[i].parent->id(); long idj = children[1].parent->id(); if ( externalCluster && children[1].parent->CC() ) idj = -idj; for ( set::const_iterator pij = v->outgoing().begin(); pij != v->outgoing().end() ; ++pij ) { long idij = (**pij).id(); if ( v->allowed(idij,idi,idj) || v->allowed(idj,idij,idi) || v->allowed(idi,idj,idij) || v->allowed(idij,idj,idi) || v->allowed(idi,idij,idj) || v->allowed(idj,idi,idij) ) { PDPtr dij = (**pij).CC() ? (**pij).CC() : *pij; vector cled; for ( size_t k = 0; k < children.size(); ++k ) { if ( k != 1 && k != i ) cled.push_back(children[k]); if ( k == 1 ) { Vertex merge; merge.children.push_back(children[1]); merge.children.push_back(children[i]); merge.parent = dij; merge.spacelike = true; cled.push_back(merge); } if ( k == i ) continue; } res.push_back(cled); } } } } // timelike clusterings for ( size_t i = 2; i < children.size(); ++i ) { for ( size_t j = i+1; j < children.size(); ++j ) { for ( auto const & v : theVertices ) { if ( v->getNpoint() != 3 ) continue; if ( find(theExcludeVertices.begin(), theExcludeVertices.end(), v) != theExcludeVertices.end() ) continue; - if ( v->orderInGs() != orderInGs || - v->orderInGem() != orderInGem || + if ( v->orderInGs() != int(orderInGs) || + v->orderInGem() != int(orderInGem) || !v->isOutgoing(children[i].parent) || !v->isOutgoing(children[j].parent) ) continue; long idi = children[i].parent->id(); long idj = children[j].parent->id(); for ( set::const_iterator pij = v->outgoing().begin(); pij != v->outgoing().end() ; ++pij ) { long idij = (**pij).id(); if ( v->allowed(idij,idi,idj) || v->allowed(idj,idij,idi) || v->allowed(idi,idj,idij) || v->allowed(idij,idj,idi) || v->allowed(idi,idij,idj) || v->allowed(idj,idi,idij) ) { PDPtr dij = (**pij).CC() ? (**pij).CC() : *pij; vector cled; for ( size_t k = 0; k < children.size(); ++k ) { if ( k != i && k != j ) cled.push_back(children[k]); if ( k == i ) { Vertex merge; merge.children.push_back(children[i]); merge.children.push_back(children[j]); merge.parent = dij; merge.spacelike = false; cled.push_back(merge); } if ( k == j ) continue; } res.push_back(cled); } } } } } return res; } list > Tree2toNGenerator:: clusterAll(const list >& current, unsigned int orderInGs, unsigned int orderInGem) const { list > res; for ( list >::const_iterator c = current.begin(); c != current.end(); ++c ) { if ( c->size() == 1 ) { if ( orderInGs == 0 && orderInGem == 0 ) res.push_back(*c); continue; } for ( unsigned int gs = 0; gs <= maxOrderGs; ++gs ) for ( unsigned int gem = 0; gem <= maxOrderGem; ++gem ) { if ( gs == 0 && gem == 0 ) continue; if ( gs > orderInGs || gem > orderInGem ) continue; list > next = cluster(*c,gs,gem); if ( next.empty() ) continue; list > cled = clusterAll(next,orderInGs-gs,orderInGem-gem); copy(cled.begin(),cled.end(),back_inserter(res)); } } return res; } list > Tree2toNGenerator:: clusterAll(const PDVector& external, unsigned int orderInGs, unsigned int orderInGem) { if ( !prepared ) { for ( auto & v : theVertices ) { if ( find(theExcludeVertices.begin(), theExcludeVertices.end(), v) != theExcludeVertices.end() ) continue; v->init(); maxOrderGs = max(maxOrderGs,v->orderInGs()); maxOrderGem = max(maxOrderGem,v->orderInGem()); } for ( auto & m : spaceLikeAllowed) m.rebind(this); for ( auto & m : timeLikeAllowed ) m.rebind(this); prepared = true; } vector legs; for ( unsigned int k = 0; k < external.size(); ++k ) { Vertex v; v.parent = external[k]; v.externalId = k; v.spacelike = k < 2; legs.push_back(v); } list > firstlegs; firstlegs.push_back(legs); return clusterAll(firstlegs,orderInGs,orderInGem); } string Tree2toNGenerator::doSpaceLikeRange(string range) { if ( theRestrictLines.empty() ) return "No particle data specified to restrict internal lines."; vector bounds = StringUtils::split(range); if ( bounds.empty() || bounds.size() > 2 ) return "Need to specify a minimum, or a minimum and maximum number of internal lines."; pair irange(0,-1); istringstream in1(bounds[0]); in1 >> irange.first; if ( bounds.size() == 2 ) { istringstream in2(bounds[1]); in2 >> irange.second; } else { irange.second = irange.first; } if ( irange.second >= 0 && irange.first > irange.second ) return "invalid range specified"; spaceLikeAllowed.push_back(LineMatcher(theRestrictLines,irange)); return ""; } string Tree2toNGenerator::doTimeLikeRange(string range) { if ( theRestrictLines.empty() ) return "No particle data specified to restrict internal lines."; vector bounds = StringUtils::split(range); if ( bounds.empty() || bounds.size() > 2 ) return "Need to specify a minimum, or a minimum and maximum number of internal lines."; pair irange(0,-1); istringstream in1(bounds[0]); in1 >> irange.first; if ( bounds.size() == 2 ) { istringstream in2(bounds[1]); in2 >> irange.second; } else { irange.second = irange.first; } if ( irange.second >= 0 && irange.first > irange.second ) return "invalid range specified"; timeLikeAllowed.push_back(LineMatcher(theRestrictLines,irange)); return ""; } string Tree2toNGenerator::doClearRestrictLines(string) { theRestrictLines.clear(); return ""; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void Tree2toNGenerator::persistentOutput(PersistentOStream & os) const { os << theVertices << theExcludeInternal << maxOrderGs << maxOrderGem << prepared << theExcludeVertices << spaceLikeAllowed << timeLikeAllowed; } void Tree2toNGenerator::persistentInput(PersistentIStream & is, int) { is >> theVertices >> theExcludeInternal >> maxOrderGs >> maxOrderGem >> prepared >> theExcludeVertices >> spaceLikeAllowed >> timeLikeAllowed; } // *** Attention *** The following static variable is needed for the type // description system in ThePEG. Please check that the template arguments // are correct (the class and its base class), and that the constructor // arguments are correct (the class name and the name of the dynamically // loadable library where the class implementation can be found). DescribeClass describeHerwigTree2toNGenerator("Herwig::Tree2toNGenerator", "Herwig.so"); void Tree2toNGenerator::Init() { static ClassDocumentation documentation ("Generate Tree2toNDiagrams for a given process."); static RefVector interfaceVertices ("Vertices", "All vertices to consider.", &Tree2toNGenerator::theVertices, -1, false, false, true, false, false); static RefVector interfaceExcludeVertices ("ExcludeVertices", "The vertices to exclude.", &Tree2toNGenerator::theExcludeVertices, -1, false, false, true, false, false); static RefVector interfaceExcludeInternal ("ExcludeInternal", "Particles to be exluded from becoming internal lines.", &Tree2toNGenerator::theExcludeInternal, -1, false, false, true, false, false); static RefVector interfaceRestrictLines ("RestrictLines", "Particles to be exluded from becoming internal lines.", &Tree2toNGenerator::theRestrictLines, -1, false, false, true, false, false); static Command interfaceSpaceLikeRange ("SpaceLikeRange", "Limit the number of spacelike occurences of the specified particle.", &Tree2toNGenerator::doSpaceLikeRange, false); static Command interfaceTimeLikeRange ("TimeLikeRange", "Limit the number of timelike occurences of the specified particle.", &Tree2toNGenerator::doTimeLikeRange, false); static Command interfaceClearRestrictLines ("ClearRestrictLines", "Clear the container of lines to be considered for restrictions.", &Tree2toNGenerator::doClearRestrictLines, false); } diff --git a/MatrixElement/Powheg/MEPP2GammaGammaPowheg.cc b/MatrixElement/Powheg/MEPP2GammaGammaPowheg.cc --- a/MatrixElement/Powheg/MEPP2GammaGammaPowheg.cc +++ b/MatrixElement/Powheg/MEPP2GammaGammaPowheg.cc @@ -1,2047 +1,2051 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the MEPP2GammaGammaPowheg class. // #include "MEPP2GammaGammaPowheg.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/Cuts/Cuts.h" #include "ThePEG/Utilities/SimplePhaseSpace.h" #include "Herwig/Models/StandardModel/StandardModel.h" #include "Herwig/Utilities/Maths.h" #include "Herwig/Shower/RealEmissionProcess.h" #include "ThePEG/Utilities/DescribeClass.h" using namespace Herwig; // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeMEPP2GammaGammaPowheg("Herwig::MEPP2GammaGammaPowheg", "HwMEHadron.so HwPowhegMEHadron.so"); unsigned int MEPP2GammaGammaPowheg::orderInAlphaS() const { return 0; } unsigned int MEPP2GammaGammaPowheg::orderInAlphaEW() const { return 2; } IBPtr MEPP2GammaGammaPowheg::clone() const { return new_ptr(*this); } IBPtr MEPP2GammaGammaPowheg::fullclone() const { return new_ptr(*this); } MEPP2GammaGammaPowheg::MEPP2GammaGammaPowheg() : contrib_(1), power_(0.1), process_(0), threeBodyProcess_(0), maxflavour_(5), alphaS_(0.), fixedAlphaS_(false), supressionFunction_(0), supressionScale_(0), lambda_(20.*GeV), preQCDqqbarq_(5.), preQCDqqbarqbar_(0.5), preQCDqg_(50.), preQCDgqbar_(50.), preQEDqqbarq_(40.), preQEDqqbarqbar_(0.5), preQEDqgq_(1.), preQEDgqbarqbar_(1.), minpT_(2.*GeV), scaleChoice_(0), scalePreFactor_(1.) {} void MEPP2GammaGammaPowheg::getDiagrams() const { tcPDPtr gamma = getParticleData(ParticleID::gamma); tcPDPtr g = getParticleData(ParticleID::g); for(int ix=1;ix<=maxflavour_;++ix) { tcPDPtr qk = getParticleData(ix); tcPDPtr qb = qk->CC(); // gamma gamma if(process_==0 || process_ == 1) { add(new_ptr((Tree2toNDiagram(3), qk, qk, qb, 1, gamma, 2, gamma, -1))); add(new_ptr((Tree2toNDiagram(3), qk, qk, qb, 2, gamma, 1, gamma, -2))); } // gamma +jet if(process_==0 || process_ == 2) { add(new_ptr((Tree2toNDiagram(3), qk, qb, qb, 1, gamma, 2, g, -4))); add(new_ptr((Tree2toNDiagram(3), qk, qk, qb, 2, gamma, 1, g, -5))); add(new_ptr((Tree2toNDiagram(3), qk, qk, g, 1, gamma, 2, qk, -6))); add(new_ptr((Tree2toNDiagram(2), qk, g, 1, qk, 3, gamma, 3, qk, -7))); add(new_ptr((Tree2toNDiagram(3), g, qb, qb, 2, gamma, 1, qb, -8))); add(new_ptr((Tree2toNDiagram(2), g, qb, 1, qb, 3, gamma, 3, qb, -9))); } // gamma + jet + gamma if((process_==0 && contrib_==1) || process_ == 3) { // gamma + g + gamma if(threeBodyProcess_==0 || threeBodyProcess_==1) { add(new_ptr((Tree2toNDiagram(4), qk, qk, qk, qb, 1, gamma, 2, gamma, 3, g, -10))); add(new_ptr((Tree2toNDiagram(4), qk, qk, qk, qb, 3, gamma, 2, gamma, 1, g, -12))); } // Z + q + gamma if(threeBodyProcess_==0 || threeBodyProcess_==2) { add(new_ptr((Tree2toNDiagram(4),qk,qk,qk,g,1,gamma,2,gamma,3,qk, -20))); add(new_ptr((Tree2toNDiagram(4),qk,qk,qk,g,2,gamma,1,gamma,3,qk, -21))); add(new_ptr((Tree2toNDiagram(3),qk,qk,g,1,gamma,2,qk,5,gamma,5,qk,-22))); } // Z + qbar + gamma if(threeBodyProcess_==0 || threeBodyProcess_==3) { add(new_ptr((Tree2toNDiagram(4),g,qb,qb,qb,3,gamma,2,gamma,1,qb ,-30))); add(new_ptr((Tree2toNDiagram(4),g,qb,qb,qb,2,gamma,3,gamma,1,qb ,-31))); add(new_ptr((Tree2toNDiagram(3),g,qb,qb ,2,gamma,1,qb,5,gamma,5,qb,-32))); } } } } Energy2 MEPP2GammaGammaPowheg::scale() const { Energy2 scale; if(scaleChoice_==0) { Energy pt; if(meMomenta()[2].perp(meMomenta()[0].vect())>= meMomenta()[3].perp(meMomenta()[0].vect())){ pt = meMomenta()[2].perp(meMomenta()[0].vect()); } else { pt = meMomenta()[3].perp(meMomenta()[0].vect()); } scale = sqr(pt); } else if(scaleChoice_==1) { scale = sHat(); } return scalePreFactor_*scale; } int MEPP2GammaGammaPowheg::nDim() const { return HwMEBase::nDim() + ( contrib_>=1 ? 3 : 0 ); } bool MEPP2GammaGammaPowheg::generateKinematics(const double * r) { // radiative variables if(contrib_>=1) { zTilde_ = r[nDim()-1]; vTilde_ = r[nDim()-2]; phi_ = Constants::twopi*r[nDim()-3]; } // set the jacobian jacobian(1.0); // set up the momenta for ( int i = 2, N = meMomenta().size(); i < N; ++i ) meMomenta()[i] = Lorentz5Momentum(ZERO); // generate sHat Energy2 shat(sHat()); if(mePartonData().size()==5) { double eps = sqr(meMomenta()[2].mass())/shat; jacobian(jacobian()*(1.-eps)); shat *= eps+zTilde_*(1.-eps); } // momenta of the core process double ctmin = -1.0, ctmax = 1.0; Energy q = ZERO; try { q = SimplePhaseSpace:: getMagnitude(shat, meMomenta()[2].mass(), ZERO); } catch ( ImpossibleKinematics & e ) { return false; } Energy e = 0.5*sqrt(shat); Energy2 m22 = meMomenta()[2].mass2(); Energy2 e0e2 = 2.0*e*sqrt(sqr(q) + m22); Energy2 e1e2 = 2.0*e*sqrt(sqr(q) + m22); Energy2 e0e3 = 2.0*e*sqrt(sqr(q)); Energy2 e1e3 = 2.0*e*sqrt(sqr(q)); Energy2 pq = 2.0*e*q; if(mePartonData().size()==4) { Energy2 thmin = lastCuts().minTij(mePartonData()[0], mePartonData()[2]); if ( thmin > ZERO ) ctmax = min(ctmax, (e0e2 - m22 - thmin)/pq); thmin = lastCuts().minTij(mePartonData()[1], mePartonData()[2]); if ( thmin > ZERO ) ctmin = max(ctmin, (thmin + m22 - e1e2)/pq); thmin = lastCuts().minTij(mePartonData()[1], mePartonData()[3]); if ( thmin > ZERO ) ctmax = min(ctmax, (e1e3 - thmin)/pq); thmin = lastCuts().minTij(mePartonData()[0], mePartonData()[3]); if ( thmin > ZERO ) ctmin = max(ctmin, (thmin - e0e3)/pq); Energy ptmin = max(lastCuts().minKT(mePartonData()[2]), lastCuts().minKT(mePartonData()[3])); if ( ptmin > ZERO ) { double ctm = 1.0 - sqr(ptmin/q); if ( ctm <= 0.0 ) return false; ctmin = max(ctmin, -sqrt(ctm)); ctmax = min(ctmax, sqrt(ctm)); } double ymin2 = lastCuts().minYStar(mePartonData()[2]); double ymax2 = lastCuts().maxYStar(mePartonData()[2]); double ymin3 = lastCuts().minYStar(mePartonData()[3]); double ymax3 = lastCuts().maxYStar(mePartonData()[3]); double ytot = lastCuts().Y() + lastCuts().currentYHat(); if ( ymin2 + ytot > -0.9*Constants::MaxRapidity ) ctmin = max(ctmin, sqrt(sqr(q) + m22)*tanh(ymin2)/q); if ( ymax2 + ytot < 0.9*Constants::MaxRapidity ) ctmax = min(ctmax, sqrt(sqr(q) + m22)*tanh(ymax2)/q); if ( ymin3 + ytot > -0.9*Constants::MaxRapidity ) ctmax = min(ctmax, tanh(-ymin3)); if ( ymax3 + ytot < 0.9*Constants::MaxRapidity ) ctmin = max(ctmin, tanh(-ymax3)); if ( ctmin >= ctmax ) return false; } double cth = getCosTheta(ctmin, ctmax, r[0]); Energy pt = q*sqrt(1.0-sqr(cth)); phi(rnd(2.0*Constants::pi)); meMomenta()[2].setVect(Momentum3( pt*sin(phi()), pt*cos(phi()), q*cth)); meMomenta()[3].setVect(Momentum3(-pt*sin(phi()), -pt*cos(phi()), -q*cth)); meMomenta()[2].rescaleEnergy(); meMomenta()[3].rescaleEnergy(); // jacobian tHat(pq*cth + m22 - e0e2); uHat(m22 - shat - tHat()); jacobian(pq/shat*Constants::pi*jacobian()); // end for 2->2 processes if(mePartonData().size()==4) { vector out(2); out[0] = meMomenta()[2]; out[1] = meMomenta()[3]; tcPDVector tout(2); tout[0] = mePartonData()[2]; tout[1] = mePartonData()[3]; if ( !lastCuts().passCuts(tout, out, mePartonData()[0], mePartonData()[1]) ) return false; return true; } // special for 2-3 processes pair x = make_pair(lastX1(),lastX2()); // partons pair partons = make_pair(mePartonData()[0],mePartonData()[1]); // If necessary swap the particle data objects so that // first beam gives the incoming quark if(lastPartons().first ->dataPtr()!=partons.first) { swap(x.first,x.second); } // use vTilde to select the dipole for emission // gamma gamma g processes if(mePartonData()[4]->id()==ParticleID::g) { if(vTilde_<=0.5) { dipole_ = IIQCD1; vTilde_ = 4.*vTilde_; } else { dipole_ = IIQCD2; vTilde_ = 4.*(vTilde_-0.25); } jacobian(2.*jacobian()); } // gamma gamma q processes else if(mePartonData()[4]->id()>0&&mePartonData()[4]->id()<6) { if(vTilde_<=1./3.) { dipole_ = IIQCD2; vTilde_ = 3.*vTilde_; } else if(vTilde_<=2./3.) { dipole_ = IFQED1; vTilde_ = 3.*vTilde_-1.; } else { dipole_ = FIQED1; vTilde_ = 3.*vTilde_-2.; } jacobian(3.*jacobian()); } // gamma gamma qbar processes else if(mePartonData()[4]->id()<0&&mePartonData()[4]->id()>-6) { if(vTilde_<=1./3.) { dipole_ = IIQCD1; vTilde_ = 3.*vTilde_; } else if(vTilde_<=2./3.) { dipole_ = IFQED2; vTilde_ = 3.*vTilde_-1.; } else { dipole_ = FIQED2; vTilde_ = 3.*vTilde_-2.; } jacobian(3.*jacobian()); } else { assert(false); } // initial-initial dipoles if(dipole_<=4) { double z = shat/sHat(); double vt = vTilde_*(1.-z); double vJac = 1.-z; Energy pT = sqrt(shat*vt*(1.-vt-z)/z); if(pT pnew(5); pnew [0] = Lorentz5Momentum(ZERO,ZERO,0.5*rs*x.first, 0.5*rs*x.first,ZERO); pnew [1] = Lorentz5Momentum(ZERO,ZERO,-0.5*rs*x.second, 0.5*rs*x.second,ZERO) ; pnew [2] = meMomenta()[2]; pnew [3] = meMomenta()[3]; pnew [4] = Lorentz5Momentum(pT*cos(phi_),pT*sin(phi_), pT*sinh(rapidity), pT*cosh(rapidity), ZERO); pnew[4].rescaleEnergy(); Lorentz5Momentum K = pnew [0]+pnew [1]-pnew [4]; Lorentz5Momentum Kt = pcmf; Lorentz5Momentum Ksum = K+Kt; Energy2 K2 = K.m2(); Energy2 Ksum2 = Ksum.m2(); for(unsigned int ix=2;ix<4;++ix) { pnew [ix].boost(blab); pnew [ix] = pnew [ix] - 2.*Ksum*(Ksum*pnew [ix])/Ksum2 +2*K*(Kt*pnew [ix])/K2; pnew[ix].rescaleEnergy(); } pcmf = Lorentz5Momentum(ZERO,ZERO, 0.5*rs*(x.first-x.second), 0.5*rs*(x.first+x.second)); pcmf.rescaleMass(); blab = pcmf.boostVector(); for(unsigned int ix=0;ix1e-20) { rot.setRotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.)); rot.rotateX(Constants::pi); } if(abs(1.-q.e()/q.vect().mag())>1e-6) rot.boostZ(q.e()/q.vect().mag()); pin *= rot; if(pin.perp2()/GeV2>1e-20) { Boost trans = -1./pin.e()*pin.vect(); trans.setZ(0.); rot.boost(trans); } rot.invert(); Energy Q = sqrt(-q.m2()); meMomenta()[4] = rot*Lorentz5Momentum( 0.5*Q*xT*cos(phi_), 0.5*Q*xT*sin(phi_), -0.5*Q*x2,0.5*Q*sqrt(sqr(x2)+sqr(xT))); meMomenta()[3] = rot*Lorentz5Momentum(-0.5*Q*xT*cos(phi_),-0.5*Q*xT*sin(phi_), -0.5*Q*x3,0.5*Q*sqrt(sqr(x3)+sqr(xT))); double ratio; if(dipole_<=6) { ratio = 2.*((meMomenta()[3]+meMomenta()[4])*meMomenta()[0])/sHat(); } else { ratio = 2.*((meMomenta()[3]+meMomenta()[4])*meMomenta()[1])/sHat(); } jacobian(jacobian()*ratio); } else { assert(false); } vector out(3); tcPDVector tout(3); for(unsigned int ix=0;ix<3;++ix) { out[ix] = meMomenta() [2+ix]; tout[ix] = mePartonData()[2+ix]; } return lastCuts().passCuts(tout, out, mePartonData()[0], mePartonData()[1]); } double MEPP2GammaGammaPowheg::me2() const { // Born configurations if(mePartonData().size()==4) { // gamma gamma core process if(mePartonData()[3]->id()==ParticleID::gamma) { return 2.*Constants::twopi*alphaEM_* loGammaGammaME(mePartonData(),meMomenta(),true); } // V jet core process else if(mePartonData()[3]->id()==ParticleID::g) { return 2.*Constants::twopi*alphaS_* loGammagME(mePartonData(),meMomenta(),true); } else if(mePartonData()[3]->id()>0) { return 2.*Constants::twopi*alphaS_* loGammaqME(mePartonData(),meMomenta(),true); } else if(mePartonData()[3]->id()<0) { return 2.*Constants::twopi*alphaS_* loGammaqbarME(mePartonData(),meMomenta(),true); } - else + else { assert(false); + return 0.; + } } // hard emission configurations else { if(mePartonData()[4]->id()==ParticleID::g) return sHat()*realGammaGammagME (mePartonData(),meMomenta(),dipole_,Hard,true); else if(mePartonData()[4]->id()>0&&mePartonData()[4]->id()<6) return sHat()*realGammaGammaqME (mePartonData(),meMomenta(),dipole_,Hard,true); else if(mePartonData()[4]->id()<0&&mePartonData()[4]->id()>-6) return sHat()*realGammaGammaqbarME(mePartonData(),meMomenta(),dipole_,Hard,true); - else + else { assert(false); + return 0.; + } } } CrossSection MEPP2GammaGammaPowheg::dSigHatDR() const { // couplings if(!fixedAlphaS_) alphaS_ = SM().alphaS(scale()); alphaEM_ = SM().alphaEM(); // cross section CrossSection preFactor = jacobian()/(16.0*sqr(Constants::pi)*sHat())*sqr(hbarc); loME_ = me2(); if( contrib_== 0 || mePartonData().size()==5 || (mePartonData().size()==4&& mePartonData()[3]->coloured())) return loME_*preFactor; else return NLOWeight()*preFactor; } Selector MEPP2GammaGammaPowheg::diagrams(const DiagramVector & diags) const { if(mePartonData().size()==4) { if(mePartonData()[3]->id()==ParticleID::gamma) { Selector sel; for ( DiagramIndex i = 0; i < diags.size(); ++i ){ sel.insert(meInfo()[abs(diags[i]->id())], i); } return sel; } else { Selector sel; for ( DiagramIndex i = 0; i < diags.size(); ++i ){ sel.insert(meInfo()[abs(diags[i]->id())%2], i); } return sel; } } else { Selector sel; for ( DiagramIndex i = 0; i < diags.size(); ++i ) { if(abs(diags[i]->id()) == 10 && dipole_ == IIQCD2 ) sel.insert(1., i); else if(abs(diags[i]->id()) == 12 && dipole_ == IIQCD1 ) sel.insert(1., i); else if(abs(diags[i]->id()) == 20 && dipole_ == IIQCD2 ) sel.insert(1., i); else if(abs(diags[i]->id()) == 21 && dipole_ == IFQED1 ) sel.insert(1., i); else if(abs(diags[i]->id()) == 22 && dipole_ == FIQED1 ) sel.insert(1., i); else sel.insert(0., i); } return sel; } } Selector MEPP2GammaGammaPowheg::colourGeometries(tcDiagPtr diag) const { // colour lines for V gamma static ColourLines cs("1 -2"); static ColourLines ct("1 2 -3"); // colour lines for q qbar -> V g static const ColourLines cqqbar[2]={ColourLines("1 -2 5,-3 -5"), ColourLines("1 5,-5 2 -3")}; // colour lines for q g -> V q static const ColourLines cqg [2]={ColourLines("1 2 -3,3 5"), ColourLines("1 -2,2 3 5")}; // colour lines for g qbar -> V qbar static const ColourLines cgqbar[2]={ColourLines("-3 -2 1,-1 -5"), ColourLines("-2 1,-1 -3 -5")}; // colour lines for q qbar -> V gamma g static const ColourLines cqqbarg[4]={ColourLines("1 2 3 7,-4 -7"), ColourLines("1 2 7,-4 3 -7"), ColourLines("1 7,-4 3 2 -7"), ColourLines("1 2 7,-4 3 -7")}; // colour lines for q g -> V gamma q static const ColourLines cqgq [3]={ColourLines("1 2 3 -4,4 7"), ColourLines("1 2 3 -4,4 7"), ColourLines("1 2 -3,3 5 7")}; // colour lines for gbar -> V gamma qbar static const ColourLines cqbargqbar[3]={ColourLines("1 -2 -3 -4,-1 -7"), ColourLines("1 -2 -3 -4,-1 -7"), ColourLines("1 -2 -3,-1 -5 -7")}; Selector sel; switch(abs(diag->id())) { case 1 :case 2 : sel.insert(1.0, &ct); break; case 3 : sel.insert(1.0, &cs); break; case 4 : sel.insert(1.0, &cqqbar[0]); break; case 5: sel.insert(1.0, &cqqbar[1]); break; case 6: sel.insert(1.0, &cqg[0]); break; case 7: sel.insert(1.0, &cqg[1]); break; case 8: sel.insert(1.0, &cgqbar[0]); break; case 9: sel.insert(1.0, &cgqbar[1]); break; case 10: case 11: case 12: case 13: sel.insert(1.0, &cqqbarg[abs(diag->id())-10]); break; case 20: case 21: case 22: sel.insert(1.0, &cqgq[abs(diag->id())-20]); break; case 30: case 31: case 32: sel.insert(1.0, &cqbargqbar[abs(diag->id())-30]); break; default: assert(false); } return sel; } void MEPP2GammaGammaPowheg::persistentOutput(PersistentOStream & os) const { os << FFPvertex_ << FFGvertex_ << contrib_ << power_ << gluon_ << prefactor_ << process_ << threeBodyProcess_<< maxflavour_ << alphaS_ << fixedAlphaS_ << supressionFunction_ << supressionScale_ << ounit(lambda_,GeV) << alphaQCD_ << alphaQED_ << ounit(minpT_,GeV) << preQCDqqbarq_ << preQCDqqbarqbar_ << preQCDqg_ << preQCDgqbar_ << preQEDqqbarq_ << preQEDqqbarqbar_ << preQEDqgq_ << preQEDgqbarqbar_ << scaleChoice_ << scalePreFactor_; } void MEPP2GammaGammaPowheg::persistentInput(PersistentIStream & is, int) { is >> FFPvertex_ >> FFGvertex_ >> contrib_ >> power_ >> gluon_ >> prefactor_ >> process_ >> threeBodyProcess_ >> maxflavour_ >> alphaS_ >> fixedAlphaS_ >> supressionFunction_ >> supressionScale_ >> iunit(lambda_,GeV) >> alphaQCD_ >> alphaQED_ >> iunit(minpT_,GeV) >> preQCDqqbarq_ >> preQCDqqbarqbar_ >> preQCDqg_ >> preQCDgqbar_ >> preQEDqqbarq_ >> preQEDqqbarqbar_ >> preQEDqgq_ >> preQEDgqbarqbar_ >> scaleChoice_ >> scalePreFactor_; } void MEPP2GammaGammaPowheg::Init() { static ClassDocumentation documentation ("TheMEPP2GammaGammaPowheg class implements gamma gamma production at NLO"); static Switch interfaceProcess ("Process", "Which processes to include", &MEPP2GammaGammaPowheg::process_, 0, false, false); static SwitchOption interfaceProcessAll (interfaceProcess, "All", "Include all the processes", 0); static SwitchOption interfaceProcessGammaGamma (interfaceProcess, "GammaGamma", "Only include gamma gamma", 1); static SwitchOption interfaceProcessVJet (interfaceProcess, "VJet", "Only include gamma + jet", 2); static SwitchOption interfaceProcessHard (interfaceProcess, "Hard", "Only include hard radiation contributions", 3); static Switch interfaceThreeBodyProcess ("ThreeBodyProcess", "The possible three body processes to include", &MEPP2GammaGammaPowheg::threeBodyProcess_, 0, false, false); static SwitchOption interfaceThreeBodyProcessAll (interfaceThreeBodyProcess, "All", "Include all processes", 0); static SwitchOption interfaceThreeBodyProcessqqbar (interfaceThreeBodyProcess, "qqbar", "Only include q qbar -> gamma gamma g processes", 1); static SwitchOption interfaceThreeBodyProcessqg (interfaceThreeBodyProcess, "qg", "Only include q g -> gamma gamma q processes", 2); static SwitchOption interfaceThreeBodyProcessgqbar (interfaceThreeBodyProcess, "gqbar", "Only include g qbar -> gamma gamma qbar processes", 3); static Switch interfaceContribution ("Contribution", "Which contributions to the cross section to include", &MEPP2GammaGammaPowheg::contrib_, 1, false, false); static SwitchOption interfaceContributionLeadingOrder (interfaceContribution, "LeadingOrder", "Just generate the leading order cross section", 0); static SwitchOption interfaceContributionPositiveNLO (interfaceContribution, "PositiveNLO", "Generate the positive contribution to the full NLO cross section", 1); static SwitchOption interfaceContributionNegativeNLO (interfaceContribution, "NegativeNLO", "Generate the negative contribution to the full NLO cross section", 2); static Parameter interfaceMaximumFlavour ("MaximumFlavour", "The maximum flavour allowed for the incoming quarks", &MEPP2GammaGammaPowheg::maxflavour_, 5, 1, 5, false, false, Interface::limited); static Parameter interfaceAlphaS ("AlphaS", "The value of alphaS to use if using a fixed alphaS", &MEPP2GammaGammaPowheg::alphaS_, 0.118, 0.0, 0.2, false, false, Interface::limited); static Switch interfaceFixedAlphaS ("FixedAlphaS", "Use a fixed value of alphaS", &MEPP2GammaGammaPowheg::fixedAlphaS_, false, false, false); static SwitchOption interfaceFixedAlphaSYes (interfaceFixedAlphaS, "Yes", "Use a fixed alphaS", true); static SwitchOption interfaceFixedAlphaSNo (interfaceFixedAlphaS, "No", "Use a running alphaS", false); static Switch interfaceSupressionFunction ("SupressionFunction", "Choice of the supression function", &MEPP2GammaGammaPowheg::supressionFunction_, 0, false, false); static SwitchOption interfaceSupressionFunctionNone (interfaceSupressionFunction, "None", "Default POWHEG approach", 0); static SwitchOption interfaceSupressionFunctionThetaFunction (interfaceSupressionFunction, "ThetaFunction", "Use theta functions at scale Lambda", 1); static SwitchOption interfaceSupressionFunctionSmooth (interfaceSupressionFunction, "Smooth", "Supress high pT by pt^2/(pt^2+lambda^2)", 2); static Parameter interfaceSupressionScale ("SupressionScale", "The square of the scale for the supression function", &MEPP2GammaGammaPowheg::lambda_, GeV, 20.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Switch interfaceSupressionScaleChoice ("SupressionScaleChoice", "Choice of the supression scale", &MEPP2GammaGammaPowheg::supressionScale_, 0, false, false); static SwitchOption interfaceSupressionScaleChoiceFixed (interfaceSupressionScaleChoice, "Fixed", "Use a fixed scale", 0); static SwitchOption interfaceSupressionScaleChoiceVariable (interfaceSupressionScaleChoice, "Variable", "Use the pT of the hard process as the scale", 1); static Reference interfaceShowerAlphaQCD ("ShowerAlphaQCD", "Reference to the object calculating the QCD coupling for the shower", &MEPP2GammaGammaPowheg::alphaQCD_, false, false, true, false, false); static Reference interfaceShowerAlphaQED ("ShowerAlphaQED", "Reference to the object calculating the QED coupling for the shower", &MEPP2GammaGammaPowheg::alphaQED_, false, false, true, false, false); static Parameter interfacepreQCDqqbarq ("preQCDqqbarq", "The constant for the Sudakov overestimate for the " "q qbar -> V Gamma +g with emission from the q", &MEPP2GammaGammaPowheg::preQCDqqbarq_, 23.0, 0.0, 1000.0, false, false, Interface::limited); static Parameter interfacepreQCDqqbarqbar ("preQCDqqbarqbar", "The constant for the Sudakov overestimate for the " "q qbar -> V Gamma +g with emission from the qbar", &MEPP2GammaGammaPowheg::preQCDqqbarqbar_, 23.0, 0.0, 1000.0, false, false, Interface::limited); static Switch interfaceScaleChoice ("ScaleChoice", "The scale choice to use", &MEPP2GammaGammaPowheg::scaleChoice_, 0, false, false); static SwitchOption interfaceScaleChoicepT (interfaceScaleChoice, "pT", "Use the pT of the photons", 0); static SwitchOption interfaceScaleChoiceMGammaGamma (interfaceScaleChoice, "MGammaGamma", "Use the mass of the photon pair", 1); static Parameter interfaceScalePreFactor ("ScalePreFactor", "Prefactor to change factorization/renormalisation scale", &MEPP2GammaGammaPowheg::scalePreFactor_, 1.0, 0.1, 10.0, false, false, Interface::limited); // prefactor_.push_back(preQCDqg_); // prefactor_.push_back(preQCDgqbar_); // prefactor_.push_back(preQEDqqbarq_); // prefactor_.push_back(preQEDqqbarqbar_); // prefactor_.push_back(preQEDqgq_); // prefactor_.push_back(preQEDgqbarqbar_); } double MEPP2GammaGammaPowheg::NLOWeight() const { // if leading-order return if(contrib_==0) return loME_; // prefactors CFfact_ = 4./3.*alphaS_/Constants::twopi; TRfact_ = 1./2.*alphaS_/Constants::twopi; // scale Energy2 mu2 = scale(); // virtual pieces double virt = CFfact_*subtractedVirtual(); // extract the partons and stuff for the real emission // and collinear counter terms // hadrons pair hadrons= make_pair(dynamic_ptr_cast(lastParticles().first->dataPtr() ), dynamic_ptr_cast(lastParticles().second->dataPtr())); // momentum fractions pair x = make_pair(lastX1(),lastX2()); // partons pair partons = make_pair(mePartonData()[0],mePartonData()[1]); // If necessary swap the particle data objects so that // first beam gives the incoming quark if(lastPartons().first ->dataPtr()!=partons.first) { swap(x.first,x.second); swap(hadrons.first,hadrons.second); } // convert the values of z tilde to z pair z; pair zJac; double rhomax(pow(1.-x.first,1.-power_)); double rho = zTilde_*rhomax; z.first = 1.-pow(rho,1./(1.-power_)); zJac.first = rhomax*pow(1.-z.first,power_)/(1.-power_); rhomax = pow(1.-x.second,1.-power_); rho = zTilde_*rhomax; z.second = 1.-pow(rho,1./(1.-power_)); zJac.second = rhomax*pow(1.-z.second,power_)/(1.-power_); // calculate the PDFs pair oldqPDF = make_pair(hadrons.first ->pdf()->xfx(hadrons.first ,partons.first ,scale(), x.first )/x.first , hadrons.second->pdf()->xfx(hadrons.second,partons.second,scale(), x.second)/x.second); // real/coll q/qbar pair newqPDF = make_pair(hadrons.first ->pdf()->xfx(hadrons.first ,partons.first ,scale(), x.first /z.first )*z.first /x.first , hadrons.second->pdf()->xfx(hadrons.second,partons.second,scale(), x.second/z.second)*z.second/x.second); // real/coll gluon pair newgPDF = make_pair(hadrons.first ->pdf()->xfx(hadrons.first ,gluon_,scale(), x.first /z.first )*z.first /x.first , hadrons.second->pdf()->xfx(hadrons.second,gluon_,scale(), x.second/z.second)*z.second/x.second); // coll terms // g -> q double collGQ = collinearGluon(mu2,zJac.first,z.first, oldqPDF.first,newgPDF.first); // g -> qbar double collGQbar = collinearGluon(mu2,zJac.second,z.second, oldqPDF.second,newgPDF.second); // q -> q double collQQ = collinearQuark(x.first ,mu2,zJac.first ,z.first , oldqPDF.first ,newqPDF.first ); // qbar -> qbar double collQbarQbar = collinearQuark(x.second,mu2,zJac.second,z.second, oldqPDF.second,newqPDF.second); // collinear remnants double coll = collQQ+collQbarQbar+collGQ+collGQbar; // real emission contribution double real1 = subtractedReal(x,z. first,zJac. first,oldqPDF. first, newqPDF. first,newgPDF. first, true); double real2 = subtractedReal(x,z.second,zJac.second,oldqPDF.second, newqPDF.second,newgPDF.second,false); // the total weight double wgt = loME_ + loME_*virt + loME_*coll + real1 + real2; return contrib_ == 1 ? max(0.,wgt) : max(0.,-wgt); } double MEPP2GammaGammaPowheg::loGammaGammaME(const cPDVector & particles, const vector & momenta, bool first) const { double output(0.); // analytic formula for speed if(!first) { Energy2 th = (momenta[0]-momenta[2]).m2(); Energy2 uh = (momenta[0]-momenta[3]).m2(); output = 4./3.*Constants::pi*SM().alphaEM(ZERO)*(th/uh+uh/th)* pow(double(particles[0]->iCharge())/3.,4); } // HE code result else { // wavefunctions for the incoming fermions SpinorWaveFunction em_in( momenta[0],particles[0],incoming); SpinorBarWaveFunction ep_in( momenta[1],particles[1],incoming); // wavefunctions for the outgoing bosons VectorWaveFunction v1_out(momenta[2],particles[2],outgoing); VectorWaveFunction v2_out(momenta[3],particles[3],outgoing); vector f1; vector a1; vector v1,v2; // calculate the wavefunctions for(unsigned int ix=0;ix<2;++ix) { em_in.reset(ix); f1.push_back(em_in); ep_in.reset(ix); a1.push_back(ep_in); v1_out.reset(2*ix); v1.push_back(v1_out); v2_out.reset(2*ix); v2.push_back(v2_out); } vector me(4,0.0); me_.reset(ProductionMatrixElement(PDT::Spin1Half,PDT::Spin1Half, PDT::Spin1,PDT::Spin1)); vector diag(2,0.0); SpinorWaveFunction inter; for(unsigned int ihel1=0;ihel1<2;++ihel1) { for(unsigned int ihel2=0;ihel2<2;++ihel2) { for(unsigned int ohel1=0;ohel1<2;++ohel1) { for(unsigned int ohel2=0;ohel2<2;++ohel2) { inter = FFPvertex_->evaluate(ZERO,5,f1[ihel1].particle()->CC(), f1[ihel1],v1[ohel1]); diag[0] = FFPvertex_->evaluate(ZERO,inter,a1[ihel2],v2[ohel2]); inter = FFPvertex_->evaluate(ZERO,5,f1[ihel1].particle()->CC(), f1[ihel1] ,v2[ohel2]); diag[1] = FFPvertex_->evaluate(ZERO,inter,a1[ihel2],v1[ohel1]); // individual diagrams for (size_t ii=0; ii<2; ++ii) me[ii] += std::norm(diag[ii]); // full matrix element diag[0] += diag[1]; output += std::norm(diag[0]); // storage of the matrix element for spin correlations me_(ihel1,ihel2,2*ohel1,2*ohel2) = diag[0]; } } } } // store diagram info, etc. DVector save(3); for (size_t i = 0; i < 3; ++i) save[i] = 0.25 * me[i]; meInfo(save); // spin and colour factors output *= 0.125/3./norm(FFPvertex_->norm()); } return output; } double MEPP2GammaGammaPowheg::loGammaqME(const cPDVector & particles, const vector & momenta, bool first) const { double output(0.); // analytic formula for speed if(!first) { Energy2 sh = (momenta[0]+momenta[1]).m2(); Energy2 th = (momenta[0]-momenta[2]).m2(); Energy2 uh = (momenta[0]-momenta[3]).m2(); output = -1./3./sh/th*(sh*sh+th*th+2.*uh*(sh+th+uh))* 4.*Constants::pi*SM().alphaEM(ZERO)* sqr(particles[0]->iCharge()/3.); } // HE result else { vector fin; vector gin; vector fout; vector vout; SpinorWaveFunction qin (momenta[0],particles[0],incoming); VectorWaveFunction glin(momenta[1],particles[1],incoming); VectorWaveFunction wout(momenta[2],particles[2],outgoing); SpinorBarWaveFunction qout(momenta[3],particles[3],outgoing); // polarization states for the particles for(unsigned int ix=0;ix<2;++ix) { qin.reset(ix) ; fin.push_back(qin); qout.reset(ix); fout.push_back(qout); glin.reset(2*ix); gin.push_back(glin); wout.reset(2*ix); vout.push_back(wout); } me_.reset(ProductionMatrixElement(PDT::Spin1Half,PDT::Spin1, PDT::Spin1,PDT::Spin1Half)); // compute the matrix elements double me[3]={0.,0.,0.}; Complex diag[2]; SpinorWaveFunction inters; SpinorBarWaveFunction interb; for(unsigned int ihel1=0;ihel1<2;++ihel1) { for(unsigned int ihel2=0;ihel2<2;++ihel2) { for(unsigned int ohel1=0;ohel1<2;++ohel1) { // intermediates for the diagrams interb= FFGvertex_->evaluate(scale(),5,particles[3]->CC(), fout[ohel1],gin[ihel2]); inters= FFGvertex_->evaluate(scale(),5,particles[0], fin[ihel1],gin[ihel2]); for(unsigned int vhel=0;vhel<2;++vhel) { diag[0] = FFPvertex_->evaluate(ZERO,fin[ihel1],interb,vout[vhel]); diag[1] = FFPvertex_->evaluate(ZERO,inters,fout[ohel1],vout[vhel]); // diagram contributions me[1] += norm(diag[0]); me[2] += norm(diag[1]); // total diag[0] += diag[1]; me[0] += norm(diag[0]); me_(ihel1,2*ihel2,2*vhel,ohel1) = diag[0]; } } } } // results // initial state spin and colour average double colspin = 1./24./4.; // and C_F N_c from matrix element colspin *= 4.; DVector save; for(unsigned int ix=0;ix<3;++ix) { me[ix] *= colspin; if(ix>0) save.push_back(me[ix]); } meInfo(save); output = me[0]/norm(FFGvertex_->norm()); } return output; } double MEPP2GammaGammaPowheg::loGammaqbarME(const cPDVector & particles, const vector & momenta, bool first) const { double output(0.); // analytic formula for speed if(!first) { Energy2 sh = (momenta[0]+momenta[1]).m2(); Energy2 uh = (momenta[0]-momenta[2]).m2(); Energy2 th = (momenta[0]-momenta[3]).m2(); output = -1./3./sh/th*(sh*sh+th*th+2.*uh*(sh+th+uh))* 4.*Constants::pi*SM().alphaEM()* sqr(particles[1]->iCharge()/3.); } // HE result else { vector ain; vector gin; vector aout; vector vout; VectorWaveFunction glin (momenta[0],particles[0],incoming); SpinorBarWaveFunction qbin (momenta[1],particles[1],incoming); VectorWaveFunction wout (momenta[2],particles[2],outgoing); SpinorWaveFunction qbout(momenta[3],particles[3],outgoing); // polarization states for the particles for(unsigned int ix=0;ix<2;++ix) { qbin .reset(ix ); ain .push_back(qbin ); qbout.reset(ix ); aout.push_back(qbout); glin.reset(2*ix); gin.push_back(glin); wout.reset(2*ix); vout.push_back(wout); } // if calculation spin corrections construct the me me_.reset(ProductionMatrixElement(PDT::Spin1,PDT::Spin1Half, PDT::Spin1,PDT::Spin1Half)); // compute the matrix elements double me[3]={0.,0.,0.}; Complex diag[2]; SpinorWaveFunction inters; SpinorBarWaveFunction interb; for(unsigned int ihel1=0;ihel1<2;++ihel1) { for(unsigned int ihel2=0;ihel2<2;++ihel2) { for(unsigned int ohel1=0;ohel1<2;++ohel1) { // intermediates for the diagrams inters= FFGvertex_->evaluate(scale(),5,particles[3]->CC(), aout[ohel1],gin[ihel1]); interb= FFGvertex_->evaluate(scale(),5,particles[1], ain[ihel2],gin[ihel1]); for(unsigned int vhel=0;vhel<2;++vhel) { diag[0]= FFPvertex_->evaluate(ZERO,inters,ain[ihel2],vout[vhel]); diag[1]= FFPvertex_->evaluate(ZERO,aout[ohel1],interb,vout[vhel]); // diagram contributions me[1] += norm(diag[0]); me[2] += norm(diag[1]); // total diag[0] += diag[1]; me[0] += norm(diag[0]); me_(2*ihel1,ihel2,2*vhel,ohel1) = diag[0]; } } } } // results // initial state spin and colour average double colspin = 1./24./4.; // and C_F N_c from matrix element colspin *= 4.; DVector save; for(unsigned int ix=0;ix<3;++ix) { me[ix] *= colspin; if(ix>0) save.push_back(me[ix]); } meInfo(save); output = me[0]/norm(FFGvertex_->norm()); } return output; } double MEPP2GammaGammaPowheg::loGammagME(const cPDVector & particles, const vector & momenta, bool first) const { double output(0.); // analytic formula for speed if(!first) { Energy2 uh = (momenta[0]-momenta[2]).m2(); Energy2 th = (momenta[0]-momenta[3]).m2(); output = 8./9.*double((th*th+uh*uh)/uh/th)* 4.*Constants::pi*SM().alphaEM(ZERO)* sqr(particles[0]->iCharge()/3.); } else { vector fin; vector ain; vector gout; vector vout; SpinorWaveFunction qin (momenta[0],particles[0],incoming); SpinorBarWaveFunction qbin(momenta[1],particles[1],incoming); VectorWaveFunction wout(momenta[2],particles[2],outgoing); VectorWaveFunction glout(momenta[3],particles[3],outgoing); // polarization states for the particles for(unsigned int ix=0;ix<2;++ix) { qin.reset(ix) ; fin.push_back(qin); qbin.reset(ix) ; ain.push_back(qbin); glout.reset(2*ix); gout.push_back(glout); wout.reset(2*ix); vout.push_back(wout); } // if calculation spin corrections construct the me if(first) me_.reset(ProductionMatrixElement(PDT::Spin1Half,PDT::Spin1Half, PDT::Spin1,PDT::Spin1)); // compute the matrix elements double me[3]={0.,0.,0.}; Complex diag[2]; SpinorWaveFunction inters; SpinorBarWaveFunction interb; for(unsigned int ihel1=0;ihel1<2;++ihel1) { for(unsigned int ihel2=0;ihel2<2;++ihel2) { for(unsigned int ohel1=0;ohel1<2;++ohel1) { // intermediates for the diagrams inters= FFGvertex_->evaluate(scale(),5,particles[0], fin[ihel1],gout[ohel1]); interb= FFGvertex_->evaluate(scale(),5,particles[1], ain[ihel2],gout[ohel1]); for(unsigned int vhel=0;vhel<2;++vhel) { diag[0]= FFPvertex_->evaluate(ZERO,fin[ihel1],interb,vout[vhel]); diag[1]= FFPvertex_->evaluate(ZERO,inters,ain[ihel2],vout[vhel]); // diagram contributions me[1] += norm(diag[0]); me[2] += norm(diag[1]); // total diag[0] += diag[1]; me[0] += norm(diag[0]); if(first) me_(ihel1,ihel2,vhel,2*ohel1) = diag[0]; } } } } // results // initial state spin and colour average double colspin = 1./9./4.; // and C_F N_c from matrix element colspin *= 4.; DVector save; for(unsigned int ix=0;ix<3;++ix) { me[ix] *= colspin; if(ix>0) save.push_back(me[ix]); } meInfo(save); output = me[0]/norm(FFGvertex_->norm()); } return output; } InvEnergy2 MEPP2GammaGammaPowheg:: realGammaGammagME(const cPDVector & particles, const vector & momenta, DipoleType dipole, RadiationType rad, bool ) const { // matrix element double sum = realME(particles,momenta); // loop over the QCD and QCD dipoles InvEnergy2 dipoles[2]; pair supress[2]; // compute the two dipole terms unsigned int iemit = 4, ihard = 3; double x = (momenta[0]*momenta[1]-momenta[iemit]*momenta[1]- momenta[iemit]*momenta[0])/(momenta[0]*momenta[1]); Lorentz5Momentum Kt = momenta[0]+momenta[1]-momenta[iemit]; vector pa(4),pb(4); // momenta for q -> q g/gamma emission pa[0] = x*momenta[0]; pa[1] = momenta[1]; Lorentz5Momentum K = pa[0]+pa[1]; Lorentz5Momentum Ksum = K+Kt; Energy2 K2 = K.m2(); Energy2 Ksum2 = Ksum.m2(); pa[2] = momenta[2]-2.*Ksum*(Ksum*momenta[2])/Ksum2+2*K*(Kt*momenta[2])/K2; pa[2].setMass(momenta[2].mass()); pa[3] = momenta[ihard] -2.*Ksum*(Ksum*momenta[ihard])/Ksum2+2*K*(Kt*momenta[ihard])/K2; pa[3].setMass(ZERO); cPDVector part(particles.begin(),--particles.end()); part[3] = particles[ihard]; // first leading-order matrix element double lo1 = loGammaGammaME(part,pa); // first dipole dipoles[0] = 1./(momenta[0]*momenta[iemit])/x*(2./(1.-x)-(1.+x))*lo1; supress[0] = supressionFunction(momenta[iemit].perp(),pa[3].perp()); // momenta for qbar -> qbar g/gamma emission pb[0] = momenta[0]; pb[1] = x*momenta[1]; K = pb[0]+pb[1]; Ksum = K+Kt; K2 = K.m2(); Ksum2 = Ksum.m2(); pb[2] = momenta[2]-2.*Ksum*(Ksum*momenta[2])/Ksum2+2*K*(Kt*momenta[2])/K2; pb[2].setMass(momenta[2].mass()); pb[3] = momenta[ihard] -2.*Ksum*(Ksum*momenta[ihard])/Ksum2+2*K*(Kt*momenta[ihard])/K2; pb[3].setMass(ZERO); // second LO matrix element double lo2 = loGammaGammaME(part,pb); // second dipole dipoles[1] = 1./(momenta[1]*momenta[iemit])/x*(2./(1.-x)-(1.+x))*lo2; supress[1] = supressionFunction(momenta[iemit].perp(),pb[3].perp()); for(unsigned int ix=0;ix<2;++ix) dipoles[ix] *= 4./3.; // denominator for the matrix element InvEnergy2 denom = abs(dipoles[0]) + abs(dipoles[1]); // contribution if( denom==ZERO || dipoles[(dipole-1)/2]==ZERO ) return ZERO; sum *= abs(dipoles[(dipole-1)/2])/denom; // final coupling factors InvEnergy2 output; if(rad==Subtraction) { output = alphaS_*alphaEM_* (sum*UnitRemoval::InvE2*supress[(dipole-1)/2].first - dipoles[(dipole-1)/2]); } else { output = alphaS_*alphaEM_*sum*UnitRemoval::InvE2; if(rad==Hard) output *=supress[(dipole-1)/2].second; else if(rad==Shower) output *=supress[(dipole-1)/2].first ; } return output; } InvEnergy2 MEPP2GammaGammaPowheg::realGammaGammaqME(const cPDVector & particles, const vector & momenta, DipoleType dipole, RadiationType rad, bool ) const { double sum = realME(particles,momenta); // initial-state QCD dipole double x = (momenta[0]*momenta[1]-momenta[4]*momenta[1]- momenta[4]*momenta[0])/(momenta[0]*momenta[1]); Lorentz5Momentum Kt = momenta[0]+momenta[1]-momenta[4]; vector pa(4); pa[0] = momenta[0]; pa[1] = x*momenta[1]; Lorentz5Momentum K = pa[0]+pa[1]; Lorentz5Momentum Ksum = K+Kt; Energy2 K2 = K.m2(); Energy2 Ksum2 = Ksum.m2(); pa[2] = momenta[2]-2.*Ksum*(Ksum*momenta[2])/Ksum2+2*K*(Kt*momenta[2])/K2; pa[2].setMass(momenta[2].mass()); pa[3] = momenta[3] -2.*Ksum*(Ksum*momenta[3])/Ksum2+2*K*(Kt*momenta[3])/K2; pa[3].setMass(ZERO); cPDVector part(particles.begin(),--particles.end()); part[1] = particles[4]->CC(); double lo1 = loGammaGammaME(part,pa); InvEnergy2 D1 = 0.5/(momenta[1]*momenta[4])/x*(1.-2.*x*(1.-x))*lo1; // initial-final QED dipole vector pb(4); x = 1.-(momenta[3]*momenta[4])/(momenta[4]*momenta[0]+momenta[0]*momenta[3]); pb[3] = momenta[4]+momenta[3]-(1.-x)*momenta[0]; pb[0] = x*momenta[0]; pb[1] = momenta[1]; pb[2] = momenta[2]; double z = momenta[0]*momenta[3]/(momenta[0]*momenta[3]+momenta[0]*momenta[4]); part[1] = particles[1]; part[3] = particles[4]; double lo2 = loGammaqME(part,pb); Energy pT = sqrt(-(pb[0]-pb[3]).m2()*(1.-x)*(1.-z)*z/x); InvEnergy2 DF = 1./(momenta[4]*momenta[3])/x*(1./(1.-x+z)-2.+z)*lo2; InvEnergy2 DI = 1./(momenta[0]*momenta[3])/x*(1./(1.-x+z)-1.-x)*lo2; DI *= sqr(double(particles[0]->iCharge())/3.); DF *= sqr(double(particles[0]->iCharge())/3.); InvEnergy2 denom = abs(D1)+abs(DI)+abs(DF); pair supress; InvEnergy2 term; if ( dipole == IFQED1 ) { term = DI; supress = supressionFunction(pT,pb[3].perp()); } else if( dipole == FIQED1 ) { term = DF; supress = supressionFunction(pT,pb[3].perp()); } else { term = D1; supress = supressionFunction(momenta[4].perp(),pa[3].perp()); } if( denom==ZERO || term == ZERO ) return ZERO; sum *= abs(term)/denom; // final coupling factors InvEnergy2 output; if(rad==Subtraction) { output = alphaS_*alphaEM_* (sum*UnitRemoval::InvE2*supress.first - term); } else { output = alphaS_*alphaEM_*sum*UnitRemoval::InvE2; if(rad==Hard) output *= supress.second; else if(rad==Shower) output *= supress.first ; } // final coupling factors return output; } InvEnergy2 MEPP2GammaGammaPowheg:: realGammaGammaqbarME(const cPDVector & particles, const vector & momenta, DipoleType dipole, RadiationType rad, bool) const { double sum = realME(particles,momenta); // initial-state QCD dipole double x = (momenta[0]*momenta[1]-momenta[4]*momenta[1]-momenta[4]*momenta[0])/ (momenta[0]*momenta[1]); Lorentz5Momentum Kt = momenta[0]+momenta[1]-momenta[4]; vector pa(4); pa[0] = x*momenta[0]; pa[1] = momenta[1]; Lorentz5Momentum K = pa[0]+pa[1]; Lorentz5Momentum Ksum = K+Kt; Energy2 K2 = K.m2(); Energy2 Ksum2 = Ksum.m2(); pa[2] = momenta[2]-2.*Ksum*(Ksum*momenta[2])/Ksum2+2*K*(Kt*momenta[2])/K2; pa[2].setMass(momenta[2].mass()); pa[3] = momenta[3] -2.*Ksum*(Ksum*momenta[3])/Ksum2+2*K*(Kt*momenta[3])/K2; pa[3].setMass(ZERO); cPDVector part(particles.begin(),--particles.end()); part[0] = particles[4]->CC(); double lo1 = loGammaGammaME(part,pa); InvEnergy2 D1 = 0.5/(momenta[0]*momenta[4])/x*(1.-2.*x*(1.-x))*lo1; // initial-final QED dipole vector pb(4); x = 1.-(momenta[3]*momenta[4])/(momenta[4]*momenta[1]+momenta[1]*momenta[3]); pb[3] = momenta[4]+momenta[3]-(1.-x)*momenta[1]; pb[0] = momenta[0]; pb[1] = x*momenta[1]; pb[2] = momenta[2]; double z = momenta[1]*momenta[3]/(momenta[1]*momenta[3]+momenta[1]*momenta[4]); part[0] = particles[0]; part[3] = particles[4]; double lo2 = loGammaqbarME(part,pb); Energy pT = sqrt(-(pb[1]-pb[3]).m2()*(1.-x)*(1.-z)*z/x); InvEnergy2 DF = 1./(momenta[4]*momenta[3])/x*(2./(1.-x+z)-2.+z)*lo2; InvEnergy2 DI = 1./(momenta[0]*momenta[3])/x*(2./(1.-x+z)-1.-x)*lo2; InvEnergy2 term; DI *= sqr(double(particles[1]->iCharge())/3.); DF *= sqr(double(particles[1]->iCharge())/3.); InvEnergy2 denom = abs(D1)+abs(DI)+abs(DF); pair supress; if ( dipole == IFQED2 ) { term = DI; supress = supressionFunction(pT,pb[3].perp()); } else if( dipole == FIQED2 ) { term = DF; supress = supressionFunction(pT,pb[3].perp()); } else { term = D1; supress = supressionFunction(momenta[4].perp(),pa[3].perp()); } if( denom==ZERO || dipole==ZERO ) return ZERO; sum *= abs(term)/denom; // final coupling factors InvEnergy2 output; if(rad==Subtraction) { output = alphaS_*alphaEM_* (sum*UnitRemoval::InvE2*supress.first - term); } else { output = alphaS_*alphaEM_*sum*UnitRemoval::InvE2; if(rad==Hard) output *= supress.second; else if(rad==Shower) output *= supress.first ; } // final coupling factors return output; } double MEPP2GammaGammaPowheg:: realME(const cPDVector & particles, const vector & momenta) const { vector qin; vector qbarin; vector wout,pout,gout; SpinorWaveFunction q_in; SpinorBarWaveFunction qbar_in; VectorWaveFunction g_out; VectorWaveFunction v_out (momenta[2],particles[2],outgoing); VectorWaveFunction p_out (momenta[3],particles[3],outgoing); // q qbar -> gamma gamma g if(particles[4]->id()==ParticleID::g) { q_in = SpinorWaveFunction (momenta[0],particles[0],incoming); qbar_in = SpinorBarWaveFunction (momenta[1],particles[1],incoming); g_out = VectorWaveFunction (momenta[4],particles[4],outgoing); } // q g -> gamma gamma q else if(particles[4]->id()>0) { q_in = SpinorWaveFunction (momenta[0],particles[0],incoming); qbar_in = SpinorBarWaveFunction (momenta[4],particles[4],outgoing); g_out = VectorWaveFunction (momenta[1],particles[1],incoming); } else if(particles[4]->id()<0) { q_in = SpinorWaveFunction (momenta[4],particles[4],outgoing); qbar_in = SpinorBarWaveFunction (momenta[1],particles[1],incoming); g_out = VectorWaveFunction (momenta[0],particles[0],incoming); } else assert(false); for(unsigned int ix=0;ix<2;++ix) { q_in.reset(ix); qin.push_back(q_in); qbar_in.reset(ix); qbarin.push_back(qbar_in); g_out.reset(2*ix); gout.push_back(g_out); p_out.reset(2*ix); pout.push_back(p_out); v_out.reset(2*ix); wout.push_back(v_out); } vector diag(6 , 0.); Energy2 mu2 = scale(); double sum(0.); for(unsigned int ihel1=0;ihel1<2;++ihel1) { for(unsigned int ihel2=0;ihel2<2;++ihel2) { for(unsigned int whel=0;whel<2;++whel) { for(unsigned int phel=0;phel<2;++phel) { for(unsigned int ghel=0;ghel<2;++ghel) { // first diagram SpinorWaveFunction inters1 = FFPvertex_->evaluate(ZERO,5,qin[ihel1].particle()->CC(),qin[ihel1],pout[phel]); SpinorBarWaveFunction inters2 = FFPvertex_->evaluate(ZERO,5,qin[ihel1].particle(), qbarin[ihel2],wout[whel]); diag[0] = FFGvertex_->evaluate(mu2,inters1,inters2,gout[ghel]); // second diagram SpinorWaveFunction inters3 = FFGvertex_->evaluate(mu2,5,qin[ihel1].particle()->CC(),qin[ihel1],gout[ghel]); SpinorBarWaveFunction inters4 = FFPvertex_->evaluate(ZERO,5,qbarin[ihel2].particle()->CC(), qbarin[ihel2],pout[phel]); diag[1] = FFPvertex_->evaluate(ZERO,inters3,inters4,wout[whel]); // fourth diagram diag[2] = FFPvertex_->evaluate(ZERO,inters3,inters2,pout[phel]); // fifth diagram SpinorBarWaveFunction inters5 = FFGvertex_->evaluate(mu2,5,qbarin[ihel2].particle()->CC(), qbarin[ihel2],gout[ghel]); diag[3] = FFPvertex_->evaluate(ZERO,inters1,inters5,wout[whel]); // sixth diagram SpinorWaveFunction inters6 = FFPvertex_->evaluate(ZERO,5,qbarin[ihel2].particle(), qin[ihel1],wout[whel]); diag[4] = FFGvertex_->evaluate(mu2,inters6,inters4,gout[ghel]); // eighth diagram diag[5] = FFPvertex_->evaluate(ZERO,inters6,inters5,pout[phel]); // sum Complex dsum = std::accumulate(diag.begin(),diag.end(),Complex(0.)); sum += norm(dsum); } } } } } // divide out the em and strong couplings sum /= norm(FFGvertex_->norm()*FFPvertex_->norm()); // final spin and colour factors spin = 1/4 colour = 4/9 if(particles[4]->id()==ParticleID::g) sum /= 9.; // final spin and colour factors spin = 1/4 colour = 4/(3*8) else sum /= 24.; // finally identical particle factor return 0.5*sum; } double MEPP2GammaGammaPowheg::subtractedVirtual() const { double v = 1+tHat()/sHat(); double born = (1-v)/v+v/(1-v); double finite_term = born* (2./3.*sqr(Constants::pi)-3.+sqr(log(v))+sqr(log(1-v))+3.*log(1-v))+ 2.+2.*log(v)+2.*log(1-v)+3.*(1-v)/v*(log(v)-log(1-v))+ (2.+v/(1-v))*sqr(log(v))+(2.+(1-v)/v)*sqr(log(1-v)); double virt = ((6.-(2./3.)*sqr(Constants::pi))* born-2.+finite_term); return virt/born; } double MEPP2GammaGammaPowheg::subtractedReal(pair x, double z, double zJac, double oldqPDF, double newqPDF, double newgPDF,bool order) const { double vt = vTilde_*(1.-z); double vJac = 1.-z; Energy pT = sqrt(sHat()*vt*(1.-vt-z)/z); // rapidities double rapidity; if(order) { rapidity = -log(x.second*sqrt(lastS())/pT*vt); } else { rapidity = log(x.first *sqrt(lastS())/pT*vt); } // CMS system Energy rs=sqrt(lastS()); Lorentz5Momentum pcmf = Lorentz5Momentum(ZERO,ZERO,0.5*rs*(x.first-x.second), 0.5*rs*(x.first+x.second)); pcmf.rescaleMass(); Boost blab(pcmf.boostVector()); // emission from the quark radiation vector pnew(5); if(order) { pnew [0] = Lorentz5Momentum(ZERO,ZERO,0.5*rs*x.first/z, 0.5*rs*x.first/z,ZERO); pnew [1] = Lorentz5Momentum(ZERO,ZERO,-0.5*rs*x.second, 0.5*rs*x.second,ZERO) ; } else { pnew[0] = Lorentz5Momentum(ZERO,ZERO,0.5*rs*x.first, 0.5*rs*x.first,ZERO); pnew[1] = Lorentz5Momentum(ZERO,ZERO,-0.5*rs*x.second/z, 0.5*rs*x.second/z,ZERO) ; } pnew [2] = meMomenta()[2]; pnew [3] = meMomenta()[3]; pnew [4] = Lorentz5Momentum(pT*cos(phi_),pT*sin(phi_), pT*sinh(rapidity), pT*cosh(rapidity), ZERO); Lorentz5Momentum K = pnew [0]+pnew [1]-pnew [4]; Lorentz5Momentum Kt = pcmf; Lorentz5Momentum Ksum = K+Kt; Energy2 K2 = K.m2(); Energy2 Ksum2 = Ksum.m2(); for(unsigned int ix=2;ix<4;++ix) { pnew [ix].boost(blab); pnew [ix] = pnew [ix] - 2.*Ksum*(Ksum*pnew [ix])/Ksum2 +2*K*(Kt*pnew [ix])/K2; } // phase-space prefactors double phase = zJac*vJac/z; // real emission q qbar vector output(4,0.); double realQQ(0.),realGQ(0.); if(!(zTilde_<1e-7 || vt<1e-7 || 1.-z-vt < 1e-7 )) { cPDVector particles(mePartonData()); particles.push_back(gluon_); // calculate the full 2->3 matrix element realQQ = sHat()*phase*newqPDF/oldqPDF* realGammaGammagME(particles,pnew,order ? IIQCD1 : IIQCD2,Subtraction,false); if(order) { particles[0] = gluon_; particles[4] = mePartonData()[0]->CC(); realGQ = sHat()*phase*newgPDF/oldqPDF* realGammaGammaqbarME(particles,pnew,IIQCD2,Subtraction,false); } else { particles[1] = gluon_; particles[4] = mePartonData()[1]->CC(); realGQ = sHat()*phase*newgPDF/oldqPDF* realGammaGammaqME (particles,pnew,IIQCD1,Subtraction,false); } } // return the answer return realQQ+realGQ; } double MEPP2GammaGammaPowheg::collinearQuark(double x, Energy2 mu2, double jac, double z, double oldPDF, double newPDF) const { if(1.-z < 1.e-8) return 0.; return CFfact_*( // this bit is multiplied by LO PDF sqr(Constants::pi)/3.-5.+2.*sqr(log(1.-x )) +(1.5+2.*log(1.-x ))*log(sHat()/mu2) // NLO PDF bit +jac /z * newPDF /oldPDF * (1.-z -(1.+z )*log(sqr(1.-z )/z ) -(1.+z )*log(sHat()/mu2)-2.*log(z )/(1.-z )) // + function bit +jac /z *(newPDF /oldPDF -z )* 2./(1.-z )*log(sHat()*sqr(1.-z )/mu2)); } double MEPP2GammaGammaPowheg::collinearGluon(Energy2 mu2, double jac, double z, double oldPDF, double newPDF) const { if(1.-z < 1.e-8) return 0.; return TRfact_*jac/z*newPDF/oldPDF* ((sqr(z)+sqr(1.-z))*log(sqr(1.-z)*sHat()/z/mu2) +2.*z*(1.-z)); } void MEPP2GammaGammaPowheg::doinit() { HwMEBase::doinit(); vector mopt(2,1); massOption(mopt); // get the vertices we need // get a pointer to the standard model object in the run static const tcHwSMPtr hwsm = dynamic_ptr_cast(standardModel()); if (!hwsm) throw InitException() << "hwsm pointer is null in" << " MEPP2GammaGamma::doinit()" << Exception::abortnow; // get pointers to all required Vertex objects FFPvertex_ = hwsm->vertexFFP(); FFGvertex_ = hwsm->vertexFFG(); gluon_ = getParticleData(ParticleID::g); // sampling factors prefactor_.push_back(preQCDqqbarq_); prefactor_.push_back(preQCDqqbarqbar_); prefactor_.push_back(preQCDqg_); prefactor_.push_back(preQCDgqbar_); prefactor_.push_back(preQEDqqbarq_); prefactor_.push_back(preQEDqqbarqbar_); prefactor_.push_back(preQEDqgq_); prefactor_.push_back(preQEDgqbarqbar_); } RealEmissionProcessPtr MEPP2GammaGammaPowheg:: generateHardest(RealEmissionProcessPtr born, ShowerInteraction inter) { beams_.clear(); partons_.clear(); bool QCDAllowed = inter !=ShowerInteraction::QED; bool QEDAllowed = inter !=ShowerInteraction::QCD; // find the incoming particles // and get the particles to be showered ParticleVector incoming,particlesToShower; pair x; 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] ); if(ix==0) x.first = incoming.back()->momentum().rho()/born->hadrons()[ix]->momentum().rho(); else x.second = incoming.back()->momentum().rho()/born->hadrons()[ix]->momentum().rho(); } // find the parton which should be first if( ( particlesToShower[1]->id() > 0 && particlesToShower[0]->id() < 0 ) || ( particlesToShower[0]->id() == ParticleID::g && particlesToShower[1]->id() < 6 && particlesToShower[1]->id() > 0 ) ) { swap(particlesToShower[0],particlesToShower[1]); swap(partons_[0],partons_[1]); swap(beams_ [0],beams_ [1]); swap(x.first ,x.second ); } // check that quark is along +ve z direction quarkplus_ = particlesToShower[0]->momentum().z() > ZERO; // outgoing partons for(unsigned int ix=0;ixbornOutgoing().size();++ix) { particlesToShower.push_back( born->bornOutgoing()[ix] ); } if(particlesToShower.size()!=4) return RealEmissionProcessPtr(); if(particlesToShower[2]->id()!=ParticleID::gamma) swap(particlesToShower[2],particlesToShower[3]); if(particlesToShower[3]->id()==ParticleID::gamma) { if(QCDAllowed) return hardQCDEmission(born,particlesToShower,x); } else { if(QEDAllowed) return hardQEDEmission(born,particlesToShower,x); } return born; } RealEmissionProcessPtr MEPP2GammaGammaPowheg:: hardQCDEmission(RealEmissionProcessPtr born, ParticleVector particlesToShower, pair x) { Energy rootS = sqrt(lastS()); // limits on the rapidity of the jet double minyj = -8.0,maxyj = 8.0; // generate the hard emission vector pT; Energy pTmax(-GeV); cPDVector selectedParticles; vector selectedMomenta; int iemit(-1); for(unsigned int ix=0;ix<4;++ix) { pT.push_back(0.5*generator()->maximumCMEnergy()); double a = alphaQCD_->overestimateValue()/Constants::twopi* prefactor_[ix]*(maxyj-minyj); cPDVector particles; for(unsigned int iy=0;iydataPtr()); if(ix<2) particles.push_back(gluon_); else if(ix==2) { particles.push_back(particles[0]->CC()); particles[0] = gluon_; } else { particles.push_back(particles[1]->CC()); particles[1] = gluon_; } vector momenta(5); do { pT[ix] *= pow(UseRandom::rnd(),1./a); double y = UseRandom::rnd()*(maxyj-minyj)+ minyj; double vt,z; if(ix%2==0) { vt = pT[ix]*exp(-y)/rootS/x.second; z = (1.-pT[ix]*exp(-y)/rootS/x.second)/(1.+pT[ix]*exp( y)/rootS/x.first ); if(z>1.||z1.||z1.-z || vt<0.) continue; if(ix%2==0) { momenta[0] = particlesToShower[0]->momentum()/z; momenta[1] = particlesToShower[1]->momentum(); } else { momenta[0] = particlesToShower[0]->momentum(); momenta[1] = particlesToShower[1]->momentum()/z; } double phi = Constants::twopi*UseRandom::rnd(); momenta[2] = particlesToShower[2]->momentum(); momenta[3] = particlesToShower[3]->momentum(); if(!quarkplus_) y *= -1.; momenta[4] = Lorentz5Momentum(pT[ix]*cos(phi),pT[ix]*sin(phi), pT[ix]*sinh(y),pT[ix]*cosh(y), ZERO); Lorentz5Momentum K = momenta[0] + momenta[1] - momenta[4]; Lorentz5Momentum Kt = momenta[2]+momenta[3]; Lorentz5Momentum Ksum = K+Kt; Energy2 K2 = K.m2(), Ksum2 = Ksum.m2(); for(unsigned int iy=2;iy<4;++iy) { momenta [iy] = momenta [iy] - 2.*Ksum*(Ksum*momenta [iy])/Ksum2 +2*K*(Kt*momenta [iy])/K2; } // matrix element piece double wgt = alphaQCD_->ratio(sqr(pT[ix]))*z/(1.-vt)/prefactor_[ix]/loME_; if(ix==0) wgt *= sqr(pT[ix])*realGammaGammagME(particles,momenta,IIQCD1,Shower,false); else if(ix==1) wgt *= sqr(pT[ix])*realGammaGammagME(particles,momenta,IIQCD2,Shower,false); else if(ix==2) wgt *= sqr(pT[ix])*realGammaGammaqbarME(particles,momenta,IIQCD1,Shower,false); else if(ix==3) wgt *= sqr(pT[ix])*realGammaGammaqME(particles,momenta,IIQCD2,Shower,false); wgt *= 4.*Constants::pi/alphaS_; // pdf piece double pdf[2]; if(ix%2==0) { pdf[0] = beams_[0]->pdf()->xfx(beams_[0],partons_ [0], scale(), x.first ) /x.first; pdf[1] = beams_[0]->pdf()->xfx(beams_[0],particles[0], scale()+sqr(pT[ix]),x.first /z)*z/x.first; } else { pdf[0] = beams_[1]->pdf()->xfx(beams_[1],partons_ [1], scale() ,x.second ) /x.second; pdf[1] = beams_[1]->pdf()->xfx(beams_[1],particles[1], scale()+sqr(pT[ix]),x.second/z)*z/x.second; } if(pdf[0]<=0.||pdf[1]<=0.) continue; wgt *= pdf[1]/pdf[0]; if(wgt>1.) generator()->log() << "Weight greater than one in " << "MEPP2GammaGammaPowheg::hardQCDEmission() " << "for channel " << ix << " Weight = " << wgt << "\n"; if(UseRandom::rnd()minpT_); if(pT[ix]>minpT_ && pT[ix]>pTmax) { pTmax = pT[ix]; selectedParticles = particles; selectedMomenta = momenta; iemit=ix; } } // if no emission if(pTmaxpT()[ShowerInteraction::QCD] = minpT_; return born; } // construct the HardTree object needed to perform the showers // create the partons ParticleVector newparticles; newparticles.push_back(selectedParticles[0]->produceParticle(selectedMomenta[0])); newparticles.push_back(selectedParticles[1]->produceParticle(selectedMomenta[1])); for(unsigned int ix=2;ixdataPtr()-> produceParticle(selectedMomenta[ix])); } newparticles.push_back(selectedParticles[4]->produceParticle(selectedMomenta[4])); // identify the type of process // gluon emission if(newparticles.back()->id()==ParticleID::g) { newparticles[4]->incomingColour(newparticles[0]); newparticles[4]->incomingColour(newparticles[1],true); } // quark else if(newparticles.back()->id()>0) { iemit=1; newparticles[4]->incomingColour(newparticles[1]); newparticles[1]-> colourConnect(newparticles[0]); } // antiquark else { iemit=0; newparticles[4]->incomingColour(newparticles[0],true); newparticles[1]-> colourConnect(newparticles[0]); } // add incoming int ispect = iemit==0 ? 1 : 0; if(particlesToShower[0]==born->bornIncoming()[0]) { born->incoming().push_back(newparticles[0]); born->incoming().push_back(newparticles[1]); } else { born->incoming().push_back(newparticles[1]); born->incoming().push_back(newparticles[0]); swap(iemit,ispect); } // add the outgoing for(unsigned int ix=2;ixoutgoing().push_back(newparticles[ix]); // emitter spectator etc born->emitter (iemit ); born->spectator(ispect); born->emitted(4); // x values pair xnew; for(unsigned int ix=0;ix<2;++ix) { double x = born->incoming()[ix]->momentum().rho()/born->hadrons()[ix]->momentum().rho(); if(ix==0) xnew.first = x; else xnew.second = x; } born->x(xnew); // max pT born->pT()[ShowerInteraction::QCD] = pTmax; born->interaction(ShowerInteraction::QCD); // return the process return born; } RealEmissionProcessPtr MEPP2GammaGammaPowheg:: hardQEDEmission(RealEmissionProcessPtr born, ParticleVector particlesToShower, pair x) { // return if not emission from quark if(particlesToShower[0]->id()!=ParticleID::g && particlesToShower[1]->id()!=ParticleID::g ) return RealEmissionProcessPtr(); // generate the hard emission vector pT; Energy pTmax(-GeV); cPDVector selectedParticles; vector selectedMomenta; int iemit(-1); pair mewgt(make_pair(0.,0.)); for(unsigned int ix=0;ixdataPtr()); selectedMomenta.push_back(particlesToShower[ix]->momentum()); } selectedParticles.push_back(getParticleData(ParticleID::gamma)); swap(selectedParticles[3],selectedParticles[4]); selectedMomenta.push_back(Lorentz5Momentum()); swap(selectedMomenta[3],selectedMomenta[4]); Lorentz5Momentum pin,pout; double xB; unsigned int iloc; if(particlesToShower[0]->dataPtr()->charged()) { pin = particlesToShower[0]->momentum(); xB = x.first; iloc = 6; } else { pin = particlesToShower[1]->momentum(); xB = x.second; iloc = 7; } pout = particlesToShower[3]->momentum(); Lorentz5Momentum q = pout-pin; Axis axis(q.vect().unit()); LorentzRotation rot; double sinth(sqrt(sqr(axis.x())+sqr(axis.y()))); rot = LorentzRotation(); if(axis.perp2()>1e-20) { rot.setRotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.)); rot.rotateX(Constants::pi); } if(abs(1.-q.e()/q.vect().mag())>1e-6) rot.boostZ(q.e()/q.vect().mag()); Lorentz5Momentum ptemp = rot*pin; if(ptemp.perp2()/GeV2>1e-20) { Boost trans = -1./ptemp.e()*ptemp.vect(); trans.setZ(0.); rot.boost(trans); } rot.invert(); Energy Q = sqrt(-q.m2()); double xT = sqrt((1.-xB)/xB); double xTMin = 2.*minpT_/Q; double wgt(0.); double a = alphaQED_->overestimateValue()*prefactor_[iloc]/Constants::twopi; Lorentz5Momentum p1,p2,p3; do { wgt = 0.; // intergration variables dxT/xT^3 xT *= 1./sqrt(1.-2.*log(UseRandom::rnd())/a*sqr(xT)); // dz double zp = UseRandom::rnd(); double xp = 1./(1.+0.25*sqr(xT)/zp/(1.-zp)); if(xT1.) continue; // phase-space piece of the weight wgt = 4.*sqr(1.-xp)*(1.-zp)*zp/prefactor_[iloc]/loME_; // coupling Energy2 pT2 = 0.25*sqr(Q*xT); wgt *= alphaQED_->ratio(pT2); // matrix element wgt *= 4.*Constants::pi/alphaEM_; // PDF double pdf[2]; if(iloc==6) { pdf[0] = beams_[0]->pdf()-> xfx(beams_[0],partons_[0],scale() ,x.first ); pdf[1] = beams_[0]->pdf()-> xfx(beams_[0],partons_[0],scale()+pT2,x.first /xp); } else { pdf[0] = beams_[1]->pdf()-> xfx(beams_[1],partons_[1],scale() ,x.second ); pdf[1] = beams_[1]->pdf()-> xfx(beams_[1],partons_[1],scale()+pT2,x.second/xp); } if(pdf[0]<=0.||pdf[1]<=0.) { wgt = 0.; continue; } wgt *= pdf[1]/pdf[0]; // matrix element piece double phi = Constants::twopi*UseRandom::rnd(); double x2 = 1.-(1.-zp)/xp; double x3 = 2.-1./xp-x2; p1=Lorentz5Momentum(ZERO,ZERO,0.5*Q/xp,0.5*Q/xp,ZERO); p2=Lorentz5Momentum( 0.5*Q*xT*cos(phi), 0.5*Q*xT*sin(phi), -0.5*Q*x2,0.5*Q*sqrt(sqr(xT)+sqr(x2))); p3=Lorentz5Momentum(-0.5*Q*xT*cos(phi),-0.5*Q*xT*sin(phi), -0.5*Q*x3,0.5*Q*sqrt(sqr(xT)+sqr(x3))); selectedMomenta[iloc-6] = rot*p1; selectedMomenta[3] = rot*p3; selectedMomenta[4] = rot*p2; if(iloc==6) { mewgt.first = sqr(Q)*realGammaGammaqME(selectedParticles,selectedMomenta,IFQED1,Shower,false); mewgt.second = sqr(Q)*realGammaGammaqME(selectedParticles,selectedMomenta,FIQED1,Shower,false); wgt *= mewgt.first+mewgt.second; } else { mewgt.first = sqr(Q)*realGammaGammaqbarME(selectedParticles,selectedMomenta,IFQED2,Shower,false); mewgt.second = sqr(Q)*realGammaGammaqbarME(selectedParticles,selectedMomenta,FIQED2,Shower,false); wgt *= mewgt.first+mewgt.second; } if(wgt>1.) generator()->log() << "Weight greater than one in " << "MEPP2GammaGammaPowheg::hardQEDEmission() " << "for IF channel " << " Weight = " << wgt << "\n"; } while(xT>xTMin&&UseRandom::rnd()>wgt); // if no emission if(xTpT()[ShowerInteraction::QED] = minpT_; return born; } pTmax = 0.5*xT*Q; iemit = mewgt.first>mewgt.second ? 2 : 3; // construct the object needed to perform the showers // create the partons ParticleVector newparticles; newparticles.push_back(selectedParticles[0]->produceParticle(selectedMomenta[0])); newparticles.push_back(selectedParticles[1]->produceParticle(selectedMomenta[1])); for(unsigned int ix=2;ix dataPtr()->produceParticle(selectedMomenta[ix==2 ? 2 : 4 ])); } newparticles.push_back(selectedParticles[3]->produceParticle(selectedMomenta[3])); // make the colour connections bool col = newparticles[3]->id()<0; if(particlesToShower[0]->dataPtr()->charged()) { newparticles[3]->incomingColour(newparticles[1],col); newparticles[1]->colourConnect (newparticles[0],col); } else { newparticles[3]->incomingColour(newparticles[0],col); newparticles[0]->colourConnect (newparticles[1],col); } bool FSR = iemit==3; // add incoming particles if(particlesToShower[0]==born->bornIncoming()[0]) { born->incoming().push_back(newparticles[0]); born->incoming().push_back(newparticles[1]); } else { born->incoming().push_back(newparticles[1]); born->incoming().push_back(newparticles[0]); } // IS radiatng particle unsigned int iemitter = born->incoming()[0]->dataPtr()->charged() ? 0 : 1; // add outgoing particles if(particlesToShower[2]==born->bornOutgoing()[0]) { born->outgoing().push_back(newparticles[2]); born->outgoing().push_back(newparticles[3]); } else { born->outgoing().push_back(newparticles[3]); born->outgoing().push_back(newparticles[2]); } born->outgoing().push_back(newparticles[4]); // outgoing radiating particle unsigned int ispectator = born->outgoing()[0]->dataPtr()->charged() ? 2 : 3; // get emitter and spectator right if(FSR) swap(iemitter,ispectator); born->emitter (iemitter ); born->spectator(ispectator); born->emitted(4); // x values pair xnew; for(unsigned int ix=0;ix<2;++ix) { double x = born->incoming()[ix]->momentum().rho()/born->hadrons()[ix]->momentum().rho(); if(ix==0) xnew.first = x; else xnew.second = x; } born->x(xnew); // max pT born->pT()[ShowerInteraction::QED] = pTmax; // return the process born->interaction(ShowerInteraction::QED); return born; } diff --git a/MatrixElement/Powheg/MEPP2GammaGammaPowheg.h b/MatrixElement/Powheg/MEPP2GammaGammaPowheg.h --- a/MatrixElement/Powheg/MEPP2GammaGammaPowheg.h +++ b/MatrixElement/Powheg/MEPP2GammaGammaPowheg.h @@ -1,542 +1,543 @@ // -*- C++ -*- #ifndef HERWIG_MEPP2GammaGammaPowheg_H #define HERWIG_MEPP2GammaGammaPowheg_H // // This is the declaration of the MEPP2GammaGammaPowheg class. // #include "Herwig/MatrixElement/HwMEBase.h" #include "ThePEG/Helicity/Vertex/Vector/FFVVertex.h" #include "Herwig/MatrixElement/ProductionMatrixElement.h" #include "Herwig/Shower/ShowerAlpha.h" namespace Herwig { using namespace ThePEG; /** * Here is the documentation of the MEPP2GammaGammaPowheg class. * * @see \ref MEPP2GammaGammaPowhegInterfaces "The interfaces" * defined for MEPP2GammaGammaPowheg. */ class MEPP2GammaGammaPowheg: public HwMEBase { enum DipoleType { IIQCD1=2, IIQCD2=4, IFQED1=5, FIQED1=6, IFQED2=7, FIQED2=8 }; enum RadiationType {Subtraction,Hard,Shower}; public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ MEPP2GammaGammaPowheg(); //@} /** @name Member functions for the generation of hard QCD radiation */ //@{ /** * Has a POWHEG style correction */ virtual POWHEGType hasPOWHEGCorrection() {return ISR;} /** * Apply the POWHEG style correction */ virtual RealEmissionProcessPtr generateHardest(RealEmissionProcessPtr, ShowerInteraction); //@} public: /** @name Virtual functions required by the MEBase class. */ //@{ /** * Return the order in \f$\alpha_S\f$ in which this matrix * element is given. */ virtual unsigned int orderInAlphaS() const; /** * Return the order in \f$\alpha_{EW}\f$ in which this matrix * element is given. */ virtual unsigned int orderInAlphaEW() const; /** * The matrix element for the kinematical configuration * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. * @return the matrix element scaled with sHat() to give a * dimensionless number. */ virtual double me2() const; /** * Return the scale associated with the last set phase space point. */ virtual Energy2 scale() const; /** * The number of internal degrees of freedom used in the matrix * element. */ virtual int nDim() const; /** * Generate internal degrees of freedom given nDim() uniform * random numbers in the interval \f$ ]0,1[ \f$. To help the phase space * generator, the dSigHatDR should be a smooth function of these * numbers, although this is not strictly necessary. * @param r a pointer to the first of nDim() consecutive random numbers. * @return true if the generation succeeded, otherwise false. */ virtual bool generateKinematics(const double * r); /** * Return the matrix element squared differential in the variables * given by the last call to generateKinematics(). */ virtual CrossSection dSigHatDR() const; /** * Add all possible diagrams with the add() function. */ virtual void getDiagrams() const; /** * Get diagram selector. With the information previously supplied with the * setKinematics method, a derived class may optionally * override this method to weight the given diagrams with their * (although certainly not physical) relative probabilities. * @param dv the diagrams to be weighted. * @return a Selector relating the given diagrams to their weights. */ virtual Selector diagrams(const DiagramVector & dv) const; /** * Return a Selector with possible colour geometries for the selected * diagram weighted by their relative probabilities. * @param diag the diagram chosen. * @return the possible colour geometries weighted by their * relative probabilities. */ virtual Selector colourGeometries(tcDiagPtr diag) const; //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** * Calculate of the full next-to-leading order weight */ virtual double NLOWeight() const; /** * Leading-order matrix element for \f$q\bar q\to \gamma\gamma\f$ */ double loGammaGammaME(const cPDVector & particles, const vector & momenta, bool first=false) const; /** * Leading-order matrix element for \f$qg\to \gamma q\f$ */ double loGammaqME(const cPDVector & particles, const vector & momenta, bool first=false) const; /** * Leading-order matrix element for \f$g\bar q\to \gamma \bar q\f$ */ double loGammaqbarME(const cPDVector & particles, const vector & momenta, bool first=false) const; /** * Leading-order matrix element for \f$q\bar q\to \gamma g\f$ */ double loGammagME(const cPDVector & particles, const vector & momenta, bool first=false) const; /** * Real emission matrix element for \f$q\bar q\to \gamma \gamma g\f$ */ InvEnergy2 realGammaGammagME(const cPDVector & particles, const vector & momenta, DipoleType dipole, RadiationType rad, bool first=false) const; /** * Real emission matrix element for \f$qg\to \gamma \gamma q\f$ */ InvEnergy2 realGammaGammaqME(const cPDVector & particles, const vector & momenta, DipoleType dipole, RadiationType rad, bool first=false) const; /** * Real emission matrix element for \f$g\bar q\to \gamma \gamma \bar q\f$ */ InvEnergy2 realGammaGammaqbarME(const cPDVector & particles, const vector & momenta, DipoleType dipole, RadiationType rad, bool first=false) const; /** * The dipole subtractedvirtual contribution */ double subtractedVirtual() const; /** * Subtracted real contribution */ double subtractedReal(pair x, double z, double zJac, double oldqPDF, double newqPDF, double newgPDF,bool order) const; /** * Calculate of the collinear counterterms */ //@{ /** * Quark collinear counter term */ double collinearQuark(double x, Energy2 mu2, double jac, double z, double oldPDF, double newPDF) const; /** * Gluon collinear counter term */ double collinearGluon(Energy2 mu2, double jac, double z, double oldPDF, double newPDF) const; //@} /** * The real matrix element divided by \f$2 g_S^2\f$, to be implemented in the * inheriting classes. * @param particles The ParticleData objects of the particles * @param momenta The momenta of the particles */ double realME(const cPDVector & particles, const vector & momenta) const; /** * Generate hard QCD emission */ RealEmissionProcessPtr hardQCDEmission(RealEmissionProcessPtr, ParticleVector, pair); /** * Generate hard QED emission */ RealEmissionProcessPtr hardQEDEmission(RealEmissionProcessPtr, ParticleVector, pair); /** * The supression function */ pair supressionFunction(Energy pT,Energy scale) const { if(supressionScale_==0) scale = lambda_; Energy2 scale2 = sqr(scale), pT2 = sqr(pT); switch( supressionFunction_ ) { case 0: return make_pair(1.,0.); case 1: if(pT < scale ) return make_pair(1.,0.); else return make_pair(0.,1.); case 2: return make_pair(scale2/(pT2+scale2),pT2/(pT2+scale2)); default: assert(false); + return make_pair(0.,0.); } } protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); //@} private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ MEPP2GammaGammaPowheg & operator=(const MEPP2GammaGammaPowheg &) = delete; private: /** * Vertices */ //@{ /** * FFPVertex */ AbstractFFVVertexPtr FFPvertex_; /** * FFGVertex */ AbstractFFVVertexPtr FFGvertex_; //@} /** * Kinematic variables for the real radiation */ //@{ /** * First variable */ mutable double zTilde_; /** * Second variable */ mutable double vTilde_; /** * Azimuthal angle */ mutable double phi_; //@} /** * Whether to generate the positive, negative or leading order contribution */ unsigned int contrib_; /** * Power for sampling \f$x_p\f$ */ double power_; /** * Pointer to the gluon ParticleData object */ tcPDPtr gluon_; /** * Processes */ unsigned int process_; /** * Processes */ unsigned int threeBodyProcess_; /** * Allowed flavours of the incoming quarks */ int maxflavour_; /** * Factor for \f$C_F\f$ dependent pieces */ mutable double CFfact_; /** * Factor for \f$T_R\f$ dependent pieces */ mutable double TRfact_; /** * Strong coupling */ mutable double alphaS_; /** * Use a fixed value of \f$\alpha_S\f$ */ bool fixedAlphaS_; /** * Electromagnetic coupling */ mutable double alphaEM_; /** * Leading-order matrix element */ mutable double loME_; /** * The matrix element */ mutable ProductionMatrixElement me_; /** * the selected dipole */ mutable DipoleType dipole_; /** * Supression Function */ //@{ /** * Choice of the supression function */ unsigned int supressionFunction_; /** * Choice for the scale in the supression function */ unsigned int supressionScale_; /** * Scalar for the supression function */ Energy lambda_; //@} /** * Hard emission stuff */ //@{ /** * Whether the quark is in the + or - z direction */ bool quarkplus_; //@} /** * Properties of the incoming particles */ //@{ /** * Pointers to the BeamParticleData objects */ vector beams_; /** * Pointers to the ParticleDataObjects for the partons */ vector partons_; //@} /** * Constants for the sampling. The distribution is assumed to have the * form \f$\frac{c}{{\rm GeV}}\times\left(\frac{{\rm GeV}}{p_T}\right)^n\f$ */ //@{ /** * The prefactor, \f$c\f$ for the \f$q\bar{q}\f$ channel */ double preQCDqqbarq_; /** * The prefactor, \f$c\f$ for the \f$q\bar{q}\f$ channel */ double preQCDqqbarqbar_; /** * The prefactor, \f$c\f$ for the \f$qg\f$ channel */ double preQCDqg_; /** * The prefactor, \f$c\f$ for the \f$g\bar{q}\f$ channel */ double preQCDgqbar_; double preQEDqqbarq_; double preQEDqqbarqbar_; double preQEDqgq_; double preQEDgqbarqbar_; /** * The prefactors as a vector for easy use */ vector prefactor_; //@} /** * The transverse momentum of the jet */ Energy minpT_; /** * Pointer to the object calculating the strong coupling */ ShowerAlphaPtr alphaQCD_; /** * Pointer to the object calculating the EM */ ShowerAlphaPtr alphaQED_; /** * Scale choice */ unsigned int scaleChoice_; /** * Scale factor */ double scalePreFactor_; }; } #endif /* HERWIG_MEPP2GammaGammaPowheg_H */ diff --git a/MatrixElement/Powheg/MEPP2WHPowheg.cc b/MatrixElement/Powheg/MEPP2WHPowheg.cc --- a/MatrixElement/Powheg/MEPP2WHPowheg.cc +++ b/MatrixElement/Powheg/MEPP2WHPowheg.cc @@ -1,392 +1,392 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the MEPP2WHPowheg class. // #include "MEPP2WHPowheg.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/PDT/DecayMode.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Handlers/StandardXComb.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/Repository/EventGenerator.h" using namespace Herwig; MEPP2WHPowheg::MEPP2WHPowheg() : _gluon(), TR_(0.5), CF_(4./3.), _contrib(1) ,_nlo_alphaS_opt(0), _fixed_alphaS(0.115895), - _a(0.5) ,_p(0.7) , _eps(1.0e-8), _scaleopt(1), + _a(0.5) ,_p(0.7) , _scaleopt(1), _fixedScale(100.*GeV), _scaleFact(1.) {} // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeHerwigMEPP2WHPowheg("Herwig::MEPP2WHPowheg", "HwMEHadron.so HwPowhegMEHadron.so"); void MEPP2WHPowheg::persistentOutput(PersistentOStream & os) const { os << _contrib << _nlo_alphaS_opt << _fixed_alphaS << _a << _p << _gluon << _scaleopt << ounit(_fixedScale,GeV) << _scaleFact; } void MEPP2WHPowheg::persistentInput(PersistentIStream & is, int) { is >> _contrib >> _nlo_alphaS_opt >> _fixed_alphaS >> _a >> _p >> _gluon >> _scaleopt >> iunit(_fixedScale,GeV) >> _scaleFact; } void MEPP2WHPowheg::Init() { static ClassDocumentation documentation ("The MEPP2WHPowheg class implements the matrix element for the Bjorken" " process q qbar -> WH", "The PP$\\to$W Higgs POWHEG matrix element is described in \\cite{Hamilton:2009za}.", "%\\cite{Hamilton:2009za}\n" "\\bibitem{Hamilton:2009za}\n" " K.~Hamilton, P.~Richardson and J.~Tully,\n" " ``A Positive-Weight Next-to-Leading Order Monte Carlo Simulation for Higgs\n" " Boson Production,''\n" " JHEP {\\bf 0904} (2009) 116\n" " [arXiv:0903.4345 [hep-ph]].\n" " %%CITATION = JHEPA,0904,116;%%\n" ); static Switch interfaceContribution ("Contribution", "Which contributions to the cross section to include", &MEPP2WHPowheg::_contrib, 1, false, false); static SwitchOption interfaceContributionLeadingOrder (interfaceContribution, "LeadingOrder", "Just generate the leading order cross section", 0); static SwitchOption interfaceContributionPositiveNLO (interfaceContribution, "PositiveNLO", "Generate the positive contribution to the full NLO cross section", 1); static SwitchOption interfaceContributionNegativeNLO (interfaceContribution, "NegativeNLO", "Generate the negative contribution to the full NLO cross section", 2); static Switch interfaceNLOalphaSopt ("NLOalphaSopt", "Whether to use a fixed or a running QCD coupling for the NLO weight", &MEPP2WHPowheg::_nlo_alphaS_opt, 0, false, false); static SwitchOption interfaceNLOalphaSoptRunningAlphaS (interfaceNLOalphaSopt, "RunningAlphaS", "Use the usual running QCD coupling evaluated at scale scale()", 0); static SwitchOption interfaceNLOalphaSoptFixedAlphaS (interfaceNLOalphaSopt, "FixedAlphaS", "Use a constant QCD coupling for comparison/debugging purposes", 1); static Parameter interfaceFixedNLOalphaS ("FixedNLOalphaS", "The value of alphaS to use for the nlo weight if _nlo_alphaS_opt=1", &MEPP2WHPowheg::_fixed_alphaS, 0.115895, 0., 1.0, false, false, Interface::limited); static Parameter interfaceCorrectionCoefficient ("CorrectionCoefficient", "The magnitude of the correction term to reduce the negative contribution", &MEPP2WHPowheg::_a, 0.5, -10., 10.0, false, false, Interface::limited); static Parameter interfaceCorrectionPower ("CorrectionPower", "The power of the correction term to reduce the negative contribution", &MEPP2WHPowheg::_p, 0.7, 0.0, 1.0, false, false, Interface::limited); static Switch interfaceFactorizationScaleOption ("FactorizationScaleOption", "Option for the scale to be used", &MEPP2WHPowheg::_scaleopt, 1, false, false); static SwitchOption interfaceScaleOptionFixed (interfaceFactorizationScaleOption, "Fixed", "Use a fixed scale", 0); static SwitchOption interfaceScaleOptionsHat (interfaceFactorizationScaleOption, "Dynamic", "Use the mass of the vector boson-Higgs boson system", 1); static Parameter interfaceFactorizationScaleValue ("FactorizationScaleValue", "The fixed scale to use if required", &MEPP2WHPowheg::_fixedScale, GeV, 100.0*GeV, 10.0*GeV, 1000.0*GeV, false, false, Interface::limited); static Parameter interfaceScaleFactor ("ScaleFactor", "The factor used before sHat if using a running scale", &MEPP2WHPowheg::_scaleFact, 1.0, 0.0, 10.0, false, false, Interface::limited); } void MEPP2WHPowheg::doinit() { // gluon ParticleData object _gluon = getParticleData(ParticleID::g); MEPP2WH::doinit(); } Energy2 MEPP2WHPowheg::scale() const { return _scaleopt == 0 ? sqr(_fixedScale) : _scaleFact*sHat(); } int MEPP2WHPowheg::nDim() const { return 7; } bool MEPP2WHPowheg::generateKinematics(const double * r) { _xt=*(r+5); _v =*(r+6); return MEPP2WH::generateKinematics(r); } CrossSection MEPP2WHPowheg::dSigHatDR() const { // Get Born momentum fractions xbar_a and xbar_b: _xb_a = lastX1(); _xb_b = lastX2(); return MEPP2WH::dSigHatDR()*NLOweight(); } double MEPP2WHPowheg::NLOweight() const { // If only leading order is required return 1: if(_contrib==0) return 1.; useMe(); // Get particle data for QCD particles: _parton_a=mePartonData()[0]; _parton_b=mePartonData()[1]; // get BeamParticleData objects for PDF's _hadron_A=dynamic_ptr_cast::transient_const_pointer> (lastParticles().first->dataPtr()); _hadron_B=dynamic_ptr_cast::transient_const_pointer> (lastParticles().second->dataPtr()); // If necessary swap the particle data vectors so that _xb_a, // mePartonData[0], beam[0] relate to the inbound quark: if(!(lastPartons().first ->dataPtr()==_parton_a&& lastPartons().second->dataPtr()==_parton_b)) { swap(_xb_a ,_xb_b); swap(_hadron_A,_hadron_B); } // calculate the PDF's for the Born process _oldq = _hadron_A->pdf()->xfx(_hadron_A,_parton_a,scale(),_xb_a)/_xb_a; _oldqbar = _hadron_B->pdf()->xfx(_hadron_B,_parton_b,scale(),_xb_b)/_xb_b; // Calculate alpha_S _alphaS2Pi = _nlo_alphaS_opt==1 ? _fixed_alphaS : SM().alphaS(scale()); _alphaS2Pi /= 2.*Constants::pi; // Calculate the invariant mass of the dilepton pair _mll2 = sHat(); _mu2 = scale(); // Calculate the integrand // q qbar contribution double wqqvirt = Vtilde_qq(); double wqqcollin = Ctilde_qq(x(_xt,1.),1.) + Ctilde_qq(x(_xt,0.),0.); double wqqreal = Ftilde_qq(_xt,_v); double wqq = wqqvirt+wqqcollin+wqqreal; // q g contribution double wqgcollin = Ctilde_qg(x(_xt,0.),0.); double wqgreal = Ftilde_qg(_xt,_v); double wqg = wqgreal+wqgcollin; // g qbar contribution double wgqbarcollin = Ctilde_gq(x(_xt,1.),1.); double wgqbarreal = Ftilde_gq(_xt,_v); double wgqbar = wgqbarreal+wgqbarcollin; // total double wgt = 1.+(wqq+wqg+wgqbar); // KMH - 06/08 - This seems to give wrong NLO results for // associated Higgs so I'm omitting it. // //trick to try and reduce neg wgt contribution // if(_xt<1.-_eps) // wgt += _a*(1./pow(1.-_xt,_p)-(1.-pow(_eps,1.-_p))/(1.-_p)/(1.-_eps)); // return the answer assert(isfinite(wgt)); return _contrib==1 ? max(0.,wgt) : max(0.,-wgt); } double MEPP2WHPowheg::x(double xt, double v) const { double x0(xbar(v)); return x0+(1.-x0)*xt; } double MEPP2WHPowheg::x_a(double x, double v) const { if(x==1.) return _xb_a; if(v==0.) return _xb_a; if(v==1.) return _xb_a/x; return (_xb_a/sqrt(x))*sqrt((1.-(1.-x)*(1.-v))/(1.-(1.-x)*v)); } double MEPP2WHPowheg::x_b(double x, double v) const { if(x==1.) return _xb_b; if(v==0.) return _xb_b/x; if(v==1.) return _xb_b; return (_xb_b/sqrt(x))*sqrt((1.-(1.-x)*v)/(1.-(1.-x)*(1.-v))); } double MEPP2WHPowheg::xbar(double v) const { double xba2(sqr(_xb_a)), xbb2(sqr(_xb_b)), omv(-999.); double xbar1(-999.), xbar2(-999.); if(v==1.) return _xb_a; if(v==0.) return _xb_b; omv = 1.-v; xbar1=4.* v*xba2/ (sqrt(sqr(1.+xba2)*4.*sqr(omv)+16.*(1.-2.*omv)*xba2)+2.*omv*(1.-_xb_a)*(1.+_xb_a)); xbar2=4.*omv*xbb2/ (sqrt(sqr(1.+xbb2)*4.*sqr( v)+16.*(1.-2.* v)*xbb2)+2.* v*(1.-_xb_b)*(1.+_xb_b)); return max(xbar1,xbar2); } double MEPP2WHPowheg::Ltilde_qq(double x, double v) const { if(x==1.) return 1.; double xa(x_a(x,v)),xb(x_b(x,v)); double newq = (_hadron_A->pdf()->xfx(_hadron_A,_parton_a,scale(), xa)/ xa); double newqbar = (_hadron_B->pdf()->xfx(_hadron_B,_parton_b,scale(), xb)/ xb); return( newq * newqbar / _oldq / _oldqbar ); } double MEPP2WHPowheg::Ltilde_qg(double x, double v) const { double xa(x_a(x,v)),xb(x_b(x,v)); double newq = (_hadron_A->pdf()->xfx(_hadron_A,_parton_a,scale(), xa)/ xa); double newg2 = (_hadron_B->pdf()->xfx(_hadron_B,_gluon ,scale(), xb)/ xb); return( newq * newg2 / _oldq / _oldqbar ); } double MEPP2WHPowheg::Ltilde_gq(double x, double v) const { double xa(x_a(x,v)),xb(x_b(x,v)); double newg1 = (_hadron_A->pdf()->xfx(_hadron_A,_gluon ,scale(), xa)/ xa); double newqbar = (_hadron_B->pdf()->xfx(_hadron_B,_parton_b,scale(), xb)/ xb); return( newg1 * newqbar / _oldq / _oldqbar ); } double MEPP2WHPowheg::Vtilde_qq() const { return _alphaS2Pi*CF_*(-3.*log(_mu2/_mll2)+(2.*sqr(Constants::pi)/3.)-8.); } double MEPP2WHPowheg::Ccalbar_qg(double x) const { return (sqr(x)+sqr(1.-x))*(log(_mll2/(_mu2*x))+2.*log(1.-x))+2.*x*(1.-x); } double MEPP2WHPowheg::Ctilde_qg(double x, double v) const { return _alphaS2Pi*TR_ * ((1.-xbar(v))/x) * Ccalbar_qg(x)*Ltilde_qg(x,v); } double MEPP2WHPowheg::Ctilde_gq(double x, double v) const { return _alphaS2Pi*TR_ * ((1.-xbar(v))/x) * Ccalbar_qg(x)*Ltilde_gq(x,v); } double MEPP2WHPowheg::Ctilde_qq(double x, double v) const { double wgt = ((1.-x)/x+(1.+x*x)/(1.-x)/x*(2.*log(1.-x)-log(x)))*Ltilde_qq(x,v) - 4.*log(1.-x)/(1.-x) + 2./(1.-xbar(v))*log(1.-xbar(v))*log(1.-xbar(v)) + (2./(1.-xbar(v))*log(1.-xbar(v))-2./(1.-x)+(1.+x*x)/x/(1.-x)*Ltilde_qq(x,v)) *log(_mll2/_mu2); return _alphaS2Pi*CF_*(1.-xbar(v))*wgt; } double MEPP2WHPowheg::Fcal_qq(double x, double v) const { return (sqr(1.-x)*(1.-2.*v*(1.-v))+2.*x)/x*Ltilde_qq(x,v); } double MEPP2WHPowheg::Fcal_qg(double x, double v) const { return ((1.-xbar(v))/x)* (2.*x*(1.-x)*v+sqr((1.-x)*v)+sqr(x)+sqr(1.-x))*Ltilde_qg(x,v); } double MEPP2WHPowheg::Fcal_gq(double x, double v) const { return ((1.-xbar(v))/x)* (2.*x*(1.-x)*(1.-v)+sqr((1.-x)*(1.-v))+sqr(x)+sqr(1.-x))*Ltilde_gq(x,v); } double MEPP2WHPowheg::Ftilde_qg(double xt, double v) const { return _alphaS2Pi*TR_* ( Fcal_qg(x(xt,v),v) - Fcal_qg(x(xt,0.),0.) )/v; } double MEPP2WHPowheg::Ftilde_gq(double xt, double v) const { return _alphaS2Pi*TR_* ( Fcal_gq(x(xt,v),v) - Fcal_gq(x(xt,1.),1.) )/(1.-v); } double MEPP2WHPowheg::Ftilde_qq(double xt, double v) const { double eps(1e-10); // is emission into regular or singular region? if(xt>=0. && xt<1.-eps && v>eps && v<1.-eps) { // x<1, v>0, v<1 (regular emission, neither soft or collinear): return _alphaS2Pi*CF_* (( ( Fcal_qq(x(xt, v), v) - Fcal_qq(x(xt,1.),1.) ) / (1.-v)+ ( Fcal_qq(x(xt, v), v) - Fcal_qq(x(xt,0.),0.) ) / v )/(1.-xt) + ( log(1.-xbar(v)) - log(1.-_xb_a))*2./(1.-v) + ( log(1.-xbar(v)) - log(1.-_xb_b))*2./v); } else { // make sure emission is actually in the allowed phase space: if(!(v>=0. && v<=1. && xt>=0. && xt<=1.)) { ostringstream s; s << "MEPP2WHPowheg::Ftilde_qq : \n" << "xt(" << xt << ") and / or v(" << v << ") not in the phase space."; generator()->logWarning(Exception(s.str(),Exception::warning)); return 0.; } // is emission soft singular? if(xt>=1.-eps) { // x=1: if(v<=eps) { // x==1, v=0 (soft and collinear with particle b): return _alphaS2Pi*CF_* ( ( log(1.-xbar(v)) - log(1.-_xb_a))*2./(1.-v) ); } else if(v>=1.-eps) { // x==1, v=1 (soft and collinear with particle a): return _alphaS2Pi*CF_* ( ( log(1.-xbar(v)) - log(1.-_xb_b))*2./v ); } else { // x==1, 0=1.-eps) { // x<1 but v=1 (collinear with particle a, but not soft): return _alphaS2Pi*CF_* ( ( ( Fcal_qq(x(xt, v), v) - Fcal_qq(x(xt,0.),0.) ) / v )/(1.-xt) + ( log(1.-xbar(v)) - log(1.-_xb_b))*2./v ); } } } return 0.; } diff --git a/MatrixElement/Powheg/MEPP2WHPowheg.h b/MatrixElement/Powheg/MEPP2WHPowheg.h --- a/MatrixElement/Powheg/MEPP2WHPowheg.h +++ b/MatrixElement/Powheg/MEPP2WHPowheg.h @@ -1,386 +1,382 @@ // -*- C++ -*- #ifndef HERWIG_MEPP2WHPowheg_H #define HERWIG_MEPP2WHPowheg_H // // This is the declaration of the MEPP2WHPowheg class. // #include "Herwig/MatrixElement/Hadron/MEPP2WH.h" #include "ThePEG/PDF/BeamParticleData.h" namespace Herwig { using namespace ThePEG; /** * The MEPP2WHPowheg class provides the next-to-leading order * matrix elements for \f$W^\pm\f$ in assoication with a Higgs boson * in the PoOWHEG scheme. * * @see \ref MEPP2WHPowhegInterfaces "The interfaces" * defined for MEPP2WHPowheg. */ class MEPP2WHPowheg: public MEPP2WH { public: /** * Default constructor */ MEPP2WHPowheg(); /** @name Virtual functions required by the MEBase class. */ //@{ /** * Return the scale associated with the last set phase space point. */ virtual Energy2 scale() const; /** * The number of internal degreed of freedom used in the matrix * element. */ virtual int nDim() const; /** * Generate internal degrees of freedom given 'nDim()' uniform * random numbers in the interval ]0,1[. To help the phase space * generator, the 'dSigHatDR()' should be a smooth function of these * numbers, although this is not strictly necessary. Return * false if the chosen points failed the kinematical cuts. */ virtual bool generateKinematics(const double * r); /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(). Uses * me(). */ virtual CrossSection dSigHatDR() const; //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** * Calculate the correction weight with which leading-order * configurations are re-weighted. */ double NLOweight() const; /** * Calculate the variable \f$x=M_{B}^2/s\f$ from the integration variables. */ double x(double xt, double v) const; /** * Calculate the momentum fraction of the first parton. */ double x_a(double x, double v) const; /** * Calculate the momentum fraction of second parton. */ double x_b(double x, double v) const; /** * Calculate the minimum of \f$x\f$. */ double xbar(double v) const; /** * Calculate the ratio of the radiative luminosity funcion to the * Born luminosity function for the \f$qg\f$ initiated channel. */ double Ltilde_qg(double x, double v) const; /** * Calculate the ratio of the radiative luminosity funcion to the * Born luminosity function for the \f$g\bar{q}\f$ initiated channel. */ double Ltilde_gq(double x, double v) const; /** * Calculate the ratio of the radiative luminosity funcion to the * Born luminosity function for the \f$q\bar{q}\f$ initiated channel. */ double Ltilde_qq(double x, double v) const; /** * Calculate the soft-virtual contribution to the NLO weight. */ double Vtilde_qq() const; /** * Function for calculation of the \f$g\bar{q}\f$ and \f$g\bar{q}\f$ * initiated real contribution. */ double Ccalbar_qg(double x) const; /** * Function for calculation of the \f$qg\f$ * initiated real contribution. */ double Fcal_qg(double x, double v) const; /** * Function for calculation of the \f$g\bar{q}\f$ initiated real * contribution. */ double Fcal_gq(double x, double v) const; /** * Function for calculation of the \f$q\bar{q}\f$ initiated real * contribution. */ double Fcal_qq(double x, double v) const; /** * Function for calculation of the \f$qg\f$ initiated real * contribution. */ double Ftilde_qg(double xt, double v) const; /** * Function for calculation of the \f$g\bar{q}\f$ initiated real * contribution. */ double Ftilde_gq(double xt, double v) const; /** * Function for calculation of the \f$q\bar{q}\f$ initiated real * contribution. */ double Ftilde_qq(double xt, double v) const; /** * Function for calculation of the \f$qg\f$ initiated real * contribution. */ double Ctilde_qg(double x, double v) const; /** * Function for calculation of the \f$g\bar{q}\f$ initiated real * contribution. */ double Ctilde_gq(double x, double v) const; /** * Function for calculation of the \f$q\bar{q}\f$ initiated real * contribution. */ double Ctilde_qq(double x, double v) const; protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const { return new_ptr(*this); } /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const { return new_ptr(*this); } //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); //@} private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ MEPP2WHPowheg & operator=(const MEPP2WHPowheg &) = delete; private: /** * The momentum fraction of the first parton in the Born process */ mutable double _xb_a; /** * The momentum fraction of the second parton in the Born process */ mutable double _xb_b; /** * The ParticleData object for the first parton in the Born process */ mutable tcPDPtr _parton_a; /** * The ParticleData object for the second parton in the Born process */ mutable tcPDPtr _parton_b; /** * The BeamParticleData object for the first hadron */ mutable Ptr::transient_const_pointer _hadron_A; /** * The BeamParticleData object for the second hadron */ mutable Ptr::transient_const_pointer _hadron_B; /** * the ParticleData object for the gluon */ tcPDPtr _gluon; /** * The \f$T_R\f$ colour factor */ const double TR_; /** * The \f$C_F\f$ colour factor */ const double CF_; /** * The value of \f$\frac{\alpha_S}{2\pi}\f$ used for the calculation */ mutable double _alphaS2Pi; /** * The mass squared of the lepton pair */ mutable Energy2 _mll2; /** * The renormalization/factorization scale */ mutable Energy2 _mu2; /** * Parameters for the NLO weight */ //@{ /** * Whether to generate the positive, negative or leading order contribution */ unsigned int _contrib; /** * Whether to use a fixed or a running QCD coupling for the NLO weight */ unsigned int _nlo_alphaS_opt; /** * The value of alphaS to use for the nlo weight if _nloalphaSopt=1 */ double _fixed_alphaS; /** * The magnitude of the correction term to reduce the negative contribution */ double _a; /** * The power of the correction term to reduce the negative contribution */ double _p; - /** - * Cut-off for the correction function - */ - double _eps; //@} /** * Choice of the scale */ //@{ /** * Type of scale */ unsigned int _scaleopt; /** * Fixed scale if used */ Energy _fixedScale; /** * Prefactor if variable scale used */ double _scaleFact; //@} /** * Radiation variables */ //@{ /** * The \f$\tilde{x}\f$ variable */ double _xt; /** * The \f$v\f$ angular variable */ double _v; //@} /** * Values of the PDF's before radiation */ //@{ /** * For the quark */ mutable double _oldq; /** * For the antiquark */ mutable double _oldqbar; //@} }; } #endif /* HERWIG_MEPP2WHPowheg_H */ diff --git a/MatrixElement/Powheg/MEPP2ZHPowheg.cc b/MatrixElement/Powheg/MEPP2ZHPowheg.cc --- a/MatrixElement/Powheg/MEPP2ZHPowheg.cc +++ b/MatrixElement/Powheg/MEPP2ZHPowheg.cc @@ -1,391 +1,391 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the MEPP2ZHPowheg class. // #include "MEPP2ZHPowheg.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Handlers/StandardXComb.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/PDT/DecayMode.h" using namespace Herwig; MEPP2ZHPowheg::MEPP2ZHPowheg() : _gluon(), TR_(0.5), CF_(4./3.), _contrib(1) ,_nlo_alphaS_opt(0), _fixed_alphaS(0.115895), - _a(0.5) ,_p(0.7) , _eps(1.0e-8), _scaleopt(1), + _a(0.5) ,_p(0.7) , _scaleopt(1), _fixedScale(100.*GeV), _scaleFact(1.) {} void MEPP2ZHPowheg::persistentOutput(PersistentOStream & os) const { os << _contrib << _nlo_alphaS_opt << _fixed_alphaS << _a << _p << _gluon << _scaleopt << ounit(_fixedScale,GeV) << _scaleFact; } void MEPP2ZHPowheg::persistentInput(PersistentIStream & is, int) { is >> _contrib >> _nlo_alphaS_opt >> _fixed_alphaS >> _a >> _p >> _gluon >> _scaleopt >> iunit(_fixedScale,GeV) >> _scaleFact; } // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeHerwigMEPP2ZHPowheg("Herwig::MEPP2ZHPowheg", "HwMEHadron.so HwPowhegMEHadron.so"); void MEPP2ZHPowheg::Init() { static ClassDocumentation documentation ("The MEPP2ZHPowheg class implements the matrix element for q qbar -> Z H", "The PP$\\to$Z Higgs POWHEG matrix element is described in \\cite{Hamilton:2009za}.", "\\bibitem{Hamilton:2009za}\n" " K.~Hamilton, P.~Richardson and J.~Tully,\n" " %``A Positive-Weight Next-to-Leading Order Monte Carlo Simulation for Higgs\n" " %Boson Production,''\n" " JHEP {\\bf 0904} (2009) 116\n" " [arXiv:0903.4345 [hep-ph]].\n" " %%CITATION = JHEPA,0904,116;%%\n" ); static Switch interfaceContribution ("Contribution", "Which contributions to the cross section to include", &MEPP2ZHPowheg::_contrib, 1, false, false); static SwitchOption interfaceContributionLeadingOrder (interfaceContribution, "LeadingOrder", "Just generate the leading order cross section", 0); static SwitchOption interfaceContributionPositiveNLO (interfaceContribution, "PositiveNLO", "Generate the positive contribution to the full NLO cross section", 1); static SwitchOption interfaceContributionNegativeNLO (interfaceContribution, "NegativeNLO", "Generate the negative contribution to the full NLO cross section", 2); static Switch interfaceNLOalphaSopt ("NLOalphaSopt", "Whether to use a fixed or a running QCD coupling for the NLO weight", &MEPP2ZHPowheg::_nlo_alphaS_opt, 0, false, false); static SwitchOption interfaceNLOalphaSoptRunningAlphaS (interfaceNLOalphaSopt, "RunningAlphaS", "Use the usual running QCD coupling evaluated at scale scale()", 0); static SwitchOption interfaceNLOalphaSoptFixedAlphaS (interfaceNLOalphaSopt, "FixedAlphaS", "Use a constant QCD coupling for comparison/debugging purposes", 1); static Parameter interfaceFixedNLOalphaS ("FixedNLOalphaS", "The value of alphaS to use for the nlo weight if _nlo_alphaS_opt=1", &MEPP2ZHPowheg::_fixed_alphaS, 0.115895, 0., 1.0, false, false, Interface::limited); static Parameter interfaceCorrectionCoefficient ("CorrectionCoefficient", "The magnitude of the correction term to reduce the negative contribution", &MEPP2ZHPowheg::_a, 0.5, -10., 10.0, false, false, Interface::limited); static Parameter interfaceCorrectionPower ("CorrectionPower", "The power of the correction term to reduce the negative contribution", &MEPP2ZHPowheg::_p, 0.7, 0.0, 1.0, false, false, Interface::limited); static Switch interfaceFactorizationScaleOption ("FactorizationScaleOption", "Option for the scale to be used", &MEPP2ZHPowheg::_scaleopt, 1, false, false); static SwitchOption interfaceScaleOptionFixed (interfaceFactorizationScaleOption, "Fixed", "Use a fixed scale", 0); static SwitchOption interfaceScaleOptionsHat (interfaceFactorizationScaleOption, "Dynamic", "Use the mass of the vector boson-Higgs boson system", 1); static Parameter interfaceFactorizationScaleValue ("FactorizationScaleValue", "The fixed scale to use if required", &MEPP2ZHPowheg::_fixedScale, GeV, 100.0*GeV, 10.0*GeV, 1000.0*GeV, false, false, Interface::limited); static Parameter interfaceScaleFactor ("ScaleFactor", "The factor used before sHat if using a running scale", &MEPP2ZHPowheg::_scaleFact, 1.0, 0.0, 10.0, false, false, Interface::limited); } void MEPP2ZHPowheg::doinit() { // gluon ParticleData object _gluon = getParticleData(ParticleID::g); MEPP2ZH::doinit(); } Energy2 MEPP2ZHPowheg::scale() const { return _scaleopt == 0 ? sqr(_fixedScale) : _scaleFact*sHat(); } int MEPP2ZHPowheg::nDim() const { return 7; } bool MEPP2ZHPowheg::generateKinematics(const double * r) { _xt=*(r+5); _v =*(r+6); return MEPP2ZH::generateKinematics(r); } CrossSection MEPP2ZHPowheg::dSigHatDR() const { // Get Born momentum fractions xbar_a and xbar_b: _xb_a = lastX1(); _xb_b = lastX2(); return MEPP2ZH::dSigHatDR()*NLOweight(); } double MEPP2ZHPowheg::NLOweight() const { // If only leading order is required return 1: if(_contrib==0) return 1.; useMe(); // Get particle data for QCD particles: _parton_a=mePartonData()[0]; _parton_b=mePartonData()[1]; // get BeamParticleData objects for PDF's _hadron_A=dynamic_ptr_cast::transient_const_pointer> (lastParticles().first->dataPtr()); _hadron_B=dynamic_ptr_cast::transient_const_pointer> (lastParticles().second->dataPtr()); // If necessary swap the particle data vectors so that _xb_a, // mePartonData[0], beam[0] relate to the inbound quark: if(!(lastPartons().first ->dataPtr()==_parton_a&& lastPartons().second->dataPtr()==_parton_b)) { swap(_xb_a ,_xb_b); swap(_hadron_A,_hadron_B); } // calculate the PDF's for the Born process _oldq = _hadron_A->pdf()->xfx(_hadron_A,_parton_a,scale(),_xb_a)/_xb_a; _oldqbar = _hadron_B->pdf()->xfx(_hadron_B,_parton_b,scale(),_xb_b)/_xb_b; // Calculate alpha_S _alphaS2Pi = _nlo_alphaS_opt==1 ? _fixed_alphaS : SM().alphaS(scale()); _alphaS2Pi /= 2.*Constants::pi; // Calculate the invariant mass of the dilepton pair _mll2 = sHat(); _mu2 = scale(); // Calculate the integrand // q qbar contribution double wqqvirt = Vtilde_qq(); double wqqcollin = Ctilde_qq(x(_xt,1.),1.) + Ctilde_qq(x(_xt,0.),0.); double wqqreal = Ftilde_qq(_xt,_v); double wqq = wqqvirt+wqqcollin+wqqreal; // q g contribution double wqgcollin = Ctilde_qg(x(_xt,0.),0.); double wqgreal = Ftilde_qg(_xt,_v); double wqg = wqgreal+wqgcollin; // g qbar contribution double wgqbarcollin = Ctilde_gq(x(_xt,1.),1.); double wgqbarreal = Ftilde_gq(_xt,_v); double wgqbar = wgqbarreal+wgqbarcollin; // total double wgt = 1.+(wqq+wqg+wgqbar); // KMH - 06/08 - This seems to give wrong NLO results for // associated Higgs so I'm omitting it. // //trick to try and reduce neg wgt contribution // if(_xt<1.-_eps) // wgt += _a*(1./pow(1.-_xt,_p)-(1.-pow(_eps,1.-_p))/(1.-_p)/(1.-_eps)); // return the answer assert(isfinite(wgt)); return _contrib==1 ? max(0.,wgt) : max(0.,-wgt); } double MEPP2ZHPowheg::x(double xt, double v) const { double x0(xbar(v)); return x0+(1.-x0)*xt; } double MEPP2ZHPowheg::x_a(double x, double v) const { if(x==1.) return _xb_a; if(v==0.) return _xb_a; if(v==1.) return _xb_a/x; return (_xb_a/sqrt(x))*sqrt((1.-(1.-x)*(1.-v))/(1.-(1.-x)*v)); } double MEPP2ZHPowheg::x_b(double x, double v) const { if(x==1.) return _xb_b; if(v==0.) return _xb_b/x; if(v==1.) return _xb_b; return (_xb_b/sqrt(x))*sqrt((1.-(1.-x)*v)/(1.-(1.-x)*(1.-v))); } double MEPP2ZHPowheg::xbar(double v) const { double xba2(sqr(_xb_a)), xbb2(sqr(_xb_b)), omv(-999.); double xbar1(-999.), xbar2(-999.); if(v==1.) return _xb_a; if(v==0.) return _xb_b; omv = 1.-v; xbar1=4.* v*xba2/ (sqrt(sqr(1.+xba2)*4.*sqr(omv)+16.*(1.-2.*omv)*xba2)+2.*omv*(1.-_xb_a)*(1.+_xb_a)); xbar2=4.*omv*xbb2/ (sqrt(sqr(1.+xbb2)*4.*sqr( v)+16.*(1.-2.* v)*xbb2)+2.* v*(1.-_xb_b)*(1.+_xb_b)); return max(xbar1,xbar2); } double MEPP2ZHPowheg::Ltilde_qq(double x, double v) const { if(x==1.) return 1.; double xa(x_a(x,v)),xb(x_b(x,v)); double newq = (_hadron_A->pdf()->xfx(_hadron_A,_parton_a,scale(), xa)/ xa); double newqbar = (_hadron_B->pdf()->xfx(_hadron_B,_parton_b,scale(), xb)/ xb); return( newq * newqbar / _oldq / _oldqbar ); } double MEPP2ZHPowheg::Ltilde_qg(double x, double v) const { double xa(x_a(x,v)),xb(x_b(x,v)); double newq = (_hadron_A->pdf()->xfx(_hadron_A,_parton_a,scale(), xa)/ xa); double newg2 = (_hadron_B->pdf()->xfx(_hadron_B,_gluon ,scale(), xb)/ xb); return( newq * newg2 / _oldq / _oldqbar ); } double MEPP2ZHPowheg::Ltilde_gq(double x, double v) const { double xa(x_a(x,v)),xb(x_b(x,v)); double newg1 = (_hadron_A->pdf()->xfx(_hadron_A,_gluon ,scale(), xa)/ xa); double newqbar = (_hadron_B->pdf()->xfx(_hadron_B,_parton_b,scale(), xb)/ xb); return( newg1 * newqbar / _oldq / _oldqbar ); } double MEPP2ZHPowheg::Vtilde_qq() const { return _alphaS2Pi*CF_*(-3.*log(_mu2/_mll2)+(2.*sqr(Constants::pi)/3.)-8.); } double MEPP2ZHPowheg::Ccalbar_qg(double x) const { return (sqr(x)+sqr(1.-x))*(log(_mll2/(_mu2*x))+2.*log(1.-x))+2.*x*(1.-x); } double MEPP2ZHPowheg::Ctilde_qg(double x, double v) const { return _alphaS2Pi*TR_ * ((1.-xbar(v))/x) * Ccalbar_qg(x)*Ltilde_qg(x,v); } double MEPP2ZHPowheg::Ctilde_gq(double x, double v) const { return _alphaS2Pi*TR_ * ((1.-xbar(v))/x) * Ccalbar_qg(x)*Ltilde_gq(x,v); } double MEPP2ZHPowheg::Ctilde_qq(double x, double v) const { double wgt = ((1.-x)/x+(1.+x*x)/(1.-x)/x*(2.*log(1.-x)-log(x)))*Ltilde_qq(x,v) - 4.*log(1.-x)/(1.-x) + 2./(1.-xbar(v))*log(1.-xbar(v))*log(1.-xbar(v)) + (2./(1.-xbar(v))*log(1.-xbar(v))-2./(1.-x)+(1.+x*x)/x/(1.-x)*Ltilde_qq(x,v)) *log(_mll2/_mu2); return _alphaS2Pi*CF_*(1.-xbar(v))*wgt; } double MEPP2ZHPowheg::Fcal_qq(double x, double v) const { return (sqr(1.-x)*(1.-2.*v*(1.-v))+2.*x)/x*Ltilde_qq(x,v); } double MEPP2ZHPowheg::Fcal_qg(double x, double v) const { return ((1.-xbar(v))/x)* (2.*x*(1.-x)*v+sqr((1.-x)*v)+sqr(x)+sqr(1.-x))*Ltilde_qg(x,v); } double MEPP2ZHPowheg::Fcal_gq(double x, double v) const { return ((1.-xbar(v))/x)* (2.*x*(1.-x)*(1.-v)+sqr((1.-x)*(1.-v))+sqr(x)+sqr(1.-x))*Ltilde_gq(x,v); } double MEPP2ZHPowheg::Ftilde_qg(double xt, double v) const { return _alphaS2Pi*TR_* ( Fcal_qg(x(xt,v),v) - Fcal_qg(x(xt,0.),0.) )/v; } double MEPP2ZHPowheg::Ftilde_gq(double xt, double v) const { return _alphaS2Pi*TR_* ( Fcal_gq(x(xt,v),v) - Fcal_gq(x(xt,1.),1.) )/(1.-v); } double MEPP2ZHPowheg::Ftilde_qq(double xt, double v) const { double eps(1e-10); // is emission into regular or singular region? if(xt>=0. && xt<1.-eps && v>eps && v<1.-eps) { // x<1, v>0, v<1 (regular emission, neither soft or collinear): return _alphaS2Pi*CF_* (( ( Fcal_qq(x(xt, v), v) - Fcal_qq(x(xt,1.),1.) ) / (1.-v)+ ( Fcal_qq(x(xt, v), v) - Fcal_qq(x(xt,0.),0.) ) / v )/(1.-xt) + ( log(1.-xbar(v)) - log(1.-_xb_a))*2./(1.-v) + ( log(1.-xbar(v)) - log(1.-_xb_b))*2./v); } else { // make sure emission is actually in the allowed phase space: if(!(v>=0. && v<=1. && xt>=0. && xt<=1.)) { ostringstream s; s << "MEPP2ZHPowheg::Ftilde_qq : \n" << "xt(" << xt << ") and / or v(" << v << ") not in the phase space."; generator()->logWarning(Exception(s.str(),Exception::warning)); return 0.; } // is emission soft singular? if(xt>=1.-eps) { // x=1: if(v<=eps) { // x==1, v=0 (soft and collinear with particle b): return _alphaS2Pi*CF_* ( ( log(1.-xbar(v)) - log(1.-_xb_a))*2./(1.-v) ); } else if(v>=1.-eps) { // x==1, v=1 (soft and collinear with particle a): return _alphaS2Pi*CF_* ( ( log(1.-xbar(v)) - log(1.-_xb_b))*2./v ); } else { // x==1, 0=1.-eps) { // x<1 but v=1 (collinear with particle a, but not soft): return _alphaS2Pi*CF_* ( ( ( Fcal_qq(x(xt, v), v) - Fcal_qq(x(xt,0.),0.) ) / v )/(1.-xt) + ( log(1.-xbar(v)) - log(1.-_xb_b))*2./v ); } } } return 0.; } diff --git a/MatrixElement/Powheg/MEPP2ZHPowheg.h b/MatrixElement/Powheg/MEPP2ZHPowheg.h --- a/MatrixElement/Powheg/MEPP2ZHPowheg.h +++ b/MatrixElement/Powheg/MEPP2ZHPowheg.h @@ -1,384 +1,380 @@ // -*- C++ -*- #ifndef HERWIG_MEPP2ZHPowheg_H #define HERWIG_MEPP2ZHPowheg_H // // This is the declaration of the MEPP2ZHPowheg class. // #include "Herwig/MatrixElement/Hadron/MEPP2ZH.h" #include "ThePEG/PDF/BeamParticleData.h" namespace Herwig { using namespace ThePEG; /** * The MEPP2ZHPowheg class implements the matrix element * for \f$q\bar{q}\to Z^0h^0\f$. * * @see \ref MEPP2ZHPowhegInterfaces "The interfaces" * defined for MEPP2ZHPowheg. */ class MEPP2ZHPowheg: public MEPP2ZH { public: /** * The default constructor. */ MEPP2ZHPowheg(); /** @name Virtual functions required by the MEBase class. */ //@{ /** * Return the scale associated with the last set phase space point. */ virtual Energy2 scale() const; /** * The number of internal degreed of freedom used in the matrix * element. */ virtual int nDim() const; /** * Generate internal degrees of freedom given 'nDim()' uniform * random numbers in the interval ]0,1[. To help the phase space * generator, the 'dSigHatDR()' should be a smooth function of these * numbers, although this is not strictly necessary. Return * false if the chosen points failed the kinematical cuts. */ virtual bool generateKinematics(const double * r); /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(). Uses * me(). */ virtual CrossSection dSigHatDR() const; //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** * Calculate the correction weight with which leading-order * configurations are re-weighted. */ double NLOweight() const; /** * Calculate the variable \f$x=M_{B}^2/s\f$ from the integration variables. */ double x(double xt, double v) const; /** * Calculate the momentum fraction of the first parton. */ double x_a(double x, double v) const; /** * Calculate the momentum fraction of second parton. */ double x_b(double x, double v) const; /** * Calculate the minimum of \f$x\f$. */ double xbar(double v) const; /** * Calculate the ratio of the radiative luminosity funcion to the * Born luminosity function for the \f$qg\f$ initiated channel. */ double Ltilde_qg(double x, double v) const; /** * Calculate the ratio of the radiative luminosity funcion to the * Born luminosity function for the \f$g\bar{q}\f$ initiated channel. */ double Ltilde_gq(double x, double v) const; /** * Calculate the ratio of the radiative luminosity funcion to the * Born luminosity function for the \f$q\bar{q}\f$ initiated channel. */ double Ltilde_qq(double x, double v) const; /** * Calculate the soft-virtual contribution to the NLO weight. */ double Vtilde_qq() const; /** * Function for calculation of the \f$g\bar{q}\f$ and \f$g\bar{q}\f$ * initiated real contribution. */ double Ccalbar_qg(double x) const; /** * Function for calculation of the \f$qg\f$ * initiated real contribution. */ double Fcal_qg(double x, double v) const; /** * Function for calculation of the \f$g\bar{q}\f$ initiated real * contribution. */ double Fcal_gq(double x, double v) const; /** * Function for calculation of the \f$q\bar{q}\f$ initiated real * contribution. */ double Fcal_qq(double x, double v) const; /** * Function for calculation of the \f$qg\f$ initiated real * contribution. */ double Ftilde_qg(double xt, double v) const; /** * Function for calculation of the \f$g\bar{q}\f$ initiated real * contribution. */ double Ftilde_gq(double xt, double v) const; /** * Function for calculation of the \f$q\bar{q}\f$ initiated real * contribution. */ double Ftilde_qq(double xt, double v) const; /** * Function for calculation of the \f$qg\f$ initiated real * contribution. */ double Ctilde_qg(double x, double v) const; /** * Function for calculation of the \f$g\bar{q}\f$ initiated real * contribution. */ double Ctilde_gq(double x, double v) const; /** * Function for calculation of the \f$q\bar{q}\f$ initiated real * contribution. */ double Ctilde_qq(double x, double v) const; protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const { return new_ptr(*this); } /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const { return new_ptr(*this); } //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); //@} private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ MEPP2ZHPowheg & operator=(const MEPP2ZHPowheg &) = delete; private: /** * The momentum fraction of the first parton in the Born process */ mutable double _xb_a; /** * The momentum fraction of the second parton in the Born process */ mutable double _xb_b; /** * The ParticleData object for the first parton in the Born process */ mutable tcPDPtr _parton_a; /** * The ParticleData object for the second parton in the Born process */ mutable tcPDPtr _parton_b; /** * The BeamParticleData object for the first hadron */ mutable Ptr::transient_const_pointer _hadron_A; /** * The BeamParticleData object for the second hadron */ mutable Ptr::transient_const_pointer _hadron_B; /** * the ParticleData object for the gluon */ tcPDPtr _gluon; /** * The \f$T_R\f$ colour factor */ const double TR_; /** * The \f$C_F\f$ colour factor */ const double CF_; /** * The value of \f$\frac{\alpha_S}{2\pi}\f$ used for the calculation */ mutable double _alphaS2Pi; /** * The mass squared of the lepton pair */ mutable Energy2 _mll2; /** * The renormalization/factorization scale */ mutable Energy2 _mu2; /** * Parameters for the NLO weight */ //@{ /** * Whether to generate the positive, negative or leading order contribution */ unsigned int _contrib; /** * Whether to use a fixed or a running QCD coupling for the NLO weight */ unsigned int _nlo_alphaS_opt; /** * The value of alphaS to use for the nlo weight if _nloalphaSopt=1 */ double _fixed_alphaS; /** * The magnitude of the correction term to reduce the negative contribution */ double _a; /** * The power of the correction term to reduce the negative contribution */ double _p; - /** - * Cut-off for the correction function - */ - double _eps; //@} /** * Choice of the scale */ //@{ /** * Type of scale */ unsigned int _scaleopt; /** * Fixed scale if used */ Energy _fixedScale; /** * Prefactor if variable scale used */ double _scaleFact; //@} /** * Radiation variables */ //@{ /** * The \f$\tilde{x}\f$ variable */ double _xt; /** * The \f$v\f$ angular variable */ double _v; //@} /** * Values of the PDF's before radiation */ //@{ /** * For the quark */ mutable double _oldq; /** * For the antiquark */ mutable double _oldqbar; //@} }; } #endif /* HERWIG_MEPP2ZHPowheg_H */ diff --git a/Models/ADD/ADDModelFFGGRVertex.cc b/Models/ADD/ADDModelFFGGRVertex.cc --- a/Models/ADD/ADDModelFFGGRVertex.cc +++ b/Models/ADD/ADDModelFFGGRVertex.cc @@ -1,92 +1,91 @@ // -*- C++ -*- // // ADDModelFFGGRVertex.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2017 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the ADDModelFFGGRVertex class. // #include "ADDModelFFGGRVertex.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; using namespace ThePEG; ADDModelFFGGRVertex::ADDModelFFGGRVertex() : couplast_(0.), q2last_(ZERO), kappa_(ZERO), r_(ZERO) { orderInGem(1); orderInGs (1); colourStructure(ColourStructure::SU3TFUND); } void ADDModelFFGGRVertex::doinit() { for(int ix=1;ix<7;++ix) { addToList(-ix,ix,21,39); } FFVTVertex::doinit(); tcHwADDPtr hwADD=dynamic_ptr_cast(generator()->standardModel()); if(!hwADD) throw Exception() << "Must have ADDModel in ADDModelFFGGRVertex::doinit()" << Exception::runerror; kappa_ = 2./hwADD->MPlanckBar(); r_ = sqr(hwADD->LambdaT())/hwADD->MPlanckBar(); } void ADDModelFFGGRVertex::persistentOutput(PersistentOStream & os) const { os << ounit(kappa_,InvGeV) << ounit(r_,GeV); } void ADDModelFFGGRVertex::persistentInput(PersistentIStream & is, int) { is >> iunit(kappa_,InvGeV) >> iunit(r_,GeV); } // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeHerwigADDModelFFGGRVertex("Herwig::ADDModelFFGGRVertex", "HwADDModel.so"); void ADDModelFFGGRVertex::Init() { static ClassDocumentation documentation ("The ADDModelFFGGRVertexxs class is the implementation" " of the two fermion vector coupling for the ADD model."); } #ifndef NDEBUG void ADDModelFFGGRVertex::setCoupling(Energy2 q2,tcPDPtr aa,tcPDPtr, tcPDPtr cc, tcPDPtr) { #else void ADDModelFFGGRVertex::setCoupling(Energy2 q2,tcPDPtr,tcPDPtr, tcPDPtr, tcPDPtr) { #endif // work out the particles assert(cc->id()==ParticleID::g && abs(aa->id()) <= 6); - Complex coup; // overall factor if(q2last_!=q2||couplast_==0.) { couplast_ = strongCoupling(q2); q2last_=q2; } left (1.); right(1.); // set the coupling norm(UnitRemoval::E * kappa_ * couplast_); } Complex ADDModelFFGGRVertex::propagator(int iopt, Energy2 q2,tcPDPtr part, Energy mass, Energy width) { if(part->id()!=ParticleID::Graviton) return VertexBase::propagator(iopt,q2,part,mass,width); else return Complex(4.*Constants::pi*UnitRemoval::E2/sqr(r_)); } diff --git a/Models/General/VVSLoopVertex.cc b/Models/General/VVSLoopVertex.cc --- a/Models/General/VVSLoopVertex.cc +++ b/Models/General/VVSLoopVertex.cc @@ -1,134 +1,134 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the VVSLoopVertex class. // #include "VVSLoopVertex.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/Looptools/clooptools.h" using namespace Herwig; using namespace ThePEG; namespace LT = Looptools; IBPtr VVSLoopVertex::clone() const { return new_ptr(*this); } IBPtr VVSLoopVertex::fullclone() const { return new_ptr(*this); } void VVSLoopVertex::persistentOutput(PersistentOStream & os) const { os << ounit(masses,GeV) << type << couplings << Npart_; } void VVSLoopVertex::persistentInput(PersistentIStream & is, int) { is >> iunit(masses,GeV) >> type >> couplings >> Npart_; } void VVSLoopVertex::dofinish() { if(loopToolsInit_) Looptools::ltexi(); GeneralVVSVertex::dofinish(); } // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeHerwigVVSLoopVertex("Herwig::VVSLoopVertex", "Herwig.so"); void VVSLoopVertex::Init() { static ClassDocumentation documentation ("The VVSLoopVertex class calculates the tensor integral" " coefficients using Looptools."); } void VVSLoopVertex::setCoupling(Energy2, tcPDPtr p1, tcPDPtr,tcPDPtr) { if(!loopToolsInit_) { Looptools::ltini(); loopToolsInit_ = true; } //Kinematic invariants double ps2 = invariant(0,0) / MeV2; double pv1s = invariant(1,1) / MeV2; double pv2s = invariant(2,2) / MeV2; Complex a(0.),b(0.),c(0.),d(0.),e(0.),f(0.); for(unsigned int i = 0; i< Npart_;++i) { double lmass = masses[i] / MeV; double mls = sqr(lmass); // left coupling for fermions or the total coupling // for scalars or vectors Complex lc = couplings[i].first; // double p1p2 = 0.5*(ps2-pv1s-pv2s); Complex C0A = LT::C0i(LT::cc0,pv2s,ps2,pv1s,mls,mls,mls); long theC = LT::Cget(pv2s,ps2,pv1s, mls,mls,mls); // Complex C1A = LT::Cval(LT::cc1,theC); // Complex C2A = LT::Cval(LT::cc2,theC); // Complex C11A = LT::Cval(LT::cc11,theC); Complex C12A = LT::Cval(LT::cc12,theC); // Complex C22A = LT::Cval(LT::cc22,theC); // Complex C00A = LT::Cval(LT::cc00,theC); Complex C0B = LT::C0i(LT::cc0,pv1s,ps2,pv2s,mls,mls,mls); theC = LT::Cget(pv1s,ps2,pv2s, mls,mls,mls); // Complex C1B = LT::Cval(LT::cc1,theC); // Complex C2B = LT::Cval(LT::cc2,theC); // Complex C11B = LT::Cval(LT::cc11,theC); Complex C12B = LT::Cval(LT::cc12,theC); // Complex C22B = LT::Cval(LT::cc22,theC); // Complex C00B = LT::Cval(LT::cc00,theC); if(type[i] == PDT::Spin1Half) { Complex lpr = lc + couplings[i].second; Complex loop = 2.*lpr*lmass*( - 4.*(C12A + C12B) + C0A + C0B ); a -= loop; d += loop; f += 2.*(lc - couplings[i].second)*lmass*(C0A+C0B); // a += 2.*lpr*lmass*(2.*C12A-C0A+2.*C12B-C0B+ // (1. - pv1s*(C22A+C11B)- pv2s*(C11A+C22B) + mls*(C0A+C0B) )/p1p2); // b += 8.*lpr*lmass*(2.*C22A + C2A +2.*C11B + C1B); // c += 2.*lpr*lmass*(- 4.*(C12A + C12B) - 2.*(C2A + C1A + C2B + C1B) - C0A - C0B); // d += 2.*lpr*lmass*( - 4.*(C12A + C12B) + C0A + C0B ); // e += 4.*lpr*lmass*( 2.*(C11A + C22B) + C1A + C2B); } else if(type[i] == PDT::Spin1) { - Complex B0W(LT::B0(ps2 ,mls,mls)); + //Complex B0W(LT::B0(ps2 ,mls,mls)); double mr(sqr(p1->mass()/masses[i])); Complex loop = 2.*lc*( -(6.+mr)*(C12A+C12B) + 4.*(C0A +C0B)); a -= loop; d += loop; // a += lc*(-8.*(C0A+C0B) +(6.+mr)*(2.*(C00A+C00B)-B0W)/p1p2); // b += lc*(6.+mr)*(2.*(C22A+C11B)+C2A+C1B); // c += 0.5*lc*(6.+mr)*( - 4.*(C12A+C12B) - 2.*(C1A+C2A+C1B+C2B) - C0A - C0B ); // d += 2.*lc*( -(6.+mr)*(C12A+C12B) + 4.*(C0A +C0B)); // e += lc*(6.+mr)*( 2.*(C11A+C22B) + C1A + C2B ); } else if(type[i] == PDT::Spin0) { Complex loop = 4.*lc*(C12A+C12B); a -= loop; d += loop; // a += -2.*lc*( 2.*(C00A+C00B) - LT::B0(ps2,mls,mls))/p1p2; // b += -2.*lc* ( 2.*(C22A + C11B) + C2A + C1B); // c += -lc*( - 4.*(C12A + C12B) - 2.*(C2A + C1A + C2B + C1B) - C0A - C0B); // d += 4.*lc*(C12A+C12B); // e += -lc*( 2.*(C11A + C22B) + C1A + C2B ); } else { throw Helicity::HelicityConsistencyError() << "SVVLoopVertex::setCoupling - Incorrect particle in SVV loop. " << "Spin: " << type[i] << Exception::runerror; } } //Looptools defines integrals differently double fact = 1./16./sqr(Constants::pi); a00(fact*a); a11(fact*b); a12(fact*c); a21(fact*d); a22(fact*e); aEp(fact*f); } diff --git a/Models/LH/LHFFGVertex.cc b/Models/LH/LHFFGVertex.cc --- a/Models/LH/LHFFGVertex.cc +++ b/Models/LH/LHFFGVertex.cc @@ -1,54 +1,62 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the LHFFGVertex class. // #include "LHFFGVertex.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/StandardModel/StandardModelBase.h" using namespace Herwig; // Static variable needed for the type description system in ThePEG. DescribeNoPIOClass describeHerwigLHFFGVertex("Herwig::LHFFGVertex", "HwLHModel.so"); void LHFFGVertex::Init() { static ClassDocumentation documentation ("The LHFFGVertex class implements the coupling of the quarks" " to the gluon in the Little Higgs model"); } // coupling for FFG vertex -void LHFFGVertex::setCoupling(Energy2 q2,tcPDPtr a,tcPDPtr,tcPDPtr) { +void LHFFGVertex::setCoupling(Energy2 q2, +#ifndef NDEBUG + tcPDPtr a, +#else + tcPDPtr , +#endif + tcPDPtr,tcPDPtr) { // check allowed +#ifndef NDEBUG int iferm=abs(a->id()); +#endif assert((iferm>=1 && iferm<=6) || iferm==8); // first the overall normalisation if(q2!=_q2last) { _couplast = -strongCoupling(q2); _q2last=q2; } norm(_couplast); left(1.); right(1.); } void LHFFGVertex::doinit() { // PDG codes for the particles for(int ix=1;ix<7;++ix) { addToList(-ix, ix, 21); } addToList(-8, 8, 21); FFVVertex::doinit(); } LHFFGVertex::LHFFGVertex() : _couplast(0.), _q2last(0.*GeV2) { orderInGs(1); orderInGem(0); colourStructure(ColourStructure::SU3TFUND); } diff --git a/Models/Sextet/SextetFFSVertex.cc b/Models/Sextet/SextetFFSVertex.cc --- a/Models/Sextet/SextetFFSVertex.cc +++ b/Models/Sextet/SextetFFSVertex.cc @@ -1,213 +1,215 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the SextetFFSVertex class. // #include "SextetFFSVertex.h" #include "SextetModel.h" #include "SextetParticles.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; IBPtr SextetFFSVertex::clone() const { return new_ptr(*this); } IBPtr SextetFFSVertex::fullclone() const { return new_ptr(*this); } void SextetFFSVertex::persistentOutput(PersistentOStream & os) const { os << g1L_ << g1R_ << g1pR_ << g1ppR_ << g3L_; } void SextetFFSVertex::persistentInput(PersistentIStream & is, int) { is >> g1L_ >> g1R_ >> g1pR_ >> g1ppR_ >> g3L_; } // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeSextetFFSVertex("Herwig::SextetFFSVertex", "HwSextetModel.so"); void SextetFFSVertex::Init() { static ClassDocumentation documentation ("The SextetFFSVertex class implements the coupling of two " "fermions to a scalar sextet particle."); } void SextetFFSVertex::doinit() { orderInGs (0); orderInGem(1); SextetModelPtr model = dynamic_ptr_cast(generator()->standardModel()); if(!model) throw Exception() << "Must be using the SextetModel" << " in SextetGSSVertex::doinit()" << Exception::runerror; // extract the couplings g1L_ = model->g1L(); g1R_ = model->g1R(); g1pR_ = model->g1pR(); g1ppR_ = model->g1ppR(); g3L_ = model->g3L(); // add the enabled particles if(model->ScalarSingletY43Enabled()) { for(long ix=0;ix<3;++ix) { long iu = 2*ix + 2; if(g1ppR_[ix]!=0.) { addToList( iu, iu, ParticleID::ScalarDQSingletY43bar); addToList( -iu, -iu, ParticleID::ScalarDQSingletY43); } } } if(model->ScalarSingletY13Enabled()) { for(long ix=0;ix<3;++ix) { long iu = 2*ix + 2; long id = 2*ix + 1; if(g1L_[ix]!=0. || g1R_[ix]!=0.) { addToList( id, iu, ParticleID::ScalarDQSingletY13bar); addToList( -id, -iu, ParticleID::ScalarDQSingletY13); } } } if(model->ScalarSingletY23Enabled()) { for(long ix=0;ix<3;++ix) { long id = 2*ix + 1; if(g1pR_[ix]!=0. ) { addToList( id, id,ParticleID::ScalarDQSingletY23bar); addToList(-id,-id,ParticleID::ScalarDQSingletY23); } } } if(model->ScalarTripletY13Enabled()) { for(long ix=0;ix<3;++ix) { long iu = 2*ix + 2; long id = 2*ix + 1; if(g3L_[ix]!=0. ) { addToList( iu, iu, ParticleID::ScalarDQTripletPbar); addToList( -iu, -iu, ParticleID::ScalarDQTripletP); addToList( iu, id, ParticleID::ScalarDQTriplet0bar); addToList( -iu, -id, ParticleID::ScalarDQTriplet0); addToList( id, id, ParticleID::ScalarDQTripletMbar); addToList( -id, -id, ParticleID::ScalarDQTripletM); } } } Helicity::FFSVertex::doinit(); } void SextetFFSVertex::setCoupling(Energy2,tcPDPtr part1, tcPDPtr part2,tcPDPtr part3) { long q1ID=(abs(part1->id())), q2ID=(abs(part2->id())), sDQID=(abs(part3->id())); //check scalar diquark assert( sDQID == ParticleID::ScalarDQSingletY43 || sDQID == ParticleID::ScalarDQSingletY13 || sDQID == ParticleID::ScalarDQSingletY23 || sDQID == ParticleID::ScalarDQTripletP || sDQID == ParticleID::ScalarDQTriplet0 || sDQID == ParticleID::ScalarDQTripletM); //check quarks assert(!(q1ID>6) && !(q2ID>6)); bool part1Up = (q1ID==2 || q1ID==4 || q1ID==6); +#ifndef NDEBUG bool part2Up = (q2ID==2 || q2ID==4 || q2ID==6); +#endif Complex cRight, cLeft, prefactor(1.); if(sDQID==ParticleID::ScalarDQSingletY43){ //should both be up type assert(part1Up && part2Up); if(q1ID==2) cRight=Complex(g1ppR_[0]); else if(q1ID==4) cRight=Complex(g1ppR_[1]); else cRight=Complex(g1ppR_[2]); cLeft=Complex(0.); } if(sDQID==ParticleID::ScalarDQSingletY13){ //should be one up one down type assert((part1Up && !part2Up) || (!part1Up && part2Up)); long upType; if(part1Up) upType=q1ID; else upType=q2ID; if(upType==2){ cRight=Complex(g1R_[0]); cLeft=Complex(2.*g1L_[0]); } else if(upType==4){ cRight=Complex(g1R_[1]); cLeft=Complex(2.*g1L_[1]); } else cRight=Complex(g1R_[2]);{ cLeft=Complex(2.*g1L_[2]); } } if(sDQID==ParticleID::ScalarDQSingletY23){ //should both be down type assert(!part1Up && !part2Up); if(q1ID==1) cRight=Complex(g1pR_[0]); else if(q1ID==3) cRight=Complex(g1pR_[1]); else cRight=Complex(g1pR_[2]); cLeft=Complex(0.); } if(sDQID==ParticleID::ScalarDQTripletP){ //should both be up type assert(part1Up && part2Up); if(q1ID==2) cLeft=Complex(g3L_[0]); else if(q1ID==4) cLeft=Complex(g3L_[1]); else cLeft=Complex(g3L_[2]); cRight=Complex(0.); } if(sDQID==ParticleID::ScalarDQTriplet0){ //should both one up and down type assert((part1Up && !part2Up) || (!part1Up && part2Up)); //possibly doesn't couple long upType; if(part1Up) upType=q1ID; else upType=q2ID; if(upType==2) cLeft=Complex(g3L_[0]); else if(upType==4) cLeft=Complex(g3L_[1]); else cLeft=Complex(g3L_[2]); cRight=Complex(0.); } if(sDQID==ParticleID::ScalarDQTripletM){ //should one both be down type assert(!part1Up && !part2Up); if(q1ID==1) cLeft=Complex(g3L_[0]); else if(q1ID==3) cLeft=Complex(g3L_[1]); else cLeft=Complex(g3L_[2]); cRight=Complex(0.); prefactor=Complex(-1.); } left(cLeft); right(cRight); norm(prefactor); } diff --git a/Models/Sextet/SextetFFVVertex.cc b/Models/Sextet/SextetFFVVertex.cc --- a/Models/Sextet/SextetFFVVertex.cc +++ b/Models/Sextet/SextetFFVVertex.cc @@ -1,168 +1,170 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the SextetFFVVertex class. // #include "SextetFFVVertex.h" #include "SextetModel.h" #include "SextetParticles.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; IBPtr SextetFFVVertex::clone() const { return new_ptr(*this); } IBPtr SextetFFVVertex::fullclone() const { return new_ptr(*this); } void SextetFFVVertex::persistentOutput(PersistentOStream & os) const { os << g2_ << g2p_ ; } void SextetFFVVertex::persistentInput(PersistentIStream & is, int) { is >> g2_ >> g2p_ ; } // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeSextetFFVVertex("Herwig::SextetFFVVertex", "HwSextetModel.so"); void SextetFFVVertex::Init() { static ClassDocumentation documentation ("The SextetFFVVertex class implements the coupling of two " "fermions to a scalar sextet particle."); } void SextetFFVVertex::doinit() { orderInGs (0); orderInGem(1); SextetModelPtr model = dynamic_ptr_cast(generator()->standardModel()); if(!model) throw Exception() << "Must be using the SextetModel" << " in SextetGSSVertex::doinit()" << Exception::runerror; // extract the couplings g2_ = model->g2(); g2p_= model->g2p(); // add the enabled particles if(model->VectorDoubletY16Enabled()) { for(long ix=0;ix<3;++ix) { long iu = 2*ix + 2; long id = 2*ix + 1; if(g2_[ix]!=0.) { addToList( -id, -iu, ParticleID::VectorDQY16P); addToList( id, iu, ParticleID::VectorDQY16Pbar); addToList( -id, -id, ParticleID::VectorDQY16M); addToList( id, id, ParticleID::VectorDQY16Mbar); } } } if(model->VectorDoubletY56Enabled()) { for(long ix=0;ix<3;++ix) { long iu = 2*ix + 2; long id = 2*ix + 1; if(g2p_[ix]!=0.) { addToList( -iu, -iu, ParticleID::VectorDQY56P); addToList( iu, iu, ParticleID::VectorDQY56Pbar); addToList( -id, -iu, ParticleID::VectorDQY56M); addToList( id, iu, ParticleID::VectorDQY56Mbar); } } } Helicity::FFVVertex::doinit(); } void SextetFFVVertex::setCoupling(Energy2, tcPDPtr part1, tcPDPtr part2,tcPDPtr part3) { long q1ID=(abs(part1->id())), q2ID=(abs(part2->id())), vDQID=(abs(part3->id())); //check scalar diquark assert( vDQID == ParticleID::VectorDQY16P || vDQID == ParticleID::VectorDQY16M || vDQID == ParticleID::VectorDQY56P || vDQID == ParticleID::VectorDQY56M); //check quarks assert(!(q1ID>6) && !(q2ID>6)); bool part1Up = (q1ID==2 || q1ID==4 || q1ID==6) ? true : false; +#ifndef NDEBUG bool part2Up = (q2ID==2 || q2ID==4 || q2ID==6) ? true : false; +#endif Complex cRight(1.,1.), cLeft(1.,1.), prefactor(1.,0.); if(vDQID==ParticleID::VectorDQY16P){ //should be one up and down type assert((!part1Up && part2Up) || (part1Up && !part2Up)); long upType; if(part1Up) upType=q1ID; else upType=q2ID; if(upType==2) cRight=Complex(g2_[0]); else if(upType==4) cRight=Complex(g2_[1]); else cRight=Complex(g2_[2]); cLeft=Complex(0.); } if(vDQID==ParticleID::VectorDQY16M) { //should be both be down type assert(!part1Up && !part2Up); if(q1ID==1) cRight=Complex(g2_[0]); else if(q1ID==2) cRight=Complex(g2_[1]); else cRight=Complex(g2_[2]); cLeft=Complex(0.); } if(vDQID==ParticleID::VectorDQY56P) { //should both be up type assert(part1Up && part2Up); if(q1ID==2) cRight=Complex(g2p_[0]); else if(q1ID==4) cRight=Complex(g2p_[1]); else cRight=Complex(g2p_[2]); cLeft=Complex(0.); } if(vDQID==ParticleID::VectorDQY56M){ //should be one up and down type assert((!part1Up && part2Up) || (part1Up && !part2Up)); long upType; if(part1Up) upType=q1ID; else upType=q2ID; if(upType==2) cRight=Complex(g2p_[0]); else if(upType==4) cRight=Complex(g2p_[1]); else cRight=Complex(g2p_[2]); cLeft=Complex(0.); } left(cLeft); right(cRight); norm(prefactor); } diff --git a/Models/Sextet/SextetGSSVertex.cc b/Models/Sextet/SextetGSSVertex.cc --- a/Models/Sextet/SextetGSSVertex.cc +++ b/Models/Sextet/SextetGSSVertex.cc @@ -1,88 +1,95 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the SextetGSSVertex class. // #include "SextetGSSVertex.h" #include "SextetModel.h" #include "SextetParticles.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; IBPtr SextetGSSVertex::clone() const { return new_ptr(*this); } IBPtr SextetGSSVertex::fullclone() const { return new_ptr(*this); } // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeSextetGSSVertex("Herwig::SextetGSSVertex", "HwSextetModel.so"); void SextetGSSVertex::Init() { static ClassDocumentation documentation ("The SextetGSSVertex class implements the coupling of the gluon" " to scalar diquarks."); } void SextetGSSVertex::doinit() { orderInGs (1); orderInGem(0); SextetModelPtr model = dynamic_ptr_cast(generator()->standardModel()); if(!model) throw Exception() << "Must be using the SextetModel" << " in SextetGSSVertex::doinit()" << Exception::runerror; // add the enabled particles if(model->ScalarSingletY43Enabled()) addToList(21,ParticleID::ScalarDQSingletY43, ParticleID::ScalarDQSingletY43bar); if(model->ScalarSingletY13Enabled()) addToList(21,ParticleID::ScalarDQSingletY13, ParticleID::ScalarDQSingletY13bar); if(model->ScalarSingletY23Enabled()) addToList(21,ParticleID::ScalarDQSingletY23, ParticleID::ScalarDQSingletY23bar); if(model->ScalarTripletY13Enabled()) { addToList(21,ParticleID::ScalarDQTripletP, ParticleID::ScalarDQTripletPbar); addToList(21,ParticleID::ScalarDQTriplet0, ParticleID::ScalarDQTriplet0bar); addToList(21,ParticleID::ScalarDQTripletM, ParticleID::ScalarDQTripletMbar); } Helicity::VSSVertex::doinit(); } -void SextetGSSVertex::setCoupling(Energy2 q2, tcPDPtr part1, +void SextetGSSVertex::setCoupling(Energy2 q2, +#ifndef NDEBUG + tcPDPtr part1, +#else + tcPDPtr , +#endif tcPDPtr part2, tcPDPtr ) { assert(part1->id()==ParticleID::g); +#ifndef NDEBUG long idq = abs(part2->id()); +#endif assert(idq == ParticleID::ScalarDQSingletY43 || idq == ParticleID::ScalarDQSingletY13 || idq == ParticleID::ScalarDQSingletY23 || idq == ParticleID::ScalarDQTripletP || idq == ParticleID::ScalarDQTriplet0 || idq == ParticleID::ScalarDQTripletM); if(q2 != q2Last_ || coupLast_ == 0.) { coupLast_ = strongCoupling(q2); q2Last_ = q2; } if(part2->id()>0) norm(-coupLast_); else norm( coupLast_); } diff --git a/Models/Sextet/SextetPSSVertex.cc b/Models/Sextet/SextetPSSVertex.cc --- a/Models/Sextet/SextetPSSVertex.cc +++ b/Models/Sextet/SextetPSSVertex.cc @@ -1,88 +1,93 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the SextetPSSVertex class. // #include "SextetPSSVertex.h" #include "SextetModel.h" #include "SextetParticles.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; IBPtr SextetPSSVertex::clone() const { return new_ptr(*this); } IBPtr SextetPSSVertex::fullclone() const { return new_ptr(*this); } // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeSextetPSSVertex("Herwig::SextetPSSVertex", "HwSextetModel.so"); void SextetPSSVertex::Init() { static ClassDocumentation documentation ("The SextetPSSVertex class implements the coupling of the gluon" " to scalar diquarks."); } void SextetPSSVertex::doinit() { orderInGs (0); orderInGem(1); SextetModelPtr model = dynamic_ptr_cast(generator()->standardModel()); if(!model) throw Exception() << "Must be using the SextetModel" << " in SextetPSSVertex::doinit()" << Exception::runerror; // add the enabled particles if(model->ScalarSingletY43Enabled()) addToList(22,ParticleID::ScalarDQSingletY43, ParticleID::ScalarDQSingletY43bar); if(model->ScalarSingletY13Enabled()) addToList(22,ParticleID::ScalarDQSingletY13, ParticleID::ScalarDQSingletY13bar); if(model->ScalarSingletY23Enabled()) addToList(22,ParticleID::ScalarDQSingletY23, ParticleID::ScalarDQSingletY23bar); if(model->ScalarTripletY13Enabled()) { addToList(22,ParticleID::ScalarDQTripletP, ParticleID::ScalarDQTripletPbar); addToList(22,ParticleID::ScalarDQTriplet0, ParticleID::ScalarDQTriplet0bar); addToList(22,ParticleID::ScalarDQTripletM, ParticleID::ScalarDQTripletMbar); } Helicity::VSSVertex::doinit(); } -void SextetPSSVertex::setCoupling(Energy2 q2, tcPDPtr part1, +void SextetPSSVertex::setCoupling(Energy2 q2, +#ifndef NDEBUG + tcPDPtr part1, +#else + tcPDPtr , +#endif tcPDPtr part2, tcPDPtr ) { assert(part1->id()==ParticleID::gamma); tcPDPtr sca = part2->id()>0 ? part2 : tcPDPtr(part2->CC()); assert(sca->id() == ParticleID::ScalarDQSingletY43 || sca->id() == ParticleID::ScalarDQSingletY13 || sca->id() == ParticleID::ScalarDQSingletY23 || sca->id() == ParticleID::ScalarDQTripletP || sca->id() == ParticleID::ScalarDQTriplet0 || sca->id() == ParticleID::ScalarDQTripletM); if(q2 != q2Last_ || coupLast_ == 0.) { coupLast_ = electroMagneticCoupling(q2); q2Last_ = q2; } if(part2->id()>0) norm(-sca->iCharge()/3.*coupLast_); else norm( sca->iCharge()/3.*coupLast_); } diff --git a/Models/StandardModel/GenericSVVVertex.cc b/Models/StandardModel/GenericSVVVertex.cc --- a/Models/StandardModel/GenericSVVVertex.cc +++ b/Models/StandardModel/GenericSVVVertex.cc @@ -1,100 +1,115 @@ // -*- C++ -*- // // GenericSVVVertex.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 GenericSVVVertex class. // #include "GenericSVVVertex.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Command.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; using namespace ThePEG; GenericSVVVertex::GenericSVVVertex() :pids(ZERO),oas(0),oaew(0) {} void GenericSVVVertex::doinit() { //PDG codes for particles at vertices addToList(pids[0],pids[1],pids[2]); orderInGs(oas); orderInGem(oaew); GeneralVVSVertex::doinit(); } string GenericSVVVertex::dopids(string in) { vector process = StringUtils::split(in); if ( process.size() != 3 ) throw InitException() << "accepts only three particles."; for ( vector::iterator p = process.begin(); p != process.end(); ++p ) { int tmp; istringstream(*p) >> tmp; pids.push_back(tmp); } return ""; } void GenericSVVVertex::persistentOutput(PersistentOStream & os) const { os << pids<> pids>>oas>>oaew; } // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeHerwigGenericSVVVertex("Herwig::GenericSVVVertex", "Herwig.so"); void GenericSVVVertex::Init() { static ClassDocumentation documentation ("This class implements the s->v,v vertex"); static Command interfacepids ("pids", "Set the pids.", &GenericSVVVertex::dopids, false); static Parameter interfaceOrderoas ("OrderInAlphaS", "The order in alpha_S", &GenericSVVVertex::oas, 2, 0, 0, false, false, Interface::lowerlim); static Parameter interfaceOrderoaew ("OrderInAlphaEW", "The order in alpha_EW", &GenericSVVVertex::oaew, 2, 0, 0, false, false, Interface::lowerlim); } -void GenericSVVVertex::setCoupling(Energy2, tcPDPtr part2, tcPDPtr part3, tcPDPtr part1) { +void GenericSVVVertex::setCoupling(Energy2, +#ifndef NDEBUG + tcPDPtr part2, +#else + tcPDPtr, +#endif +#ifndef NDEBUG + tcPDPtr part3, +#else + tcPDPtr, +#endif +#ifndef NDEBUG + tcPDPtr part1) { +#else + tcPDPtr) { +#endif assert(part1 && part2 && part3); assert(part1->id() == pids[0] && part2->id() == pids[1] && part3->id() == pids[2] ); } diff --git a/Models/StandardModel/GenericVVVVertex.cc b/Models/StandardModel/GenericVVVVertex.cc --- a/Models/StandardModel/GenericVVVVertex.cc +++ b/Models/StandardModel/GenericVVVVertex.cc @@ -1,100 +1,115 @@ // -*- C++ -*- // // GenericVVVVertex.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 GenericVVVVertex class. // #include "GenericVVVVertex.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Command.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; using namespace ThePEG; GenericVVVVertex::GenericVVVVertex() :pids(ZERO),oas(0),oaew(0) {} void GenericVVVVertex::doinit() { //PDG codes for particles at vertices addToList(pids[0],pids[1],pids[2]); orderInGs(oas); orderInGem(oaew); VVVVertex::doinit(); } string GenericVVVVertex::dopids(string in) { vector process = StringUtils::split(in); if ( process.size() != 3 ) throw InitException() << "accepts only three particles."; for ( vector::iterator p = process.begin(); p != process.end(); ++p ) { int tmp; istringstream(*p) >> tmp; pids.push_back(tmp); } return ""; } void GenericVVVVertex::persistentOutput(PersistentOStream & os) const { os << pids<> pids>>oas>>oaew; } // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeHerwigGenericVVVVertex("Herwig::GenericVVVVertex", "Herwig.so"); void GenericVVVVertex::Init() { static ClassDocumentation documentation ("This class implements the v->v,v vertex"); static Command interfacepids ("pids", "Set the pids.", &GenericVVVVertex::dopids, false); static Parameter interfaceOrderoas ("OrderInAlphaS", "The order in alpha_S", &GenericVVVVertex::oas, 2, 0, 0, false, false, Interface::lowerlim); static Parameter interfaceOrderoaew ("OrderInAlphaEW", "The order in alpha_EW", &GenericVVVVertex::oaew, 2, 0, 0, false, false, Interface::lowerlim); } -void GenericVVVVertex::setCoupling(Energy2, tcPDPtr part2, tcPDPtr part3, tcPDPtr part1) { +void GenericVVVVertex::setCoupling(Energy2, +#ifndef NDEBUG + tcPDPtr part2, +#else + tcPDPtr, +#endif +#ifndef NDEBUG + tcPDPtr part3, +#else + tcPDPtr, +#endif +#ifndef NDEBUG + tcPDPtr part1) { +#else + tcPDPtr) { +#endif assert(part1 && part2 && part3); assert(part1->id() == pids[0] && part2->id() == pids[1] && part3->id() == pids[2] ); } diff --git a/Models/StandardModel/SMHZPVertex.cc b/Models/StandardModel/SMHZPVertex.cc --- a/Models/StandardModel/SMHZPVertex.cc +++ b/Models/StandardModel/SMHZPVertex.cc @@ -1,188 +1,197 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the SMHZPVertex class. // #include "SMHZPVertex.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; SMHZPVertex::SMHZPVertex() :_couplast(0.),_q2last(),_mw(),_mz(),_massopt(1), _minloop(6),_maxloop(6) { orderInGs(0); orderInGem(3); kinematics(true); colourStructure(ColourStructure::SINGLET); } IBPtr SMHZPVertex::clone() const { return new_ptr(*this); } IBPtr SMHZPVertex::fullclone() const { return new_ptr(*this); } void SMHZPVertex::doinit() { GeneralVVSVertex::doinit(); //PDG codes for particles at vertices addToList(23,22,25); _theSM = dynamic_ptr_cast(generator()->standardModel()); if( !_theSM ) throw InitException() << "SMHGGVertex::doinit() - The pointer to the SM object is null." << Exception::abortnow; _mw = getParticleData(ThePEG::ParticleID::Wplus)->mass(); _mz = getParticleData(ThePEG::ParticleID::Z0)->mass(); GeneralVVSVertex::doinit(); } void SMHZPVertex::persistentOutput(PersistentOStream & os) const { os << _theSM << ounit(_mw,GeV) << ounit(_mz,GeV) << _massopt << _minloop << _maxloop; } void SMHZPVertex::persistentInput(PersistentIStream & is, int) { is >> _theSM >> iunit(_mw, GeV) >> iunit(_mz,GeV) >> _massopt >> _minloop >> _maxloop; } // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeHerwigSMHZPVertex("Herwig::SMHZPVertex", "libHerwig.so"); void SMHZPVertex::Init() { static ClassDocumentation documentation ("The SMHZPVertex class provides a simple implementation of the " "Higgs-Z-Photon loop looping to allow the calculation of the " "associated Higgs decay mode H -> Z gamma."); static Parameter interfaceMinQuarkInLoop ("MinQuarkInLoop", "The minimum flavour of the quarks to include in the loops", &SMHZPVertex::_minloop, 6, 1, 6, false, false, Interface::limited); static Parameter interfaceMaxQuarkInLoop ("MaxQuarkInLoop", "The maximum flavour of the quarks to include in the loops", &SMHZPVertex::_maxloop, 6, 1, 6, false, false, Interface::limited); static Switch interfaceMassOption ("LoopMassScheme", "Switch for the treatment of the masses in the loops ", &SMHZPVertex::_massopt, 2, false, false); static SwitchOption interfaceHeavyMass (interfaceMassOption, "PoleMasses", "The loop is calculcated with the pole quark masses", 1); static SwitchOption interfaceNormalMass (interfaceMassOption, "RunningMasses", "running quark masses are taken in the loop", 2); } void SMHZPVertex::setCoupling(Energy2 q2, tcPDPtr part2, - tcPDPtr part3, tcPDPtr part1) { + tcPDPtr part3, +#ifndef NDEBUG + tcPDPtr part1) { +#else + tcPDPtr) { +#endif if(part3->id()==ParticleID::Z0) swap(part2,part3); assert( part1->id() == ParticleID::h0 && part2->id() == ParticleID::Z0 && part3->id() == ParticleID::gamma ); int Qminloop = _minloop; int Qmaxloop = _maxloop; if (_maxloop < _minloop) swap(Qmaxloop,Qminloop); double cw = sqrt(1.-sin2ThetaW()),sw=sqrt(sin2ThetaW()),tw = sw/cw; if(q2 != _q2last||_couplast==0.) { double g = weakCoupling(q2); double e2 = sqr(electroMagneticCoupling(q2)); _couplast = UnitRemoval::E * e2 * g / 16. / _mw/ sqr(Constants::pi); _q2last = q2; } norm(_couplast); Complex loop(0.); // quark loops for ( int i = Qminloop; i <= Qmaxloop; ++i ) { tcPDPtr qrk = getParticleData(i); Energy mass = (2 == _massopt) ? _theSM->mass(q2,qrk) : qrk->mass(); double charge = i%2==0 ? generator()->standardModel()->eu() : generator()->standardModel()->ed(); double gv = i%2==0 ? generator()->standardModel()->vu() : generator()->standardModel()->vd(); double tau = 0.25*invariant(0,0)/sqr(mass), lambda(0.25*sqr(_mz/mass)); loop += 3.*charge*gv *(I1(tau,lambda)-I2(tau,lambda))/(sw*cw); } // lepton loops int Lminloop = 3; // still fixed value int Lmaxloop = 3; // still fixed value for (int i = Lminloop; i <= Lmaxloop; ++i) { tcPDPtr lpt = getParticleData(9 + 2*i); Energy mass = (2 == _massopt) ? _theSM->mass(q2,lpt) : lpt->mass(); double charge = generator()->standardModel()->ee(); double gv = generator()->standardModel()->ve(); double tau = 0.25*invariant(0,0)/sqr(mass), lambda(0.25*sqr(_mz/mass)); loop += charge*gv*(I1(tau,lambda)-I2(tau,lambda))/(sw*cw); } // W loop double tau = 0.25*invariant(0,0)/sqr(_mw), lambda(0.25*sqr(_mz/_mw)); loop += ( 4.*(3.-sqr(tw))*I2(tau,lambda) + ((1.+2.*tau)*sqr(tw)-(5.+2.*tau))*I1(tau,lambda))/tw; a00(loop); a11(0.0); a12(0.0); a21(-loop); a22(0.0); aEp(0.0); // test of the width calculation // Energy mh = getParticleData(25)->mass(); // Energy pre = sqr(weakCoupling(q2))*pow(electroMagneticCoupling(q2),4)*mh*sqr(mh/_mw) // /128./16./pow(Constants::pi,5)*pow(double(1.-sqr(_mz/mh)),3)* // std::real(std::norm(loop)); } Complex SMHZPVertex::I1(double tau,double lambda) const { return (-0.5+0.5/(tau-lambda)*(f(tau)-f(lambda))+ lambda/(tau-lambda)*(g(tau)-g(lambda)))/(tau-lambda); } Complex SMHZPVertex::I2(double tau,double lambda) const { return 0.5/(tau-lambda)*(f(tau)-f(lambda)); } Complex SMHZPVertex::f(double tau) const { if(tau>0 && tau<= 1.) { return sqr(asin(sqrt(tau))); } else if(tau>1.) { double lx = log(sqrt(tau)+sqrt(tau-1)); return -sqr(lx)+0.25*sqr(Constants::pi)+Complex(0.,1.)*Constants::pi*lx; } - else + else { assert(false); + return 0.; + } } Complex SMHZPVertex::g(double tau) const { if(tau>0 && tau<= 1.) { return sqrt((1.-tau)/tau)*asin(sqrt(tau)); } else if(tau>1.) { double lx = log(sqrt(tau)+sqrt(tau-1)); double root = sqrt((tau-1.)/tau); return root*(lx-0.5*Complex(0,1)*Constants::pi); } - else + else { assert(false); + return 0.; + } } diff --git a/Models/Susy/RPV/RPVFFWVertex.cc b/Models/Susy/RPV/RPVFFWVertex.cc --- a/Models/Susy/RPV/RPVFFWVertex.cc +++ b/Models/Susy/RPV/RPVFFWVertex.cc @@ -1,268 +1,273 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the RPVFFWVertex class. // #include "RPVFFWVertex.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/Models/StandardModel/StandardCKM.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "RPVhelper.h" using namespace Herwig; RPVFFWVertex::RPVFFWVertex() : _diagonal(false), _ckm(3,vector(3,0.0)), _sw(0.), _couplast(0.), _q2last(ZERO), _id1last(0), _id2last(0), _leftlast(0.), _rightlast(0.), _interactions(0) { orderInGs(0); orderInGem(1); colourStructure(ColourStructure::DELTA); } IBPtr RPVFFWVertex::clone() const { return new_ptr(*this); } IBPtr RPVFFWVertex::fullclone() const { return new_ptr(*this); } void RPVFFWVertex::doinit() { // SUSY mixing matrices tSusyBasePtr model = dynamic_ptr_cast(generator()->standardModel()); if(!model) throw InitException() << "RPVFFWVertex::doinit() - The model pointer is null!" << Exception::abortnow; _theN = model->neutralinoMix(); _theU = model->charginoUMix(); _theV = model->charginoVMix(); if(!_theN || !_theU || ! _theV) throw InitException() << "RPVFFWVertex::doinit() - " << "A mixing matrix pointer is null." << " N: " << _theN << " U: " << _theU << " V: " << _theV << Exception::abortnow; // SM interactions if(_interactions==0 || _interactions==1) { // particles for outgoing W- // quarks for(int ix=1;ix<6;ix+=2) { for(int iy=2;iy<7;iy+=2) { bool isOff = iy/2 != (ix+1)/2; if ( isOff && _diagonal ) continue; addToList(-ix, iy, -24); } } // leptons for(int ix=11;ix<17;ix+=2) { int inu = model->majoranaNeutrinos() ? (ix+23)/2 : ix+1; addToList(-ix, inu, -24); } // particles for outgoing W+ // quarks for(int ix=2;ix<7;ix+=2) { for(int iy=1;iy<6;iy+=2) { bool isOff = ix/2 != (iy+1)/2; if ( isOff && _diagonal ) continue; addToList(-ix, iy, 24); } } // leptons for(int ix=11;ix<17;ix+=2) { int inu = model->majoranaNeutrinos() ? (ix+23)/2 : -ix-1; addToList(inu, ix, 24); } } // neutralino and chargino if(_interactions==0 || _interactions==2) { vector neu(4); neu[0] = 1000022; neu[1] = 1000023; neu[2] = 1000025; neu[3] = 1000035; if(_theN->size().first==7) { if(model->majoranaNeutrinos()) { neu.push_back(17); neu.push_back(18); neu.push_back(19); } else { neu.push_back(12); neu.push_back(14); neu.push_back(16); } } vector cha(2); cha[0] = 1000024; cha[1] = 1000037; if(_theV->size().first==5) { cha.push_back(-11); cha.push_back(-13); cha.push_back(-15); } // sign == -1 outgoing W-, sign == +1 outgoing W+ for(int sign = -1; sign < 2; sign += 2) { for(unsigned int ine = 0; ine < neu.size(); ++ine) { for(unsigned int ic = 0; ic < cha.size(); ++ic ) { if(ic>1&&ine>3&&ic==ine-2) continue; addToList(-sign*cha[ic], neu[ine], sign*24); } } } } Helicity::FFVVertex::doinit(); // CKM matric if ( !_diagonal ) { Ptr::transient_pointer CKM = model->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 RPVFFWVertex::doinit()" << Exception::runerror; } } _sw = sqrt(sin2ThetaW()); } void RPVFFWVertex::persistentOutput(PersistentOStream & os) const { os << _sw << _theN << _theU << _theV << _diagonal << _ckm << _interactions; } void RPVFFWVertex::persistentInput(PersistentIStream & is, int) { is >> _sw >> _theN >> _theU >> _theV >> _diagonal >> _ckm >> _interactions; } // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeHerwigRPVFFWVertex("Herwig::RPVFFWVertex", "HwSusy.so HwRPV.so"); void RPVFFWVertex::Init() { static ClassDocumentation documentation ("The couplings of the fermions to the W boson in the RPV model" " with bilinear R-parity violation"); static Switch interfaceInteractions ("Interactions", "Which interactions to include", &RPVFFWVertex::_interactions, 0, false, false); static SwitchOption interfaceInteractionsAll (interfaceInteractions, "All", "Include all the interactions", 0); static SwitchOption interfaceInteractionsSM (interfaceInteractions, "SM", "Only include the MS terms", 1); static SwitchOption interfaceInteractionsSUSY (interfaceInteractions, "SUSY", "Include the neutralino/chargino terms", 2); static Switch interfaceDiagonal ("Diagonal", "Use a diagonal CKM matrix (ignoring the CKM object of the StandardModel).", &RPVFFWVertex::_diagonal, false, false, false); static SwitchOption interfaceDiagonalYes (interfaceDiagonal, "Yes", "Use a diagonal CKM matrix.", true); static SwitchOption interfaceDiagonalNo (interfaceDiagonal, "No", "Use the CKM object as used by the StandardModel.", false); } void RPVFFWVertex::setCoupling(Energy2 q2,tcPDPtr part1, - tcPDPtr part2,tcPDPtr part3) { + tcPDPtr part2, +#ifndef NDEBUG + tcPDPtr part3) { +#else + tcPDPtr) { +#endif assert(abs(part3->id()) == ParticleID::Wplus); // normalization // first the overall normalisation if(q2 != _q2last||_couplast==0.) { _couplast = weakCoupling(q2); _q2last=q2; } norm(_couplast); // left and right couplings for quarks if(abs(part1->id()) <= 6) { int iferm=abs(part1->id()); int ianti=abs(part2->id()); if(iferm%2!=0) swap(iferm,ianti); iferm = iferm/2; ianti = (ianti+1)/2; assert( iferm>=1 && iferm<=3 && ianti>=1 && ianti<=3); left(-sqrt(0.5)*_ckm[iferm-1][ianti-1]); right(0.); } else { long neu, cha; if(part1->charged()) { cha = part1->id(); neu = part2->id(); } else { cha = part2->id(); neu = part1->id(); } if(_theV->size().first==2&&abs(neu)<=16) { left(-sqrt(0.5)); right(0.); } else { if(cha != _id1last || neu != _id2last) { _id1last = cha; _id2last = neu; unsigned int eigc = RPV_helper::charginoIndex(cha); unsigned int eign = RPV_helper::neutralinoIndex(neu); _leftlast = (*_theN)(eign, 1)*conj((*_theV)(eigc, 0)) - ( (*_theN)(eign, 3)*conj((*_theV)(eigc, 1))/sqrt(2)); _rightlast = conj((*_theN)(eign, 1))*(*_theU)(eigc, 0) + ( conj((*_theN)(eign, 2))*(*_theU)(eigc, 1)/sqrt(2)); if(_theV->size().first==5) { for(unsigned int k=0;k<3;++k) _rightlast += ( conj((*_theN)(eign, 4+k))*(*_theU)(eigc, 2+k)/sqrt(2)); } } Complex ltemp = _leftlast; Complex rtemp = _rightlast; bool chapart = abs(cha)>1000000 ? cha>0 : cha<0; // conjugate if +ve chargino if(chapart) { ltemp = conj(ltemp); rtemp = conj(rtemp); } if((part1->id()==cha&&chapart)||(part2->id()==cha&&!chapart)) { Complex temp = ltemp; ltemp = -rtemp; rtemp = -temp; } left (ltemp); right(rtemp); } } } diff --git a/Models/Susy/SSFFHVertex.h b/Models/Susy/SSFFHVertex.h --- a/Models/Susy/SSFFHVertex.h +++ b/Models/Susy/SSFFHVertex.h @@ -1,171 +1,166 @@ // -*- C++ -*- // // SSFFHVertex.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2017 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_SSFFHVertex_H #define HERWIG_SSFFHVertex_H // // This is the declaration of the SSFFHVertex class. // #include "ThePEG/Helicity/Vertex/Scalar/FFSVertex.h" #include "MSSM.h" namespace Herwig { /** * The is the coupling of higgs bosons in the MSSM to a pair * of SM fermions. * * @see \ref SSFFHVertexInterfaces "The interfaces" * defined for SSFFHVertex. */ class SSFFHVertex: public FFSVertex { public: /** * The default constructor. */ SSFFHVertex(); /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); /** * Calculate the coupling for the vertex * @param q2 The scale to at which evaluate the coupling. * @param particle1 The first particle in the vertex. * @param particle2 The second particle in the vertex. * @param particle3 The third particle in the vertex. */ virtual void setCoupling(Energy2 q2, tcPDPtr particle1, tcPDPtr particle2, tcPDPtr particle3); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const {return new_ptr(*this);} /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const {return new_ptr(*this);} //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); //@} private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ SSFFHVertex & operator=(const SSFFHVertex &) = delete; private: /** * Pointer to the SM object. */ tcMSSMPtr theMSSM; /** * The value of \f$\tan\beta\f$. */ double thetanb; /** * The mass of the \f$W\f$. */ Energy theMw; /** - * The value of \f$\sin\theta_W\f$ - */ - double theSw; - - /** * The value of \f$\sin\alpha\f$ */ double theSa; /** * The value of \f$\sin\beta\f$ */ double theSb; /** * The value of \f$\cos\alpha\f$ */ double theCa; /** * The value of \f$\cos\beta\f$ */ double theCb; /** * The ID of the last fermion for which the vertex was evaluated */ pair theFLast; /** * The value of \f$ \frac{e}{\sin\theta_W} \f$ when it was last evaluated. */ double theGlast; /** * The scale at which then coupling was last evaluated. */ Energy2 theq2last; /** * Values of the masses */ pair theMassLast; }; } #endif /* HERWIG_SSFFHVertex_H */ diff --git a/Models/Susy/SSGSGSGVertex.cc b/Models/Susy/SSGSGSGVertex.cc --- a/Models/Susy/SSGSGSGVertex.cc +++ b/Models/Susy/SSGSGSGVertex.cc @@ -1,59 +1,73 @@ // -*- C++ -*- // // SSGSGSGVertex.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 SSGSGSGVertex class. // #include "SSGSGSGVertex.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/PDT/EnumParticles.h" using namespace ThePEG::Helicity; using namespace Herwig; SSGSGSGVertex::SSGSGSGVertex() : _couplast(0.),_q2last(ZERO) { orderInGs(1); orderInGem(0); colourStructure(ColourStructure::SU3F); } // Static variable needed for the type description system in ThePEG. DescribeNoPIOClass describeHerwigSSGSGSGVertex("Herwig::SSGSGSGVertex", "HwSusy.so"); void SSGSGSGVertex::Init() { static ClassDocumentation documentation ("This class implements the gluon-gluino-gluino vertex"); } -void SSGSGSGVertex::setCoupling(Energy2 q2,tcPDPtr part1, - tcPDPtr part2,tcPDPtr part3) { +void SSGSGSGVertex::setCoupling(Energy2 q2, +#ifndef NDEBUG + tcPDPtr part1, +#else + tcPDPtr , +#endif +#ifndef NDEBUG + tcPDPtr part2, +#else + tcPDPtr , +#endif +#ifndef NDEBUG + tcPDPtr part3) { +#else + tcPDPtr ) { +#endif assert(part1->id()==ParticleID::SUSY_g && part2->id()==ParticleID::SUSY_g && part3->id() == ParticleID::g); if(q2 != _q2last || _couplast==0.) { _couplast = strongCoupling(q2); _q2last = q2; } norm(_couplast); left(1.); right(1.); } void SSGSGSGVertex::doinit() { addToList(1000021, 1000021, 21); FFVVertex::doinit(); } diff --git a/Models/Susy/SSGSSVertex.cc b/Models/Susy/SSGSSVertex.cc --- a/Models/Susy/SSGSSVertex.cc +++ b/Models/Susy/SSGSSVertex.cc @@ -1,68 +1,80 @@ // -*- C++ -*- // // SSGSSVertex.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 SSGSSVertex class. // #include "SSGSSVertex.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/PDT/EnumParticles.h" using namespace ThePEG::Helicity; using namespace Herwig; SSGSSVertex::SSGSSVertex() : _couplast(0.),_q2last(ZERO) { orderInGs(1); orderInGem(0); colourStructure(ColourStructure::SU3TFUND); } void SSGSSVertex::doinit() { for(long ix=1000001;ix<1000007;++ix) { addToList(21,ix,-ix); } for(long ix=2000001;ix<2000007;++ix) { addToList(21,ix,-ix); } VSSVertex::doinit(); } // The following static variable is needed for the type // description system in ThePEG. DescribeNoPIOClass describeSSGSSVertex("Herwig::SSGSSVertex", "HwSusy.so"); void SSGSSVertex::Init() { static ClassDocumentation documentation ("The SSGSSVertex class implements the coupling" " of the gluon to the squarks"); } -void SSGSSVertex::setCoupling(Energy2 q2, tcPDPtr part1, - tcPDPtr part2, tcPDPtr part3) { +void SSGSSVertex::setCoupling(Energy2 q2, +#ifndef NDEBUG + tcPDPtr part1, +#else + tcPDPtr, +#endif + tcPDPtr part2, +#ifndef NDEBUG + tcPDPtr part3) { +#else + tcPDPtr ) { +#endif assert(part1->id()==ParticleID::g); +#ifndef NDEBUG long isf = abs(part2->id()); +#endif assert( (isf >= 1000001 && isf <= 1000006) || (isf >= 2000001 && isf <= 2000006) ); assert(part2->id()==-part3->id()); if(q2 != _q2last || _couplast == 0.) { _couplast = strongCoupling(q2); _q2last = q2; } if(part2->id()>0) norm(-_couplast); else norm( _couplast); } diff --git a/PDF/HwRemDecayer.cc b/PDF/HwRemDecayer.cc --- a/PDF/HwRemDecayer.cc +++ b/PDF/HwRemDecayer.cc @@ -1,1973 +1,1987 @@ // -*- C++ -*- // // HwRemDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2017 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the HwRemDecayer class. // #include "HwRemDecayer.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Utilities/UtilityBase.h" #include "ThePEG/Utilities/SimplePhaseSpace.h" #include "ThePEG/Utilities/Throw.h" #include "Herwig/Shower/ShowerHandler.h" using namespace Herwig; namespace{ const bool dbg = false; void reShuffle(Lorentz5Momentum &p1, Lorentz5Momentum &p2, Energy m1, Energy m2){ Lorentz5Momentum ptotal(p1+p2); ptotal.rescaleMass(); if( ptotal.m() < m1+m2 ) { if(dbg) cerr << "Not enough energy to perform reshuffling \n"; throw HwRemDecayer::ExtraSoftScatterVeto(); } Boost boostv = -ptotal.boostVector(); ptotal.boost(boostv); p1.boost(boostv); // set the masses and energies, p1.setMass(m1); p1.setE(0.5/ptotal.m()*(ptotal.m2()+sqr(m1)-sqr(m2))); p1.rescaleRho(); // boost back to the lab p1.boost(-boostv); p2.boost(boostv); // set the masses and energies, p2.setMass(m2); p2.setE(0.5/ptotal.m()*(ptotal.m2()+sqr(m2)-sqr(m1))); p2.rescaleRho(); // boost back to the lab p2.boost(-boostv); } } void HwRemDecayer::initialize(pair rems, tPPair beam, Step & step, Energy forcedSplitScale) { // the step thestep = &step; // valence content of the hadrons theContent.first = getHadronContent(beam.first); theContent.second = getHadronContent(beam.second); // momentum extracted from the hadrons theUsed.first = Lorentz5Momentum(); theUsed.second = Lorentz5Momentum(); theMaps.first.clear(); theMaps.second.clear(); theX.first = 0.0; theX.second = 0.0; theRems = rems; _forcedSplitScale = forcedSplitScale; // check remnants attached to the right hadrons if( (theRems.first && parent(theRems.first ) != beam.first ) || (theRems.second && parent(theRems.second) != beam.second) ) throw Exception() << "Remnant order wrong in " << "HwRemDecayer::initialize(...)" << Exception::runerror; return; } void HwRemDecayer::split(tPPtr parton, HadronContent & content, tRemPPtr rem, Lorentz5Momentum & used, PartnerMap &partners, tcPDFPtr pdf, bool first) { theBeam = parent(rem); theBeamData = dynamic_ptr_cast::const_pointer> (theBeam->dataPtr()); double currentx = parton->momentum().rho()/theBeam->momentum().rho(); double check = rem==theRems.first ? theX.first : theX.second; check += currentx; if(1.0-check < 1e-3) throw ShowerHandler::ExtraScatterVeto(); bool anti; Lorentz5Momentum lastp(parton->momentum()); int lastID(parton->id()); Energy oldQ(_forcedSplitScale); _pdf = pdf; //do nothing if already valence quark if(first && content.isValenceQuark(parton)) { //set the extracted value, because otherwise no RemID could be generated. content.extract(lastID); // add the particle to the colour partners partners.push_back(make_pair(parton, tPPtr())); //set the sign anti = parton->hasAntiColour() && parton->id()!=ParticleID::g; if(rem==theRems.first) theanti.first = anti; else theanti.second = anti; // add the x and return if(rem==theRems.first) theX.first += currentx; else theX.second += currentx; return; } //or gluon for secondaries else if(!first && lastID == ParticleID::g) { partners.push_back(make_pair(parton, tPPtr())); // add the x and return if(rem==theRems.first) theX.first += currentx; else theX.second += currentx; return; } // if a sea quark.antiquark forced splitting to a gluon // Create the new parton with its momentum and parent/child relationship set PPtr newSea; if( !(lastID == ParticleID::g || lastID == ParticleID::gamma) ) { newSea = forceSplit(rem, -lastID, oldQ, currentx, lastp, used,content); ColinePtr cl = new_ptr(ColourLine()); if(newSea->id() > 0) cl-> addColoured(newSea); else cl->addAntiColoured(newSea); // if a secondard scatter finished so return if(!first || content.isValenceQuark(ParticleID::g) ){ partners.push_back(make_pair(parton, newSea)); // add the x and return if(rem==theRems.first) theX.first += currentx; else theX.second += currentx; if(first) content.extract(ParticleID::g); return; } } // otherwise evolve back to valence // final valence splitting PPtr newValence = forceSplit(rem, lastID!=ParticleID::gamma ? ParticleID::g : ParticleID::gamma, oldQ, currentx , lastp, used, content); // extract from the hadron to allow remnant to be determined content.extract(newValence->id()); // case of a gluon going into the hard subprocess if( lastID == ParticleID::g ) { partners.push_back(make_pair(parton, tPPtr())); anti = newValence->hasAntiColour(); if(rem==theRems.first) theanti.first = anti; else theanti.second = anti; parton->colourLine(!anti)->addColoured(newValence, anti); return; } else if( lastID == ParticleID::gamma) { partners.push_back(make_pair(parton, newValence)); anti = newValence->hasAntiColour(); ColinePtr newLine(new_ptr(ColourLine())); newLine->addColoured(newValence, anti); if(rem==theRems.first) theanti.first = anti; else theanti.second = anti; // add the x and return if(rem==theRems.first) theX.first += currentx; else theX.second += currentx; return; } //The valence quark will always be connected to the sea quark with opposite sign tcPPtr particle; if(lastID*newValence->id() < 0){ particle = parton; partners.push_back(make_pair(newSea, tPPtr())); } else { particle = newSea; partners.push_back(make_pair(parton, tPPtr())); } anti = newValence->hasAntiColour(); if(rem==theRems.first) theanti.first = anti; else theanti.second = anti; if(particle->colourLine()) particle->colourLine()->addAntiColoured(newValence); if(particle->antiColourLine()) particle->antiColourLine()->addColoured(newValence); // add the x and return if(rem==theRems.first) theX.first += currentx; else theX.second += currentx; return; } void HwRemDecayer::doSplit(pair partons, pair pdfs, bool first) { if(theRems.first) { ParticleVector children=theRems.first->children(); for(unsigned int ix=0;ixdataPtr()==theRems.first->dataPtr()) theRems.first = dynamic_ptr_cast(children[ix]); } } if(theRems.second) { ParticleVector children=theRems.second->children(); for(unsigned int ix=0;ixdataPtr()==theRems.second->dataPtr()) theRems.second = dynamic_ptr_cast(children[ix]); } } // forced splitting for first parton if(isPartonic(partons.first )) { try { split(partons.first, theContent.first, theRems.first, theUsed.first, theMaps.first, pdfs.first, first); } catch(ShowerHandler::ExtraScatterVeto) { throw ShowerHandler::ExtraScatterVeto(); } } // forced splitting for second parton if(isPartonic(partons.second)) { try { split(partons.second, theContent.second, theRems.second, theUsed.second, theMaps.second, pdfs.second, first); // additional check for the remnants // if can't do the rescale veto the emission if(!first&&partons.first->data().coloured()&& partons.second->data().coloured()) { Lorentz5Momentum pnew[2]= {theRems.first->momentum() - theUsed.first - partons.first->momentum(), theRems.second->momentum() - theUsed.second - partons.second->momentum()}; pnew[0].setMass(getParticleData(theContent.first.RemID())->constituentMass()); pnew[0].rescaleEnergy(); pnew[1].setMass(getParticleData(theContent.second.RemID())->constituentMass()); pnew[1].rescaleEnergy(); for(unsigned int iy=0; iychildren().size(); ++iy) pnew[0] += theRems.first->children()[iy]->momentum(); for(unsigned int iy=0; iychildren().size(); ++iy) pnew[1] += theRems.second->children()[iy]->momentum(); Lorentz5Momentum ptotal= theRems.first ->momentum()-partons.first ->momentum()+ theRems.second->momentum()-partons.second->momentum(); // add x limits if(ptotal.m() < (pnew[0].m() + pnew[1].m()) ) { if(partons.second->id() != ParticleID::g){ if(partons.second==theMaps.second.back().first) theUsed.second -= theMaps.second.back().second->momentum(); else theUsed.second -= theMaps.second.back().first->momentum(); thestep->removeParticle(theMaps.second.back().first); thestep->removeParticle(theMaps.second.back().second); } theMaps.second.pop_back(); theX.second -= partons.second->momentum().rho()/ parent(theRems.second)->momentum().rho(); throw ShowerHandler::ExtraScatterVeto(); } } } catch(ShowerHandler::ExtraScatterVeto){ if(!partons.first||!partons.second|| !theRems.first||!theRems.second) throw ShowerHandler::ExtraScatterVeto(); //case of the first forcedSplitting worked fine theX.first -= partons.first->momentum().rho()/ parent(theRems.first)->momentum().rho(); //case of the first interaction //throw veto immediately, because event get rejected anyway. if(first) throw ShowerHandler::ExtraScatterVeto(); //secondary interactions have to end on a gluon, if parton //was NOT a gluon, the forced splitting particles must be removed if(partons.first->id() != ParticleID::g) { if(partons.first==theMaps.first.back().first) theUsed.first -= theMaps.first.back().second->momentum(); else theUsed.first -= theMaps.first.back().first->momentum(); thestep->removeParticle(theMaps.first.back().first); thestep->removeParticle(theMaps.first.back().second); } theMaps.first.pop_back(); throw ShowerHandler::ExtraScatterVeto(); } } // veto if not enough energy for extraction if( !first &&(theRems.first ->momentum().e() - partons.first ->momentum().e() < 1.0e-3*MeV || theRems.second->momentum().e() - partons.second->momentum().e() < 1.0e-3*MeV )) { if(partons.first->id() != ParticleID::g) { if(partons.first==theMaps.first.back().first) theUsed.first -= theMaps.first.back().second->momentum(); else theUsed.first -= theMaps.first.back().first->momentum(); thestep->removeParticle(theMaps.first.back().first); thestep->removeParticle(theMaps.first.back().second); } theMaps.first.pop_back(); if(partons.second->id() != ParticleID::g) { if(partons.second==theMaps.second.back().first) theUsed.second -= theMaps.second.back().second->momentum(); else theUsed.second -= theMaps.second.back().first->momentum(); thestep->removeParticle(theMaps.second.back().first); thestep->removeParticle(theMaps.second.back().second); } theMaps.second.pop_back(); throw ShowerHandler::ExtraScatterVeto(); } } void HwRemDecayer::mergeColour(tPPtr pold, tPPtr pnew, bool anti) const { ColinePtr clnew, clold; //save the corresponding colour lines clold = pold->colourLine(anti); clnew = pnew->colourLine(!anti); assert(clold); // There is already a colour line (not the final diquark) if(clnew){ if( (clnew->coloured().size() + clnew->antiColoured().size()) > 1 ){ if( (clold->coloured().size() + clold->antiColoured().size()) > 1 ){ //join the colour lines //I don't use the join method, because potentially only (anti)coloured //particles belong to one colour line if(clold!=clnew){//procs are not already connected while ( !clnew->coloured().empty() ) { tPPtr p = clnew->coloured()[0]; clnew->removeColoured(p); clold->addColoured(p); } while ( !clnew->antiColoured().empty() ) { tPPtr p = clnew->antiColoured()[0]; clnew->removeAntiColoured(p); clold->addAntiColoured(p); } } }else{ //if pold is the only member on it's //colour line, remove it. clold->removeColoured(pold, anti); //and add it to clnew clnew->addColoured(pold, anti); } } else{//pnnew is the only member on it's colour line. clnew->removeColoured(pnew, !anti); clold->addColoured(pnew, !anti); } } else {//there is no coline at all for pnew clold->addColoured(pnew, !anti); } } void HwRemDecayer::fixColours(PartnerMap partners, bool anti, double colourDisrupt) const { PartnerMap::iterator prev; tPPtr pnew, pold; assert(partners.size()>=2); PartnerMap::iterator it=partners.begin(); while(it != partners.end()) { //skip the first one to have a partner if(it==partners.begin()){ it++; continue; } prev = it - 1; //determine the particles to work with pold = prev->first; if(prev->second) { if(!pold->coloured()) pold = prev->second; else if(pold->hasAntiColour() != anti) pold = prev->second; } assert(pold); pnew = it->first; if(it->second) { if(it->second->colourLine(!anti)) //look for the opposite colour pnew = it->second; } assert(pnew); // Implement the disruption of colour connections if( it != partners.end()-1 ) {//last one is diquark-has to be connected //has to be inside the if statement, so that the probability is //correctly counted: if( UseRandom::rnd() < colourDisrupt ){ if(!it->second){//check, whether we have a gluon mergeColour(pnew, pnew, anti); }else{ if(pnew==it->first)//be careful about the order mergeColour(it->second, it->first, anti); else mergeColour(it->first, it->second, anti); } it = partners.erase(it); continue; } } // regular merging mergeColour(pold, pnew, anti); //end of loop it++; } return; } PPtr HwRemDecayer::forceSplit(const tRemPPtr rem, long child, Energy &lastQ, double &lastx, Lorentz5Momentum &pf, Lorentz5Momentum &p, HadronContent & content) const { static const double eps=1e-6; // beam momentum Lorentz5Momentum beam = theBeam->momentum(); // the last scale is minimum of last value and upper limit Energy minQ=_range*_kinCutoff*sqrt(lastx)/(1-lastx); if(minQ>lastQ) lastQ=minQ; // generate the new value of qtilde // weighted towards the lower value: dP/dQ = 1/Q -> Q(R) = // Q0 (Qmax/Q0)^R Energy q; unsigned int ntry=0,maxtry=100; double xExtracted = rem==theRems.first ? theX.first : theX.second; double zmin= lastx/(1.-xExtracted) ,zmax,yy; if(1-lastx ids; if(child==21||child==22) { ids=content.flav; for(unsigned int ix=0;ix > > partonprob; double ptotal(0.); for(unsigned int iflav=0;iflav prob; for(unsigned int iz=0;izvalue(sqr(max(wz*q,_kinCutoff))) : _alphaEM->value(sqr(max(wz*q,_kinCutoff))); double az=wz*zz*coup; // g -> q qbar if(ids[iflav]==ParticleID::g) { // calculate splitting function // SP as q is always less than forcedSplitScale, the pdf scale is fixed // pdfval = _pdf->xfx(theBeamData,in,sqr(q),lastx*zr); double pdfval=_pdf->xfx(theBeamData,in,sqr(_forcedSplitScale),lastx*zr); if(pdfval>0.) psum += pdfval*az*0.5*(sqr(zz)+sqr(wz)); } // q -> q g else { // calculate splitting function // SP as q is always less than forcedSplitScale, the pdf scale is fixed // pdfval = _pdf->xfx(theBeamData,in,sqr(q),lastx*zr); double pdfval=_pdf->xfx(theBeamData,in,sqr(_forcedSplitScale),lastx*zr); if(pdfval>0.) psum += pdfval*az*4./3.*(1.+sqr(wz))*zr; } if(psum>0.) prob.push_back(psum); yy+=dely; } if(psum>0.) partonprob[ids[iflav]] = make_pair(psum,prob); ptotal+=psum; } // select the flavour if(ptotal==0.) throw ShowerHandler::ExtraScatterVeto(); ptotal *= UseRandom::rnd(); map > >::const_iterator pit; for(pit=partonprob.begin();pit!=partonprob.end();++pit) { if(pit->second.first>=ptotal) break; else ptotal -= pit->second.first; } if(pit==partonprob.end()) throw Exception() << "Can't select parton for forced backward evolution in " << "HwRemDecayer::forceSplit" << Exception::eventerror; // select z unsigned int iz=0; for(;izsecond.second.size();++iz) { if(pit->second.second[iz]>ptotal) break; } if(iz==pit->second.second.size()) --iz; double ey=exp(ymin+dely*(float(iz+1)-UseRandom::rnd())); double z=ey/(1.+ey); Energy2 pt2=sqr((1.-z)*q)- z*sqr(_kinCutoff); // create the particle if(pit->first!=ParticleID::g) child=pit->first; PPtr parton = getParticleData(child)->produceParticle(); Energy2 emittedm2 = sqr(parton->dataPtr()->constituentMass()); // Now boost pcm and pf to z only frame Lorentz5Momentum p_ref = Lorentz5Momentum(ZERO, beam.vect()); Lorentz5Momentum n_ref = Lorentz5Momentum(ZERO, -beam.vect()); // generate phi and compute pt of branching double phi = Constants::twopi*UseRandom::rnd(); Energy pt=sqrt(pt2); Lorentz5Momentum qt = LorentzMomentum(pt*cos(phi), pt*sin(phi), ZERO, ZERO); Axis axis(p_ref.vect().unit()); if(axis.perp2()>0.) { LorentzRotation rot; double sinth(sqrt(sqr(axis.x())+sqr(axis.y()))); rot.setRotate(acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.)); qt.transform(rot); } // compute alpha for previous particle Energy2 p_dot_n = p_ref*n_ref; double lastalpha = pf*n_ref/p_dot_n; Lorentz5Momentum qtout=qt; Energy2 qtout2=-qt*qt; double alphaout=(1.-z)/z*lastalpha; double betaout=0.5*(emittedm2+qtout2)/alphaout/p_dot_n; Lorentz5Momentum k=alphaout*p_ref+betaout*n_ref+qtout; k.rescaleMass(); parton->set5Momentum(k); pf+=k; lastQ=q; lastx/=z; p += parton->momentum(); thestep->addDecayProduct(rem,parton,false); return parton; } void HwRemDecayer::setRemMasses() const { // get the masses of the remnants Energy mrem[2]; Lorentz5Momentum ptotal,pnew[2]; vector theprocessed; theprocessed.push_back(theRems.first); theprocessed.push_back(theRems.second); // one remnant in e.g. DIS if(!theprocessed[0]||!theprocessed[1]) { tRemPPtr rem = theprocessed[0] ? theprocessed[0] : theprocessed[1]; Lorentz5Momentum deltap(rem->momentum()); // find the diquark and momentum we still need in the energy tPPtr diquark; vector progenitors; for(unsigned int ix=0;ixchildren().size();++ix) { if(!DiquarkMatcher::Check(rem->children()[ix]->data())) { progenitors.push_back(rem->children()[ix]); deltap -= rem->children()[ix]->momentum(); } else diquark = rem->children()[ix]; } // now find the total momentum of the hadronic final-state to // reshuffle against // find the hadron for this remnant tPPtr hadron=rem; do hadron=hadron->parents()[0]; while(!hadron->parents().empty()); // find incoming parton to hard process from this hadron tPPtr hardin = generator()->currentEvent()->primaryCollision()->incoming().first==hadron ? generator()->currentEvent()->primarySubProcess()->incoming().first : generator()->currentEvent()->primarySubProcess()->incoming().second; tPPtr parent=hardin; vector tempprog; // find the outgoing particles emitted from the backward shower do { assert(!parent->parents().empty()); tPPtr newparent=parent->parents()[0]; if(newparent==hadron) break; for(unsigned int ix=0;ixchildren().size();++ix) { if(newparent->children()[ix]!=parent) findChildren(newparent->children()[ix],tempprog); } parent=newparent; } while(parent!=hadron); // add to list of potential particles to reshuffle against in right order for(unsigned int ix=tempprog.size();ix>0;--ix) progenitors.push_back(tempprog[ix-1]); // final-state particles which are colour connected tColinePair lines = make_pair(hardin->colourLine(),hardin->antiColourLine()); vector others; for(ParticleVector::const_iterator cit = generator()->currentEvent()->primarySubProcess()->outgoing().begin(); cit!= generator()->currentEvent()->primarySubProcess()->outgoing().end();++cit) { // colour connected if(lines.first&&lines.first==(**cit).colourLine()) { findChildren(*cit,progenitors); continue; } // anticolour connected if(lines.second&&lines.second==(**cit).antiColourLine()) { findChildren(*cit,progenitors); continue; } // not connected for(unsigned int ix=0;ix<(**cit).children().size();++ix) others.push_back((**cit).children()[ix]); } // work out how much of the system needed for rescaling unsigned int iloc=0; Lorentz5Momentum psystem,ptotal; do { psystem+=progenitors[iloc]->momentum(); ptotal = psystem + deltap; ptotal.rescaleMass(); psystem.rescaleMass(); ++iloc; if(ptotal.mass() > psystem.mass() + diquark->mass() && psystem.mass()>1*MeV && DISRemnantOpt_<2 && ptotal.e() > 0.*GeV ) break; } while(iloc psystem.mass() + diquark->mass()) --iloc; if(iloc==progenitors.size()) { // try touching the lepton in dis as a last restort for(unsigned int ix=0;ixmomentum(); ptotal = psystem + deltap; ptotal.rescaleMass(); psystem.rescaleMass(); ++iloc; } --iloc; if(ptotal.mass() > psystem.mass() + diquark->mass()) { if(DISRemnantOpt_==0||DISRemnantOpt_==2) Throw() << "Warning had to adjust the momentum of the" << " non-colour connected" << " final-state, e.g. the scattered lepton in DIS" << Exception::warning; else throw Exception() << "Can't set remnant momentum without adjusting " << "the momentum of the" << " non-colour connected" << " final-state, e.g. the scattered lepton in DIS" << " vetoing event" << Exception::eventerror; } else { throw Exception() << "Can't put the remnant on-shell in HwRemDecayer::setRemMasses()" << Exception::eventerror; } } psystem.rescaleMass(); LorentzRotation R = Utilities::getBoostToCM(make_pair(psystem, deltap)); Energy pz = SimplePhaseSpace::getMagnitude(sqr(ptotal.mass()), psystem.mass(), diquark->mass()); LorentzRotation Rs(-(R*psystem).boostVector()); Rs.boost(0.0, 0.0, pz/sqrt(sqr(pz) + sqr(psystem.mass()))); Rs = Rs*R; // put remnant on shell deltap.transform(R); deltap.setMass(diquark->mass()); deltap.setE(sqrt(sqr(diquark->mass())+sqr(pz))); deltap.rescaleRho(); R.invert(); deltap.transform(R); Rs = R*Rs; // apply transformation to required particles to absorb recoil for(unsigned int ix=0;ix<=iloc;++ix) { progenitors[ix]->deepTransform(Rs); } diquark->set5Momentum(deltap); } // two remnants else { for(unsigned int ix=0;ix<2;++ix) { if(!theprocessed[ix]) continue; pnew[ix]=Lorentz5Momentum(); for(unsigned int iy=0;iychildren().size();++iy) { pnew[ix]+=theprocessed[ix]->children()[iy]->momentum(); } mrem[ix]=sqrt(pnew[ix].m2()); } // now find the remnant remnant cmf frame Lorentz5Momentum prem[2]={theprocessed[0]->momentum(), theprocessed[1]->momentum()}; ptotal=prem[0]+prem[1]; ptotal.rescaleMass(); // boost momenta to this frame if(ptotal.m()< (pnew[0].m()+pnew[1].m())) throw Exception() << "Not enough energy in both remnants in " << "HwRemDecayer::setRemMasses() " << Exception::eventerror; Boost boostv(-ptotal.boostVector()); ptotal.boost(boostv); for(unsigned int ix=0;ix<2;++ix) { prem[ix].boost(boostv); // set the masses and energies, prem[ix].setMass(mrem[ix]); prem[ix].setE(0.5/ptotal.m()*(sqr(ptotal.m())+sqr(mrem[ix])-sqr(mrem[1-ix]))); prem[ix].rescaleRho(); // boost back to the lab prem[ix].boost(-boostv); // set the momenta of the remnants theprocessed[ix]->set5Momentum(prem[ix]); } // boost the decay products Lorentz5Momentum ptemp; for(unsigned int ix=0;ix<2;++ix) { Boost btorest(-pnew[ix].boostVector()); Boost bfmrest( prem[ix].boostVector()); for(unsigned int iy=0;iychildren().size();++iy) { ptemp=theprocessed[ix]->children()[iy]->momentum(); ptemp.boost(btorest); ptemp.boost(bfmrest); theprocessed[ix]->children()[iy]->set5Momentum(ptemp); } } } } void HwRemDecayer::initSoftInteractions(Energy ptmin, InvEnergy2 beta){ ptmin_ = ptmin; beta_ = beta; } Energy HwRemDecayer::softPt() const { Energy2 pt2(ZERO); double xmin(0.0), xmax(1.0), x(0); if(beta_ == ZERO){ return UseRandom::rnd(0.0,(double)(ptmin_/GeV))*GeV; } if(beta_ < ZERO){ xmin = 1.0; xmax = exp( -beta_*sqr(ptmin_) ); }else{ xmin = exp( -beta_*sqr(ptmin_) ); xmax = 1.0; } x = UseRandom::rnd(xmin, xmax); pt2 = 1.0/beta_ * log(1/x); if( pt2 < ZERO || pt2 > sqr(ptmin_) ) throw Exception() << "HwRemDecayer::softPt generation of pt " << "outside allowed range [0," << ptmin_/GeV << "]." << Exception::runerror; //ofstream myfile2("softPt.txt", ios::app ); //myfile2 << pt2/GeV2 <<" "<currentEventHandler()->currentCollision()->incoming()); Lorentz5Momentum P1(beam.first->momentum()), P2(beam.second->momentum()); if(dbg){ cerr << "new event --------------------\n" << *(beam.first) << *(softRems_.first) << "-------------------\n" << *(beam.second) << *(softRems_.second) << endl; } //parton mass Energy mp; if(quarkPair_){ mp = getParticleData(ParticleID::u)->constituentMass(); }else{ mp = mg_; } //Get x_g1 and x_g2 //first limits double xmin = sqr(ptmin_)/4.0/(P1+P2).m2(); double x1max = (r1.e()+abs(r1.z()))/(P1.e() + abs(P1.z())); double x2max = (r2.e()+abs(r2.z()))/(P2.e() + abs(P2.z())); double x1; if(!multiPeriph_){ //now generate according to 1/x x_g1 = xmin * exp(UseRandom::rnd(log(x1max/xmin))); x_g2 = xmin * exp(UseRandom::rnd(log(x2max/xmin))); }else{ if(valOfN_==0) return; double param = (1/(2*valOfN_+1))*initTotRap_; do{ // need 1-x instead of x to get the proper final momenta x1 = UseRandom::rndGauss(gaussWidth_, 1 - (exp(param)-1)/exp(param)); }while(x1 < 0 || x1>=1.0); x_g1 = x1max*x1; x_g2 = x2max*x1; } if(dbg) cerr << x1max << " " << x_g1 << endl << x2max << " " << x_g2 << endl; Lorentz5Momentum ig1, ig2, cmf; ig1 = x_g1*P1; ig2 = x_g2*P2; ig1.setMass(mp); ig2.setMass(mp); ig1.rescaleEnergy(); ig2.rescaleEnergy(); cmf = ig1 + ig2; //boost vector from cmf to lab Boost boostv(cmf.boostVector()); //outgoing gluons in cmf g1.setMass(mp); g2.setMass(mp); g1.setX(pt*cos(phi)); g2.setX(-pt*cos(phi)); g1.setY(pt*sin(phi)); g2.setY(-pt*sin(phi)); pz2 = cmf.m2()/4 - sqr(mp) - (pt*pt); if( pz2/GeV2 < 0.0 ){ if(dbg) cerr << "EXCEPTION not enough energy...." << endl; throw ExtraSoftScatterVeto(); } if(!multiPeriph_){ if(UseRandom::rndbool()){ pz = sqrt(pz2); }else pz = -sqrt(pz2); }else{ pz = pz2 > ZERO ? sqrt(pz2) : ZERO; } if(dbg) cerr << "pz1 has been calculated to: " << pz/GeV << endl; g1.setZ(pz); g2.setZ(-pz); g1.rescaleEnergy(); g2.rescaleEnergy(); if(dbg){ cerr << "check inv mass in cmf frame: " << (g1+g2).m()/GeV << " vs. lab frame: " << (ig1+ig2).m()/GeV << endl; } g1.boost(boostv); g2.boost(boostv); //recalc the remnant momenta Lorentz5Momentum r1old(r1), r2old(r2); r1 -= g1; r2 -= g2; try{ reShuffle(r1, r2, r1old.m(), r2old.m()); }catch(ExtraSoftScatterVeto){ r1 = r1old; r2 = r2old; throw ExtraSoftScatterVeto(); } if(dbg){ cerr << "remnant 1,2 momenta: " << r1/GeV << "--" << r2/GeV << endl; cerr << "remnant 1,2 masses: " << r1.m()/GeV << " " << r2.m()/GeV << endl; cerr << "check momenta in the lab..." << (-r1old-r2old+r1+r2+g1+g2)/GeV << endl; } } void HwRemDecayer::doSoftInteractions_old(unsigned int N) { if(N == 0) return; if(!softRems_.first || !softRems_.second) throw Exception() << "HwRemDecayer::doSoftInteractions: no " << "Remnants available." << Exception::runerror; if( ptmin_ == -1.*GeV ) throw Exception() << "HwRemDecayer::doSoftInteractions: init " << "code has not been called! call initSoftInteractions." << Exception::runerror; Lorentz5Momentum g1, g2; Lorentz5Momentum r1(softRems_.first->momentum()), r2(softRems_.second->momentum()); unsigned int tries(1), i(0); for(i=0; i maxtrySoft_) break; if(dbg){ cerr << "new try \n" << *softRems_.first << *softRems_.second << endl; } try{ softKinematics(r1, r2, g1, g2); }catch(ExtraSoftScatterVeto){ tries++; i--; continue; } PPair oldrems = softRems_; PPair gluons = make_pair(addParticle(softRems_.first, ParticleID::g, g1), addParticle(softRems_.second, ParticleID::g, g2)); //now reset the remnants with the new ones softRems_.first = addParticle(softRems_.first, softRems_.first->id(), r1); softRems_.second = addParticle(softRems_.second, softRems_.second->id(), r2); //do the colour connections pair anti = make_pair(oldrems.first->hasAntiColour(), oldrems.second->hasAntiColour()); ColinePtr cl1 = new_ptr(ColourLine()); ColinePtr cl2 = new_ptr(ColourLine()); // case 2: oldrems.first->colourLine(anti.first) ->addColoured(gluons.second,anti.second); cl2->addColoured(softRems_.first, anti.second); cl2->addColoured(gluons.second, !anti.second); oldrems.first->colourLine(anti.first) ->addColoured(gluons.second,anti.second); oldrems.second->colourLine(anti.second) ->addColoured(gluons.first,anti.first); cl1->addColoured(softRems_.second, anti.first); cl1->addColoured(gluons.first, !anti.first); cl2->addColoured(softRems_.first, anti.second); cl2->addColoured(gluons.second, !anti.second); //reset counter tries = 1; } if(dbg) cerr << "generated " << i << "th soft scatters\n"; } // Solve the reshuffling equation to rescale the remnant momenta double bisectReshuffling(const vector& particles, Energy w, double target = -16., double maxLevel = 80.) { double level = 0; double left = 0; double right = 1; double check = -1.; double xi = -1; while ( level < maxLevel ) { xi = (left+right)*pow(0.5,level+1.); check = 0.; for (vector::const_iterator p = particles.begin(); p != particles.end(); ++p){ check += sqrt(sqr(xi)*((*p)->momentum().vect().mag2())+sqr((*p)->mass()))/w; } if ( check==1. || log10(abs(1.-check)) <= target ) break; left *= 2.; right *= 2.; if ( check >= 1. ) { right -= 1.; ++level; } if ( check < 1. ) { left += 1.; ++level; } } return xi; } LorentzRotation HwRemDecayer::rotate(const LorentzMomentum &p) const { LorentzRotation R; static const double ptcut = 1e-20; Energy2 pt2 = sqr(p.x())+sqr(p.y()); Energy2 pp2 = sqr(p.z())+pt2; double phi, theta; if(pt2 <= pp2*ptcut) { if(p.z() > ZERO) theta = 0.; else theta = Constants::pi; phi = 0.; } else { Energy pp = sqrt(pp2); Energy pt = sqrt(pt2); double ct = p.z()/pp; double cf = p.x()/pt; phi = -acos(cf); theta = acos(ct); } // Rotate first around the z axis to put p in the x-z plane // Then rotate around the Y axis to put p on the z axis R.rotateZ(phi).rotateY(theta); return R; } struct vectorSort{ bool operator() (Lorentz5Momentum i,Lorentz5Momentum j) {return(i.rapidity() < j.rapidity());} } ySort; void HwRemDecayer::doSoftInteractions_multiPeriph(unsigned int N) { if(N == 0) return; int Nmpi = N; for(int j=0;jmaximumCMEnergy()); + //Energy energy(generator()->maximumCMEnergy()); //double reference = sqr(energy/TeV); // double ladderMult_; // Parametrization of the ladder multiplicity // ladderMult_ = ladderNorm_ * pow( ( reference ) , ladderPower_ ); double avgN = 2.*ladderMult_*log((softRems_.first->momentum() +softRems_.second->momentum()).m()/mg_) + ladderbFactor_; initTotRap_ = abs(softRems_.first->momentum().rapidity()) +abs(softRems_.second->momentum().rapidity()); // Generate the poisson distribution with mean avgN N=UseRandom::rndPoisson(avgN); valOfN_=N; if(N <= 1){ // j--; //TODO: Do we want to make all Nmpi soft MPIs? // Compare to MaxTryMPI for hard mpis. continue; } if(!softRems_.first || !softRems_.second) throw Exception() << "HwRemDecayer::doSoftInteractions: no " << "Remnants available." << Exception::runerror; if( ptmin_ == -1.*GeV ) throw Exception() << "HwRemDecayer::doSoftInteractions: init " << "code has not been called! call initSoftInteractions." << Exception::runerror; // The remnants PPtr rem1 = softRems_.first; PPtr rem2 = softRems_.second; // Vector for the ladder particles vector ladderMomenta; // Remnant momenta Lorentz5Momentum r1(softRems_.first->momentum()), r2(softRems_.second->momentum()); Lorentz5Momentum cm =r1+r2; // Initialize partons in the ladder // The toy masses are needed for the correct calculation of the available energy Lorentz5Momentum sumMomenta; for(unsigned int i = 0; i < N; i++) { // choose constituents Energy newMass = ZERO; Energy toyMass; if(i<2){ // u and d have the same mass so its enough to use u toyMass = getParticleData(ParticleID::u)->constituentMass(); } else{ toyMass = getParticleData(ParticleID::g)->constituentMass(); } Lorentz5Momentum cp(ZERO,ZERO,ZERO,newMass,newMass); // dummy container for the momentum that is used for momentum conservation Lorentz5Momentum dummy(ZERO,ZERO,ZERO,toyMass,toyMass); ladderMomenta.push_back(cp); sumMomenta+=dummy; } // Get the beam energy tcPPair beam(generator()->currentEventHandler()->currentCollision()->incoming()); - Lorentz5Momentum P1(beam.first->momentum()), P2(beam.second->momentum()); + //Lorentz5Momentum P1(beam.first->momentum()), P2(beam.second->momentum()); // Calculate available energy for the partons - double x1,x2; + double x1;//,x2; double param = (1./(valOfN_+1.))*initTotRap_; do{ // Need 1-x instead of x to get the proper final momenta // TODO: physical to use different x's (see comment below) x1 = UseRandom::rndGauss( gaussWidth_ , exp(-param) ); // x2 = UseRandom::rndGauss( gaussWidth_ , exp(-param) ); }while(x1 < 0 || x1>=1.0); // x2 < 0 || x2>=1.0); // Remnants 1 and 2 need to be rescaled later by this amount Lorentz5Momentum ig1 = x1*r1; Lorentz5Momentum ig2 = x1*r2; //TODO: x2*r2 // requires boost of Ladder in x1/x2-dependent // frame. + // If the remaining remnant energy is not sufficient for the restmass of the remnants + // then continue/try again + if ( cm.m() - (ig1+ig2).m() < r1.m()+r2.m() ){ + continue; + } + // The available energy that is used to generate the ladder // sumMomenta is the the sum of rest masses of the ladder partons // the available energy goes all into the kinematics + Energy availableEnergy = (ig1+ig2).m() - sumMomenta.m(); // If not enough energy then continue // The available energy has to be larger then the rest mass of the remnants if ( availableEnergy < ZERO ) { // j--; //TODO: Do we want to make all Nmpi soft MPIs? continue; } unsigned int its(0); // Generate the momenta of the partons in the ladder if ( !(doPhaseSpaceGenerationGluons(ladderMomenta,availableEnergy,its)) ){ // j--; //TODO: Do we want to make all Nmpi soft MPIs? continue; } // Add gluon mass and rescale Lorentz5Momentum totalMomPartons; Lorentz5Momentum totalMassLessPartons; // Sort the ladder partons according to their rapidity and then choose which ones will be the quarks sort(ladderMomenta.begin(),ladderMomenta.end(),ySort); int countPartons=0; long quarkID=0; // Choose between up and down quarks int choice = UseRandom::rnd2(1,1); switch (choice) { case 0: quarkID = ParticleID::u; break; case 1: quarkID = ParticleID::d; break; } for (auto &p:ladderMomenta){ totalMomPartons+=p; // Set the mass of the gluons and the two quarks in the ladder - if(countPartons==0 || countPartons==(ladderMomenta.size()-1)){ + if(countPartons==0 || countPartons==int(ladderMomenta.size()-1)){ p.setMass( getParticleData(quarkID)->constituentMass() ); }else{ p.setMass( getParticleData(ParticleID::g)->constituentMass() ); } p.rescaleEnergy(); countPartons++; } // Continue if energy conservation is violated if ( abs(availableEnergy - totalMomPartons.m()) > 1e-8*GeV){ // j--; //TODO: Do we want to make all Nmpi soft MPIs? continue; } // Boost momenta into CM frame const Boost boostv(-totalMomPartons.boostVector()); Lorentz5Momentum totalMomentumAfterBoost; for ( unsigned int i=0; i remnants; rem1->set5Momentum(r1); rem2->set5Momentum(r2); remnants.push_back(rem1); remnants.push_back(rem2); vector reshuffledRemnants; Lorentz5Momentum totalMomentumAll; // Bisect reshuffling for rescaling of remnants double xi_remnants = bisectReshuffling(remnants,remainingEnergy); // Rescale remnants for ( auto &rems: remnants ) { Lorentz5Momentum reshuffledMomentum; reshuffledMomentum = xi_remnants*rems->momentum(); reshuffledMomentum.setMass(getParticleData(softRems_.first->id())->constituentMass()); reshuffledMomentum.rescaleEnergy(); reshuffledMomentum.boost(-boostvR); rems->set5Momentum(reshuffledMomentum); totalMomentumAll+=reshuffledMomentum; } // Then the other particles for ( auto &p:ladderMomenta ) { p.boost(-boostvR); totalMomentumAll+=p; } - // sort again - sort(ladderMomenta.begin(),ladderMomenta.end(),ySort); + // sanity check + if ( abs(cm.m() - totalMomentumAll.m()) > 1e-8*GeV) { + continue; + } + + // sort again + sort(ladderMomenta.begin(),ladderMomenta.end(),ySort); // Do the colour connections // Original rems are the ones which are connected to other parts of the event PPair oldRems_ = softRems_; pair anti = make_pair(oldRems_.first->hasAntiColour(), oldRems_.second->hasAntiColour()); // Replace first remnant softRems_.first = addParticle(softRems_.first, softRems_.first->id(), remnants[0]->momentum()); // Connect the old remnant to the new remnant oldRems_.first->colourLine(anti.first)->addColoured(softRems_.first, anti.first); // Replace second remnant softRems_.second = addParticle(softRems_.second, softRems_.second->id(), remnants[1]->momentum()); // This connects the old remnants to the new remnants oldRems_.second->colourLine(anti.second)->addColoured(softRems_.second, anti.second); // Add all partons to the first remnant for the event record vector partons; vector quarks; int count=0; // Choose the colour connections and position of quark antiquark // Choose between R1-q-g..g-qbar-R2 or R1-qbar-g...g-q-R2 // (place of quark antiquarks in the ladder) int quarkPosition = UseRandom::rnd2(1,1); for (auto &p:ladderMomenta){ if(p.mass()==getParticleData(ParticleID::u)->constituentMass()){ if(count==0){ if(quarkPosition==0){ quarks.push_back(addParticle(softRems_.first, quarkID, p)); count++; }else{ quarks.push_back(addParticle(softRems_.first, -quarkID, p)); count++; } }else{ if(quarkPosition==0){ quarks.push_back(addParticle(softRems_.first, -quarkID, p)); }else{ quarks.push_back(addParticle(softRems_.first, quarkID, p)); } } }else{ partons.push_back(addParticle(softRems_.first, ParticleID::g, p)); } softRems_.first = addParticle(softRems_.first, softRems_.first->id(), softRems_.first->momentum()); oldRems_.first->colourLine(anti.first)->addColoured(softRems_.first, anti.first); } // Need to differenciate between the two quark positions, this defines the // colour connections to the new remnants and old remnants if(quarkPosition==0){ // ladder self contained if(partons.size()==0 && quarks.size()>0){ ColinePtr clq = new_ptr(ColourLine()); clq->addColoured(quarks[0]); clq->addAntiColoured(quarks[1]); } ColinePtr clfirst = new_ptr(ColourLine()); ColinePtr cllast = new_ptr(ColourLine()); if(partons.size()>0){ clfirst->addColoured(quarks[0]); clfirst->addAntiColoured(partons[0]); cllast->addAntiColoured(quarks[1]); cllast->addColoured(partons[partons.size()-1]); //now the remaining gluons for (unsigned int i=0; iaddColoured(partons[i]); cl->addAntiColoured(partons[i+1]); } } } else { if(partons.size()==0 && quarks.size()>0){ ColinePtr clq = new_ptr(ColourLine()); clq->addAntiColoured(quarks[0]); clq->addColoured(quarks[1]); } ColinePtr clfirst = new_ptr(ColourLine()); ColinePtr cllast = new_ptr(ColourLine()); if(partons.size()>0){ clfirst->addAntiColoured(quarks[0]); clfirst->addColoured(partons[0]); cllast->addColoured(quarks[1]); cllast->addAntiColoured(partons[partons.size()-1]); //now the remaining gluons for (unsigned int i=0; iaddAntiColoured(partons[i]); cl->addColoured(partons[i+1]); } } }// end colour connection loop }// end Nmpi loop }//end function // Do the phase space generation here is 1 to 1 the same from UA5 model bool HwRemDecayer::doPhaseSpaceGenerationGluons(vector &softGluons, Energy CME, unsigned int &its) const{ // Define the parameters unsigned int _maxtries = 300; double alog = log(CME*CME/GeV2); unsigned int ncl = softGluons.size(); // calculate the slope parameters for the different clusters // outside loop to save time vector mom(ncl); // Sets the slopes depending on the constituent quarks of the cluster for(unsigned int ix=0;ix xi(ncl); vector tempEnergy(ncl); Energy sum1(ZERO); double yy(0.); // We want to make sure that the first Pt is from the // desired pt-distribution. If we select the first pt in the // trial loop we introduce a bias. Energy firstPt=softPt(); while(its < _maxtries) { ++its; Energy sumx = ZERO; Energy sumy = ZERO; unsigned int iterations(0); unsigned int _maxtriesNew = 100; while(iterations < _maxtriesNew) { iterations++; Energy sumxIt = ZERO; Energy sumyIt = ZERO; bool success=false; Energy pTmax=ZERO; for(unsigned int i = 0; ipT2...pTN //2) pT1>pT2>..>pTN //3) flat //4) y dependent //5) Frist then flat int triesPt=0; Energy pt; - Energy ptTest; + //Energy ptTest; switch(PtDistribution_) { case 0: //default softPt() pt=softPt(); break; case 1: //pTordered if(i==0){ pt=softPt(); pTmax=pt; }else{ do{ pt=softPt(); }while(pt>pTmax); } break; case 2: //strongly pT ordered if ( i==0 ) { pt=softPt(); pTmax=pt; } else { do { if ( triesPt==20 ) { pt=pTmax; break; } pt=softPt(); triesPt++; } while ( pt>pTmax ); pTmax=pt; } break; case 3: //flat pt = UseRandom::rnd(0.0,(double)(ptmin_/GeV))*GeV; break; case 4: //flat below first pT if ( i==0 ) { pt = firstPt; } else { pt = firstPt * UseRandom::rnd(); } break; case 5: //flat but rising below first pT if ( i==0 ) { pt=firstPt; } else { pt = firstPt * pow(UseRandom::rnd(),1/2); } } Energy2 ptp = pt*pt; if(ptp <= ZERO) pt = - sqrt(-ptp); else pt = sqrt(ptp); // randomize azimuth Energy px,py; //randomize the azimuth, but the last one should cancel all others if(i CME) continue; // randomize the mom vector to get the first and the compensating parton // at all possible positions: long (*p_irnd)(long) = UseRandom::irnd; random_shuffle(mom.begin(),mom.end(),p_irnd); for(unsigned int i = 0; i=1; i--) xi[i+1] = (xi[i]-ximin)/ximax; xi[1] = 1.; yy= log(CME*CME/(mom[0].z()*mom[1].z())); bool suceeded=false; Energy sum2,sum3,sum4; for(unsigned int j = 0; j<10; j++) { sum1 = sum2 = sum3 = sum4 = ZERO; for(unsigned int i = 0; i 100) eps *= 10.; } if(its==_maxtries){ return false; } // throw Exception() << "Can't generate soft underlying event in " // << "UA5Handler::generateCylindricalPS" // << Exception::eventerror; double zz = log(CME/sum1); for(unsigned int i = 0; iDiquark or Rem->quark "decay" if(theRems.first) { diquarks.first = finalSplit(theRems.first, theContent.first.RemID(), theUsed.first); theMaps.first.push_back(make_pair(diquarks.first, tPPtr())); } if(theRems.second) { diquarks.second = finalSplit(theRems.second, theContent.second.RemID(), theUsed.second); theMaps.second.push_back(make_pair(diquarks.second, tPPtr())); } setRemMasses(); if(theRems.first) { fixColours(theMaps.first, theanti.first, colourDisrupt); if(theContent.first.hadron->id()==ParticleID::pomeron&& pomeronStructure_==0) fixColours(theMaps.first, !theanti.first, colourDisrupt); } if(theRems.second) { fixColours(theMaps.second, theanti.second, colourDisrupt); if(theContent.second.hadron->id()==ParticleID::pomeron&& pomeronStructure_==0) fixColours(theMaps.second, !theanti.second, colourDisrupt); } if( !theRems.first || !theRems.second ) return; //stop here if we don't have two remnants softRems_ = diquarks; doSoftInteractions(softInt); } HwRemDecayer::HadronContent HwRemDecayer::getHadronContent(tcPPtr hadron) const { HadronContent hc; hc.hadron = hadron->dataPtr(); long id(hadron->id()); // baryon if(BaryonMatcher::Check(hadron->data())) { hc.sign = id < 0? -1: 1; hc.flav.push_back((id = abs(id)/10)%10); hc.flav.push_back((id /= 10)%10); hc.flav.push_back((id /= 10)%10); hc.extracted = -1; } else if(hadron->data().id()==ParticleID::gamma || (hadron->data().id()==ParticleID::pomeron && pomeronStructure_==1)) { hc.sign = 1; for(int ix=1;ix<6;++ix) { hc.flav.push_back( ix); hc.flav.push_back(-ix); } } else if(hadron->data().id()==ParticleID::pomeron ) { hc.sign = 1; hc.flav.push_back(ParticleID::g); hc.flav.push_back(ParticleID::g); } else if(hadron->data().id()==ParticleID::reggeon ) { hc.sign = 1; for(int ix=1;ix<3;++ix) { hc.flav.push_back( ix); hc.flav.push_back(-ix); } } hc.pomeronStructure = pomeronStructure_; return hc; } long HwRemDecayer::HadronContent::RemID() const{ if(extracted == -1) throw Exception() << "Try to build a Diquark id without " << "having extracted something in " << "HwRemDecayer::RemID(...)" << Exception::runerror; //the hadron was a meson or photon if(flav.size()==2) return sign*flav[(extracted+1)%2]; long remId; int id1(sign*flav[(extracted+1)%3]), id2(sign*flav[(extracted+2)%3]), sign(0), spin(0); if (abs(id1) > abs(id2)) swap(id1, id2); sign = (id1 < 0) ? -1 : 1; // Needed for the spin 0/1 part remId = id2*1000+id1*100; // Now decide if we have spin 0 diquark or spin 1 diquark if(id1 == id2) spin = 3; // spin 1 else spin = 1; // otherwise spin 0 remId += sign*spin; return remId; } tPPtr HwRemDecayer::addParticle(tcPPtr parent, long id, Lorentz5Momentum p) const { PPtr newp = new_ptr(Particle(getParticleData(id))); newp->set5Momentum(p); // Add the new remnant to the step, but don't do colour connections thestep->addDecayProduct(parent,newp,false); return newp; } void HwRemDecayer::findChildren(tPPtr part,vector & particles) const { if(part->children().empty()) particles.push_back(part); else { for(unsigned int ix=0;ixchildren().size();++ix) findChildren(part->children()[ix],particles); } } ParticleVector HwRemDecayer::decay(const DecayMode &, const Particle &, Step &) const { throw Exception() << "HwRemDecayer::decay(...) " << "must not be called explicitely." << Exception::runerror; } void HwRemDecayer::persistentOutput(PersistentOStream & os) const { os << ounit(_kinCutoff, GeV) << _range << _zbin << _ybin << _nbinmax << _alphaS << _alphaEM << DISRemnantOpt_ << maxtrySoft_ << colourDisrupt_ << ladderPower_<< ladderNorm_ << ladderMult_ << ladderbFactor_ << pomeronStructure_ << ounit(mg_,GeV) << ounit(ptmin_,GeV) << ounit(beta_,sqr(InvGeV)) << allowTop_ << multiPeriph_ << valOfN_ << initTotRap_ << PtDistribution_; } void HwRemDecayer::persistentInput(PersistentIStream & is, int) { is >> iunit(_kinCutoff, GeV) >> _range >> _zbin >> _ybin >> _nbinmax >> _alphaS >> _alphaEM >> DISRemnantOpt_ >> maxtrySoft_ >> colourDisrupt_ >> ladderPower_ >> ladderNorm_ >> ladderMult_ >> ladderbFactor_ >> pomeronStructure_ >> iunit(mg_,GeV) >> iunit(ptmin_,GeV) >> iunit(beta_,sqr(InvGeV)) >> allowTop_ >> multiPeriph_ >> valOfN_ >> initTotRap_ >> PtDistribution_; } // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeHerwigHwRemDecayer("Herwig::HwRemDecayer", "HwShower.so"); void HwRemDecayer::Init() { static ClassDocumentation documentation ("The HwRemDecayer class decays the remnant for Herwig"); static Parameter interfaceZBinSize ("ZBinSize", "The size of the vbins in z for the interpolation of the splitting function.", &HwRemDecayer::_zbin, 0.05, 0.001, 0.1, false, false, Interface::limited); static Parameter interfaceMaxBin ("MaxBin", "Maximum number of z bins", &HwRemDecayer::_nbinmax, 100, 10, 1000, false, false, Interface::limited); static Reference interfaceAlphaS ("AlphaS", "Pointer to object to calculate the strong coupling", &HwRemDecayer::_alphaS, false, false, true, false, false); static Reference interfaceAlphaEM ("AlphaEM", "Pointer to object to calculate the electromagnetic coupling", &HwRemDecayer::_alphaEM, false, false, true, false, false); static Parameter interfaceKinCutoff ("KinCutoff", "Parameter kinCutoff used to constrain qtilde", &HwRemDecayer::_kinCutoff, GeV, 0.75*GeV, 0.5*GeV, 10.0*GeV, false, false, Interface::limited); static Parameter interfaceEmissionRange ("EmissionRange", "Factor above the minimum possible value in which the forced splitting is allowed.", &HwRemDecayer::_range, 1.1, 1.0, 10.0, false, false, Interface::limited); static Switch interfaceDISRemnantOption ("DISRemnantOption", "Options for the treatment of the remnant in DIS", &HwRemDecayer::DISRemnantOpt_, 0, false, false); static SwitchOption interfaceDISRemnantOptionDefault (interfaceDISRemnantOption, "Default", "Use the minimum number of particles needed to take the recoil" " and allow the lepton to be used if needed", 0); static SwitchOption interfaceDISRemnantOptionNoLepton (interfaceDISRemnantOption, "NoLepton", "Use the minimum number of particles needed to take the recoil but" " veto events where the lepton kinematics would need to be altered", 1); static SwitchOption interfaceDISRemnantOptionAllParticles (interfaceDISRemnantOption, "AllParticles", "Use all particles in the colour connected system to take the recoil" " and use the lepton if needed.", 2); static SwitchOption interfaceDISRemnantOptionAllParticlesNoLepton (interfaceDISRemnantOption, "AllParticlesNoLepton", "Use all the particles in the colour connected system to take the" " recoil but don't use the lepton.", 3); static Parameter interfaceMaxTrySoft ("MaxTrySoft", "The maximum number of regeneration attempts for an additional soft scattering", &HwRemDecayer::maxtrySoft_, 10, 0, 100, false, false, Interface::limited); static Parameter interfacecolourDisrupt ("colourDisrupt", "Fraction of connections to additional soft subprocesses, which are colour disrupted.", &HwRemDecayer::colourDisrupt_, 1.0, 0.0, 1.0, false, false, Interface::limited); static Parameter interaceladderPower ("ladderPower", "The power factor in the ladder parameterization.", &HwRemDecayer::ladderPower_, 1.0, -5.0, 10.0, false, false, Interface::limited); static Parameter interfaceladderNorm ("ladderNorm", "The normalization factor in the ladder parameterization", &HwRemDecayer::ladderNorm_, 1.0, 0.0, 10.0, false, false, Interface::limited); static Parameter interfaceladderMult ("ladderMult", "The ladder multiplicity factor ", &HwRemDecayer::ladderMult_, 1.0, 0.0, 10.0, false, false, Interface::limited); static Parameter interfaceladderbFactor ("ladderbFactor", "The additive factor in the multiperipheral ladder multiplicity.", &HwRemDecayer::ladderbFactor_, 1.0, 0.0, 10.0, false, false, Interface::limited); static Parameter interfacegaussWidth ("gaussWidth", "The gaussian width of the fluctuation of longitudinal momentum fraction.", &HwRemDecayer::gaussWidth_, 0.1, 0.0, 1.0, false, false, Interface::limited); static Switch interfacePomeronStructure ("PomeronStructure", "Option for the treatment of the valance structure of the pomeron", &HwRemDecayer::pomeronStructure_, 0, false, false); static SwitchOption interfacePomeronStructureGluon (interfacePomeronStructure, "Gluon", "Assume the pomeron is a two gluon state", 0); static SwitchOption interfacePomeronStructureQQBar (interfacePomeronStructure, "QQBar", "Assumne the pomeron is q qbar as for the photon," " this option is not recommended and is provide for compatiblity with POMWIG", 1); static Switch interfaceAllowTop ("AllowTop", "Allow top quarks in the hadron", &HwRemDecayer::allowTop_, false, false, false); static SwitchOption interfaceAllowTopNo (interfaceAllowTop, "No", "Don't allow them", false); static SwitchOption interfaceAllowTopYes (interfaceAllowTop, "Yes", "Allow them", true); static Switch interfaceMultiPeriph ("MultiPeriph", "Use multiperipheral kinematics", &HwRemDecayer::multiPeriph_, false, false, false); static SwitchOption interfaceMultiPeriphNo (interfaceMultiPeriph, "No", "Don't use multiperipheral", false); static SwitchOption interfaceMultiPeriphYes (interfaceMultiPeriph, "Yes", "Use multiperipheral kinematics", true); static Switch interfacePtDistribution ("PtDistribution", "Options for different pT generation methods", &HwRemDecayer::PtDistribution_, 0, false, false); static SwitchOption interfacePtDistributionDefault (interfacePtDistribution, "Default", "Default generation of pT", 0); static SwitchOption interfacePtDistributionOrdered (interfacePtDistribution, "Ordered", "Ordered generation of pT,where the first pT is the hardest", 1); static SwitchOption interfacePtDistributionStronglyOrdered (interfacePtDistribution, "StronglyOrdered", "Strongly ordered generation of pT", 2); static SwitchOption interfacePtDistributionFlat (interfacePtDistribution, "Flat", "Sample from a flat pT distribution", 3); static SwitchOption interfacePtDistributionFlatOrdered (interfacePtDistribution, "FlatOrdered", "First pT normal, then flat", 4); static SwitchOption interfacePtDistributionFlatOrdered2 (interfacePtDistribution, "FlatOrdered2", "First pT normal, then flat but steep", 5); } bool HwRemDecayer::canHandle(tcPDPtr particle, tcPDPtr parton) const { if(! (StandardQCDPartonMatcher::Check(*parton) || parton->id()==ParticleID::gamma) ) { if(abs(parton->id())==ParticleID::t) { if(!allowTop_) throw Exception() << "Top is not allow as a parton in the remant handling, please " << "use a PDF which does not contain top for the remnant" << " handling (preferred) or allow top in the remnant using\n" << " set " << fullName() << ":AllowTop Yes\n" << Exception::runerror; } else return false; } return HadronMatcher::Check(*particle) || particle->id()==ParticleID::gamma || particle->id()==ParticleID::pomeron || particle->id()==ParticleID::reggeon; } bool HwRemDecayer::isPartonic(tPPtr parton) const { if(parton->parents().empty()) return false; tPPtr parent = parton->parents()[0]; bool partonic = false; for(unsigned int ix=0;ixchildren().size();++ix) { if(dynamic_ptr_cast(parent->children()[ix])) { partonic = true; break; } } return partonic; } diff --git a/PDT/StandardMatchers.cc b/PDT/StandardMatchers.cc --- a/PDT/StandardMatchers.cc +++ b/PDT/StandardMatchers.cc @@ -1,31 +1,53 @@ // -*- C++ -*- // // StandardMatchers.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. // // // Ensures the StandardMatchers get created // #include "ThePEG/PDT/Matcher.h" #include "ThePEG/PDT/StandardMatchers.h" #include "StandardMatchers.h" using namespace Herwig; -using namespace ThePEG; + +#define THEPEG_MATCH_DESC(T) \ +/** \ + * This template specialization registers the Matcher \ + */ \ +template <> \ +NoPIOClassDescription T::initMatcher \ + = NoPIOClassDescription(); \ + + + +namespace ThePEG { + THEPEG_MATCH_DESC(MatchPhoton) + THEPEG_MATCH_DESC(MatchBottom) + THEPEG_MATCH_DESC(MatchTop) + THEPEG_MATCH_DESC(MatchHadron) + THEPEG_MATCH_DESC(MatchWBoson) + THEPEG_MATCH_DESC(MatchZBoson) + THEPEG_MATCH_DESC(MatchHiggsBoson) + THEPEG_MATCH_DESC(MatchChargedLepton) + THEPEG_MATCH_DESC(MatchLightParticle) +} namespace { + using namespace ThePEG; static MatchPhoton m00; static MatchBottom m01; static MatchTop m02; static MatchHadron m03; static MatchWBoson m04; static MatchZBoson m05; static MatchHiggsBoson m06; static MatchChargedLepton m07; static MatchLightParticle m08; } diff --git a/Shower/Dipole/Base/Dipole.cc b/Shower/Dipole/Base/Dipole.cc --- a/Shower/Dipole/Base/Dipole.cc +++ b/Shower/Dipole/Base/Dipole.cc @@ -1,455 +1,455 @@ // -*- C++ -*- // // Dipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2017 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the Dipole class. // #include "Dipole.h" #include "Herwig/Shower/Dipole/Utility/DipolePartonSplitter.h" using namespace Herwig; Dipole::Dipole() : theParticles(), thePDFs(), theFractions(1.0,1.0), theIndices(), theDecaying(false,false), theOffShell(false,false), theScales(0.0*GeV,0.0*GeV) {} Dipole::Dipole(const pair& newParticles, const pair& newPDFs, pair newFractions, pair newScales) : theParticles(newParticles), thePDFs(newPDFs), theFractions(newFractions), theIndices(), theDecaying(false,false), theOffShell(false,false), theScales(newScales) { theIndices.first = DipoleIndex(theParticles.first->dataPtr(), theParticles.second->dataPtr(), newPDFs.first,newPDFs.second, theDecaying.first,theDecaying.second, theOffShell.first,theOffShell.second); theIndices.second = theIndices.first; theIndices.second.swap(); } Dipole::Dipole(const pair& newParticles, const pair& newPDFs, pair newFractions, pair decaying, pair offShell, pair newScales) : theParticles(newParticles), thePDFs(newPDFs), theFractions(newFractions), theIndices(), theDecaying(decaying), theOffShell(offShell), theScales(newScales) { theIndices.first = DipoleIndex(theParticles.first->dataPtr(), theParticles.second->dataPtr(), newPDFs.first,newPDFs.second, theDecaying.first,theDecaying.second, theOffShell.first,theOffShell.second); theIndices.second = theIndices.first; theIndices.second.swap(); } void Dipole::update() { theIndices.first = DipoleIndex(theParticles.first->dataPtr(), theParticles.second->dataPtr(), thePDFs.first,thePDFs.second, theDecaying.first,theDecaying.second, theOffShell.first,theOffShell.second); theIndices.second = theIndices.first; theIndices.second.swap(); assert(DipolePartonSplitter::colourConnected(theParticles.first, theParticles.second)); } pair Dipole::split(DipoleSplittingInfo& dsplit, bool colourSpectator, - bool subleadingNc) const { + bool ) const { // check contracts assert(dsplit.splittingKinematics()); assert(dsplit.emitterData() && dsplit.emissionData() && dsplit.spectatorData()); if ( !colourSpectator ) { assert(index(dsplit.configuration()) == dsplit.index()); assert(emitterX(dsplit.configuration()) == dsplit.emitterX()); assert(spectatorX(dsplit.configuration()) == dsplit.spectatorX()); } else { assert(emitterX(dsplit.configuration()) == dsplit.emitterX()); assert(emitterPDF(dsplit.configuration()) == dsplit.index().emitterPDF()); assert((dsplit.configuration().first ? theParticles.first->dataPtr() : theParticles.second->dataPtr()) == dsplit.index().emitterData()); } // generate full kinematics dsplit.splittingKinematics()->generateKinematics( emitter(dsplit.configuration())->momentum(), spectator(dsplit.configuration())->momentum(), dsplit); // Treat the case of decay splittings as backward evolution. // i.e. Put the new emitter and new emission or new spectator // and new emission respectively into the new dipoles. bool emitter_decay = dsplit.index().incomingDecayEmitter(); if ( emitter_decay ) assert(false); bool spectator_decay = dsplit.index().incomingDecaySpectator(); tPPtr oldSpectator = spectator(dsplit.configuration()); PPtr newSpectator; // get a new spectator if ( !colourSpectator ) { newSpectator = dsplit.spectatorData()->produceParticle( dsplit.splittingKinematics()->lastSpectatorMomentum()); DipolePartonSplitter::change(oldSpectator, newSpectator, spectatorPDF(dsplit.configuration()).pdf(), spectator_decay); dsplit.spectator(oldSpectator); dsplit.splitSpectator(newSpectator); } else { newSpectator = oldSpectator; } // perform the splitting tPPtr oldEmitter = emitter(dsplit.configuration()); PPtr newEmitter, newEmission; double z = dsplit.lastZ(); // Do not swap momenta for splittings different from g->gg or // initial state emitters bool noSwap = !(dsplit.emitterData()->id() == ParticleID::g && dsplit.emissionData()->id() == ParticleID::g ) || dsplit.index().initialStateEmitter(); if ( noSwap || z > UseRandom::rnd(1.0) ) { newEmitter = dsplit.emitterData()->produceParticle( dsplit.splittingKinematics()->lastEmitterMomentum()); newEmission = dsplit.emissionData()->produceParticle( dsplit.splittingKinematics()->lastEmissionMomentum()); } else { newEmitter = dsplit.emitterData()->produceParticle( dsplit.splittingKinematics()->lastEmissionMomentum()); newEmission = dsplit.emissionData()->produceParticle( dsplit.splittingKinematics()->lastEmitterMomentum()); } newEmitter->scale(sqr(dsplit.lastPt())); newEmission->scale(sqr(dsplit.lastPt())); newSpectator->scale(oldSpectator->scale()); DipolePartonSplitter::split(oldEmitter,newEmitter,newEmission, oldSpectator,emitterPDF(dsplit.configuration()).pdf(), emitter_decay); dsplit.emitter(oldEmitter); dsplit.splitEmitter(newEmitter); dsplit.emission(newEmission); double emitter_x = emitterX(dsplit.configuration()) / dsplit.lastEmitterZ(); double spectator_x = spectatorX(dsplit.configuration()) / dsplit.lastSpectatorZ(); PDF emitter_pdf = emitterPDF(dsplit.configuration()); PDF spectator_pdf = spectatorPDF(dsplit.configuration()); // Communicate off-shell parton flags // Note that as gluons aren't off-shell, the only possibility // in qcd splittings is gluon emissions off an off-shell emitter // -> off-shell emitter => off-shell new emitter bool emitter_off_shell = dsplit.index().offShellEmitter(); bool spectator_off_shell = dsplit.index().offShellSpectator(); // now check how we need to arrange the children // assignment is 0 = emitter, 1 = emission, 2 = spectator int left = 0; int middle = 1; int right = 2; if (dsplit.configuration().first) { // spectator is unique right = 2; // middle is the one connecting to the spectator if (DipolePartonSplitter::colourConnected(newSpectator,newEmission)) { middle = 1; left = 0; } else { assert(DipolePartonSplitter::colourConnected(newSpectator,newEmitter)); middle = 0; left = 1; } } else { // spectator is unique left = 2; // middle is the one connecting to the spectator if (DipolePartonSplitter::colourConnected(newSpectator,newEmission)) { middle = 1; right = 0; } else { assert(DipolePartonSplitter::colourConnected(newSpectator,newEmitter)); middle = 0; right = 1; } } pair left_particles; pair right_particles; pair left_pdfs; pair right_pdfs; pair left_fractions; pair right_fractions; // Pairs containing indicators for decayed particles pair left_decays = {false,false}; pair right_decays = {false,false}; // Pairs containing indicators for off-shell particles pair left_off_shells = {false,false}; pair right_off_shells = {false,false}; switch (left) { case 0: if (emitter_decay) { assert(false); left_decays.first = emitter_decay; } left_particles.first = newEmitter; left_pdfs.first = emitter_pdf; left_fractions.first = emitter_x; left_off_shells.first = emitter_off_shell; break; case 1: left_particles.first = newEmission; left_pdfs.first = PDF(); left_fractions.first = 1.; left_decays.first = false; left_off_shells.first = false; break; case 2: left_particles.first = newSpectator; left_pdfs.first = spectator_pdf; left_fractions.first = spectator_x; left_decays.first = spectator_decay; left_off_shells.first = spectator_off_shell; break; } switch (middle) { case 0: if (emitter_decay) { assert(false); left_decays.second = emitter_decay; } left_particles.second = newEmitter; left_pdfs.second = emitter_pdf; left_fractions.second = emitter_x; left_off_shells.second = emitter_off_shell; break; case 1: left_particles.second = newEmission; left_pdfs.second = PDF(); left_fractions.second = 1.; left_decays.second = false; left_off_shells.second = false; break; case 2: left_decays.second = spectator_decay; left_particles.second = newSpectator; left_pdfs.second = spectator_pdf; left_fractions.second = spectator_x; left_off_shells.second = spectator_off_shell; break; } right_particles.first = left_particles.second; right_pdfs.first = left_pdfs.second; right_fractions.first = left_fractions.second; right_decays.first = left_decays.second; right_off_shells.first = left_off_shells.second; switch (right) { case 0: if (emitter_decay) { assert(false); right_decays.second = emitter_decay; } right_particles.second = newEmitter; right_pdfs.second = emitter_pdf; right_fractions.second = emitter_x; right_off_shells.second = emitter_off_shell; break; case 1: right_particles.second = newEmission; right_pdfs.second = PDF(); right_fractions.second = 1.; right_decays.second = false; right_off_shells.second = false; break; case 2: right_particles.second = newSpectator; right_pdfs.second = spectator_pdf; right_fractions.second = spectator_x; right_decays.second = spectator_decay; right_off_shells.second = spectator_off_shell; break; } Energy scale = dsplit.lastPt(); return { Dipole(left_particles, left_pdfs, left_fractions, left_decays, left_off_shells, {scale,scale}), Dipole(right_particles, right_pdfs, right_fractions, right_decays, right_off_shells, {scale,scale})}; } void Dipole::tmpsplit(DipoleSplittingInfo& dsplit, bool colourSpectator) const { // generate full kinematics dsplit.splittingKinematics()->generateKinematics(emitter(dsplit.configuration())->momentum(), spectator(dsplit.configuration())->momentum(), dsplit); tPPtr oldSpectator = spectator(dsplit.configuration()); PPtr newSpectator; // get a new spectator if ( !colourSpectator ) { newSpectator = dsplit.spectatorData()->produceParticle(dsplit.splittingKinematics()->lastSpectatorMomentum()); dsplit.spectator(oldSpectator); dsplit.splitSpectator(newSpectator); } else { newSpectator = oldSpectator; } // perform the splitting tPPtr oldEmitter = emitter(dsplit.configuration()); PPtr newEmitter = dsplit.emitterData()->produceParticle(dsplit.splittingKinematics()->lastEmitterMomentum()); PPtr newEmission = dsplit.emissionData()->produceParticle(dsplit.splittingKinematics()->lastEmissionMomentum()); dsplit.emitter(oldEmitter); dsplit.splitEmitter(newEmitter); dsplit.emission(newEmission); } void Dipole::recoil (DipoleSplittingInfo& dsplit) { // check contracts assert(dsplit.splittingKinematics()); assert(dsplit.spectatorData()); assert(spectatorX(dsplit.spectatorConfiguration()) == dsplit.spectatorX()); assert(spectatorPDF(dsplit.spectatorConfiguration()) == dsplit.index().spectatorPDF()); assert((dsplit.spectatorConfiguration().first ? theParticles.first->dataPtr() : theParticles.second->dataPtr()) == dsplit.index().spectatorData()); tPPtr oldSpectator = spectator(dsplit.spectatorConfiguration()); PPtr newSpectator = dsplit.spectatorData()->produceParticle( dsplit.splittingKinematics()->lastSpectatorMomentum()); DipolePartonSplitter::change(oldSpectator,newSpectator, spectatorPDF(dsplit.spectatorConfiguration()).pdf()); newSpectator->scale(sqr(dsplit.lastPt())); dsplit.spectator(oldSpectator); dsplit.splitSpectator(newSpectator); if ( dsplit.spectatorConfiguration().first ) { theParticles.second = newSpectator; theFractions.second /= dsplit.lastSpectatorZ(); } else { theParticles.first = newSpectator; theFractions.first /= dsplit.lastSpectatorZ(); } } void Dipole::print(ostream& os) const { os << "--- "; // Check for decays first if ( theDecaying.first || theDecaying.second) { assert(!(theDecaying.first && theDecaying.second)); if ( theDecaying.first && !theDecaying.second ) os << "Decay IF"; else if ( theDecaying.second && !theDecaying.first ) os << "Decay FI"; } else if ( !thePDFs.first.pdf() && !thePDFs.second.pdf() ) os << "FF"; else if ( thePDFs.first.pdf() && !thePDFs.second.pdf() ) os << "IF"; else if ( !thePDFs.first.pdf() && thePDFs.second.pdf() ) os << "FI"; else os << "II"; os << " Dipole ------------------------------------------------------------------\n"; if ( !theParticles.first || !theParticles.second ) { os << " *** This Dipole has not been setup properly. ***\n"; } else { os << " particles\n" << *theParticles.first << *theParticles.second; os << " scales/GeV = (" << (theScales.first/GeV) << "," << (theScales.second/GeV) << ") fractions = (" << theFractions.first << "," << theFractions.second << ")\n"; } os << "--------------------------------------------------------------------------------\n"; os << flush; } diff --git a/Shower/Dipole/Base/DipoleChain.cc b/Shower/Dipole/Base/DipoleChain.cc --- a/Shower/Dipole/Base/DipoleChain.cc +++ b/Shower/Dipole/Base/DipoleChain.cc @@ -1,342 +1,334 @@ // -*- C++ -*- // // DipoleChain.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 DipoleChain class. // #include "DipoleChain.h" #include "Herwig/Shower/Dipole/Utility/DipolePartonSplitter.h" -#include "Herwig/Shower/Dipole/Colorea/Colorea.h" #include using namespace Herwig; DipoleChain::DipoleChain() : ggSingleDipole(false) {} bool DipoleChain::circular () const { return (theDipoles.front().leftParticle() == theDipoles.back().rightParticle()); } bool DipoleChain::hasLeftNeighbour (list::const_iterator dc) const { if ( dc == dipoles().begin() ) return circular(); return true; } Dipole& DipoleChain::leftNeighbour (list::iterator dc) { assert(hasLeftNeighbour(dc)); if ( dc == dipoles().begin() ) return dipoles().back(); return *(--dc); } const Dipole& DipoleChain::leftNeighbour (list::const_iterator dc) const { assert(hasLeftNeighbour(dc)); if ( dc == dipoles().begin() ) return dipoles().back(); return *(--dc); } list::iterator DipoleChain::leftNeighbourIterator(list::iterator dc) { assert(hasLeftNeighbour(dc)); if ( dc == dipoles().begin() ) return --dipoles().end(); return --dc; } bool DipoleChain::hasRightNeighbour (list::const_iterator dc) const { if (dc == --dipoles().end()) return circular(); return true; } Dipole& DipoleChain::rightNeighbour (list::iterator dc) { assert(hasRightNeighbour(dc)); if ( dc == --dipoles().end() ) return dipoles().front(); return *(++dc); } const Dipole& DipoleChain::rightNeighbour (list::const_iterator dc) const { assert(hasRightNeighbour(dc)); if ( dc == --dipoles().end() ) return dipoles().front(); return *(++dc); } list::iterator DipoleChain::rightNeighbourIterator(list::iterator dc) { assert(hasRightNeighbour(dc)); if ( dc == --dipoles().end() ) return dipoles().begin(); return ++dc; } void DipoleChain::check() { if ( theDipoles.begin() == std::prev(theDipoles.end()) ) { if ( theDipoles.front().leftParticle()->hasColour() && theDipoles.front().leftParticle()->hasAntiColour() ) { assert(theDipoles.front().rightParticle()->hasColour() && theDipoles.front().rightParticle()->hasAntiColour()); ggSingleDipole = true; } } } - -void DipoleChain::rearrange(int dipmax,int diplong){ - static auto colorea = Colorea(); - colorea.setChain(this); - colorea.rearrange( dipmax, diplong); -} - list::iterator DipoleChain::insertSplitting(list::iterator emittingDipole, pair children, pair::iterator,list::iterator>& childIterators) { assert(DipolePartonSplitter::colourConnected(children.first.leftParticle(),children.first.rightParticle()) || DipolePartonSplitter::colourConnected(children.second.leftParticle(),children.second.rightParticle())); bool was_circular = circular(); if (hasLeftNeighbour(emittingDipole)) { list::iterator theLeftNeighbour = leftNeighbourIterator(emittingDipole); theLeftNeighbour->rightParticle(children.first.leftParticle()); if ( children.first.leftParticle()->scale() < sqr(theLeftNeighbour->rightScale()) ) theLeftNeighbour->rightScale(sqrt(children.first.leftParticle()->scale())); theLeftNeighbour->rightPDF(children.first.leftPDF()); theLeftNeighbour->rightFraction(children.first.leftFraction()); theLeftNeighbour->rightDecaying(children.first.leftDecaying()); theLeftNeighbour->update(); } if (hasRightNeighbour(emittingDipole)) { list::iterator theRightNeighbour = rightNeighbourIterator(emittingDipole); theRightNeighbour->leftParticle(children.second.rightParticle()); if ( children.second.rightParticle()->scale() < sqr(theRightNeighbour->leftScale()) ) theRightNeighbour->leftScale(sqrt(children.second.rightParticle()->scale())); theRightNeighbour->leftPDF(children.second.rightPDF()); theRightNeighbour->leftFraction(children.second.rightFraction()); theRightNeighbour->leftDecaying(children.second.rightDecaying()); theRightNeighbour->update(); } if (DipolePartonSplitter::colourConnected(children.first.leftParticle(),children.first.rightParticle()) && DipolePartonSplitter::colourConnected(children.second.leftParticle(),children.second.rightParticle())) { // nothing special to do, just replace the emitting dipole // by the right one and insert the left one before it *emittingDipole = children.second; childIterators.second = emittingDipole; childIterators.first = dipoles().insert(emittingDipole,children.first); if ( ggSingleDipole ) { ggSingleDipole = false; Dipole miss; miss.leftParticle(dipoles().back().rightParticle()); miss.rightParticle(dipoles().front().leftParticle()); miss.leftScale(dipoles().back().rightScale()); miss.rightScale(dipoles().front().leftScale()); miss.leftPDF(dipoles().back().rightPDF()); miss.rightPDF(dipoles().front().leftPDF()); miss.leftFraction(dipoles().back().rightFraction()); miss.rightFraction(dipoles().front().leftFraction()); miss.leftDecaying(dipoles().back().rightDecaying()); miss.rightDecaying(dipoles().front().leftDecaying()); miss.update(); dipoles().push_back(miss); } return dipoles().end(); } if (!DipolePartonSplitter::colourConnected(children.first.leftParticle(),children.first.rightParticle())) { if ( !was_circular && !ggSingleDipole ) { *emittingDipole = children.second; childIterators.second = emittingDipole; assert(emittingDipole != dipoles().begin()); childIterators.first = std::prev(emittingDipole); return emittingDipole; } *emittingDipole = children.second; if ( ggSingleDipole ) { ggSingleDipole = false; Dipole miss; miss.leftParticle(children.second.rightParticle()); miss.rightParticle(children.first.leftParticle()); miss.leftScale(children.second.rightScale()); miss.rightScale(children.first.leftScale()); miss.leftPDF(children.second.rightPDF()); miss.rightPDF(children.first.leftPDF()); miss.leftFraction(children.second.rightFraction()); miss.rightFraction(children.first.leftFraction()); miss.leftDecaying(dipoles().back().rightDecaying()); miss.rightDecaying(dipoles().front().leftDecaying()); miss.update(); dipoles().push_back(miss); childIterators.first = dipoles().begin(); childIterators.second = std::prev(dipoles().end()); return dipoles().end(); } childIterators.second = emittingDipole; if ( emittingDipole == dipoles().begin() ) childIterators.first = --dipoles().end(); else childIterators.first = std::prev(emittingDipole); if ( emittingDipole == dipoles().begin() ) return dipoles().end(); dipoles().splice(dipoles().begin(),dipoles(),emittingDipole,dipoles().end()); // explicitly fix iterators in case the splice implementation // at hand does invalidate iterators (the SGI docu says, it doesn't, // but it seems that this behaviour is not part of the standard) childIterators.second = dipoles().begin(); childIterators.first = --dipoles().end(); return dipoles().end(); } if (!DipolePartonSplitter::colourConnected(children.second.leftParticle(),children.second.rightParticle())) { if ( !was_circular && !ggSingleDipole ) { *emittingDipole = children.first; childIterators.first = emittingDipole; assert(emittingDipole != --dipoles().end()); childIterators.second = std::next(emittingDipole); return std::next(emittingDipole); } *emittingDipole = children.first; if ( ggSingleDipole ) { ggSingleDipole = false; Dipole miss; miss.leftParticle(children.second.rightParticle()); miss.rightParticle(children.first.leftParticle()); miss.leftScale(children.second.rightScale()); miss.rightScale(children.first.leftScale()); miss.leftPDF(children.second.rightPDF()); miss.rightPDF(children.first.leftPDF()); miss.leftFraction(children.second.rightFraction()); miss.rightFraction(children.first.leftFraction()); miss.leftDecaying(dipoles().back().rightDecaying()); miss.rightDecaying(dipoles().front().leftDecaying()); miss.update(); dipoles().push_front(miss); childIterators.first = dipoles().begin(); childIterators.second = std::prev(dipoles().end()); return dipoles().end(); } childIterators.first = emittingDipole; if ( emittingDipole == --dipoles().end() ) childIterators.second = dipoles().begin(); else childIterators.second = std::next(emittingDipole); if ( emittingDipole == --dipoles().end() ) return dipoles().end(); dipoles().splice(dipoles().begin(),dipoles(),std::next(emittingDipole),dipoles().end()); // explicitly fix iterators in case the splice implementation // at hand does invalidate iterators (the SGI docu says, it doesn't, // but it seems that this behaviour is not part of the standard) childIterators.first = dipoles().begin(); childIterators.second = --dipoles().end(); return dipoles().end(); } return dipoles().end(); } void DipoleChain::updateDipole(list::iterator dip) { dip->update(); if (hasLeftNeighbour(dip)) { list::iterator theLeftNeighbour = leftNeighbourIterator(dip); theLeftNeighbour->rightParticle(dip->leftParticle()); theLeftNeighbour->rightPDF(dip->leftPDF()); theLeftNeighbour->rightFraction(dip->leftFraction()); theLeftNeighbour->rightDecaying(dip->leftDecaying()); theLeftNeighbour->update(); } if (hasRightNeighbour(dip)) { list::iterator theRightNeighbour = rightNeighbourIterator(dip); theRightNeighbour->leftParticle(dip->rightParticle()); theRightNeighbour->leftPDF(dip->rightPDF()); theRightNeighbour->leftFraction(dip->rightFraction()); theRightNeighbour->leftDecaying(dip->rightDecaying()); theRightNeighbour->update(); } } void DipoleChain::print(ostream& os) const { os << "--- DipoleChain ----------------------------------------------------------------\n"; if ( theDipoles.empty() ) { os << " *** This DipoleChain is empty. ***\n"; } else { os << " " << (!circular() ? "non-" : "") << "circular with " << theDipoles.size() << " dipoles\n"; for (list::const_iterator dit = theDipoles.begin(); dit != theDipoles.end(); ++dit) { os << (*dit); } } os << "--------------------------------------------------------------------------------\n"; os << flush; } diff --git a/Shower/Dipole/Base/DipoleChain.h b/Shower/Dipole/Base/DipoleChain.h --- a/Shower/Dipole/Base/DipoleChain.h +++ b/Shower/Dipole/Base/DipoleChain.h @@ -1,158 +1,153 @@ // -*- C++ -*- // // DipoleChain.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_DipoleChain_H #define HERWIG_DipoleChain_H // // This is the declaration of the DipoleChain class. // #include "Dipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup DipoleShower * \author Simon Platzer * * \brief The DipoleChain class is used by the dipole shower to * represent a chain of dipoles. * */ class DipoleChain { public: /** * Default constructor */ DipoleChain(); /** * Return true, if this chain is circular. */ bool circular () const; /* * Return true, if the dipole referred to * has a left neighbour */ bool hasLeftNeighbour(list::const_iterator dc) const; /* * Return a reference to the left neighbour, * if existing */ Dipole& leftNeighbour(list::iterator dc); /* * Return a const reference to the left neighbour, * if existing */ const Dipole& leftNeighbour(list::const_iterator dc) const; /** * Return an iterator to the left neighbour */ list::iterator leftNeighbourIterator(list::iterator dc); /* * Return true, if the dipole referred to * has a right neighbour */ bool hasRightNeighbour (list::const_iterator dc) const; /* * Return a reference to the right neighbour, * if existing */ Dipole& rightNeighbour (list::iterator dc); /* * Return a const reference to the right neighbour, * if existing */ const Dipole& rightNeighbour (list::const_iterator dc) const; /** * Return an iterator to the right neighbour */ list::iterator rightNeighbourIterator(list::iterator dc); public: /** * Access the dipole list */ list& dipoles() { return theDipoles; } /** * Return the dipole list */ const list& dipoles() const { return theDipoles; } /** * Check for gg single dipole */ void check(); - /** - * Rearrange the dipole chain (arXiv:1801.06113). - */ - void rearrange(int dipmax,int diplong); - public: /* * Insert the given splitting; if this contains a chain-breakup emission and * the chain is circular, reshuffle the chain to make it non-circular; if it is * already non-circular return the iterator starting the new chain. If no * splitting is needed return the end iterator of the dipole list. * Set the iterators pointing to the children dipoles. */ list::iterator insertSplitting(list::iterator emittingDipole, pair children, pair::iterator,list::iterator>& childIterators); /** * Indicate a change in the given dipole. */ void updateDipole(list::iterator dip); public: /** * Put information to ostream */ void print(ostream&) const; private: /** * The dipoles contained in this chain */ list theDipoles; /** * Switch on special treatment for * gg single dipole */ bool ggSingleDipole; }; inline ostream& operator << (ostream& os, const DipoleChain& di) { di.print(os); return os; } } #endif /* HERWIG_DipoleChain_H */ diff --git a/Shower/Dipole/Base/DipoleEventRecord.cc b/Shower/Dipole/Base/DipoleEventRecord.cc --- a/Shower/Dipole/Base/DipoleEventRecord.cc +++ b/Shower/Dipole/Base/DipoleEventRecord.cc @@ -1,1965 +1,1965 @@ // -*- C++ -*- // // DipoleEventRecord.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 DipoleEventRecord class. // #include "DipoleEventRecord.h" #include "Herwig/Shower/Dipole/DipoleShowerHandler.h" #include "Herwig/Shower/Dipole/Utility/DipolePartonSplitter.h" #include "Herwig/Shower/ShowerHandler.h" #include "ThePEG/PDT/DecayMode.h" #include "Herwig/Decay/HwDecayerBase.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/PDF/PartonExtractor.h" #include "Herwig/Shower/RealEmissionProcess.h" #include "Herwig/MatrixElement/Matchbox/Base/MatchboxMEBase.h" #include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h" #include #include #include using namespace Herwig; PList DipoleEventRecord::colourOrdered(PPair & in, PList & out) { PList colour_ordered; size_t done_size = out.size(); if (in.first->coloured()) ++done_size; if (in.second && in.second->coloured()) ++done_size; while (colour_ordered.size() != done_size) { PPtr current; // start with singlets, as long as we have some if (find(colour_ordered.begin(),colour_ordered.end(),in.first) == colour_ordered.end() && in.first->coloured()) { if (!in.first->hasColour() || !in.first->hasAntiColour()) current = in.first; } if (!current) { for (PList::iterator p = out.begin(); p != out.end(); ++p) { if (find(colour_ordered.begin(),colour_ordered.end(),*p) == colour_ordered.end() && (**p).coloured()) { if (!(**p).hasColour() || !(**p).hasAntiColour()) { current = *p; break; } } } } if (!current) { if (in.second && find(colour_ordered.begin(),colour_ordered.end(),in.second) == colour_ordered.end() && in.second->coloured()) { if (!in.second->hasColour() || !in.second->hasAntiColour()) current = in.second; } } // then go on with anything else if (!current) { if (find(colour_ordered.begin(),colour_ordered.end(),in.first) == colour_ordered.end() && in.first->coloured()) { current = in.first; } } if (!current) { for (PList::iterator p = out.begin(); p != out.end(); ++p) { if (find(colour_ordered.begin(),colour_ordered.end(),*p) == colour_ordered.end() && (**p).coloured()) { current = *p; break; } } } if (!current) { if (in.second && find(colour_ordered.begin(),colour_ordered.end(),in.second) == colour_ordered.end() && in.second->coloured()) { current = in.second; } } assert(current); PPtr next; Ptr::ptr walk_the_line; while (true) { if (!walk_the_line) { if (current->hasColour()) { walk_the_line = current->colourLine(); } else if (current->hasAntiColour()) { walk_the_line = current->antiColourLine(); } } if (!next) for (tPVector::const_iterator p = walk_the_line->coloured().begin(); p != walk_the_line->coloured().end(); ++p) { if (*p == current) continue; if (find(out.begin(),out.end(),*p) != out.end() || *p == in.first || (in.second && *p == in.second)) { next = *p; if (next->hasColour() && next->hasAntiColour()) { walk_the_line = walk_the_line == next->colourLine() ? next->antiColourLine() : next->colourLine(); } break; } } if (!next) for (tPVector::const_iterator p = walk_the_line->antiColoured().begin(); p != walk_the_line->antiColoured().end(); ++p) { if (*p == current) continue; if (find(out.begin(),out.end(),*p) != out.end() || *p == in.first || (in.second && *p == in.second)) { next = *p; if (next->hasColour() && next->hasAntiColour()) { walk_the_line = walk_the_line == next->colourLine() ? next->antiColourLine() : next->colourLine(); } break; } } assert(next); colour_ordered.push_back(current); current = next; // done if next is not a gluon or next is already in colour_ordered if ((current->hasColour() && !current->hasAntiColour()) || (!current->hasColour() && current->hasAntiColour())) { colour_ordered.push_back(current); break; } if (next->hasColour() && next->hasAntiColour()) { if (find(colour_ordered.begin(),colour_ordered.end(),next) != colour_ordered.end()) break; } next = PPtr(); } } return colour_ordered; } void DipoleEventRecord::popChain() { assert(!theChains.empty()); theDoneChains.push_back(DipoleChain()); theDoneChains.back().dipoles().splice(theDoneChains.back().dipoles().begin(),theChains.front().dipoles()); theChains.pop_front(); } void DipoleEventRecord::popChain(list::iterator ch) { assert(!theChains.empty()); theDoneChains.push_back(DipoleChain()); theDoneChains.back().dipoles().splice(theDoneChains.back().dipoles().begin(),ch->dipoles()); theChains.erase(ch); } void DipoleEventRecord::popChains(const list::iterator>& chs) { assert(!theChains.empty()); for ( list::iterator>::const_iterator ch = chs.begin(); ch != chs.end(); ++ch ) { theDoneChains.push_back(DipoleChain()); theDoneChains.back().dipoles().splice(theDoneChains.back().dipoles().begin(),(*ch)->dipoles()); } for ( list::iterator>::const_iterator ch = chs.begin(); ch != chs.end(); ++ch ) theChains.erase(*ch); } DipoleIndex DipoleEventRecord::mergeIndex(list::iterator firstDipole, const pair& whichFirst, list::iterator secondDipole, const pair& whichSecond) const { tcPDPtr emitterData = whichFirst.first ? firstDipole->leftParticle()->dataPtr() : firstDipole->rightParticle()->dataPtr(); tcPDPtr spectatorData = whichSecond.first ? secondDipole->leftParticle()->dataPtr() : secondDipole->rightParticle()->dataPtr(); const PDF& emitterPDF = whichFirst.first ? firstDipole->leftPDF() : firstDipole->rightPDF(); const PDF& spectatorPDF = whichSecond.first ? secondDipole->leftPDF() : secondDipole->rightPDF(); return DipoleIndex(emitterData,spectatorData,emitterPDF,spectatorPDF); } SubleadingSplittingInfo DipoleEventRecord::mergeSplittingInfo(list::iterator firstChain, list::iterator firstDipole, const pair& whichFirst, list::iterator secondChain, list::iterator secondDipole, const pair& whichSecond) const { SubleadingSplittingInfo res; res.index(mergeIndex(firstDipole,whichFirst,secondDipole,whichSecond)); res.emitter(whichFirst.first ? firstDipole->leftParticle() : firstDipole->rightParticle()); res.spectator(whichSecond.first ? secondDipole->leftParticle() : secondDipole->rightParticle()); res.emitterX(whichFirst.first ? firstDipole->leftFraction() : firstDipole->rightFraction()); res.spectatorX(whichSecond.first ? secondDipole->leftFraction() : secondDipole->rightFraction()); res.configuration(whichFirst); res.spectatorConfiguration(whichSecond); res.emitterChain(firstChain); res.emitterDipole(firstDipole); res.spectatorChain(secondChain); res.spectatorDipole(secondDipole); return res; } void DipoleEventRecord::getSubleadingSplittings(list& res) { static pair left(true,false); static pair right(false,true); res.clear(); for ( list::iterator cit = theChains.begin(); cit != theChains.end(); ++cit ) { for ( list::iterator dit = cit->dipoles().begin(); dit != cit->dipoles().end(); ++dit ) { for ( list::iterator djt = dit; djt != cit->dipoles().end(); ++djt ) { res.push_back(mergeSplittingInfo(cit,dit,left,cit,djt,left)); res.push_back(mergeSplittingInfo(cit,dit,right,cit,djt,right)); if ( dit != djt ) { res.push_back(mergeSplittingInfo(cit,dit,left,cit,djt,right)); res.push_back(mergeSplittingInfo(cit,dit,right,cit,djt,left)); } } } list::iterator cjt = cit; ++cjt; for ( ; cjt != theChains.end(); ++cjt ) { for ( list::iterator dit = cit->dipoles().begin(); dit != cit->dipoles().end(); ++dit ) { for ( list::iterator djt = cjt->dipoles().begin(); djt != cjt->dipoles().end(); ++djt ) { res.push_back(mergeSplittingInfo(cit,dit,left,cjt,djt,left)); res.push_back(mergeSplittingInfo(cit,dit,right,cjt,djt,right)); res.push_back(mergeSplittingInfo(cit,dit,left,cjt,djt,right)); res.push_back(mergeSplittingInfo(cit,dit,right,cjt,djt,left)); } } } } } void DipoleEventRecord::splitSubleading(SubleadingSplittingInfo& dsplit, pair::iterator,list::iterator>& childIterators, DipoleChain*& firstChain, DipoleChain*& secondChain) { if ( dsplit.emitterDipole() == dsplit.spectatorDipole() ) { assert(dsplit.emitterChain() == dsplit.spectatorChain()); split(dsplit.emitterDipole(),dsplit.emitterChain(),dsplit, childIterators,firstChain,secondChain,false); } else { // first need to recoil, then split recoil(dsplit.spectatorDipole(),dsplit.spectatorChain(),dsplit); split(dsplit.emitterDipole(),dsplit.emitterChain(),dsplit, childIterators,firstChain,secondChain,true); } } void DipoleEventRecord::findChains(const PList& ordered, const set& offShellPartons, const bool decay) { // All uses of findChains should guarantee // a non-empty list of particles assert( !ordered.empty() ); theChains.clear(); theDoneChains.clear(); DipoleChain current_chain; // this whole thing needs to have a more elegant implementation at some point bool startIsTriplet = (ordered.front()->hasColour() && !ordered.front()->hasAntiColour()) || (!ordered.front()->hasColour() && ordered.front()->hasAntiColour()); bool endIsTriplet = (ordered.back()->hasColour() && !ordered.back()->hasAntiColour()) || (!ordered.back()->hasColour() && ordered.back()->hasAntiColour()); if (!( ordered.size() == 2 && startIsTriplet && endIsTriplet)) { PList::const_iterator theStart = ordered.begin(); bool onceMore = false; for (PList::const_iterator p = ordered.begin(); p != ordered.end(); ++p) { PList::const_iterator next_it = p != --ordered.end() ? std::next(p) : ordered.begin(); if (!DipolePartonSplitter::colourConnected(*p,*next_it)) { // it may have happened that we need to close the chain due to another // chain starting right now; see the above global comment for this fix bool startIsOctet = (**theStart).hasColour() && (**theStart).hasAntiColour(); bool endIsOctet = (**p).hasColour() && (**p).hasAntiColour(); if ( DipolePartonSplitter::colourConnected(*p,*theStart) && startIsOctet && endIsOctet ) { swap(next_it,theStart); onceMore = true; } else { theStart = next_it; current_chain.check(); // Randomize the chains agains biasing of directions. if(UseRandom::rndbool()) theChains.push_back(current_chain); else theChains.insert(theChains.begin(),current_chain); current_chain.dipoles().clear(); continue; } } pair initial_state (false,false); initial_state.first = (*p == incoming().first || *p == incoming().second); initial_state.second = (*next_it == incoming().first || *next_it == incoming().second); pair which_in (-1,-1); if (initial_state.first) which_in.first = *p == incoming().first ? 0 : 1; if (initial_state.second) which_in.second = *next_it == incoming().first ? 0 : 1; pair xs (1.,1.); if (initial_state.first) xs.first = *p == incoming().first ? fractions().first : fractions().second; if (initial_state.second) xs.second = *next_it == incoming().first ? fractions().first : fractions().second; pair pdf; if ( which_in.first == 0 ) pdf.first = pdfs().first; else if ( which_in.first == 1 ) pdf.first = pdfs().second; if ( which_in.second == 0 ) pdf.second = pdfs().first; else if ( which_in.second == 1 ) pdf.second = pdfs().second; // In the case of a decay process register which // parton is incoming to the decay pair decayed_parton (false,false); if (decay) { decayed_parton.first = (*p == currentDecay()->incoming()[0].first); decayed_parton.second = (*next_it == currentDecay()->incoming()[0].first); } // Identify if either parton can have an off-shell mass // The first test for partons with zero nominal mass should // avoid issues of e.g. non-zero mass gluons pair off_shell (false,false); // Note we could do away with the offShellPartons set but, // to be safe in the case of an off-shell parton with a mass // *very* close to its on-shell mass, we would need to include tests on the // offShell indicators in the DipoleIndex == and < operators AND // in canHandle and canHandleEquivalent in each massive kernel. // Testing these in every splitting will probably be more expensive // than doing the following checks for each hard process and decay process // Only do off-shell check if the nominal mass is non-zero if ( (*p)->nominalMass() != ZERO ) { if ( offShellPartons.find(abs((*p)->id())) != offShellPartons.end() ) off_shell.first = true; else assert( abs((*p)->mass() - (*p)->nominalMass()) < (*p)->nominalMass()*1.e-5 && "There is an off-shell coloured particle in the hard process or a decay" "which needs to be added to DipoleShowerHandler:OffShellInShower." ); } if ( (*next_it)->nominalMass() != ZERO ) { if ( offShellPartons.find(abs((*next_it)->id())) != offShellPartons.end() ) off_shell.second = true; else assert( abs((*next_it)->mass() - (*next_it)->nominalMass()) < (*next_it)->nominalMass()*1.e-5 && "There is an off-shell coloured particle in the hard process or a decay" "which needs to be added to DipoleShowerHandler:OffShellInShower." ); } current_chain.dipoles().push_back(Dipole({*p,*next_it},pdf,xs, decayed_parton, off_shell)); if ( onceMore ) { next_it = theStart; current_chain.check(); // Randomize the chains agains biasing of directions. if(UseRandom::rndbool()) theChains.push_back(current_chain); else theChains.insert(theChains.begin(),current_chain); current_chain.dipoles().clear(); onceMore = false; } } } else { // treat 2 -> singlet, singlet -> 2 and 1 + singlet -> 1 + singlet special // to prevent duplicate dipole assert(DipolePartonSplitter::colourConnected(ordered.front(),ordered.back())); pair initial_state (false,false); initial_state.first = (ordered.front() == incoming().first || ordered.front() == incoming().second); initial_state.second = (ordered.back() == incoming().first || ordered.back() == incoming().second); pair which_in (-1,-1); if (initial_state.first) which_in.first = ordered.front() == incoming().first ? 0 : 1; if (initial_state.second) which_in.second = ordered.back() == incoming().first ? 0 : 1; pair xs (1.,1.); if (initial_state.first) xs.first = ordered.front() == incoming().first ? fractions().first : fractions().second; if (initial_state.second) xs.second = ordered.back() == incoming().first ? fractions().first : fractions().second; pair pdf; if ( which_in.first == 0 ) pdf.first = pdfs().first; else if ( which_in.first == 1 ) pdf.first = pdfs().second; if ( which_in.second == 0 ) pdf.second = pdfs().first; else if ( which_in.second == 1 ) pdf.second = pdfs().second; // In the case of a decay process register which // parton is incoming to the decay pair decayed_parton (false,false); if (decay) { decayed_parton.first = (ordered.front() == currentDecay()->incoming()[0].first); decayed_parton.second = (ordered.back() == currentDecay()->incoming()[0].first); } // Identify if either parton can have an off-shell mass // The first test for partons with zero nominal mass should // avoid issues of e.g. non-zero mass gluons pair off_shell (false,false); // Only do off-shell check if the nominal mass is non-zero if ( ordered.front()->nominalMass() != ZERO ) { if ( offShellPartons.find(abs(ordered.front()->id())) != offShellPartons.end() ) off_shell.first = true; else assert( abs(ordered.front()->mass() - ordered.front()->nominalMass()) < ordered.front()->nominalMass()*1.e-5 && "There is an off-shell coloured particle in the hard process or a decay" "which needs to be added to DipoleShowerHandler:OffShellInShower." ); } if ( ordered.back()->nominalMass() != ZERO ) { if ( offShellPartons.find(abs(ordered.back()->id())) != offShellPartons.end() ) off_shell.second = true; else assert( abs(ordered.back()->mass() - ordered.back()->nominalMass()) < ordered.back()->nominalMass()*1.e-5 && "There is an off-shell coloured particle in the hard process or a decay" "which needs to be added to DipoleShowerHandler:OffShellInShower." ); } current_chain.dipoles().push_back(Dipole({ordered.front(),ordered.back()}, pdf,xs, decayed_parton, off_shell)); } if (!current_chain.dipoles().empty()) { current_chain.check(); // Randomize the chains agains biasing of directions. if(UseRandom::rndbool()) theChains.push_back(current_chain); else theChains.insert(theChains.begin(),current_chain); } } const map& DipoleEventRecord::prepare(tSubProPtr subpro, tStdXCombPtr xc, StepPtr step, const pair& pdf,tPPair beam, bool firstInteraction, const set& offShellPartons, bool dipoles) { // set the subprocess subProcess(subpro); // clear the event record outgoing().clear(); theHard.clear(); theOriginals.clear(); theDecays.clear(); theCurrentDecay = PerturbativeProcessPtr(); subEmDone = 0; if ( doSubleadingNc && firstInteraction ) { theDensityOperator.clear(); continueSubleadingNc = true; const Ptr::tptr MBXCombPtr = dynamic_ptr_cast::tptr >(xc); if ( !MBXCombPtr ) { throw Exception() << "Cannot cast StandardXComb as MatchboxXComb. " << "Matchbox is required for " << "colour matrix element corrections." << Exception::runerror; } // Set the colour basis if it has not been set if ( !theDensityOperator.colourBasis() ) { theDensityOperator.colourBasis(MBXCombPtr->matchboxME()->matchboxAmplitude()->colourBasis()); } else if ( theDensityOperator.colourBasis() != MBXCombPtr->matchboxME()->matchboxAmplitude()->colourBasis() ) { throw Exception() << "The colour basis used in the colour matrix " << "element corrections should not change between events. " << Exception::runerror; } } else { continueSubleadingNc = false; } // extract incoming particles PPair in = subpro->incoming(); // get the incoming momentum fractions // don't take these from the XComb as it may be null pair xs; ThePEG::Direction<0> dir(true); xs.first = in.first->momentum().dirPlus()/beam.first->momentum().dirPlus(); dir.reverse(); xs.second = in.second->momentum().dirPlus()/beam.second->momentum().dirPlus(); xcombPtr(xc); pdfs() = pdf; fractions() = xs; // use ShowerHandler to split up the hard process PerturbativeProcessPtr hard; DecayProcessMap decay; // Special handling for the first interaction: // If a post subprocess handler (e.g. QED radiation) // is applied, there may be particles in the step object not // present in the subprocess object (other than any remnants). // These need to be included in any transformations due to // II splittings in ::update. if ( firstInteraction ) { // Initialise a PVector for the outgoing tPVector hardProcOutgoing; // Include all outgoing particles that are not remnants for ( auto & part : step->particles() ) if ( part->id() != 82 ) { hardProcOutgoing.push_back(part); } ShowerHandler::currentHandler()->splitHardProcess(hardProcOutgoing, hard, decay); } // For secondary collisions we must use the // subProcess object and not the step as the // step stores all outgoing from the entire collision else ShowerHandler::currentHandler()->splitHardProcess(tPVector(subpro->outgoing().begin(), subpro->outgoing().end()), hard,decay); // vectors for originals and copies of the particles vector original; vector copies; // fill originals for(unsigned int ix=0;ix<2;++ix) original.push_back(hard->incoming()[ix].first); for(unsigned int ix=0;ixoutgoing().size();++ix) original.push_back(hard->outgoing()[ix].first); for(DecayProcessMap::const_iterator it=decay.begin();it!=decay.end();++it) { fillFromDecays(it->second, original); } // and make copies for ( vector::const_iterator p = original.begin(); p != original.end(); ++p ) { PPtr copy = new_ptr(Particle(**p)); copies.push_back(copy); theOriginals[*p] = copy; } // isolate the colour of the copies from the originals colourIsolate(original,copies); // set the incoming particles incoming().first = copies[0]; ParticleVector children = incoming().first->children(); for ( ParticleVector::const_iterator c = children.begin(); c != children.end(); ++c ) incoming().first->abandonChild(*c); incoming().second = copies[1]; children = incoming().second->children(); for ( ParticleVector::const_iterator c = children.begin(); c != children.end(); ++c ) incoming().second->abandonChild(*c); // set the outgoing particles for the hard process for(unsigned int ix=0;ixoutgoing().size();++ix) { if(hard->outgoing()[ix].first->coloured()) outgoing().push_back(theOriginals[hard->outgoing()[ix].first]); else theHard.push_back(theOriginals[hard->outgoing()[ix].first]); } if ( dipoles ) { PList cordered = colourOrdered(incoming(),outgoing()); if ( !cordered.empty() ) findChains(cordered, offShellPartons, false); } // sort out the decays for(auto const & dec : decay) { // If the decay particle is in original it needs // to be added to the decays and the decay needs to be // changed to the copied particles. if ( theOriginals.find(dec.second->incoming()[0].first) != theOriginals.end() ) { theDecays[theOriginals[dec.second->incoming()[0].first]] = dec.second; PerturbativeProcessPtr decayProc = theDecays[theOriginals[dec.second->incoming()[0].first]]; separateDecay(decayProc); } else { assert( find( copies.begin(), copies.end(), dec.second->incoming()[0].first ) != copies.end() ); theDecays[dec.second->incoming()[0].first] = dec.second; } } PList::const_iterator XFirst, XLast; if ( !theHard.empty() ) { XFirst = theHard.begin(); XLast = theHard.end(); } else { XFirst = outgoing().begin(); XLast = outgoing().end(); } thePX = (**XFirst).momentum(); ++XFirst; for ( ; XFirst != XLast; ++XFirst ) thePX += (**XFirst).momentum(); identifyEventType(); if ( doSubleadingNc ) { theParticlesBefore.clear(); theParticlesAfter.clear(); theMomentaAfter.clear(); theParticleIndices.clear(); // Set the particles and fill the dictionary theParticleIndices[incoming().first] = 0; theParticleIndices[incoming().second] = 1; size_t i = 2; theParticlesAfter.reserve(2 + outgoing().size() + theHard.size()); theParticlesAfter.push_back(incoming().first->dataPtr()); theParticlesAfter.push_back(incoming().second->dataPtr()); theMomentaAfter.push_back(incoming().first->momentum()); theMomentaAfter.push_back(incoming().second->momentum()); for ( PList::const_iterator it = outgoing().begin(); it != outgoing().end(); it++ ) { theParticlesAfter.push_back((*it)->dataPtr()); theMomentaAfter.push_back((*it)->momentum()); theParticleIndices[*it] = i; i++; } // theHard is not added to theParticleIndices, as they aren't needed there for ( PList::const_iterator it = theHard.begin(); it != theHard.end(); it++ ) { theParticlesAfter.push_back((*it)->dataPtr()); theMomentaAfter.push_back((*it)->momentum()); } // theParticlesAfter is required for fill const Ptr::tptr MBXCombPtr = dynamic_ptr_cast::tptr >(xc); if ( !MBXCombPtr ) { throw Exception() << "Cannot cast StandardXComb as MatchboxXComb. " << "Matchbox is required for " << "colour matrix element corrections." << Exception::runerror; } theDensityOperator.fill(MBXCombPtr,theParticlesAfter,theMomentaAfter); } return theOriginals; } void DipoleEventRecord::slimprepare(tSubProPtr subpro, tStdXCombPtr xc, const pair& pdf,tPPair beam, const set& offShellPartons, bool dipoles) { // set the subprocess subProcess(subpro); // clear the event record outgoing().clear(); theHard.clear(); theOriginals.clear(); theDecays.clear(); theCurrentDecay = PerturbativeProcessPtr(); // extract incoming particles PPair in = subpro->incoming(); // get the beam // get the incoming momentum fractions // don't take these from the XComb as it may be null pair xs; ThePEG::Direction<0> dir(true); xs.first = in.first->momentum().dirPlus()/beam.first->momentum().dirPlus(); dir.reverse(); xs.second = in.second->momentum().dirPlus()/beam.second->momentum().dirPlus(); xcombPtr(xc); pdfs() = pdf; fractions() = xs; incoming() = in; for(unsigned int ix=0;ixoutgoing().size();++ix) { if(subpro->outgoing()[ix]->coloured()) outgoing().push_back(subpro->outgoing()[ix]); } if ( dipoles ) { PList cordered = colourOrdered(incoming(),outgoing()); if ( !cordered.empty() ) findChains(cordered, offShellPartons, false); } } void DipoleEventRecord::fillFromDecays(PerturbativeProcessPtr decayProc, vector& original) { // Loop over the outgoing of the given perturbative process for ( auto const & outIt : decayProc->outgoing() ) { // Add the outgoing particle to the vector of original particles original.push_back(outIt.first); // Iterate through the outgoing if ( outIt.second ) fillFromDecays( outIt.second, original); } } void DipoleEventRecord::separateDecay(PerturbativeProcessPtr decayProc) { // Iteratively replace all entries in the incoming // with their copies. for ( auto & inIt : decayProc->incoming() ) { if ( theOriginals.find( inIt.first ) != theOriginals.end() ) inIt.first = theOriginals[inIt.first]; } // Iteratively replace all entries in the outgoing // with their copies. for ( auto & outIt : decayProc->outgoing()) { if ( theOriginals.count( outIt.first ) ) outIt.first = theOriginals[outIt.first]; if ( outIt.second ) separateDecay(outIt.second); } } void DipoleEventRecord::clear() { ShowerEventRecord::clear(); theDecays.clear(); theHard.clear(); theChains.clear(); theDoneChains.clear(); theOriginals.clear(); theDensityOperator.clear(); theParticlesBefore.clear(); theParticlesAfter.clear(); theMomentaAfter.clear(); theNextDecays.clear(); } pair DipoleEventRecord::tmpupdate(DipoleSplittingInfo& dsplit) { PVector inc; PVector out; tcPPtr IF = incoming().first; tcPPtr IS = incoming().second; tcPPtr DE = dsplit.emitter(); tcPPtr DS = dsplit.spectator(); if ( IF != DE && IF != DS ) { PPtr p = IF->data().produceParticle(IF->momentum()); inc.push_back(p); } else if ( IF == DE ) inc.push_back( dsplit.splitEmitter() ); else if ( IF == DS ) inc.push_back( dsplit.splitSpectator() ); if ( IS != DE && IS != DS ) { PPtr p = IS->data().produceParticle(IS->momentum()); inc.push_back(p); } else if ( IS == DE ) inc.push_back( dsplit.splitEmitter() ); else if ( IS == DS ) inc.push_back( dsplit.splitSpectator() ); if ( IF != DE && IS != DE) out.push_back( dsplit.splitEmitter()); if ( IF != DS && IS != DS) out.push_back( dsplit.splitSpectator()); out.push_back( dsplit.emission()); for ( tcPPtr h : theHard ){ PPtr p = h->data().produceParticle(h->momentum()); if ( dsplit.splittingKinematics()->doesTransform() ) { dsplit.splittingKinematics()->transform(p); } out.push_back(p); } for ( tcPPtr p : outgoing() ) if ( p != DE && p != DS && p != dsplit.emission() ){ PPtr ou = p->data().produceParticle(p->momentum());; if ( dsplit.splittingKinematics()->doesTransform() ){ dsplit.splittingKinematics()->transform(ou); } out.push_back(ou); } return {inc,out}; } void DipoleEventRecord::update(DipoleSplittingInfo& dsplit) { if ( continueSubleadingNc ) { subEmDone++; theParticlesBefore = theParticlesAfter; } if ( incoming().first == dsplit.emitter() ) { intermediates().push_back(dsplit.emitter()); incoming().first = dsplit.splitEmitter(); fractions().first /= dsplit.lastEmitterZ(); if ( continueSubleadingNc ) { theParticleIndices[dsplit.splitEmitter()] = 0; theParticlesAfter[0] = dsplit.splitEmitter()->dataPtr(); theEmitterEmissionIndices.first = 0; theEmitterEmissionIndices.second.first = 0; } } else if ( incoming().first == dsplit.spectator() ) { intermediates().push_back(dsplit.spectator()); incoming().first = dsplit.splitSpectator(); fractions().first /= dsplit.lastSpectatorZ(); if ( continueSubleadingNc ) { theParticleIndices[dsplit.splitSpectator()] = 0; theParticlesAfter[0] = dsplit.splitSpectator()->dataPtr(); theSpectatorIndices.first = 0; theSpectatorIndices.second = 0; } } if ( incoming().second == dsplit.emitter() ) { intermediates().push_back(dsplit.emitter()); incoming().second = dsplit.splitEmitter(); fractions().second /= dsplit.lastEmitterZ(); if ( continueSubleadingNc ) { theParticleIndices[dsplit.splitEmitter()] = 1; theParticlesAfter[1] = dsplit.splitEmitter()->dataPtr(); theEmitterEmissionIndices.first = 1; theEmitterEmissionIndices.second.first = 1; } } else if ( incoming().second == dsplit.spectator() ) { intermediates().push_back(dsplit.spectator()); incoming().second = dsplit.splitSpectator(); fractions().second /= dsplit.lastSpectatorZ(); if ( continueSubleadingNc ) { theParticleIndices[dsplit.splitSpectator()] = 1; theParticlesAfter[1] = dsplit.splitSpectator()->dataPtr(); theSpectatorIndices.first = 1; theSpectatorIndices.second = 1; } } PList::iterator pos; pos = find(outgoing().begin(), outgoing().end(), dsplit.emitter()); if (pos != outgoing().end()) { intermediates().push_back(*pos); *pos = dsplit.splitEmitter(); if ( continueSubleadingNc ) { // The two first elements in theParticlesBefore/After are the incoming theEmitterEmissionIndices.first = 2 + distance(outgoing().begin(), pos); theEmitterEmissionIndices.second.first = theEmitterEmissionIndices.first; theParticlesAfter[theEmitterEmissionIndices.second.first] = dsplit.splitEmitter()->dataPtr(); theParticleIndices[dsplit.splitEmitter()] = theEmitterEmissionIndices.second.first; } } pos = find(outgoing().begin(), outgoing().end(), dsplit.spectator()); if (pos != outgoing().end()) { intermediates().push_back(*pos); *pos = dsplit.splitSpectator(); if ( continueSubleadingNc ) { // The two first elements in theParticlesBefore/After are the incoming theSpectatorIndices.first = 2 + distance(outgoing().begin(), pos); theSpectatorIndices.second = theSpectatorIndices.first; theParticlesAfter[theSpectatorIndices.second] = dsplit.splitSpectator()->dataPtr(); theParticleIndices[dsplit.splitSpectator()] = theSpectatorIndices.second; } } if ( continueSubleadingNc ) { theEmitterEmissionIndices.second.second = 2 + outgoing().size(); theParticlesAfter.insert(theParticlesAfter.begin()+theEmitterEmissionIndices.second.second, dsplit.emission()->dataPtr()); theMomentaAfter.insert(theMomentaAfter.begin()+theEmitterEmissionIndices.second.second, dsplit.emission()->momentum()); theParticleIndices[dsplit.emission()] = theEmitterEmissionIndices.second.second; } outgoing().push_back(dsplit.emission()); if (dsplit.splittingKinematics()->doesTransform()) { for (PList::iterator h = theHard.begin(); h != theHard.end(); ++h) dsplit.splittingKinematics()->transform(*h); for (PList::iterator p = intermediates().begin(); p != intermediates().end(); ++p) dsplit.splittingKinematics()->transform(*p); for (PList::iterator p = outgoing().begin(); p != outgoing().end(); ++p) { if ((*p) != dsplit.splitEmitter() && (*p) != dsplit.splitSpectator() && (*p) != dsplit.emission()) dsplit.splittingKinematics()->transform(*p); } if ( continueSubleadingNc ) { theMomentaAfter[0] = incoming().first->momentum(); theMomentaAfter[1] = incoming().second->momentum(); size_t i = 2; for (PList::iterator p = outgoing().begin(); p != outgoing().end(); p++) { theMomentaAfter[i] = (*p)->momentum(); i++; } for (PList::iterator p = theHard.begin(); p != theHard.end(); p++) { theMomentaAfter[i] = (*p)->momentum(); i++; } } } else if ( continueSubleadingNc ) { theMomentaAfter[theEmitterEmissionIndices.second.first] = dsplit.splitEmitter()->momentum();// theMomentaAfter[theSpectatorIndices.second] = dsplit.splitSpectator()->momentum();// } // Stop with subleading emissions if the limit has been reached if ( doSubleadingNc ) if ( subEmDone == subleadingNcEmissionsLimit ) continueSubleadingNc = false; // Handle updates related to decays // Showering of decay processes // Treat the evolution of the incoming // decayed particle as in backward evolution if ( dsplit.isDecayProc() ) { // Create a pointer to the decay process PerturbativeProcessPtr decayProc = currentDecay(); // Add the emission to the outgoing of the decay process decayProc->outgoing().push_back( {dsplit.emission(), PerturbativeProcessPtr() }); // Bools to be used throughout const bool decayedEmtr = dsplit.index().incomingDecayEmitter(); const bool decayedSpec = dsplit.index().incomingDecaySpectator(); /* In the current implementation, **following the hard process** all particles in theDecays evolve independently e.g. if we have W -> XYZ where all X, Y and Z need to be showered and decayed, we only identify them as needing decaying (and hence put them in theDecays) AFTER showering the decay of W. Hence, XYZ are not even in theDecays until W has been fully showered and then they are decayed and showered completely independently KEY POINT - Never need to update other entries of theDecays Note: The PPtr in theDecays should remain unchanged and all changes should be made to the relative PerturbativeProcess. */ // Splittings from dipoles in the decay process which // do not have the decayed parton as emitter or spectator. // Update the decay process in theDecays if ( !decayedEmtr && !decayedSpec ) { // Find and replace the old spectator and // emitter in the outgoing of the decay process bool decayProcEm = false; bool decayProcSp = false; for ( auto & outIt : decayProc->outgoing() ) { if ( !decayProcEm && outIt.first == dsplit.emitter() ) { outIt = {dsplit.splitEmitter(), PerturbativeProcessPtr()}; decayProcEm = true; } if ( !decayProcSp && outIt.first == dsplit.spectator() ) { outIt = {dsplit.splitSpectator(), PerturbativeProcessPtr() }; decayProcSp = true; } if ( decayProcEm && decayProcSp ) break; } // Test that nothing strange is happening assert( (decayProcEm && decayProcSp) ); return; } // The spectator is the decayed particle else if ( decayedSpec ) { // Update the dipole event record intermediates intermediates().push_back(dsplit.splitSpectator()); // Update the the decayProcess incoming decayProc->incoming().clear(); decayProc->incoming().push_back({dsplit.splitSpectator(),decayProc}); // Update the decay process outgoing // Replace the old emitter with the new emitter for ( auto & outEmtrIt : decayProc->outgoing() ) { if ( outEmtrIt.first == dsplit.emitter() ){ outEmtrIt = {dsplit.splitEmitter(), PerturbativeProcessPtr() }; break; } } // Perform the recoil transformation // Find all particles in the recoil system PList recoilSystem; for ( auto const & outIt : decayProc->outgoing() ) { if ( outIt.first != dsplit.splitEmitter() && outIt.first != dsplit.emission() ) { recoilSystem.push_back(outIt.first); } } dsplit.splittingKinematics()->decayRecoil( recoilSystem ); return; } // The emitter is the decayed particle else { throw Exception() << "DipoleEventRecord: The emitter as a decayed particle is currently not implemented." << Exception::runerror; assert( currentDecay()->incoming()[0].first == dsplit.emitter() && decayedEmtr && !decayedSpec ); // Update the dipole event record intermediates intermediates().push_back(dsplit.splitEmitter()); // Update the the decayProcess incoming decayProc->incoming().clear(); decayProc->incoming().push_back({dsplit.splitEmitter(),decayProc}); // Update the decay process outgoing // Replace the old spectator with the new spectator for (auto & outSpecIt : decayProc->outgoing() ) { if ( outSpecIt.first == dsplit.spectator() ){ outSpecIt = { dsplit.splitSpectator(), PerturbativeProcessPtr() }; break; } } // Perform the recoil transformation assert(dsplit.splittingKinematics()->isDecay()); // Find all particles in the recoil system PList recoilSystem; for ( auto const & outIt : decayProc->outgoing() ) { if ( outIt.first != dsplit.splitSpectator() && outIt.first != dsplit.emission() ) { recoilSystem.push_back(outIt.first); } } dsplit.splittingKinematics()->decayRecoil( recoilSystem ); return; } } if ( continueSubleadingNc ) { // Fixed alphaS double alphaS = 0.118; map,Complex> Vijk; double Vtemp; const Lorentz5Momentum pEmission = dsplit.emission()->momentum(); // Special cases for the density operator evolution // g->qqbar splitting bool splitAGluon = (dsplit.emitter()->id() == ParticleID::g) && (dsplit.emission()->id() != ParticleID::g); // initial state g->qqbar splitting bool initialGluonSplitting = (dsplit.splitEmitter()->id() == ParticleID::g) && (dsplit.emission()->id() != ParticleID::g); if ( initialGluonSplitting ) assert(dsplit.splitEmitter() == incoming().first || dsplit.splitEmitter() == incoming().second); // Set up the dictionary std::tuple tmpTuple; map tmpMap; size_t n = theEmitterEmissionIndices.second.second; theEmissionsMap.clear(); if ( splitAGluon || initialGluonSplitting ) { tmpTuple = std::make_tuple(theEmitterEmissionIndices.first, theEmitterEmissionIndices.second.first, theEmitterEmissionIndices.second.second); tmpMap.clear(); for ( size_t j = 0; j < theParticlesBefore.size(); j++ ) { if ( j != theEmitterEmissionIndices.first ) tmpMap[j] = j; } theEmissionsMap[tmpTuple] = tmpMap; } else { for ( size_t i = 0; i < theParticlesBefore.size(); i++ ) { if ( theParticlesBefore[i]->coloured() ) { tmpTuple = std::make_tuple(i,i,n); tmpMap.clear(); for ( size_t j = 0; j < theParticlesBefore.size(); j++ ) { if ( j != i ) tmpMap[j] = j; } theEmissionsMap[tmpTuple] = tmpMap; } } } Energy2 pEmitpEmis; Energy2 pEmispSpec; Lorentz5Momentum pEmitter; Lorentz5Momentum pSpectator; // Calculate all required dipole factors int i,k; typedef map,map > dictMap; for(dictMap::const_iterator ijit = theEmissionsMap.begin(); ijit != theEmissionsMap.end(); ijit++) { i = std::get<1>(ijit->first); pEmitter = theMomentaAfter[i]; pEmitpEmis = pEmitter*pEmission; for(dictMap::const_iterator kit = theEmissionsMap.begin(); kit != theEmissionsMap.end(); kit++) { // For gluon splitting ijit == kit if ( ijit != kit ) { k = std::get<1>(kit->first); pSpectator = theMomentaAfter[k]; pEmispSpec = pEmission*pSpectator; Vtemp = 4*Constants::pi*alphaS*dipoleKernelForEvolution(i, k, pEmitter*pSpectator, pEmitpEmis, pEmispSpec); Vijk.insert(make_pair(make_pair(i,k),Complex(Vtemp,0.0))); } else if ( splitAGluon || initialGluonSplitting ) { k = std::get<1>(kit->first); Vijk.insert(make_pair(make_pair(i,k),Complex(1.0,0.0))); } } } theDensityOperator.evolve(Vijk,theParticlesBefore,theParticlesAfter, theEmissionsMap,splitAGluon,initialGluonSplitting); } } double DipoleEventRecord::dipoleKernelForEvolution(size_t em, size_t spec, Energy2 pEmitpSpec, Energy2 pEmitpEmis, Energy2 pEmispSpec) { double Vijk; if ( densityOperatorEvolution == 3 ) { if ( em == theEmitterEmissionIndices.second.first && spec == theSpectatorIndices.second ) { Vijk = 1.0; } else { Vijk = 0.0; } } else if ( densityOperatorEvolution == 2 ) { Vijk = 1.0; } else { if ( densityOperatorEvolution == 0 ) { if ( pEmitpEmis < densityOperatorCutoff ) pEmitpEmis = densityOperatorCutoff; if ( pEmispSpec < densityOperatorCutoff ) pEmispSpec = densityOperatorCutoff; } Vijk = ((pEmitpSpec)/GeV2)/((pEmitpEmis/GeV2)* (pEmispSpec/GeV2)); } return Vijk; } void DipoleEventRecord::split(list::iterator dip, list::iterator ch, DipoleSplittingInfo& dsplit, pair::iterator,list::iterator>& childIterators, DipoleChain*& firstChain, DipoleChain*& secondChain, bool colourSpectator) { static DipoleChain empty; pair children = dip->split(dsplit,colourSpectator, continueSubleadingNc); list::iterator breakup = ch->insertSplitting(dip,children,childIterators); if ( breakup == ch->dipoles().end() ) { firstChain = &(*ch); secondChain = ∅ } else { DipoleChain other; other.dipoles().splice(other.dipoles().end(),ch->dipoles(),breakup,ch->dipoles().end()); chains().push_back(other); firstChain = &(*ch); secondChain = &(chains().back()); // explicitly fix iterators in case the splice implementation // at hand does invalidate iterators (the SGI docu says, it doesn't, // but it seems that this behaviour is not part of the standard) childIterators.first = --firstChain->dipoles().end(); childIterators.second = secondChain->dipoles().begin(); } if ( !colourSpectator ) { update(dsplit); // otherwise done by recoil(...) } } pair DipoleEventRecord::tmpsplit(list::iterator dip, list::iterator , DipoleSplittingInfo& dsplit, pair::iterator,list::iterator>& , DipoleChain*& , DipoleChain*& , bool colourSpectator) { dip->tmpsplit(dsplit,colourSpectator); return tmpupdate(dsplit); // otherwise done by recoil(...) } void DipoleEventRecord::recoil(list::iterator dip, list::iterator ch, DipoleSplittingInfo& dsplit) { dip->recoil(dsplit); ch->updateDipole(dip); update(dsplit); } list::iterator,list::iterator> > DipoleEventRecord::inDipoles() { list::iterator,list::iterator> > res; for ( list::iterator chit = theDoneChains.begin(); chit != theDoneChains.end(); ++chit ) { bool haveOne = false; for ( list::iterator dit = chit->dipoles().begin(); dit != chit->dipoles().end(); ++dit ) { if ( dit->leftPDF().pdf() || dit->rightPDF().pdf() ) { haveOne = true; break; } } if ( haveOne ) { theChains.splice(theChains.begin(),theDoneChains,chit); for ( list::iterator dit = theChains.front().dipoles().begin(); dit != theChains.front().dipoles().end(); ++dit ) { if ( dit->leftPDF().pdf() || dit->rightPDF().pdf() ) { res.push_back({dit,theChains.begin()}); } } } } return res; } void DipoleEventRecord::transform(const LorentzRotation& rot) { Lorentz5Momentum tmp; for (PList::iterator p = intermediates().begin(); p != intermediates().end(); ++p) { tmp = (**p).momentum(); if ( (*p)->spinInfo() ) (*p)->spinInfo()->transform(tmp, rot); tmp = rot * tmp; (**p).set5Momentum(tmp); } for (PList::iterator h = theHard.begin(); h != theHard.end(); ++h) { tmp = (**h).momentum(); if ( (*h)->spinInfo() ) (*h)->spinInfo()->transform(tmp, rot); tmp = rot * tmp; (**h).set5Momentum(tmp); } for (PList::iterator p = outgoing().begin(); p != outgoing().end(); ++p) { tmp = (**p).momentum(); if ( (*p)->spinInfo() ) (*p)->spinInfo()->transform(tmp, rot); tmp = rot * tmp; (**p).set5Momentum(tmp); } } tPPair DipoleEventRecord::fillEventRecord(StepPtr step, bool firstInteraction, bool) { PPtr inSubPro = subProcess()->incoming().first; PPtr inParticle; if ( !(inSubPro->parents().empty()) ) inParticle = inSubPro->parents()[0]; else inParticle = inSubPro; PPtr inParton = theOriginals[inSubPro]; theOriginals.erase(inSubPro); updateColour(incoming().first,true); if ( inParticle != inSubPro ) inParticle->abandonChild(inSubPro); inParton->addChild(inSubPro); if ( inParticle != inSubPro ) inParticle->addChild(incoming().first); intermediates().push_back(inSubPro); intermediates().push_back(inParton); // Repeat all the above for the second incoming particle inSubPro = subProcess()->incoming().second; if ( !(inSubPro->parents().empty()) ) inParticle = inSubPro->parents()[0]; else inParticle = inSubPro; inParton = theOriginals[inSubPro]; theOriginals.erase(inSubPro); updateColour(incoming().second,true); if ( inParticle != inSubPro ) inParticle->abandonChild(inSubPro); inParton->addChild(inSubPro); if ( inParticle != inSubPro ) inParticle->addChild(incoming().second); intermediates().push_back(inSubPro); intermediates().push_back(inParton); // theOriginals is populated in ::prepare and contains all of the incoming and outgoing particles of the original hard process // Here outgoing particles from theOriginals are added into the intermediates() while ( !theOriginals.empty() ) { PPtr outSubPro = theOriginals.begin()->first; PPtr outParton = theOriginals.begin()->second; // workaround for OS X Mavericks LLVM libc++ #ifdef _LIBCPP_VERSION map::const_iterator beg = theOriginals.begin(); #else map::iterator beg = theOriginals.begin(); #endif theOriginals.erase(beg); updateColour(outParton,true); outSubPro->addChild(outParton); intermediates().push_back(outSubPro); } // Update the intermediates of the step step->addIntermediates(intermediates().begin(),intermediates().end()); for (auto const & p : outgoing()) step->addDecayProduct( p ); for (auto const & p : theHard) step->addDecayProduct( p ); if ( firstInteraction && (incoming().first->coloured() || incoming().second->coloured() ) ) { ShowerHandler::currentHandler()->lastExtractor() ->newRemnants(subProcess()->incoming(),incoming(),step); } step->addIntermediate(incoming().first); step->addIntermediate(incoming().second); return incoming(); } bool DipoleEventRecord::prepareDecay( PerturbativeProcessPtr decayProc, const set& offShellPartons ) { // Create objects containing the incoming and outgoing partons, // required as inputs for colourOrdered. PList out; for( auto const & dec : decayProc->outgoing()) { if(dec.first->coloured()) { out.push_back(dec.first); } } // Only need to shower if we have coloured outgoing particles if ( out.empty() ) return false; else { // For the incoming, use a PPair containing the incoming and a null pointer PPair in; in.first = decayProc->incoming()[0].first; // Chains are found later if the subleading shower is used if ( !doSubleadingNc ) { // Create an ordered list of particles PList cordered; cordered = colourOrdered(in,out); // Find the dipole chains for this decay findChains(cordered,offShellPartons,true); } return true; } } Energy DipoleEventRecord::decay(PPtr incoming, bool& powhegEmission) { // get the process PerturbativeProcessPtr process = theDecays[incoming]; assert(process); //tDMPtr decayMode = new_ptr(DecayMode()); tDMPtr decayMode = DMPtr(); // Do not decay particles that have already been decayed // Note the herwig decayer deals with colour connections if ( process->outgoing().empty() ) { process->incoming()[0].first = incoming; DecayProcessMap decay; // Decay the particle, returning a pointer to the decay mode decayMode = ShowerHandler::currentHandler()->decay(process,decay,true); } // Sort out the colour connections of particles already decayed else { // sort out the colour of the incoming map cmap; if(incoming->colourLine()) cmap[process->incoming()[0].first->colourLine()] = incoming->colourLine(); if(incoming->antiColourLine()) cmap[process->incoming()[0].first->antiColourLine()] = incoming->antiColourLine(); // fix colours of outgoing for(auto const & outg : process->outgoing()) { map::iterator it = cmap.find(outg.first->colourLine()); if(it!=cmap.end()) { ColinePtr c1=outg.first->colourLine(); c1->removeColoured(outg.first); it->second->addColoured(outg.first); } it = cmap.find(outg.first->antiColourLine()); if(it!=cmap.end()) { ColinePtr c1=outg.first->antiColourLine(); c1->removeAntiColoured(outg.first); it->second->addAntiColoured(outg.first); } } // swap the incoming process->incoming()[0].first = incoming; } // Set the scale of all particles involved in the decay process to the // mass of the decaying particle // Initialise the scale for the evolution of // the parton shower following the decay Energy showerScale = ZERO; // Set the scale for the evolution of the shower showerScale = process->incoming()[0].first->momentum().m(); Energy2 decayScaleSqr = sqr( showerScale ); process->incoming()[0].first->scale( decayScaleSqr ); for(auto & outg : process->outgoing()) { outg.first->scale( decayScaleSqr ); } // Update the decaying particle in the process and the event PList::iterator posOut = find(outgoing().begin(), outgoing().end(), incoming); PList::iterator posHard = find(hard().begin(), hard().end(), incoming); assert((posOut!=outgoing().end() && posHard==hard().end()) || (posOut==outgoing().end() && posHard!=hard().end()) ); if ( posOut!=outgoing().end() ) { outgoing().erase(posOut); } else { hard().erase(posHard); } intermediates().push_back(process->incoming()[0].first); // Populate the children of the incoming for(auto const & outg : process->outgoing()) { PPtr outgoing = outg.first; process->incoming()[0].first->addChild(outgoing); } // If a decayed particle is not decayed above, // e.g. a W in a 3-body top decay, find its decaymode. if ( powhegEmission && !decayMode ) { string tag = incoming->dataPtr()->name() + "->"; // Must use OrderedParticles for a tag search ShowerHandler::OrderedParticles decayOut; for(auto const & outg : process->outgoing()) { decayOut.insert(outg.first->dataPtr()); } // Construct the tag for(auto const & dec : decayOut) { if( dec!=*decayOut.begin() ) tag += ","; tag +=dec->name(); } tag += ";"; // Find the decay mode decayMode = ShowerHandler::currentHandler()->findDecayMode(tag); } // Perform the powheg emission if ( powhegEmission ) { if ( decayMode ) { HwDecayerBasePtr decayer; decayer = dynamic_ptr_cast(decayMode->decayer()); if ( decayer->hasPOWHEGCorrection() ) { // Construct a real emission process and populate its // incoming and outcoming prior to any powheg emission RealEmissionProcessPtr born = new_ptr( RealEmissionProcess() ); born->bornIncoming().push_back( incoming ); for(auto const & outg : process->outgoing()) { born->bornOutgoing().push_back(outg.first); } // Generate any powheg emission, returning 'real' RealEmissionProcessPtr real = decayer->generateHardest( born ); // If an emission has been attempted // (Note if the emission fails, a null ptr is returned) if ( real ) { showerScale = real->pT()[ShowerInteraction::QCD]; // If an emission is generated sort out the particles if ( !real->outgoing().empty() ) { // Update the decay process // Note: Do not use the new incoming particle PPtr oldEmitter; PPtr newEmitter; // Use the name recoiler to avoid confusion with // the spectator in the POWHEGDecayer // i.e. the recoiler can be coloured or non-coloured PPtr oldRecoiler; PPtr newRecoiler; if ( real->emitter() == 1 ) { oldEmitter = real->bornOutgoing()[0]; oldRecoiler = real->bornOutgoing()[1]; newEmitter = real->outgoing()[0]; newRecoiler = real->outgoing()[1]; } else if ( real->emitter() == 2) { oldEmitter = real->bornOutgoing()[1]; oldRecoiler = real->bornOutgoing()[0]; newEmitter = real->outgoing()[1]; newRecoiler = real->outgoing()[0]; } PPtr emitted = real->outgoing()[ real->emitted()-1]; // Update the scales newRecoiler->scale(oldRecoiler->scale()); newEmitter->scale(sqr(showerScale)); emitted->scale(sqr(showerScale)); // Update the colour flow of the new outgoing particles // Note the emitted and newEmitter are already colour // connected by the powheg emission function emitted->incomingColour(oldEmitter, oldEmitter->id()<0); if ( newRecoiler->coloured() ) newRecoiler->incomingColour(oldRecoiler, oldRecoiler->id()<0); // Update the children of the outgoing oldRecoiler->addChild( newRecoiler ); oldEmitter->addChild( newEmitter ); oldEmitter->addChild( emitted ); // Note: The particles in the pert proc outgoing and both outgoing // vectors of the real emission proc are in the same order for(unsigned int ix=0;ixbornOutgoing().size();++ix) { // Update the decay process assert(process->outgoing()[ix].first == real->bornOutgoing()[ix]); process->outgoing()[ix].first = real->outgoing()[ix]; // Add the outgoing from the born // decay to the event intermediates intermediates().push_back(real->bornOutgoing()[ix]); } // Add the emitted to the outgoing of the decay process process->outgoing().push_back( { emitted, PerturbativeProcessPtr() } ); } // Else, if no emission above pTmin, set particle scales else { for(auto & outg : process->outgoing()) { outg.first->scale( sqr(showerScale) ); } powhegEmission = false; } } // No powheg emission occurred: else powhegEmission = false; } // No powheg emission occurred: else powhegEmission = false; } // No powheg emission occurred: else powhegEmission = false; } // Copy the outgoing from the decay // process to the event record for(auto const & outg : process->outgoing()) { if ( outg.first->coloured() ) outgoing().push_back(outg.first); else hard().push_back(outg.first); } return showerScale; } void DipoleEventRecord::updateDecayMom( PPtr decayParent, PerturbativeProcessPtr decayProc ) { // Only particles that have already been decayed // should be passed to this function assert( !(decayProc->outgoing().empty()) ); // Create a list of the children to update their momenta PList children; for ( auto const & outg : decayProc->outgoing() ) { children.push_back( outg.first ); } // Boost the children PList::iterator beginChildren = children.begin(); PList::iterator endChildren = children.end(); const Momentum3 transformMom = decayParent->momentum().vect(); Lorentz5Momentum sum = ThePEG::UtilityBase::sumMomentum(beginChildren, endChildren); LorentzRotation rot = ThePEG::UtilityBase::transformToCMS(sum); rot = ThePEG::UtilityBase::transformFromCMS (Lorentz5Momentum(transformMom, sqrt(transformMom.mag2() + sum.m2()))) * rot; // Must transform the spinInfo using the momentum prior to transforming for ( const auto& p : children ) { if ( p->spinInfo() ) p->spinInfo()->transform(p->momentum(),rot); } ThePEG::UtilityBase::transform(beginChildren, endChildren, rot ); } void DipoleEventRecord::updateDecayChainMom( PPtr decayParent, PerturbativeProcessPtr decayProc ) { // Note - this updates the momenta of the // outgoing of the given decay process // Update the momenta of the outgoing from this decay updateDecayMom( decayParent, decayProc ); // Iteratively update the momenta of the rest of the decay chain for ( auto & outg : decayProc->outgoing() ) { // If a child has a corresponding pert proc // then it has decay products if ( outg.second ) { for ( auto & dec : theDecays ) { if ( dec.second == outg.second ) { // If the particle has spininfo if ( dec.first->spinInfo() ) { // Copied from DipoleVertexRecord::updateSpinInfo, // would be better to use a common function // Update any spin information const Lorentz5Momentum& oldMom = dec.first->momentum(); const Lorentz5Momentum& newMom = outg.first->momentum(); // Rotation from old momentum to +ve z-axis LorentzRotation oldToZAxis; Axis axisOld(oldMom.vect().unit()); if( axisOld.perp2() > 1e-12 ) { double sinth(sqrt(1.-sqr(axisOld.z()))); oldToZAxis.rotate( -acos(axisOld.z()),Axis(-axisOld.y()/sinth,axisOld.x()/sinth,0.)); } // Rotation from new momentum to +ve z-axis LorentzRotation newToZAxis; Axis axisNew(newMom.vect().unit()); if( axisNew.perp2() > 1e-12 ) { double sinth(sqrt(1.-sqr(axisNew.z()))); newToZAxis.rotate( -acos(axisNew.z()),Axis(-axisNew.y()/sinth,axisNew.x()/sinth,0.)); } // Boost from old momentum to new momentum along z-axis Lorentz5Momentum momOldRotated = oldToZAxis*Lorentz5Momentum(oldMom); Lorentz5Momentum momNewRotated = newToZAxis*Lorentz5Momentum(newMom); Energy2 a = sqr(momOldRotated.z()) + sqr(momNewRotated.t()); Energy2 b = 2.*momOldRotated.t()*momOldRotated.z(); Energy2 c = sqr(momOldRotated.t()) - sqr(momNewRotated.t()); double beta; // The rotated momentum should always lie along the +ve z-axis if ( momOldRotated.z() > ZERO ) beta = (-b + sqrt(sqr(b)-4.*a*c)) / 2. / a; else beta = (-b - sqrt(sqr(b)-4.*a*c)) / 2. / a; LorentzRotation boostOldToNew(0., 0., beta); // Total transform LorentzRotation transform = (newToZAxis.inverse())*boostOldToNew*oldToZAxis; // Transform spin info and mom dec.first->spinInfo()->transform(oldMom, transform); } dec.first->setMomentum(outg.first->momentum()); break; } } // Iteratively update any decay products if ( !outg.second->outgoing().empty() ) updateDecayChainMom( outg.first, outg.second ); } } } void DipoleEventRecord::updateDecays(PerturbativeProcessPtr decayProc, bool iterate) { // Note - This does not update the momenta of the outgoing // of decayProc. // i.e. it is for use following the (non-)showering // of a decay when the daughter momentum are correct. // With iterate = true, this updates the rest of the decay chain. // Update the list of next decays if ( decayProc == theCurrentDecay && !theNextDecays.empty() ) { assert( theNextDecays.back() == decayProc->incoming()[0].first ); theNextDecays.pop_back(); } // Loop over the outgoing from this decay for ( auto & outg : decayProc->outgoing() ) { if ( outg.second && !outg.second->outgoing().empty() ) { // Outgoing particles which have already been decayed PPtr newDecayed = outg.first; PerturbativeProcessPtr newDecayProc = outg.second; // Update the outgoing momenta from this decay updateDecayMom( newDecayed, newDecayProc); // If this decay is already in theDecays then erase it for ( auto const & dec : theDecays ) { if(dec.second==newDecayProc) { theDecays.erase(dec.first); break; } } // Add to theDecays theDecays[newDecayed] = newDecayProc; // Update the list of next decays - if ( decayProc = theCurrentDecay ) + if ( decayProc == theCurrentDecay ) theNextDecays.push_back(newDecayed); // Iteratively update theDecays from the decay chain if ( iterate ) updateDecays( newDecayProc ); } // Deal with any outgoing which need to be decayed else if ( ShowerHandler::currentHandler()->decaysInShower(outg.first->id()) ) { PerturbativeProcessPtr newDecay=new_ptr(PerturbativeProcess()); newDecay->incoming().push_back({ outg.first , decayProc } ); theDecays[outg.first] = newDecay; // Update the list of next decays if ( decayProc ) theNextDecays.push_back(outg.first); } } } void DipoleEventRecord::debugLastEvent(ostream& os) const { bool first = ShowerHandler::currentHandler()->firstInteraction(); os << "--- DipoleEventRecord ----------------------------------------------------------\n"; os << " the " << (first ? "hard" : "secondary") << " subprocess is:\n" << (*subProcess()); os << " using PDF's " << pdfs().first.pdf() << " and " << pdfs().second.pdf() << "\n"; os << " chains showering currently:\n"; for ( list::const_iterator chit = theChains.begin(); chit != theChains.end(); ++chit ) os << (*chit); os << " chains which finished showering:\n"; for ( list::const_iterator chit = theDoneChains.begin(); chit != theDoneChains.end(); ++chit ) os << (*chit); os << "--------------------------------------------------------------------------------\n"; os << flush; } diff --git a/Shower/Dipole/Base/DipoleSplittingGenerator.cc b/Shower/Dipole/Base/DipoleSplittingGenerator.cc --- a/Shower/Dipole/Base/DipoleSplittingGenerator.cc +++ b/Shower/Dipole/Base/DipoleSplittingGenerator.cc @@ -1,910 +1,911 @@ // -*- C++ -*- // // DipoleSplittingGenerator.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 DipoleSplittingGenerator class. // #include #include "DipoleSplittingGenerator.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/Shower/Dipole/DipoleShowerHandler.h" #include "ThePEG/Repository/UseRandom.h" using namespace Herwig; DipoleSplittingGenerator::DipoleSplittingGenerator() : HandlerBase(), theExponentialGenerator(0), prepared(false), presampling(false), theDoCompensate(false), theSplittingWeight(1.) { if ( ShowerHandler::currentHandler() ) setGenerator(ShowerHandler::currentHandler()->generator()); } DipoleSplittingGenerator::~DipoleSplittingGenerator() { if ( theExponentialGenerator ) { delete theExponentialGenerator; theExponentialGenerator = 0; } } IBPtr DipoleSplittingGenerator::clone() const { return new_ptr(*this); } IBPtr DipoleSplittingGenerator::fullclone() const { return new_ptr(*this); } void DipoleSplittingGenerator::wrap(Ptr::ptr other) { assert(!prepared); theOtherGenerator = other; } void DipoleSplittingGenerator::resetVariations() { for ( map::iterator w = currentWeights.begin(); w != currentWeights.end(); ++w ) w->second = 1.; } void DipoleSplittingGenerator::veto(const vector&, double p, double r) { double factor = 1.; if ( splittingReweight() ) { if ( ( ShowerHandler::currentHandler()->firstInteraction() && splittingReweight()->firstInteraction() ) || ( !ShowerHandler::currentHandler()->firstInteraction() && splittingReweight()->secondaryInteractions() ) ) { if ( !splittingReweight()->hintOnly(generatedSplitting) ) { factor = splittingReweight()->evaluate(generatedSplitting)/splittingReweight()->hint(generatedSplitting); theSplittingWeight *= (r-factor*p)/(r-p); theSplittingWeightVector.push_back(std::make_tuple(generatedSplitting.lastPt(),(r-factor*p)/(r-p),false)); } } } splittingKernel()->veto(generatedSplitting, factor*p, r, currentWeights); } void DipoleSplittingGenerator::accept(const vector&, double p, double r) { double factor = 1.; if ( splittingReweight() ) { if ( ( ShowerHandler::currentHandler()->firstInteraction() && splittingReweight()->firstInteraction() ) || ( !ShowerHandler::currentHandler()->firstInteraction() && splittingReweight()->secondaryInteractions() ) ) { if ( !splittingReweight()->hintOnly(generatedSplitting) ) { factor = splittingReweight()->evaluate(generatedSplitting)/splittingReweight()->hint(generatedSplitting); theSplittingWeight *= factor; theSplittingWeightVector.push_back(std::make_tuple(generatedSplitting.lastPt(),factor,true)); } else { theSplittingWeightVector.push_back(std::make_tuple(generatedSplitting.lastPt(),1.0,true)); } } } splittingKernel()->accept(generatedSplitting, factor*p, r, currentWeights); } void DipoleSplittingGenerator::prepare(const DipoleSplittingInfo& sp) { generatedSplitting = sp; generatedSplitting.splittingKinematics(splittingKernel()->splittingKinematics()); // The splitting kernel is needed for spin correlations generatedSplitting.splittingKernel(splittingKernel()); generatedSplitting.splittingParameters().resize(splittingKernel()->nDimAdditional()); if ( wrapping() ) { generatedSplitting.emitterData(theSplittingKernel->emitter(generatedSplitting.index())); generatedSplitting.spectatorData(theSplittingKernel->spectator(generatedSplitting.index())); generatedSplitting.emissionData(theSplittingKernel->emission(generatedSplitting.index())); parameters.resize(theOtherGenerator->nDim()); prepared = true; return; } generatedSplitting.emitterData(splittingKernel()->emitter(generatedSplitting.index())); generatedSplitting.spectatorData(splittingKernel()->spectator(generatedSplitting.index())); generatedSplitting.emissionData(splittingKernel()->emission(generatedSplitting.index())); presampledSplitting = generatedSplitting; prepared = true; parameters.resize(nDim()); theExponentialGenerator = new exsample::exponential_generator(); theExponentialGenerator->sampling_parameters().maxtry = maxtry(); theExponentialGenerator->sampling_parameters().presampling_points = presamplingPoints(); theExponentialGenerator->sampling_parameters().freeze_grid = freezeGrid(); theExponentialGenerator->detuning(detuning()); theExponentialGenerator->docompensate(theDoCompensate); theExponentialGenerator->function(this); theExponentialGenerator->initialize(); } void DipoleSplittingGenerator::fixParameters(const DipoleSplittingInfo& sp, Energy optHardPt) { assert(generator()); assert(!presampling); assert(prepared); assert(sp.index() == generatedSplitting.index()); generatedSplitting.scale(sp.scale()); // If dealing with a decay, need to set recoilMass if ( generatedSplitting.index().incomingDecaySpectator() || generatedSplitting.index().incomingDecayEmitter() ) generatedSplitting.recoilMass(sp.recoilMass()); // Need to copy emitter and spectator masses generatedSplitting.emitterMass(sp.emitterMass()); generatedSplitting.spectatorMass(sp.spectatorMass()); // Counter to track if there is an off-shell // emitter AND/OR spectator int count = parameters.size()-1; // Off shell spectator mass if ( sp.index().offShellSpectator() ) { parameters[count] = sp.spectatorMass()/generator()->maximumCMEnergy(); count -= 1; } // Off shell emitter mass if ( sp.index().offShellEmitter() ) parameters[count] = sp.emitterMass()/generator()->maximumCMEnergy(); // If not a decay, point[3] samples over the dipole scale if ( !sp.index().incomingDecaySpectator() && !sp.index().incomingDecayEmitter() ) parameters[3] = sp.scale()/generator()->maximumCMEnergy(); // If it is a decay, point[3] samples over the recoilMass else parameters[3] = sp.recoilMass()/generator()->maximumCMEnergy(); generatedSplitting.hardPt(sp.hardPt()); parameters[0] = splittingKinematics()->ptToRandom(optHardPt == ZERO ? generatedSplitting.hardPt() : min(generatedSplitting.hardPt(),optHardPt), sp.scale(), sp.emitterX(), sp.spectatorX(), generatedSplitting.index(), *splittingKernel()); size_t shift = 4; if ( generatedSplitting.index().emitterPDF().pdf() && generatedSplitting.index().spectatorPDF().pdf() ) { generatedSplitting.emitterX(sp.emitterX()); generatedSplitting.spectatorX(sp.spectatorX()); parameters[4] = sp.emitterX(); parameters[5] = sp.spectatorX(); shift += 2; } if ( generatedSplitting.index().emitterPDF().pdf() && !generatedSplitting.index().spectatorPDF().pdf() ) { generatedSplitting.emitterX(sp.emitterX()); parameters[4] = sp.emitterX(); ++shift; } if ( !generatedSplitting.index().emitterPDF().pdf() && generatedSplitting.index().spectatorPDF().pdf() ) { generatedSplitting.spectatorX(sp.spectatorX()); parameters[4] = sp.spectatorX(); ++shift; } if ( splittingKernel()->nDimAdditional() ) copy(sp.lastSplittingParameters().begin(), sp.lastSplittingParameters().end(), parameters.begin()+shift); if ( sp.emitter() ) generatedSplitting.emitter(sp.emitter()); if ( sp.spectator() ) generatedSplitting.spectator(sp.spectator()); } int DipoleSplittingGenerator::nDim() const { assert(!wrapping()); assert(prepared); // Note this use of [3] for either the scale or the recoil mass // is a bit of a nasty hack. int ret = 4; // 0 pt, 1 z, 2 phi, 3 scale or recoilMass, 4/5 xs + parameters if ( generatedSplitting.index().emitterPDF().pdf() ) { ++ret; } if ( generatedSplitting.index().spectatorPDF().pdf() ) { ++ret; } ret += splittingKernel()->nDimAdditional(); assert(splittingKernel()->nDimAdditional() == 0); // Put off-shell spectator mass at back [-1] // followed by off-shell emitter mass (i.e. [-1] or [-2]) // Off-shell emitter if ( generatedSplitting.index().offShellEmitter() ) ++ret; // Off-shell spectator if ( generatedSplitting.index().offShellSpectator() ) ++ret; return ret; } const vector& DipoleSplittingGenerator::sampleFlags() { assert(!wrapping()); if ( !theFlags.empty() ) return theFlags; theFlags.resize(nDim(),false); theFlags[0] = true; theFlags[1] = true; theFlags[2] = true; // 0 pt, 1 z, 2 phi return theFlags; } const pair,vector >& DipoleSplittingGenerator::support() { assert(!wrapping()); if ( !theSupport.first.empty() ) return theSupport; vector lower(nDim(),0.); vector upper(nDim(),1.); pair kSupport = generatedSplitting.splittingKinematics()->kappaSupport(generatedSplitting); pair xSupport = generatedSplitting.splittingKinematics()->xiSupport(generatedSplitting); lower[0] = kSupport.first; lower[1] = xSupport.first; upper[0] = kSupport.second; upper[1] = xSupport.second; theSupport.first = lower; theSupport.second = upper; return theSupport; } void DipoleSplittingGenerator::startPresampling() { assert(!wrapping()); splittingKernel()->startPresampling(generatedSplitting.index()); presampling = true; } void DipoleSplittingGenerator::stopPresampling() { assert(!wrapping()); splittingKernel()->stopPresampling(generatedSplitting.index()); presampling = false; } bool DipoleSplittingGenerator::haveOverestimate() const { assert(!wrapping()); assert(prepared); return generatedSplitting.splittingKinematics()->haveOverestimate() && splittingKernel()->haveOverestimate(generatedSplitting); } double DipoleSplittingGenerator::overestimate(const vector& point) { assert(!wrapping()); assert(prepared); assert(!presampling); assert(haveOverestimate()); if ( ! generatedSplitting.splittingKinematics()->generateSplitting(point[0],point[1],point[2], generatedSplitting, *splittingKernel()) ) return 0.; generatedSplitting.splittingKinematics()->prepareSplitting(generatedSplitting); return ( generatedSplitting.splittingKinematics()->jacobianOverestimate() * splittingKernel()->overestimate(generatedSplitting) ); } double DipoleSplittingGenerator::invertOverestimateIntegral(double value) const { assert(!wrapping()); assert(prepared); assert(!presampling); assert(haveOverestimate()); return splittingKernel()->invertOverestimateIntegral(generatedSplitting,value); } double DipoleSplittingGenerator::evaluate(const vector& point) { assert(!wrapping()); assert(prepared); assert(generator()); DipoleSplittingInfo& split = ( !presampling ? generatedSplitting : presampledSplitting ); split.continuesEvolving(); size_t shift = 4; if ( presampling ) { // Counter to track if there is an off-shell // emitter AND/OR spectator int count = parameters.size()-1; // Sample over off-shell emitter and spectator masss // Do not sample if zero mass or off-shell if ( split.index().spectatorData()->mass() != ZERO ) { if ( !split.index().offShellSpectator() ) split.spectatorMass(split.index().spectatorData()->mass()); else { split.spectatorMass(point[count] * generator()->maximumCMEnergy()); count -= 1; } } if ( split.index().emitterData()->mass() != ZERO ) { if ( !split.index().offShellEmitter() ) split.emitterMass(split.index().emitterData()->mass()); else split.emitterMass(point[count] * generator()->maximumCMEnergy()); } // If not a decay, point[3] samples over the dipole scale if ( ! split.index().incomingDecaySpectator() && ! split.index().incomingDecayEmitter() ) split.scale(point[3] * generator()->maximumCMEnergy()); // For dipoles containing a decayed spectator: // 1) Use point[3] to sample over the recoil mass // 2) The dipole scale is the spectator mass else if ( split.index().incomingDecaySpectator() ) { split.recoilMass(point[3] * generator()->maximumCMEnergy()); assert(split.spectatorMass() != ZERO ); split.scale(split.spectatorMass()); } // Not currently intended to work with decaying emitters else assert(false); if ( split.index().emitterPDF().pdf() && split.index().spectatorPDF().pdf() ) { split.emitterX(point[4]); split.spectatorX(point[5]); shift += 2; } if ( split.index().emitterPDF().pdf() && !split.index().spectatorPDF().pdf() ) { split.emitterX(point[4]); ++shift; } if ( !split.index().emitterPDF().pdf() && split.index().spectatorPDF().pdf() ) { split.spectatorX(point[4]); ++shift; } if ( splittingKernel()->nDimAdditional() ) copy(point.begin()+shift,point.end(),split.splittingParameters().begin()); split.hardPt(split.splittingKinematics()->ptMax(split.scale(), split.emitterX(), split.spectatorX(), split, *splittingKernel())); } if ( ! split.splittingKinematics()->generateSplitting(point[0], point[1], point[2], split, *splittingKernel()) ) { split.lastValue(0.); return 0.; } split.splittingKinematics()->prepareSplitting(split); if ( split.stoppedEvolving() ) { split.lastValue(0.); return 0.; } if ( !presampling ) splittingKernel()->clearAlphaPDFCache(); double kernel = splittingKernel()->evaluate(split); double jac = split.splittingKinematics()->jacobian(); // multiply in the profile scales when relevant assert(ShowerHandler::currentHandler()); if ( ShowerHandler::currentHandler()->firstInteraction() && ShowerHandler::currentHandler()->profileScales() && !presampling ) { Energy hard = ShowerHandler::currentHandler()->hardScale(); if ( hard > ZERO ) kernel *= ShowerHandler::currentHandler()->profileScales()-> hardScaleProfile(hard,split.lastPt()); } split.lastValue( abs(jac) * kernel ); if ( ! isfinite(split.lastValue()) ) { generator()->log() << "DipoleSplittingGenerator:evaluate():" <<"problematic splitting kernel encountered for " << splittingKernel()->name() << "\n" << flush; split.lastValue(0.0); } if ( kernel < 0. ) return 0.; return split.lastValue(); } void DipoleSplittingGenerator::doGenerate(map& variations, Energy optCutoff) { assert(!wrapping()); double res = 0.; Energy startPt = generatedSplitting.hardPt(); double optKappaCutoff = 0.0; if ( optCutoff > splittingKinematics()->IRCutoff() ) { optKappaCutoff = splittingKinematics()->ptToRandom(optCutoff, generatedSplitting.scale(), generatedSplitting.emitterX(), generatedSplitting.spectatorX(), generatedSplitting.index(), *splittingKernel()); } resetVariations(); theSplittingWeight = 1.; double enhance = 1.; bool detuningOff = false; if ( splittingReweight() ) { if ( ( ShowerHandler::currentHandler()->firstInteraction() && splittingReweight()->firstInteraction() ) || ( !ShowerHandler::currentHandler()->firstInteraction() && splittingReweight()->secondaryInteractions() ) ) { enhance = splittingReweight()->hint(generatedSplitting); if ( splittingReweight()->hintOnly(generatedSplitting) ) detuningOff = true; } } bool hintOnly = false; if ( splittingReweight() ) hintOnly = splittingReweight()->hintOnly(generatedSplitting); while (true) { theExponentialGenerator->detuning(detuning()); if ( detuningOff ) theExponentialGenerator->detuning(1.0); try { if ( optKappaCutoff == 0.0 ) { theSplittingWeightVector.clear(); res = theExponentialGenerator->generate(enhance); } else { theSplittingWeightVector.clear(); res = theExponentialGenerator->generate(optKappaCutoff,enhance); } //Partial unweighting if ( partialUnweighting && !hintOnly ) { if ( abs(theSplittingWeight)/theReferenceWeight < 1.0 ) { double r = UseRandom::rnd(1.0); if ( abs(theSplittingWeight)/theReferenceWeight < r ) { theSplittingWeight = 1.; continue; } else { theSplittingWeight = theSplittingWeight/abs(theSplittingWeight)*theReferenceWeight; } } } } catch (exsample::exponential_regenerate&) { resetVariations(); theSplittingWeight = 1.; generatedSplitting.hardPt(startPt); continue; } catch (exsample::hit_and_miss_maxtry&) { throw DipoleShowerHandler::RedoShower(); } catch (exsample::selection_maxtry&) { throw DipoleShowerHandler::RedoShower(); } break; } for ( map::const_iterator w = currentWeights.begin(); w != currentWeights.end(); ++w ) { map::iterator v = variations.find(w->first); if ( v != variations.end() ) v->second *= w->second; else variations[w->first] = w->second; } if ( res == 0. ) { generatedSplitting.lastPt(0.0*GeV); generatedSplitting.didStopEvolving(); } else { generatedSplitting.continuesEvolving(); if ( theMCCheck ) theMCCheck->book(generatedSplitting.emitterX(), generatedSplitting.spectatorX(), generatedSplitting.scale(), startPt, generatedSplitting.lastPt(), generatedSplitting.lastZ(), 1.); } } Energy DipoleSplittingGenerator::generate(const DipoleSplittingInfo& split, map& variations, Energy optHardPt, Energy optCutoff) { fixParameters(split,optHardPt); if ( wrapping() ) { return theOtherGenerator->generateWrapped(generatedSplitting,variations,optHardPt,optCutoff); } doGenerate(variations,optCutoff); return generatedSplitting.lastPt(); } double DipoleSplittingGenerator::sudakovExpansion(const DipoleSplittingInfo& split, Energy down,Energy fixedScale){ fixParameters(split); if ( wrapping() ) { return theOtherGenerator->wrappedSudakovExpansion( generatedSplitting, down,fixedScale); } return dosudakovExpansion( split, down,fixedScale); } double DipoleSplittingGenerator::sudakov(const DipoleSplittingInfo& split,Energy down){ fixParameters(split); if ( wrapping() ) { return theOtherGenerator->wrappedSudakov( generatedSplitting, down); } return dosudakov( split, down); } double DipoleSplittingGenerator::dosudakovExpansion(const DipoleSplittingInfo& , Energy down,Energy fixedScale){ assert(down > splittingKinematics()->IRCutoff()); double optKappaCutoffd = splittingKinematics()->ptToRandom(down, generatedSplitting.scale(), generatedSplitting.emitterX(), generatedSplitting.spectatorX(), generatedSplitting.index(), *splittingKernel()); double optKappaCutoffu = splittingKinematics()->ptToRandom(generatedSplitting.hardPt(), generatedSplitting.scale(), generatedSplitting.emitterX(), generatedSplitting.spectatorX(), generatedSplitting.index(), *splittingKernel()); pair xSupport = generatedSplitting.splittingKinematics()->xiSupport(generatedSplitting); vector RN; RN.resize(3); double res=0.; double resq=0.; double varx=10.; int k=0; generatedSplitting.setCalcFixedExpansion(true); generatedSplitting.fixedScale(fixedScale); while ( k<1000 ){ k+=1.; RN[0]= optKappaCutoffd+(optKappaCutoffu-optKappaCutoffd)*UseRandom::rnd(); //PT RN[1]=xSupport.first+UseRandom::rnd()*(xSupport.second-xSupport.first); // RN[2]= UseRandom::rnd(); //PHI double tmp=(xSupport.second-xSupport.first)* (optKappaCutoffu-optKappaCutoffd)* evaluate(RN); res+= tmp; resq+=pow(tmp,2.); if(k%50==0.){ varx=sqrt((resq/pow(1.*k,2)-pow(res,2)/pow(1.*k,3)))/(res/(1.0*k)); if(varxptToRandom(down, generatedSplitting.scale(), generatedSplitting.emitterX(), generatedSplitting.spectatorX(), generatedSplitting.index(), *splittingKernel()); double optKappaCutoffu = splittingKinematics()->ptToRandom(generatedSplitting.hardPt(), generatedSplitting.scale(), generatedSplitting.emitterX(), generatedSplitting.spectatorX(), generatedSplitting.index(), *splittingKernel()); - + +#ifndef NDEBUG pair kSupport = generatedSplitting.splittingKinematics()->kappaSupport(generatedSplitting); - +#endif assert(kSupport.first==0&&kSupport.second==1); pair xSupport = generatedSplitting.splittingKinematics()->xiSupport(generatedSplitting); vector RN; RN.resize(3); double res=0.; double resq=0.; double var=10.; double varx=10.; int k=0; while (((k<40.||var>theSudakovAccuracy)&&k<50000)){ k+=1.; RN[0]= optKappaCutoffd+(optKappaCutoffu-optKappaCutoffd)*UseRandom::rnd(); //PT RN[1]=xSupport.first+UseRandom::rnd()*(xSupport.second-xSupport.first); //Z RN[2]=UseRandom::rnd(); //PHI double tmp=(xSupport.second-xSupport.first)* (optKappaCutoffu-optKappaCutoffd)* evaluate(RN); res+= tmp; resq+=pow(tmp,2.); if(k%20==0.){ varx=sqrt((resq/pow(1.*k,2)-pow(res,2)/pow(1.*k,3))); var= (exp(-(res)/(1.0*k)+varx)-exp(-(res)/(1.0*k)-varx))/exp(-res/(1.0*k)); } } return exp(-res/(1.0*k)); } double DipoleSplittingGenerator::wrappedSudakovExpansion(DipoleSplittingInfo& split, Energy down,Energy fixedScale) { assert(!wrapping()); DipoleSplittingInfo backup = generatedSplitting; generatedSplitting = split; fixParameters(split); double res=dosudakovExpansion( split, down,fixedScale); split = generatedSplitting; generatedSplitting = backup; return res; } double DipoleSplittingGenerator::wrappedSudakov(DipoleSplittingInfo& split, Energy down) { assert(!wrapping()); DipoleSplittingInfo backup = generatedSplitting; generatedSplitting = split; fixParameters(split); double res=dosudakov( split, down); split = generatedSplitting; generatedSplitting = backup; return res; } Energy DipoleSplittingGenerator::generateWrapped(DipoleSplittingInfo& split, map& variations, Energy optHardPt, Energy optCutoff) { assert(!wrapping()); DipoleSplittingInfo backup = generatedSplitting; generatedSplitting = split; fixParameters(split,optHardPt); try { doGenerate(variations,optCutoff); } catch (...) { split = generatedSplitting; generatedSplitting = backup; throw; } Energy pt = generatedSplitting.lastPt(); split = generatedSplitting; generatedSplitting = backup; return pt; } void DipoleSplittingGenerator::completeSplitting(DipoleSplittingInfo& sp) const { pair conf = sp.configuration(); sp = generatedSplitting; sp.configuration(conf); } Ptr::tptr DipoleSplittingGenerator::splittingKernel() const { if ( wrapping() ) return theOtherGenerator->splittingKernel(); return theSplittingKernel; } Ptr::tptr DipoleSplittingGenerator::splittingReweight() const { if ( wrapping() ) return theOtherGenerator->splittingReweight(); return theSplittingReweight; } Ptr::tptr DipoleSplittingGenerator::splittingKinematics() const { if ( wrapping() ) return theOtherGenerator->splittingKinematics(); return theSplittingKernel->splittingKinematics(); } void DipoleSplittingGenerator::splittingKernel(Ptr::tptr sp) { theSplittingKernel = sp; if ( theSplittingKernel->mcCheck() ) theMCCheck = theSplittingKernel->mcCheck(); } void DipoleSplittingGenerator::splittingReweight(Ptr::tptr sp) { theSplittingReweight = sp; } void DipoleSplittingGenerator::debugGenerator(ostream& os) const { os << "--- DipoleSplittingGenerator ---------------------------------------------------\n"; os << " generating splittings using\n" << " splittingKernel = " << splittingKernel()->name() << " splittingKinematics = " << generatedSplitting.splittingKinematics()->name() << "\n" << " to sample splittings of type:\n"; os << generatedSplitting; os << "--------------------------------------------------------------------------------\n"; } void DipoleSplittingGenerator::debugLastEvent(ostream& os) const { os << "--- DipoleSplittingGenerator ---------------------------------------------------\n"; os << " last generated event:\n"; os << generatedSplitting; os << "--------------------------------------------------------------------------------\n"; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void DipoleSplittingGenerator::persistentOutput(PersistentOStream & os) const { os << theOtherGenerator << theSplittingKernel << theSplittingReweight << theMCCheck << theDoCompensate; } void DipoleSplittingGenerator::persistentInput(PersistentIStream & is, int) { is >> theOtherGenerator >> theSplittingKernel >> theSplittingReweight >> theMCCheck >> theDoCompensate; } ClassDescription DipoleSplittingGenerator::initDipoleSplittingGenerator; // Definition of the static class description member. void DipoleSplittingGenerator::Init() { static ClassDocumentation documentation ("DipoleSplittingGenerator is used by the dipole shower " "to sample splittings from a given dipole splitting kernel."); static Reference interfaceSplittingKernel ("SplittingKernel", "Set the splitting kernel to sample from.", &DipoleSplittingGenerator::theSplittingKernel, false, false, true, false, false); static Reference interfaceSplittingReweight ("SplittingReweight", "Set the splitting reweight.", &DipoleSplittingGenerator::theSplittingReweight, false, false, true, true, false); static Reference interfaceMCCheck ("MCCheck", "[debug option] MCCheck", &DipoleSplittingGenerator::theMCCheck, false, false, true, true, false); interfaceMCCheck.rank(-1); } diff --git a/Shower/Dipole/Colorea/Colorea.cc b/Shower/Dipole/Colorea/Colorea.cc deleted file mode 100644 --- a/Shower/Dipole/Colorea/Colorea.cc +++ /dev/null @@ -1,716 +0,0 @@ - // -*- C++ -*- - // - // Colorea.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 Colorea class. - // - -#include "Colorea.h" -#include "eeuugg.h" -#include "eeuuggg.h" -#include "eeuugggg.h" -#include "Herwig/Shower/Dipole/Utility/DipolePartonSplitter.h" -#include "Herwig/Shower/Dipole/Base/DipoleChain.h" -#include "Herwig/Shower/Dipole/Base/Dipole.h" - - -#include - -using namespace Herwig; - -Colorea::Colorea(){} - -list& Colorea::dipoles() { return theChain->dipoles(); } - -void Colorea::rearrange( int dipmax , int diplong ){ - - assert( dipmax >= diplong ); - // if there are only 2 dipoles in the chain - //there is nothing to do for now. - if( dipoles().size() < 3 )return; - - if( dipoles().size() == 3 ){ - // get the 3 dipoles: - auto dipi=dipoles().begin(); - auto dipj=dipoles().begin();dipj++; - auto dipk=dipoles().begin();dipk++;dipk++; - rearrange3(dipi,dipj,dipk); - - if( theChain->circular () ){ - // if the chain is circular, - // we need to check also the - // connected ends. - rearrange3(dipj,dipk,dipi); - rearrange3(dipk,dipi,dipj); - } - return; - } - if( dipoles().size() == 4 && dipmax >= 4 ){ - // get the 4 dipoles - auto dipi=dipoles().begin(); - auto dipj=dipoles().begin();dipj++; - auto dipk=dipoles().begin();dipk++;dipk++; - auto dipl=dipoles().begin();dipl++;dipl++;dipl++; - rearrange4(dipi,dipj,dipk,dipl); - return; - } - if( dipoles().size() == 5 && dipmax >= 5 ){ - // get the 5 dipoles - auto dipi=dipoles().begin(); - auto dipj=dipoles().begin();dipj++; - auto dipk=dipoles().begin();dipk++;dipk++; - auto dipl=dipoles().begin();dipl++;dipl++;dipl++; - auto dipm=dipoles().begin();dipm++;dipm++;dipm++;dipm++; - rearrange5(dipi,dipj,dipk,dipl,dipm); - return; - } - // if the chain is longer than dipmax - // go though the chain with diplong dipoles. - rearrangeLong( diplong ); - return; - -} - -void Colorea::rearrangeLong( int diplong ){ - if ( diplong == 3 ){ - // get the 3 dipoles: - auto dipi=dipoles().begin(); - auto dipj=dipoles().begin();dipj++; - auto dipk=dipoles().begin();dipk++;dipk++; - while (dipk!=dipoles().end()) { - rearrange3(dipi,dipj,dipk); - dipi++;dipj++;dipk++; - } - if( theChain->circular() ){ - // if the chain is circular, - // we need to check also the - // connected ends. - dipk=dipoles().begin(); // as dipk was end - rearrange3( dipi , dipj , dipk ); - // rotate further. - dipi++;dipk++; - dipj=dipoles().begin(); - rearrange3(dipi,dipj,dipk); - } - }else if (diplong ==4){ - // get the 4 dipoles: - assert(!theChain->circular ()); - auto dipi=dipoles().begin(); - auto dipj=dipoles().begin();dipj++; - auto dipk=dipoles().begin();dipk++;dipk++; - auto dipl=dipoles().begin();dipl++;dipl++;dipl++; - while (dipl!=dipoles().end()) { - rearrange4(dipi,dipj,dipk,dipl); - dipi++;dipj++;dipk++;dipl++; - } - }else if (diplong ==5){ - // get the 5 dipoles: - assert(!theChain->circular ()); - auto dipi=dipoles().begin(); - auto dipj=dipoles().begin();dipj++; - auto dipk=dipoles().begin();dipk++;dipk++; - auto dipl=dipoles().begin();dipl++;dipl++;dipl++; - auto dipm=dipoles().begin();dipm++;dipm++;dipm++;dipm++; - - while (dipm!=dipoles().end()) { - rearrange5(dipi,dipj,dipk,dipl,dipm); - dipi++;dipj++;dipk++;dipl++;dipm++; - } - }else{ - assert(false); - } -} - - - -void Colorea::rmcol(tColinePtr A, - tColinePtr B, - list::iterator & dip){ - if(A==B){ - auto AA=A->coloured(); - for (auto col:AA){ - if(col==dip->leftParticle()) A->removeColoured (col); - if(col==dip->rightParticle())A->removeColoured (col); - } - auto BB=A->antiColoured(); - for (auto col:BB){ - if(col==dip->leftParticle()) A->removeAntiColoured (col); - if(col==dip->rightParticle())A->removeAntiColoured (col); - } - } -} - - - -void Colorea::removeColors(list::iterator dipi, - list::iterator dipj, - list::iterator dipk){ - auto ilc = dipi->leftParticle()->colourInfo()-> colourLine(); - auto irc = dipi->rightParticle()->colourInfo()-> colourLine(); - auto ila = dipi->leftParticle()->colourInfo()-> antiColourLine(); - auto ira = dipi->rightParticle()->colourInfo()-> antiColourLine(); - auto jlc = dipj->leftParticle()->colourInfo()-> colourLine(); - auto jrc = dipj->rightParticle()->colourInfo()-> colourLine(); - auto jla = dipj->leftParticle()->colourInfo()-> antiColourLine(); - auto jra = dipj->rightParticle()->colourInfo()-> antiColourLine(); - auto klc = dipk->leftParticle()->colourInfo()-> colourLine(); - auto krc = dipk->rightParticle()->colourInfo()-> colourLine(); - auto kla = dipk->leftParticle()->colourInfo()-> antiColourLine(); - auto kra = dipk->rightParticle()->colourInfo()-> antiColourLine(); - - if( ilc && irc ) rmcol(ilc,irc,dipi); - if( ila && ira ) rmcol(ila,ira,dipi); - if( jlc && jrc ) rmcol(jlc,jrc,dipj); - if( jla && jra ) rmcol(jla,jra,dipj); - if( klc && krc ) rmcol(klc,krc,dipk); - if( kla && kra ) rmcol(kla,kra,dipk); - - return; -} - - - -void Colorea::rearrange3_FF_FF_FF(list::iterator dipi, - list::iterator dipj, - list::iterator dipk){ - produceSwapping( dipi, dipj, dipk,true); - // compared to IF of FI dipoles we do not need to repair colors as - // the swapping just modified the gluon momenta. -} - - - - - -void Colorea::rearrange3_FF_FI_IF(list::iterator dipi, - list::iterator dipj, - list::iterator dipk){ - auto ilc = dipi->leftParticle()->colourInfo()-> colourLine(); - auto irc = dipi->rightParticle()->colourInfo()-> colourLine(); - auto ila = dipi->leftParticle()->colourInfo()-> antiColourLine(); - auto ira = dipi->rightParticle()->colourInfo()-> antiColourLine(); - auto jlc = dipj->leftParticle()->colourInfo()-> colourLine(); - auto jrc = dipj->rightParticle()->colourInfo()-> colourLine(); - auto jla = dipj->leftParticle()->colourInfo()-> antiColourLine(); - auto jra = dipj->rightParticle()->colourInfo()-> antiColourLine(); - auto klc = dipk->leftParticle()->colourInfo()-> colourLine(); - auto krc = dipk->rightParticle()->colourInfo()-> colourLine(); - auto kla = dipk->leftParticle()->colourInfo()-> antiColourLine(); - auto kra = dipk->rightParticle()->colourInfo()-> antiColourLine(); - - bool didperm = produceSwapping( dipi, dipj, dipk,false); - - if (!didperm)return; - removeColors(dipi,dipj,dipk); - auto new1Line = new_ptr(ColourLine()); - auto new2Line = new_ptr(ColourLine()); - auto new3Line = new_ptr(ColourLine()); - //Example: - // before - //ila (F)--irc (F) =g1(in,jl)= jla (F) -- jra(I)=g2(in,jr)=klc(I) -- krc(F) - // Should be after: - //ila (F) -- ira (I) =g2(in,jl)= jlc (I) -- jrc(F) =g1(out,jr)= kla(F) -- krc(F) - - //Then: - // FaFc_FaIa_IcFc FFFIIF aa -> FaIa_IcFc_FaFc - // FcFa_FcIc_IaFa FFFIIF cc -> FcIc_IaFa_FcFa - // FaFc_FaIa_IcIa FFFIII aa -> FaIa_IcFc_FaIa - // FcFa_FcIc_IaIc FFFIII cc -> FcIc_IaFa_FcIc - // IcFc_FaIa_IcFc IFFIIF aa -> IcIa_IcFc_FaFc - // IaFa_FcIc_IaFa IFFIIF cc -> IaIc_IaFa_FcFa - // IcFc_FaIa_IcIa IFFIII aa -> IcIa_IcFc_FaIa - // IaFa_FcIc_IaIc IFFIII cc -> IaIc_IaFa_FcIc - // end particles keep colors - // central all change color. - // - - if(ilc==irc){ - new1Line->addColoured (dipi->leftParticle()); - new1Line->addAntiColoured (dipi->rightParticle());} - if(ilc==ira){ - new1Line->addColoured (dipi->leftParticle()); - new1Line->addColoured (dipi->rightParticle());} - if(ila==irc){ - new1Line->addAntiColoured (dipi->leftParticle()); - new1Line->addAntiColoured (dipi->rightParticle());} - if(ila==ira){ - new1Line->addAntiColoured (dipi->leftParticle()); - new1Line->addColoured (dipi->rightParticle());} - - if(jlc==jrc){ - new2Line->addAntiColoured (dipj->leftParticle()); - new2Line->addAntiColoured (dipj->rightParticle());} - if(jlc==jra){ - new2Line->addAntiColoured (dipj->leftParticle()); - new2Line->addColoured (dipj->rightParticle());} - if(jla==jrc){ - new2Line->addColoured (dipj->leftParticle()); - new2Line->addAntiColoured (dipj->rightParticle());} - if(jla==jra){ - new2Line->addColoured (dipj->leftParticle()); - new2Line->addColoured (dipj->rightParticle());} - - if(klc==krc){ - new3Line->addAntiColoured (dipk->leftParticle()); - new3Line->addColoured (dipk->rightParticle());} - if(klc==kra){ - new3Line->addAntiColoured (dipk->leftParticle()); - new3Line->addAntiColoured (dipk->rightParticle());} - if(kla==krc){ - new3Line->addColoured (dipk->leftParticle()); - new3Line->addColoured (dipk->rightParticle());} - if(kla==kra){ - new3Line->addColoured (dipk->leftParticle()); - new3Line->addAntiColoured (dipk->rightParticle());} - -} - - - -void Colorea::rearrange3(list::iterator dipi, - list::iterator dipj, - list::iterator dipk){ - - // We only care about the cenral dipole. - // If central dipole is FI or IF we need to take care that - // momentum fractions and pdfs are treated correctly. - // If central dipole is FF we only swap momenta. - // Also the color lines of IF and FI swappings - // needs to be repaired. - - bool dipjisFF = dipj->leftFraction() == 1 && dipj->rightFraction() == 1; - bool dipjisIF = dipj->leftFraction() != 1 && dipj->rightFraction() == 1; - bool dipjisFI = dipj->leftFraction() == 1 && dipj->rightFraction() != 1; - bool dipjisII = dipj->leftFraction() != 1 && dipj->rightFraction() != 1; - - // if the possibly swaping dipole is II we - // do nothing as this should not be swapped!(?) - if(dipjisII) return; - - if(dipjisFF){ - // possibly swap gluon momenta - rearrange3_FF_FF_FF(dipi,dipj,dipk); - } - // If central dipole is IF or FI -> keep end colors and swap central colors - else if( dipjisIF || dipjisFI ){ - rearrange3_FF_FI_IF(dipi,dipj,dipk); - } - else { - assert(false); - } - - - return; - -} - - // local helper function to fill madgraph momenta. -void fillMGmom(double * mom,Lorentz5Momentum lmom){ - mom[0]=lmom.t()/GeV; - mom[1]=lmom.x()/GeV; - mom[2]=lmom.y()/GeV; - mom[3]=lmom.z()/GeV; -} - - -bool Colorea::produceSwapping(list::iterator dipi, - list::iterator dipj, - list::iterator dipk,bool FF){ - - // get the process for all tripple dipole swappings. - static auto pro= eeuugg(); - - // set mass of q qbar - pro.setMass( 3 , dipi->leftParticle()->momentum().m()/GeV); - pro.setMass( 4 , dipk->rightParticle()->momentum().m()/GeV); - - // If the central dipole dipj is not a FF-dipole the rearragment is - // not a simple swapping of gluon momenta. We need to take care that - // the 'new' dipoles get the correct fraction, pdf and index assignments. - if(!FF){ - // for the interfacing with madgraph we need new momenta - double mom0[4], mom1[4], mom2[4]; - double mom3[4], mom4[4], mom5[4]; - - //q - double prefact=1.;//dipi->leftFraction()!=0.?-1.:1.; ?? - auto PP=dipi->leftParticle()->momentum(); - PP.setX(prefact*PP.x()); - PP.setY(prefact*PP.y()); - PP.setZ(prefact*PP.z()); - // get the momentum sum for the triple dipole system. - // we need this for the incoming e+e-. - auto fmomsum=PP; - // lets rotate the system to be sure that momenta - // are not misinterpreted as incomming. - PP=PP.rotateX(0.3); - fillMGmom(mom2,PP); - - - //qbar - prefact=1.;//dipk->rightFraction()!=0.?-1.:1.; - PP=dipk->rightParticle()->momentum(); - PP.setX(prefact*PP.x()); - PP.setY(prefact*PP.y()); - PP.setZ(prefact*PP.z()); - fmomsum+=PP; - PP=PP.rotateX(0.3); - fillMGmom(mom3,PP); - - //g1 - prefact=1.;//dipj->leftFraction()!=0.?-1.:1.; - PP=dipj->leftParticle()->momentum(); - PP.setX(prefact*PP.x()); - PP.setY(prefact*PP.y()); - PP.setZ(prefact*PP.z()); - fmomsum+=PP; - PP=PP.rotateX(0.3); - fillMGmom(mom4,PP); - - //g2 - prefact=1.;//dipj->rightFraction()!=0.?-1.:1.; - PP=dipj->rightParticle()->momentum(); - PP.setX(prefact*PP.x()); - PP.setY(prefact*PP.y()); - PP.setZ(prefact*PP.z()); - fmomsum+=PP; - PP=PP.rotateX(0.3); - fillMGmom(mom5,PP); - - // get the boost to to triple dipole restframe - auto boostto=fmomsum.findBoostToCM(); - // center of mass energy. - auto CME=fmomsum.m2(); - // construct incoming momenta. - // point incoming axis along arbitrary y axis; - Lorentz5Momentum in1=Lorentz5Momentum(ZERO,sqrt(CME)/2.,ZERO,sqrt(CME)/2.); - Lorentz5Momentum in2=Lorentz5Momentum(ZERO,-sqrt(CME)/2.,ZERO,sqrt(CME)/2.); - - in1=in1.boost(-boostto); - in1=in1.rotateX(0.3); - in2=in2.boost(-boostto); - in2=in2.rotateX(0.3); - fillMGmom(mom0,in1); - fillMGmom(mom1,in2); - - vector < double * > momenta{{ mom0, mom1, mom2, - mom3, mom4, mom5}}; - - // calculate the permutation from madgraph process. - auto perm=pro.producePermutation(UseRandom::rnd(),momenta); - // for tripple dipoles there is only one possible permutation. - bool didperm=perm[0]!=5; - - if(!didperm) return didperm; - - // insert the original dipj fractions - vector tmpfrac{{dipj->leftFraction(),dipj->rightFraction()}}; - // insert the original dipj pdfs - vector< PDF > tmppdf; - tmppdf.push_back(dipj->leftPDF()); - tmppdf.push_back(dipj->rightPDF()); - // insert the original dipj particles - vector tmppart; - tmppart.push_back(dipj->leftParticle()); - tmppart.push_back(dipj->rightParticle()); - // make sure the dipj are gluons. - assert(dipj->leftParticle()->id()==21); - assert(dipj->rightParticle()->id()==21); - - // Now set the new or old particles in the dipole - dipi->rightParticle(tmppart[perm[0]-1-4]); - dipj->leftParticle (tmppart[perm[0]-1-4]); - dipj->rightParticle(tmppart[perm[1]-1-4]); - dipk->leftParticle(tmppart[perm[1]-1-4]); - - dipi->rightPDF(tmppdf[perm[0]-1-4]); - dipj->leftPDF (tmppdf[perm[0]-1-4]); - dipj->rightPDF(tmppdf[perm[1]-1-4]); - dipk->leftPDF (tmppdf[perm[1]-1-4]); - - dipi->rightFraction(tmpfrac[perm[0]-1-4]); - dipj->leftFraction (tmpfrac[perm[0]-1-4]); - dipj->rightFraction(tmpfrac[perm[1]-1-4]); - dipk->leftFraction (tmpfrac[perm[1]-1-4]); - - - auto firstindex =DipoleIndex(&(dipj->leftParticle()->data()), - &(dipj->rightParticle()->data()), - dipj->leftPDF(), - dipj->rightPDF()); - auto secondindex =DipoleIndex(&(dipj->rightParticle()->data()), - &(dipj->leftParticle()->data()), - dipj->rightPDF(), - dipj->leftPDF()); - dipj->setFirstIndex(firstindex); - dipj->setSecondIndex(secondindex); - - auto firstindex2 =DipoleIndex(&(dipi->leftParticle()->data()), - &(dipi->rightParticle()->data()), - dipi->leftPDF(), - dipi->rightPDF()); - auto secondindex2 =DipoleIndex(&(dipi->rightParticle()->data()), - &(dipi->leftParticle()->data()), - dipi->rightPDF(), - dipi->leftPDF()); - dipi->setFirstIndex(firstindex2); - dipi->setSecondIndex(secondindex2); - - auto firstindex3 =DipoleIndex(&(dipk->leftParticle()->data()), - &(dipk->rightParticle()->data()), - dipk->leftPDF(), - dipk->rightPDF()); - auto secondindex3 =DipoleIndex(&(dipk->rightParticle()->data()), - &(dipk->leftParticle()->data()), - dipk->rightPDF(), - dipk->leftPDF()); - dipk->setFirstIndex(firstindex3); - dipk->setSecondIndex(secondindex3); - // check a few things - // assert(dipj->leftFraction()!=1.&&(dipj->leftPDF().pdf() ) || dipj->leftFraction()==1. &&!(dipj->leftPDF().pdf())); - // assert(dipj->rightFraction()!=1.&&(dipj->rightPDF().pdf() )|| dipj->rightFraction()==1.&&!(dipj->rightPDF().pdf())); - // assert(dipi->leftFraction()!=1.&&(dipi->leftPDF().pdf() ) || dipi->leftFraction()==1. &&!(dipi->leftPDF().pdf())); - // assert(dipi->rightFraction()!=1.&&(dipi->rightPDF().pdf() )|| dipi->rightFraction()==1.&&!(dipi->rightPDF().pdf())); - // assert(dipk->leftFraction()!=1.&&(dipk->leftPDF().pdf() ) || dipk->leftFraction()==1. &&!(dipk->leftPDF().pdf())); - // assert(dipk->rightFraction()!=1.&&(dipk->rightPDF().pdf() )|| dipk->rightFraction()==1.&&!(dipk->rightPDF().pdf())); - - return didperm; - }else{ - // if dipj is a FF dipole the color rearrangement is done by - // swapping the gluon momenta. Let's do this! - - double mom0[4]; - double mom1[4]; - double mom2[4]; - double mom3[4]; - double mom4[4]; - double mom5[4]; - vector tmpvec; - - //q - auto PP=dipi->leftParticle()->momentum(); - auto fmomsum=PP; - PP=PP.rotateX(0.3); - fillMGmom(mom2,PP); - - //qbar - PP=dipk->rightParticle()->momentum(); - fmomsum+=PP; - PP=PP.rotateX(0.3); - fillMGmom(mom3,PP); - - //g1 - PP=dipj->leftParticle()->momentum(); - fmomsum+=PP; - PP=PP.rotateX(0.3); - fillMGmom(mom4,PP); - - //g2 - PP=dipj->rightParticle()->momentum(); - fmomsum+=PP; - PP=PP.rotateX(0.3); - fillMGmom(mom5,PP); - - // get the boost to to triple dipole restframe - auto boostto=fmomsum.findBoostToCM(); - - auto CME=fmomsum.m2(); - // point incoming axis along arbitrary y axis; - Lorentz5Momentum in1=Lorentz5Momentum(ZERO,sqrt(CME)/2.,ZERO,sqrt(CME)/2.); - Lorentz5Momentum in2=Lorentz5Momentum(ZERO,-sqrt(CME)/2.,ZERO,sqrt(CME)/2.); - - - - assert(dipj->leftParticle()->id()==21); - assert(dipj->rightParticle()->id()==21); - - in1=in1.boost(-boostto); - in1=in1.rotateX(0.3); - in2=in2.boost(-boostto); - in2=in2.rotateX(0.3); - fillMGmom(mom0,in1); - fillMGmom(mom1,in2); - - vector < double * > momenta{{ mom0, mom1, mom2, - mom3, mom4, mom5}}; - - // calculate the permutation from madgraph process. - auto perm=pro.producePermutation(UseRandom::rnd(),momenta); - - bool didperm=perm[0]!=5; - - // For final state we can just swap gluon momenta. - tmpvec.push_back(dipj->leftParticle()->momentum()); // g1 - tmpvec.push_back(dipj->rightParticle()->momentum()); // g2 - - dipj->leftParticle() ->setMomentum(tmpvec[perm[0]-1-4]); - dipj->rightParticle()->setMomentum(tmpvec[perm[1]-1-4]); - - return didperm; - } - -} - - - - - -void Colorea::rearrange4(list::iterator dipi, - list::iterator dipj, - list::iterator dipk, - list::iterator dipl){ - - assert(dipk->leftParticle()==dipj->rightParticle()); - assert(dipl->leftParticle()==dipk->rightParticle()); - - double mom0[4], mom1[4], mom2[4], mom3[4]; - double mom6[4], mom4[4], mom5[4]; - - // q g1 g2 g3 qbar - // il -- ir=jl -- jr=kl -- kr=ll -- lr - - //q - fillMGmom(mom2,dipi->leftParticle()->momentum()); - //qbar - fillMGmom(mom3,dipl->rightParticle()->momentum()); - //g1 - fillMGmom(mom4,dipj->leftParticle()->momentum()); - //g2 - fillMGmom(mom5,dipj->rightParticle()->momentum()); - //g3 - fillMGmom(mom6,dipl->leftParticle()->momentum()); - - // q g1 g2 g3 qbar - // il -- ir=jl -- jr=kl -- kr=ll -- lr - auto fmomsum=dipi->leftParticle()->momentum()+ - dipj->leftParticle()->momentum()+ - dipj->rightParticle()->momentum()+ - dipl->leftParticle()->momentum()+ - dipl->rightParticle()->momentum(); - - auto boostto=fmomsum.findBoostToCM(); - - auto CME=fmomsum.m2(); - // point incoming axis along arbitrary y axis; - Lorentz5Momentum in1=Lorentz5Momentum(ZERO,sqrt(CME)/2.,ZERO,sqrt(CME)/2.); - Lorentz5Momentum in2=Lorentz5Momentum(ZERO,-sqrt(CME)/2.,ZERO,sqrt(CME)/2.); - - in1=in1.boost(-boostto); - in2=in2.boost(-boostto); - fillMGmom(mom0,in1); - fillMGmom(mom1,in2); - - vector < double * > momenta{{ mom0, mom1, - mom2, mom3, - mom4, mom5, mom6}}; - - static auto pro= eeuuggg(); - - // set mass of q qbar - pro.setMass( 3 , dipi->leftParticle()->momentum().m()/GeV); - pro.setMass( 5 , dipl->rightParticle()->momentum().m()/GeV); - - - auto perm=pro.producePermutation(UseRandom::rnd(),momenta); - - vector tmpvec; - tmpvec.push_back(dipj->leftParticle()->momentum()); // g1 - tmpvec.push_back(dipj->rightParticle()->momentum()); // g2 - tmpvec.push_back(dipl->leftParticle()->momentum()); // g3 - - dipj->leftParticle() ->setMomentum(tmpvec[perm[0]-1-4]); - dipj->rightParticle()->setMomentum(tmpvec[perm[1]-1-4]); - dipl->leftParticle() ->setMomentum(tmpvec[perm[2]-1-4]); - -} - - - - - -void Colorea::rearrange5(list::iterator dipi, - list::iterator dipj, - list::iterator dipk, - list::iterator dipl, - list::iterator dipm){ - - assert(dipk->leftParticle()==dipj->rightParticle()); - assert(dipl->leftParticle()==dipk->rightParticle()); - - - double mom0[4], mom1[4], mom2[4], mom3[4]; - double mom4[4], mom5[4], mom6[4], mom7[4]; - // q g1 g2 g3 g4 qbar - // il -- ir=jl -- jr=kl -- kr=ll -- lr=ml -- mr - - //q - fillMGmom(mom2,dipi->leftParticle()->momentum()); - //qbar - fillMGmom(mom3,dipm->rightParticle()->momentum()); - //g1 - fillMGmom(mom4,dipj->leftParticle()->momentum()); - //g2 - fillMGmom(mom5,dipj->rightParticle()->momentum()); - //g3 - fillMGmom(mom6,dipl->leftParticle()->momentum()); - //g4 - fillMGmom(mom7,dipm->leftParticle()->momentum()); - - // q g1 g2 g3 g4 qbar - // il -- ir=jl -- jr=kl -- kr=ll -- lr=ml -- mr - auto fmomsum=dipi->leftParticle()->momentum()+ - dipj->leftParticle()->momentum()+ - dipj->rightParticle()->momentum()+ - dipl->leftParticle()->momentum()+ - dipl->rightParticle()->momentum()+ - dipm->rightParticle()->momentum(); - - auto boostto=fmomsum.findBoostToCM(); - - auto CME=fmomsum.m2(); - // point incoming axis along arbitrary y axis; - Lorentz5Momentum in1=Lorentz5Momentum(ZERO,sqrt(CME)/2.,ZERO,sqrt(CME)/2.); - Lorentz5Momentum in2=Lorentz5Momentum(ZERO,-sqrt(CME)/2.,ZERO,sqrt(CME)/2.); - - - in1=in1.boost(-boostto); - in2=in2.boost(-boostto); - fillMGmom(mom0,in1); - fillMGmom(mom1,in2); - - vector < double * > momenta{{ mom0, mom1, mom2, mom3, - mom4, mom5, mom6, mom7}}; - - static auto pro= eeuugggg(); - - // set mass of q qbar - pro.setMass( 3 , dipi->leftParticle()->momentum().m()/GeV); - pro.setMass( 5 , dipl->rightParticle()->momentum().m()/GeV); - - auto perm=pro.producePermutation(UseRandom::rnd(),momenta); - - vector tmpvec; - tmpvec.push_back(dipj->leftParticle()->momentum()); // g1 - tmpvec.push_back(dipj->rightParticle()->momentum()); // g2 - tmpvec.push_back(dipl->leftParticle()->momentum()); // g3 - tmpvec.push_back(dipm->leftParticle()->momentum()); // g4 - - // set the gluon momenta with permuted momenta. - dipj->leftParticle() ->setMomentum(tmpvec[perm[0]-1-4]); - dipj->rightParticle()->setMomentum(tmpvec[perm[1]-1-4]); - dipl->leftParticle() ->setMomentum(tmpvec[perm[2]-1-4]); - dipm->leftParticle() ->setMomentum(tmpvec[perm[3]-1-4]); - -} - - - - - - diff --git a/Shower/Dipole/Colorea/Colorea.fh b/Shower/Dipole/Colorea/Colorea.fh deleted file mode 100644 --- a/Shower/Dipole/Colorea/Colorea.fh +++ /dev/null @@ -1,21 +0,0 @@ -// -*- C++ -*- -// This is the forward declaration of the Colorea class - -#ifndef HERWIG_Colorea_FH -#define HERWIG_Colorea_FH - -#include "ThePEG/Config/ThePEG.h" -#include "ThePEG/Config/Pointers.h" - - -namespace Herwig { - -class Colorea; -using namespace ThePEG; - - ThePEG_DECLARE_POINTERS(Colorea , ColoreaPtr ); - - -} - -#endif // HERWIG_Colorea_FH diff --git a/Shower/Dipole/Colorea/Colorea.h b/Shower/Dipole/Colorea/Colorea.h deleted file mode 100644 --- a/Shower/Dipole/Colorea/Colorea.h +++ /dev/null @@ -1,147 +0,0 @@ -// -*- C++ -*- -// -// Colorea.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_Colorea_H -#define HERWIG_Colorea_H -// -// This is the declaration of the Colorea class. -// -#include "Herwig/Shower/Dipole/Base/DipoleChain.fh" -#include "Herwig/Shower/Dipole/Base/Dipole.h" - -namespace Herwig { - -using namespace ThePEG; - -/** - * \ingroup DipoleShower - * \author Johannes Bellm - * - * This class implemets the method described in arXiv:1801.06113. - * and it's extension described in arXiv:180X.XXXXX. - * It allows to calculate the probability to rearrange - * dipole chains with simple matrix elements. - * - * The implementation currently allows: - * - rearranging pure FF dipole chains with - * processes: eeuugg eeuuggg and eeuugggg - * - IF or FI dipoles can be rearranged with eeuugg. - * - II should not be rearranged. - * - masses of the q qbar particles are set. - * - */ -class Colorea { - -public: - - /** - * Default constructor - */ - Colorea(); - - /** - * main function to rearrange the dipole chain. - * - dipmax: chains with dipmax are rearranged with matix elements including - * dipmax dipoles: - * dipmax=3 -> eeuugg - * dipmax=4 -> eeuuggg - * dipmax=5 -> eeuugggg - * if a chain contains more than dipmax dipoles, we treat the chain - * as long. - * - diplong: this parameter allows to change the behaviour for Coloreas - * that are longer than dipmax (long chains). - * If diplong is 3 the chain is rearranged with eeuugg - * matrix elements. - * If diplong is 4 the chain is rearranged with eeuuggg - * matrix elements. diplong > 4 is currently not implemented. - * Note: We dont observe a difference between the diplong=3 or - * diplong=4 treatment. - */ - void rearrange(int dipmax,int diplong); - - /** - * Set the chain to use in the rearrangement. - */ - void setChain(Ptr::tptr ch){theChain=ch;}; - - // Everything below is private. The rearranging is acting only on the current chain. - private: - /** - * Main function for rearranging tripple dipoles. - */ - void rearrange3(list::iterator dipi, - list::iterator dipj, - list::iterator dipk); - - /** - * Function to rearrange triple dipoles in the all FF dipole case. - */ - void rearrange3_FF_FF_FF(list::iterator dipi, - list::iterator dipj, - list::iterator dipk); - - /** - * Function to rearrange triple dipoles if dipj is FI dipole. - * This function is also used for IF. - */ - void rearrange3_FF_FI_IF(list::iterator dipi, - list::iterator dipj, - list::iterator dipk); - /** - * Main function for rearranging 4 dipoles. - * This funtion currently only implements the case of 4 FF dipoles. - */ - void rearrange4(list::iterator dipi, - list::iterator dipj, - list::iterator dipk, - list::iterator dipl); - /** - * Main function for rearranging 5 dipoles. - * This funtion currently only implements the case of 5 FF dipoles. - */ - void rearrange5(list::iterator dipi, - list::iterator dipj, - list::iterator dipk, - list::iterator dipl, - list::iterator dipm); - /** - * Rearrange long chains. - */ - void rearrangeLong(int diplong); - - /** - * Produce the possible swapping or the dipj gluons. - */ - bool produceSwapping(list::iterator dipi, - list::iterator dipj, - list::iterator dipk,bool FF); - - // helper function to remove particles from color line if color line connects them. - void rmcol(tColinePtr A,tColinePtr B, list::iterator & dip); - - // remove connecting color lines from these dipoles - void removeColors(list::iterator dipi, - list::iterator dipj, - list::iterator dipk); - - // Access the dipoles of the current chain. - list& dipoles(); - - private: - // the current chain to rearrange. - Ptr::tptr theChain; - -}; - -inline ostream& operator << (ostream& os, const Colorea& ) { - return os; -} - -} - -#endif /* HERWIG_Colorea_H */ diff --git a/Shower/Dipole/Colorea/HelAmps_sm.cc b/Shower/Dipole/Colorea/HelAmps_sm.cc deleted file mode 100644 --- a/Shower/Dipole/Colorea/HelAmps_sm.cc +++ /dev/null @@ -1,1027 +0,0 @@ -//========================================================================== -// This file has been automatically generated for C++ Standalone by -// MadGraph5_aMC@NLO v. 2.5.4, 2017-03-28 -// By the MadGraph5_aMC@NLO Development Team -// Visit launchpad.net/madgraph5 and amcatnlo.web.cern.ch -//========================================================================== - -#include "HelAmps_sm.h" -#include -#include -#include -#include -using namespace std; - -namespace MG5_sm_COLOREA -{ - -void ixxxxx(double p[4], double fmass, int nhel, int nsf, complex fi[6]) -{ - complex chi[2]; - double sf[2], sfomega[2], omega[2], pp, pp3, sqp0p3, sqm[2]; - int ip, im, nh; - fi[0] = complex (-p[0] * nsf, -p[3] * nsf); - fi[1] = complex (-p[1] * nsf, -p[2] * nsf); - nh = nhel * nsf; - if (fmass != 0.0) - { - pp = min(p[0], sqrt(p[1] * p[1] + p[2] * p[2] + p[3] * p[3])); - if (pp == 0.0) - { - sqm[0] = sqrt(std::abs(fmass)); - sqm[1] = Sgn(sqm[0], fmass); - ip = (1 + nh)/2; - im = (1 - nh)/2; - fi[2] = ip * sqm[ip]; - fi[3] = im * nsf * sqm[ip]; - fi[4] = ip * nsf * sqm[im]; - fi[5] = im * sqm[im]; - } - else - { - sf[0] = (1 + nsf + (1 - nsf) * nh) * 0.5; - sf[1] = (1 + nsf - (1 - nsf) * nh) * 0.5; - omega[0] = sqrt(p[0] + pp); - omega[1] = fmass/omega[0]; - ip = (1 + nh)/2; - im = (1 - nh)/2; - sfomega[0] = sf[0] * omega[ip]; - sfomega[1] = sf[1] * omega[im]; - pp3 = max(pp + p[3], 0.0); - chi[0] = complex (sqrt(pp3 * 0.5/pp), 0); - if (pp3 == 0.0) - { - chi[1] = complex (-nh, 0); - } - else - { - chi[1] = complex (nh * p[1], p[2])/sqrt(2.0 * pp * pp3); - } - fi[2] = sfomega[0] * chi[im]; - fi[3] = sfomega[0] * chi[ip]; - fi[4] = sfomega[1] * chi[im]; - fi[5] = sfomega[1] * chi[ip]; - } - } - else - { - if (p[1] == 0.0 and p[2] == 0.0 and p[3] < 0.0) - { - sqp0p3 = 0.0; - } - else - { - sqp0p3 = sqrt(max(p[0] + p[3], 0.0)) * nsf; - } - chi[0] = complex (sqp0p3, 0.0); - if (sqp0p3 == 0.0) - { - chi[1] = complex (-nhel * sqrt(2.0 * p[0]), 0.0); - } - else - { - chi[1] = complex (nh * p[1], p[2])/sqp0p3; - } - if (nh == 1) - { - fi[2] = complex (0.0, 0.0); - fi[3] = complex (0.0, 0.0); - fi[4] = chi[0]; - fi[5] = chi[1]; - } - else - { - fi[2] = chi[1]; - fi[3] = chi[0]; - fi[4] = complex (0.0, 0.0); - fi[5] = complex (0.0, 0.0); - } - } - return; -} - - -double Sgn(double a, double b) -{ - return (b < 0)? - abs(a):abs(a); -} - - -void txxxxx(double p[4], double tmass, int nhel, int nst, complex - tc[18]) -{ - complex ft[6][4], ep[4], em[4], e0[4]; - double pt, pt2, pp, pzpt, emp, sqh, sqs; - int i, j; - - sqh = sqrt(0.5); - sqs = sqrt(0.5/3); - - pt2 = p[1] * p[1] + p[2] * p[2]; - pp = min(p[0], sqrt(pt2 + p[3] * p[3])); - pt = min(pp, sqrt(pt2)); - - ft[4][0] = complex (p[0] * nst, p[3] * nst); - ft[5][0] = complex (p[1] * nst, p[2] * nst); - - // construct eps+ - if(nhel >= 0) - { - if(pp == 0) - { - ep[0] = complex (0, 0); - ep[1] = complex (-sqh, 0); - ep[2] = complex (0, nst * sqh); - ep[3] = complex (0, 0); - } - else - { - ep[0] = complex (0, 0); - ep[3] = complex (pt/pp * sqh, 0); - - if(pt != 0) - { - pzpt = p[3]/(pp * pt) * sqh; - ep[1] = complex (-p[1] * pzpt, -nst * p[2]/pt * sqh); - ep[2] = complex (-p[2] * pzpt, nst * p[1]/pt * sqh); - } - else - { - ep[1] = complex (-sqh, 0); - ep[2] = complex (0, nst * Sgn(sqh, p[3])); - } - } - - } - - // construct eps- - if(nhel <= 0) - { - if(pp == 0) - { - em[0] = complex (0, 0); - em[1] = complex (sqh, 0); - em[2] = complex (0, nst * sqh); - em[3] = complex (0, 0); - } - else - { - em[0] = complex (0, 0); - em[3] = complex (-pt/pp * sqh, 0); - - if(pt != 0) - { - pzpt = -p[3]/(pp * pt) * sqh; - em[1] = complex (-p[1] * pzpt, -nst * p[2]/pt * sqh); - em[2] = complex (-p[2] * pzpt, nst * p[1]/pt * sqh); - } - else - { - em[1] = complex (sqh, 0); - em[2] = complex (0, nst * Sgn(sqh, p[3])); - } - } - } - - // construct eps0 - if(std::labs(nhel) <= 1) - { - if(pp == 0) - { - e0[0] = complex (0, 0); - e0[1] = complex (0, 0); - e0[2] = complex (0, 0); - e0[3] = complex (1, 0); - } - else - { - emp = p[0]/(tmass * pp); - e0[0] = complex (pp/tmass, 0); - e0[3] = complex (p[3] * emp, 0); - - if(pt != 0) - { - e0[1] = complex (p[1] * emp, 0); - e0[2] = complex (p[2] * emp, 0); - } - else - { - e0[1] = complex (0, 0); - e0[2] = complex (0, 0); - } - } - } - - if(nhel == 2) - { - for(j = 0; j < 4; j++ ) - { - for(i = 0; i < 4; i++ ) - ft[i][j] = ep[i] * ep[j]; - } - } - else if(nhel == -2) - { - for(j = 0; j < 4; j++ ) - { - for(i = 0; i < 4; i++ ) - ft[i][j] = em[i] * em[j]; - } - } - else if(tmass == 0) - { - for(j = 0; j < 4; j++ ) - { - for(i = 0; i < 4; i++ ) - ft[i][j] = 0; - } - } - else if(tmass != 0) - { - if(nhel == 1) - { - for(j = 0; j < 4; j++ ) - { - for(i = 0; i < 4; i++ ) - ft[i][j] = sqh * (ep[i] * e0[j] + e0[i] * ep[j]); - } - } - else if(nhel == 0) - { - for(j = 0; j < 4; j++ ) - { - for(i = 0; i < 4; i++ ) - ft[i][j] = sqs * (ep[i] * em[j] + em[i] * ep[j] - + 2.0 * e0[i] * e0[j]); - } - } - else if(nhel == -1) - { - for(j = 0; j < 4; j++ ) - { - for(i = 0; i < 4; i++ ) - ft[i][j] = sqh * (em[i] * e0[j] + e0[i] * em[j]); - } - } - else - { - std::cerr << "Invalid helicity in txxxxx.\n"; - std::exit(1); - } - } - - tc[0] = ft[4][0]; - tc[1] = ft[5][0]; - - for(j = 0; j < 4; j++ ) - { - for(i = 0; i < 4; i++ ) - tc[j * 4 + i + 2] = ft[j][i]; - } -} - -void vxxxxx(double p[4], double vmass, int nhel, int nsv, complex vc[6]) -{ - double hel, hel0, pt, pt2, pp, pzpt, emp, sqh; - int nsvahl; - sqh = sqrt(0.5); - hel = double(nhel); - nsvahl = nsv * std::abs(hel); - pt2 = (p[1] * p[1]) + (p[2] * p[2]); - pp = min(p[0], sqrt(pt2 + (p[3] * p[3]))); - pt = min(pp, sqrt(pt2)); - vc[0] = complex (p[0] * nsv, p[3] * nsv); - vc[1] = complex (p[1] * nsv, p[2] * nsv); - if (vmass != 0.0) - { - hel0 = 1.0 - std::abs(hel); - if(pp == 0.0) - { - vc[2] = complex (0.0, 0.0); - vc[3] = complex (-hel * sqh, 0.0); - vc[4] = complex (0.0, nsvahl * sqh); - vc[5] = complex (hel0, 0.0); - } - else - { - emp = p[0]/(vmass * pp); - vc[2] = complex (hel0 * pp/vmass, 0.0); - vc[5] = complex (hel0 * p[3] * emp + hel * pt/pp * sqh, 0.0); - if (pt != 0.0) - { - pzpt = p[3]/(pp * pt) * sqh * hel; - vc[3] = complex (hel0 * p[1] * emp - p[1] * pzpt, -nsvahl * - p[2]/pt * sqh); - vc[4] = complex (hel0 * p[2] * emp - p[2] * pzpt, nsvahl * - p[1]/pt * sqh); - } - else - { - vc[3] = complex (-hel * sqh, 0.0); - vc[4] = complex (0.0, nsvahl * Sgn(sqh, p[3])); - } - } - } - else - { - pp = p[0]; - pt = sqrt((p[1] * p[1]) + (p[2] * p[2])); - vc[2] = complex (0.0, 0.0); - vc[5] = complex (hel * pt/pp * sqh, 0.0); - if (pt != 0.0) - { - pzpt = p[3]/(pp * pt) * sqh * hel; - vc[3] = complex (-p[1] * pzpt, -nsv * p[2]/pt * sqh); - vc[4] = complex (-p[2] * pzpt, nsv * p[1]/pt * sqh); - } - else - { - vc[3] = complex (-hel * sqh, 0.0); - vc[4] = complex (0.0, nsv * Sgn(sqh, p[3])); - } - } - return; -} - -void sxxxxx(double p[4], int nss, complex sc[3]) -{ - sc[2] = complex (1.00, 0.00); - sc[0] = complex (p[0] * nss, p[3] * nss); - sc[1] = complex (p[1] * nss, p[2] * nss); - return; -} - -void oxxxxx(double p[4], double fmass, int nhel, int nsf, complex fo[6]) -{ - complex chi[2]; - double sf[2], sfomeg[2], omega[2], pp, pp3, sqp0p3, sqm[2]; - int nh, ip, im; - fo[0] = complex (p[0] * nsf, p[3] * nsf); - fo[1] = complex (p[1] * nsf, p[2] * nsf); - nh = nhel * nsf; - if (fmass != 0.000) - { - pp = min(p[0], sqrt((p[1] * p[1]) + (p[2] * p[2]) + (p[3] * p[3]))); - if (pp == 0.000) - { - sqm[0] = sqrt(std::abs(fmass)); - sqm[1] = Sgn(sqm[0], fmass); - ip = -((1 - nh)/2) * nhel; - im = (1 + nh)/2 * nhel; - fo[2] = im * sqm[std::abs(ip)]; - fo[3] = ip * nsf * sqm[std::abs(ip)]; - fo[4] = im * nsf * sqm[std::abs(im)]; - fo[5] = ip * sqm[std::abs(im)]; - } - else - { - pp = min(p[0], sqrt((p[1] * p[1]) + (p[2] * p[2]) + (p[3] * p[3]))); - sf[0] = double(1 + nsf + (1 - nsf) * nh) * 0.5; - sf[1] = double(1 + nsf - (1 - nsf) * nh) * 0.5; - omega[0] = sqrt(p[0] + pp); - omega[1] = fmass/omega[0]; - ip = (1 + nh)/2; - im = (1 - nh)/2; - sfomeg[0] = sf[0] * omega[ip]; - sfomeg[1] = sf[1] * omega[im]; - pp3 = max(pp + p[3], 0.00); - chi[0] = complex (sqrt(pp3 * 0.5/pp), 0.00); - if (pp3 == 0.00) - { - chi[1] = complex (-nh, 0.00); - } - else - { - chi[1] = complex (nh * p[1], -p[2])/sqrt(2.0 * pp * pp3); - } - fo[2] = sfomeg[1] * chi[im]; - fo[3] = sfomeg[1] * chi[ip]; - fo[4] = sfomeg[0] * chi[im]; - fo[5] = sfomeg[0] * chi[ip]; - } - } - else - { - if((p[1] == 0.00) and (p[2] == 0.00) and (p[3] < 0.00)) - { - sqp0p3 = 0.00; - } - else - { - sqp0p3 = sqrt(max(p[0] + p[3], 0.00)) * nsf; - } - chi[0] = complex (sqp0p3, 0.00); - if(sqp0p3 == 0.000) - { - chi[1] = complex (-nhel, 0.00) * sqrt(2.0 * p[0]); - } - else - { - chi[1] = complex (nh * p[1], -p[2])/sqp0p3; - } - if(nh == 1) - { - fo[2] = chi[0]; - fo[3] = chi[1]; - fo[4] = complex (0.00, 0.00); - fo[5] = complex (0.00, 0.00); - } - else - { - fo[2] = complex (0.00, 0.00); - fo[3] = complex (0.00, 0.00); - fo[4] = chi[1]; - fo[5] = chi[0]; - } - } - return; -} - -void FFV1P0_3(std::complex F1[], std::complex F2[], - std::complex COUP, double M3, double W3, std::complex V3[]) -{ - static std::complex cI = std::complex (0., 1.); - double P3[4]; - std::complex denom; - V3[0] = +F1[0] + F2[0]; - V3[1] = +F1[1] + F2[1]; - P3[0] = -V3[0].real(); - P3[1] = -V3[1].real(); - P3[2] = -V3[1].imag(); - P3[3] = -V3[0].imag(); - denom = COUP/((P3[0] * P3[0]) - (P3[1] * P3[1]) - (P3[2] * P3[2]) - (P3[3] * - P3[3]) - M3 * (M3 - cI * W3)); - V3[2] = denom * (-cI) * (F1[2] * F2[4] + F1[3] * F2[5] + F1[4] * F2[2] + - F1[5] * F2[3]); - V3[3] = denom * (-cI) * (F1[4] * F2[3] + F1[5] * F2[2] - F1[2] * F2[5] - - F1[3] * F2[4]); - V3[4] = denom * (-cI) * (-cI * (F1[2] * F2[5] + F1[5] * F2[2]) + cI * (F1[3] - * F2[4] + F1[4] * F2[3])); - V3[5] = denom * (-cI) * (F1[3] * F2[5] + F1[4] * F2[2] - F1[2] * F2[4] - - F1[5] * F2[3]); -} - - -void FFV2_2(std::complex F1[], std::complex V3[], - std::complex COUP, double M2, double W2, std::complex F2[]) -{ - static std::complex cI = std::complex (0., 1.); - double P2[4]; - std::complex denom; - F2[0] = +F1[0] + V3[0]; - F2[1] = +F1[1] + V3[1]; - P2[0] = -F2[0].real(); - P2[1] = -F2[1].real(); - P2[2] = -F2[1].imag(); - P2[3] = -F2[0].imag(); - denom = COUP/((P2[0] * P2[0]) - (P2[1] * P2[1]) - (P2[2] * P2[2]) - (P2[3] * - P2[3]) - M2 * (M2 - cI * W2)); - F2[2] = denom * cI * (F1[2] * (P2[0] * (V3[2] + V3[5]) + (P2[1] * (-1.) * - (V3[3] + cI * (V3[4])) + (P2[2] * (+cI * (V3[3]) - V3[4]) - P2[3] * - (V3[2] + V3[5])))) + F1[3] * (P2[0] * (V3[3] - cI * (V3[4])) + (P2[1] * - (V3[5] - V3[2]) + (P2[2] * (-cI * (V3[5]) + cI * (V3[2])) + P2[3] * (+cI - * (V3[4]) - V3[3]))))); - F2[3] = denom * cI * (F1[2] * (P2[0] * (V3[3] + cI * (V3[4])) + (P2[1] * - (-1.) * (V3[2] + V3[5]) + (P2[2] * (-1.) * (+cI * (V3[2] + V3[5])) + - P2[3] * (V3[3] + cI * (V3[4]))))) + F1[3] * (P2[0] * (V3[2] - V3[5]) + - (P2[1] * (+cI * (V3[4]) - V3[3]) + (P2[2] * (-1.) * (V3[4] + cI * - (V3[3])) + P2[3] * (V3[2] - V3[5]))))); - F2[4] = denom * - cI * M2 * (F1[2] * (-1.) * (V3[2] + V3[5]) + F1[3] * (+cI * - (V3[4]) - V3[3])); - F2[5] = denom * cI * M2 * (F1[2] * (V3[3] + cI * (V3[4])) + F1[3] * (V3[2] - - V3[5])); -} - -void FFV2_5_2(std::complex F1[], std::complex V3[], - std::complex COUP1, std::complex COUP2, double M2, double - W2, std::complex F2[]) -{ - std::complex Ftmp[6]; - std::complex denom; - int i; - FFV2_2(F1, V3, COUP1, M2, W2, F2); - FFV5_2(F1, V3, COUP2, M2, W2, Ftmp); - i = 2; - while (i < 6) - { - F2[i] = F2[i] + Ftmp[i]; - i++; - } -} - -void FFV1_2(std::complex F1[], std::complex V3[], - std::complex COUP, double M2, double W2, std::complex F2[]) -{ - static std::complex cI = std::complex (0., 1.); - double P2[4]; - std::complex denom; - F2[0] = +F1[0] + V3[0]; - F2[1] = +F1[1] + V3[1]; - P2[0] = -F2[0].real(); - P2[1] = -F2[1].real(); - P2[2] = -F2[1].imag(); - P2[3] = -F2[0].imag(); - denom = COUP/((P2[0] * P2[0]) - (P2[1] * P2[1]) - (P2[2] * P2[2]) - (P2[3] * - P2[3]) - M2 * (M2 - cI * W2)); - F2[2] = denom * cI * (F1[2] * (P2[0] * (V3[2] + V3[5]) + (P2[1] * (-1.) * - (V3[3] + cI * (V3[4])) + (P2[2] * (+cI * (V3[3]) - V3[4]) - P2[3] * - (V3[2] + V3[5])))) + (F1[3] * (P2[0] * (V3[3] - cI * (V3[4])) + (P2[1] * - (V3[5] - V3[2]) + (P2[2] * (-cI * (V3[5]) + cI * (V3[2])) + P2[3] * (+cI - * (V3[4]) - V3[3])))) + M2 * (F1[4] * (V3[2] - V3[5]) + F1[5] * (+cI * - (V3[4]) - V3[3])))); - F2[3] = denom * (-cI) * (F1[2] * (P2[0] * (-1.) * (V3[3] + cI * (V3[4])) + - (P2[1] * (V3[2] + V3[5]) + (P2[2] * (+cI * (V3[2] + V3[5])) - P2[3] * - (V3[3] + cI * (V3[4]))))) + (F1[3] * (P2[0] * (V3[5] - V3[2]) + (P2[1] * - (V3[3] - cI * (V3[4])) + (P2[2] * (V3[4] + cI * (V3[3])) + P2[3] * (V3[5] - - V3[2])))) + M2 * (F1[4] * (V3[3] + cI * (V3[4])) - F1[5] * (V3[2] + - V3[5])))); - F2[4] = denom * (-cI) * (F1[4] * (P2[0] * (V3[5] - V3[2]) + (P2[1] * (V3[3] + - cI * (V3[4])) + (P2[2] * (V3[4] - cI * (V3[3])) + P2[3] * (V3[5] - - V3[2])))) + (F1[5] * (P2[0] * (V3[3] - cI * (V3[4])) + (P2[1] * (-1.) * - (V3[2] + V3[5]) + (P2[2] * (+cI * (V3[2] + V3[5])) + P2[3] * (V3[3] - cI - * (V3[4]))))) + M2 * (F1[2] * (-1.) * (V3[2] + V3[5]) + F1[3] * (+cI * - (V3[4]) - V3[3])))); - F2[5] = denom * cI * (F1[4] * (P2[0] * (-1.) * (V3[3] + cI * (V3[4])) + - (P2[1] * (V3[2] - V3[5]) + (P2[2] * (-cI * (V3[5]) + cI * (V3[2])) + - P2[3] * (V3[3] + cI * (V3[4]))))) + (F1[5] * (P2[0] * (V3[2] + V3[5]) + - (P2[1] * (+cI * (V3[4]) - V3[3]) + (P2[2] * (-1.) * (V3[4] + cI * - (V3[3])) - P2[3] * (V3[2] + V3[5])))) + M2 * (F1[2] * (V3[3] + cI * - (V3[4])) + F1[3] * (V3[2] - V3[5])))); -} - - -void FFV2_0(std::complex F1[], std::complex F2[], - std::complex V3[], std::complex COUP, std::complex - & vertex) -{ - static std::complex cI = std::complex (0., 1.); - std::complex TMP9; - TMP9 = (F1[2] * (F2[4] * (V3[2] + V3[5]) + F2[5] * (V3[3] + cI * (V3[4]))) + - F1[3] * (F2[4] * (V3[3] - cI * (V3[4])) + F2[5] * (V3[2] - V3[5]))); - vertex = COUP * - cI * TMP9; -} - -void FFV2_5_0(std::complex F1[], std::complex F2[], - std::complex V3[], std::complex COUP1, std::complex - COUP2, std::complex & vertex) -{ - std::complex tmp; - FFV2_0(F1, F2, V3, COUP1, vertex); - FFV5_0(F1, F2, V3, COUP2, tmp); - vertex = vertex + tmp; -} - -void FFV5_1(std::complex F2[], std::complex V3[], - std::complex COUP, double M1, double W1, std::complex F1[]) -{ - static std::complex cI = std::complex (0., 1.); - double P1[4]; - std::complex denom; - F1[0] = +F2[0] + V3[0]; - F1[1] = +F2[1] + V3[1]; - P1[0] = -F1[0].real(); - P1[1] = -F1[1].real(); - P1[2] = -F1[1].imag(); - P1[3] = -F1[0].imag(); - denom = COUP/((P1[0] * P1[0]) - (P1[1] * P1[1]) - (P1[2] * P1[2]) - (P1[3] * - P1[3]) - M1 * (M1 - cI * W1)); - F1[2] = denom * 4. * cI * (F2[2] * (P1[0] * (V3[5] - V3[2]) + (P1[1] * (V3[3] - - cI * (V3[4])) + (P1[2] * (V3[4] + cI * (V3[3])) + P1[3] * (V3[5] - - V3[2])))) + (+1./4. * (M1 * (F2[5] * (V3[3] + cI * (V3[4])) + 4. * (F2[4] - * 1./4. * (V3[2] + V3[5])))) + F2[3] * (P1[0] * (V3[3] + cI * (V3[4])) + - (P1[1] * (-1.) * (V3[2] + V3[5]) + (P1[2] * (-1.) * (+cI * (V3[2] + - V3[5])) + P1[3] * (V3[3] + cI * (V3[4]))))))); - F1[3] = denom * 4. * cI * (F2[2] * (P1[0] * (V3[3] - cI * (V3[4])) + (P1[1] * - (V3[5] - V3[2]) + (P1[2] * (-cI * (V3[5]) + cI * (V3[2])) + P1[3] * (+cI - * (V3[4]) - V3[3])))) + (+1./4. * (M1 * (F2[5] * (V3[2] - V3[5]) + 4. * - (F2[4] * 1./4. * (V3[3] - cI * (V3[4]))))) + F2[3] * (P1[0] * (-1.) * - (V3[2] + V3[5]) + (P1[1] * (V3[3] + cI * (V3[4])) + (P1[2] * (V3[4] - cI - * (V3[3])) + P1[3] * (V3[2] + V3[5])))))); - F1[4] = denom * (-cI) * (F2[4] * (P1[0] * (V3[2] + V3[5]) + (P1[1] * (+cI * - (V3[4]) - V3[3]) + (P1[2] * (-1.) * (V3[4] + cI * (V3[3])) - P1[3] * - (V3[2] + V3[5])))) + (F2[5] * (P1[0] * (V3[3] + cI * (V3[4])) + (P1[1] * - (V3[5] - V3[2]) + (P1[2] * (-cI * (V3[2]) + cI * (V3[5])) - P1[3] * - (V3[3] + cI * (V3[4]))))) + M1 * (F2[2] * 4. * (V3[5] - V3[2]) + 4. * - (F2[3] * (V3[3] + cI * (V3[4])))))); - F1[5] = denom * cI * (F2[4] * (P1[0] * (+cI * (V3[4]) - V3[3]) + (P1[1] * - (V3[2] + V3[5]) + (P1[2] * (-1.) * (+cI * (V3[2] + V3[5])) + P1[3] * (+cI - * (V3[4]) - V3[3])))) + (F2[5] * (P1[0] * (V3[5] - V3[2]) + (P1[1] * - (V3[3] + cI * (V3[4])) + (P1[2] * (V3[4] - cI * (V3[3])) + P1[3] * (V3[5] - - V3[2])))) + M1 * (F2[2] * 4. * (+cI * (V3[4]) - V3[3]) + 4. * (F2[3] * - (V3[2] + V3[5]))))); -} - - -void FFV1_0(std::complex F1[], std::complex F2[], - std::complex V3[], std::complex COUP, std::complex - & vertex) -{ - static std::complex cI = std::complex (0., 1.); - std::complex TMP13; - TMP13 = (F1[2] * (F2[4] * (V3[2] + V3[5]) + F2[5] * (V3[3] + cI * (V3[4]))) + - (F1[3] * (F2[4] * (V3[3] - cI * (V3[4])) + F2[5] * (V3[2] - V3[5])) + - (F1[4] * (F2[2] * (V3[2] - V3[5]) - F2[3] * (V3[3] + cI * (V3[4]))) + - F1[5] * (F2[2] * (+cI * (V3[4]) - V3[3]) + F2[3] * (V3[2] + V3[5]))))); - vertex = COUP * - cI * TMP13; -} - - -void VVVV4P0_1(std::complex V2[], std::complex V3[], - std::complex V4[], std::complex COUP, double M1, double W1, - std::complex V1[]) -{ - static std::complex cI = std::complex (0., 1.); - std::complex TMP12; - std::complex TMP11; - double P1[4]; - std::complex denom; - V1[0] = +V2[0] + V3[0] + V4[0]; - V1[1] = +V2[1] + V3[1] + V4[1]; - P1[0] = -V1[0].real(); - P1[1] = -V1[1].real(); - P1[2] = -V1[1].imag(); - P1[3] = -V1[0].imag(); - TMP11 = (V2[2] * V4[2] - V2[3] * V4[3] - V2[4] * V4[4] - V2[5] * V4[5]); - TMP12 = (V3[2] * V4[2] - V3[3] * V4[3] - V3[4] * V4[4] - V3[5] * V4[5]); - denom = COUP/((P1[0] * P1[0]) - (P1[1] * P1[1]) - (P1[2] * P1[2]) - (P1[3] * - P1[3]) - M1 * (M1 - cI * W1)); - V1[2] = denom * (-cI * (V3[2] * TMP11) + cI * (V2[2] * TMP12)); - V1[3] = denom * (-cI * (V3[3] * TMP11) + cI * (V2[3] * TMP12)); - V1[4] = denom * (-cI * (V3[4] * TMP11) + cI * (V2[4] * TMP12)); - V1[5] = denom * (-cI * (V3[5] * TMP11) + cI * (V2[5] * TMP12)); -} - - -void VVVV3P0_1(std::complex V2[], std::complex V3[], - std::complex V4[], std::complex COUP, double M1, double W1, - std::complex V1[]) -{ - static std::complex cI = std::complex (0., 1.); - std::complex TMP12; - double P1[4]; - std::complex TMP6; - std::complex denom; - V1[0] = +V2[0] + V3[0] + V4[0]; - V1[1] = +V2[1] + V3[1] + V4[1]; - P1[0] = -V1[0].real(); - P1[1] = -V1[1].real(); - P1[2] = -V1[1].imag(); - P1[3] = -V1[0].imag(); - TMP6 = (V3[2] * V2[2] - V3[3] * V2[3] - V3[4] * V2[4] - V3[5] * V2[5]); - TMP12 = (V3[2] * V4[2] - V3[3] * V4[3] - V3[4] * V4[4] - V3[5] * V4[5]); - denom = COUP/((P1[0] * P1[0]) - (P1[1] * P1[1]) - (P1[2] * P1[2]) - (P1[3] * - P1[3]) - M1 * (M1 - cI * W1)); - V1[2] = denom * (-cI * (TMP6 * V4[2]) + cI * (V2[2] * TMP12)); - V1[3] = denom * (-cI * (TMP6 * V4[3]) + cI * (V2[3] * TMP12)); - V1[4] = denom * (-cI * (TMP6 * V4[4]) + cI * (V2[4] * TMP12)); - V1[5] = denom * (-cI * (TMP6 * V4[5]) + cI * (V2[5] * TMP12)); -} - - -void VVV1_0(std::complex V1[], std::complex V2[], - std::complex V3[], std::complex COUP, std::complex - & vertex) -{ - static std::complex cI = std::complex (0., 1.); - std::complex TMP2; - std::complex TMP1; - double P1[4]; - std::complex TMP0; - double P2[4]; - std::complex TMP7; - double P3[4]; - std::complex TMP6; - std::complex TMP5; - std::complex TMP4; - std::complex TMP3; - std::complex TMP8; - P1[0] = V1[0].real(); - P1[1] = V1[1].real(); - P1[2] = V1[1].imag(); - P1[3] = V1[0].imag(); - P2[0] = V2[0].real(); - P2[1] = V2[1].real(); - P2[2] = V2[1].imag(); - P2[3] = V2[0].imag(); - P3[0] = V3[0].real(); - P3[1] = V3[1].real(); - P3[2] = V3[1].imag(); - P3[3] = V3[0].imag(); - TMP8 = (V1[2] * P3[0] - V1[3] * P3[1] - V1[4] * P3[2] - V1[5] * P3[3]); - TMP5 = (V2[2] * P3[0] - V2[3] * P3[1] - V2[4] * P3[2] - V2[5] * P3[3]); - TMP4 = (P1[0] * V2[2] - P1[1] * V2[3] - P1[2] * V2[4] - P1[3] * V2[5]); - TMP7 = (V1[2] * P2[0] - V1[3] * P2[1] - V1[4] * P2[2] - V1[5] * P2[3]); - TMP6 = (V3[2] * V2[2] - V3[3] * V2[3] - V3[4] * V2[4] - V3[5] * V2[5]); - TMP1 = (V2[2] * V1[2] - V2[3] * V1[3] - V2[4] * V1[4] - V2[5] * V1[5]); - TMP0 = (V3[2] * P1[0] - V3[3] * P1[1] - V3[4] * P1[2] - V3[5] * P1[3]); - TMP3 = (V3[2] * V1[2] - V3[3] * V1[3] - V3[4] * V1[4] - V3[5] * V1[5]); - TMP2 = (V3[2] * P2[0] - V3[3] * P2[1] - V3[4] * P2[2] - V3[5] * P2[3]); - vertex = COUP * (TMP1 * (-cI * (TMP0) + cI * (TMP2)) + (TMP3 * (-cI * (TMP5) - + cI * (TMP4)) + TMP6 * (-cI * (TMP7) + cI * (TMP8)))); -} - - -void FFV2_3(std::complex F1[], std::complex F2[], - std::complex COUP, double M3, double W3, std::complex V3[]) -{ - static std::complex cI = std::complex (0., 1.); - std::complex denom; - std::complex TMP10; - double P3[4]; - double OM3; - OM3 = 0.; - if (M3 != 0.) - OM3 = 1./(M3 * M3); - V3[0] = +F1[0] + F2[0]; - V3[1] = +F1[1] + F2[1]; - P3[0] = -V3[0].real(); - P3[1] = -V3[1].real(); - P3[2] = -V3[1].imag(); - P3[3] = -V3[0].imag(); - TMP10 = (F1[2] * (F2[4] * (P3[0] + P3[3]) + F2[5] * (P3[1] + cI * (P3[2]))) + - F1[3] * (F2[4] * (P3[1] - cI * (P3[2])) + F2[5] * (P3[0] - P3[3]))); - denom = COUP/((P3[0] * P3[0]) - (P3[1] * P3[1]) - (P3[2] * P3[2]) - (P3[3] * - P3[3]) - M3 * (M3 - cI * W3)); - V3[2] = denom * (-cI) * (F1[2] * F2[4] + F1[3] * F2[5] - P3[0] * OM3 * - TMP10); - V3[3] = denom * (-cI) * (-F1[2] * F2[5] - F1[3] * F2[4] - P3[1] * OM3 * - TMP10); - V3[4] = denom * (-cI) * (-cI * (F1[2] * F2[5]) + cI * (F1[3] * F2[4]) - P3[2] - * OM3 * TMP10); - V3[5] = denom * (-cI) * (F1[3] * F2[5] - F1[2] * F2[4] - P3[3] * OM3 * - TMP10); -} - -void FFV2_4_3(std::complex F1[], std::complex F2[], - std::complex COUP1, std::complex COUP2, double M3, double - W3, std::complex V3[]) -{ - std::complex denom; - int i; - std::complex Vtmp[6]; - FFV2_3(F1, F2, COUP1, M3, W3, V3); - FFV4_3(F1, F2, COUP2, M3, W3, Vtmp); - i = 2; - while (i < 6) - { - V3[i] = V3[i] + Vtmp[i]; - i++; - } -} - -void FFV5_2(std::complex F1[], std::complex V3[], - std::complex COUP, double M2, double W2, std::complex F2[]) -{ - static std::complex cI = std::complex (0., 1.); - double P2[4]; - std::complex denom; - F2[0] = +F1[0] + V3[0]; - F2[1] = +F1[1] + V3[1]; - P2[0] = -F2[0].real(); - P2[1] = -F2[1].real(); - P2[2] = -F2[1].imag(); - P2[3] = -F2[0].imag(); - denom = COUP/((P2[0] * P2[0]) - (P2[1] * P2[1]) - (P2[2] * P2[2]) - (P2[3] * - P2[3]) - M2 * (M2 - cI * W2)); - F2[2] = denom * cI * (F1[2] * (P2[0] * (V3[2] + V3[5]) + (P2[1] * (-1.) * - (V3[3] + cI * (V3[4])) + (P2[2] * (+cI * (V3[3]) - V3[4]) - P2[3] * - (V3[2] + V3[5])))) + (F1[3] * (P2[0] * (V3[3] - cI * (V3[4])) + (P2[1] * - (V3[5] - V3[2]) + (P2[2] * (-cI * (V3[5]) + cI * (V3[2])) + P2[3] * (+cI - * (V3[4]) - V3[3])))) + M2 * (F1[4] * 4. * (V3[2] - V3[5]) + 4. * (F1[5] - * (+cI * (V3[4]) - V3[3]))))); - F2[3] = denom * cI * (F1[2] * (P2[0] * (V3[3] + cI * (V3[4])) + (P2[1] * - (-1.) * (V3[2] + V3[5]) + (P2[2] * (-1.) * (+cI * (V3[2] + V3[5])) + - P2[3] * (V3[3] + cI * (V3[4]))))) + (F1[3] * (P2[0] * (V3[2] - V3[5]) + - (P2[1] * (+cI * (V3[4]) - V3[3]) + (P2[2] * (-1.) * (V3[4] + cI * - (V3[3])) + P2[3] * (V3[2] - V3[5])))) + M2 * (F1[4] * (-4.) * (V3[3] + cI - * (V3[4])) + 4. * (F1[5] * (V3[2] + V3[5]))))); - F2[4] = denom * (-4. * cI) * (F1[4] * (P2[0] * (V3[5] - V3[2]) + (P2[1] * - (V3[3] + cI * (V3[4])) + (P2[2] * (V3[4] - cI * (V3[3])) + P2[3] * (V3[5] - - V3[2])))) + (+1./4. * (M2 * (F1[3] * (+cI * (V3[4]) - V3[3]) + 4. * - (F1[2] * (-1./4.) * (V3[2] + V3[5])))) + F1[5] * (P2[0] * (V3[3] - cI * - (V3[4])) + (P2[1] * (-1.) * (V3[2] + V3[5]) + (P2[2] * (+cI * (V3[2] + - V3[5])) + P2[3] * (V3[3] - cI * (V3[4]))))))); - F2[5] = denom * (-4. * cI) * (F1[4] * (P2[0] * (V3[3] + cI * (V3[4])) + - (P2[1] * (V3[5] - V3[2]) + (P2[2] * (-cI * (V3[2]) + cI * (V3[5])) - - P2[3] * (V3[3] + cI * (V3[4]))))) + (+1./4. * (M2 * (F1[3] * (V3[5] - - V3[2]) + 4. * (F1[2] * (-1./4.) * (V3[3] + cI * (V3[4]))))) + F1[5] * - (P2[0] * (-1.) * (V3[2] + V3[5]) + (P2[1] * (V3[3] - cI * (V3[4])) + - (P2[2] * (V3[4] + cI * (V3[3])) + P2[3] * (V3[2] + V3[5])))))); -} - - -void FFV2_1(std::complex F2[], std::complex V3[], - std::complex COUP, double M1, double W1, std::complex F1[]) -{ - static std::complex cI = std::complex (0., 1.); - double P1[4]; - std::complex denom; - F1[0] = +F2[0] + V3[0]; - F1[1] = +F2[1] + V3[1]; - P1[0] = -F1[0].real(); - P1[1] = -F1[1].real(); - P1[2] = -F1[1].imag(); - P1[3] = -F1[0].imag(); - denom = COUP/((P1[0] * P1[0]) - (P1[1] * P1[1]) - (P1[2] * P1[2]) - (P1[3] * - P1[3]) - M1 * (M1 - cI * W1)); - F1[2] = denom * cI * M1 * (F2[4] * (V3[2] + V3[5]) + F2[5] * (V3[3] + cI * - (V3[4]))); - F1[3] = denom * - cI * M1 * (F2[4] * (+cI * (V3[4]) - V3[3]) + F2[5] * (V3[5] - - V3[2])); - F1[4] = denom * (-cI) * (F2[4] * (P1[0] * (V3[2] + V3[5]) + (P1[1] * (+cI * - (V3[4]) - V3[3]) + (P1[2] * (-1.) * (V3[4] + cI * (V3[3])) - P1[3] * - (V3[2] + V3[5])))) + F2[5] * (P1[0] * (V3[3] + cI * (V3[4])) + (P1[1] * - (V3[5] - V3[2]) + (P1[2] * (-cI * (V3[2]) + cI * (V3[5])) - P1[3] * - (V3[3] + cI * (V3[4])))))); - F1[5] = denom * (-cI) * (F2[4] * (P1[0] * (V3[3] - cI * (V3[4])) + (P1[1] * - (-1.) * (V3[2] + V3[5]) + (P1[2] * (+cI * (V3[2] + V3[5])) + P1[3] * - (V3[3] - cI * (V3[4]))))) + F2[5] * (P1[0] * (V3[2] - V3[5]) + (P1[1] * - (-1.) * (V3[3] + cI * (V3[4])) + (P1[2] * (+cI * (V3[3]) - V3[4]) + P1[3] - * (V3[2] - V3[5]))))); -} - -void FFV2_5_1(std::complex F2[], std::complex V3[], - std::complex COUP1, std::complex COUP2, double M1, double - W1, std::complex F1[]) -{ - std::complex denom; - int i; - std::complex Ftmp[6]; - FFV2_1(F2, V3, COUP1, M1, W1, F1); - FFV5_1(F2, V3, COUP2, M1, W1, Ftmp); - i = 2; - while (i < 6) - { - F1[i] = F1[i] + Ftmp[i]; - i++; - } -} - -void FFV5_0(std::complex F1[], std::complex F2[], - std::complex V3[], std::complex COUP, std::complex - & vertex) -{ - static std::complex cI = std::complex (0., 1.); - std::complex TMP15; - std::complex TMP16; - TMP15 = (F1[2] * (F2[4] * (V3[2] + V3[5]) + F2[5] * (V3[3] + cI * (V3[4]))) + - F1[3] * (F2[4] * (V3[3] - cI * (V3[4])) + F2[5] * (V3[2] - V3[5]))); - TMP16 = (F1[4] * (F2[2] * (V3[2] - V3[5]) - F2[3] * (V3[3] + cI * (V3[4]))) + - F1[5] * (F2[2] * (+cI * (V3[4]) - V3[3]) + F2[3] * (V3[2] + V3[5]))); - vertex = COUP * (-1.) * (+cI * (TMP15) + 4. * cI * (TMP16)); -} - - -void FFV1_1(std::complex F2[], std::complex V3[], - std::complex COUP, double M1, double W1, std::complex F1[]) -{ - static std::complex cI = std::complex (0., 1.); - double P1[4]; - std::complex denom; - F1[0] = +F2[0] + V3[0]; - F1[1] = +F2[1] + V3[1]; - P1[0] = -F1[0].real(); - P1[1] = -F1[1].real(); - P1[2] = -F1[1].imag(); - P1[3] = -F1[0].imag(); - denom = COUP/((P1[0] * P1[0]) - (P1[1] * P1[1]) - (P1[2] * P1[2]) - (P1[3] * - P1[3]) - M1 * (M1 - cI * W1)); - F1[2] = denom * cI * (F2[2] * (P1[0] * (V3[5] - V3[2]) + (P1[1] * (V3[3] - cI - * (V3[4])) + (P1[2] * (V3[4] + cI * (V3[3])) + P1[3] * (V3[5] - V3[2])))) - + (F2[3] * (P1[0] * (V3[3] + cI * (V3[4])) + (P1[1] * (-1.) * (V3[2] + - V3[5]) + (P1[2] * (-1.) * (+cI * (V3[2] + V3[5])) + P1[3] * (V3[3] + cI * - (V3[4]))))) + M1 * (F2[4] * (V3[2] + V3[5]) + F2[5] * (V3[3] + cI * - (V3[4]))))); - F1[3] = denom * (-cI) * (F2[2] * (P1[0] * (+cI * (V3[4]) - V3[3]) + (P1[1] * - (V3[2] - V3[5]) + (P1[2] * (-cI * (V3[2]) + cI * (V3[5])) + P1[3] * - (V3[3] - cI * (V3[4]))))) + (F2[3] * (P1[0] * (V3[2] + V3[5]) + (P1[1] * - (-1.) * (V3[3] + cI * (V3[4])) + (P1[2] * (+cI * (V3[3]) - V3[4]) - P1[3] - * (V3[2] + V3[5])))) + M1 * (F2[4] * (+cI * (V3[4]) - V3[3]) + F2[5] * - (V3[5] - V3[2])))); - F1[4] = denom * (-cI) * (F2[4] * (P1[0] * (V3[2] + V3[5]) + (P1[1] * (+cI * - (V3[4]) - V3[3]) + (P1[2] * (-1.) * (V3[4] + cI * (V3[3])) - P1[3] * - (V3[2] + V3[5])))) + (F2[5] * (P1[0] * (V3[3] + cI * (V3[4])) + (P1[1] * - (V3[5] - V3[2]) + (P1[2] * (-cI * (V3[2]) + cI * (V3[5])) - P1[3] * - (V3[3] + cI * (V3[4]))))) + M1 * (F2[2] * (V3[5] - V3[2]) + F2[3] * - (V3[3] + cI * (V3[4]))))); - F1[5] = denom * cI * (F2[4] * (P1[0] * (+cI * (V3[4]) - V3[3]) + (P1[1] * - (V3[2] + V3[5]) + (P1[2] * (-1.) * (+cI * (V3[2] + V3[5])) + P1[3] * (+cI - * (V3[4]) - V3[3])))) + (F2[5] * (P1[0] * (V3[5] - V3[2]) + (P1[1] * - (V3[3] + cI * (V3[4])) + (P1[2] * (V3[4] - cI * (V3[3])) + P1[3] * (V3[5] - - V3[2])))) + M1 * (F2[2] * (+cI * (V3[4]) - V3[3]) + F2[3] * (V3[2] + - V3[5])))); -} - - -void FFV4_3(std::complex F1[], std::complex F2[], - std::complex COUP, double M3, double W3, std::complex V3[]) -{ - static std::complex cI = std::complex (0., 1.); - std::complex denom; - std::complex TMP10; - double P3[4]; - double OM3; - std::complex TMP14; - OM3 = 0.; - if (M3 != 0.) - OM3 = 1./(M3 * M3); - V3[0] = +F1[0] + F2[0]; - V3[1] = +F1[1] + F2[1]; - P3[0] = -V3[0].real(); - P3[1] = -V3[1].real(); - P3[2] = -V3[1].imag(); - P3[3] = -V3[0].imag(); - TMP14 = (F1[4] * (F2[2] * (P3[0] - P3[3]) - F2[3] * (P3[1] + cI * (P3[2]))) + - F1[5] * (F2[2] * (+cI * (P3[2]) - P3[1]) + F2[3] * (P3[0] + P3[3]))); - TMP10 = (F1[2] * (F2[4] * (P3[0] + P3[3]) + F2[5] * (P3[1] + cI * (P3[2]))) + - F1[3] * (F2[4] * (P3[1] - cI * (P3[2])) + F2[5] * (P3[0] - P3[3]))); - denom = COUP/((P3[0] * P3[0]) - (P3[1] * P3[1]) - (P3[2] * P3[2]) - (P3[3] * - P3[3]) - M3 * (M3 - cI * W3)); - V3[2] = denom * (-2. * cI) * (OM3 * - 1./2. * P3[0] * (TMP10 + 2. * (TMP14)) - + (+1./2. * (F1[2] * F2[4] + F1[3] * F2[5]) + F1[4] * F2[2] + F1[5] * - F2[3])); - V3[3] = denom * (-2. * cI) * (OM3 * - 1./2. * P3[1] * (TMP10 + 2. * (TMP14)) - + (-1./2. * (F1[2] * F2[5] + F1[3] * F2[4]) + F1[4] * F2[3] + F1[5] * - F2[2])); - V3[4] = denom * 2. * cI * (OM3 * 1./2. * P3[2] * (TMP10 + 2. * (TMP14)) + - (+1./2. * cI * (F1[2] * F2[5]) - 1./2. * cI * (F1[3] * F2[4]) - cI * - (F1[4] * F2[3]) + cI * (F1[5] * F2[2]))); - V3[5] = denom * 2. * cI * (OM3 * 1./2. * P3[3] * (TMP10 + 2. * (TMP14)) + - (+1./2. * (F1[2] * F2[4]) - 1./2. * (F1[3] * F2[5]) - F1[4] * F2[2] + - F1[5] * F2[3])); -} - - -void VVVV1P0_1(std::complex V2[], std::complex V3[], - std::complex V4[], std::complex COUP, double M1, double W1, - std::complex V1[]) -{ - static std::complex cI = std::complex (0., 1.); - std::complex TMP11; - double P1[4]; - std::complex TMP6; - std::complex denom; - V1[0] = +V2[0] + V3[0] + V4[0]; - V1[1] = +V2[1] + V3[1] + V4[1]; - P1[0] = -V1[0].real(); - P1[1] = -V1[1].real(); - P1[2] = -V1[1].imag(); - P1[3] = -V1[0].imag(); - TMP6 = (V3[2] * V2[2] - V3[3] * V2[3] - V3[4] * V2[4] - V3[5] * V2[5]); - TMP11 = (V2[2] * V4[2] - V2[3] * V4[3] - V2[4] * V4[4] - V2[5] * V4[5]); - denom = COUP/((P1[0] * P1[0]) - (P1[1] * P1[1]) - (P1[2] * P1[2]) - (P1[3] * - P1[3]) - M1 * (M1 - cI * W1)); - V1[2] = denom * (-cI * (TMP6 * V4[2]) + cI * (V3[2] * TMP11)); - V1[3] = denom * (-cI * (TMP6 * V4[3]) + cI * (V3[3] * TMP11)); - V1[4] = denom * (-cI * (TMP6 * V4[4]) + cI * (V3[4] * TMP11)); - V1[5] = denom * (-cI * (TMP6 * V4[5]) + cI * (V3[5] * TMP11)); -} - - -void VVV1P0_1(std::complex V2[], std::complex V3[], - std::complex COUP, double M1, double W1, std::complex V1[]) -{ - static std::complex cI = std::complex (0., 1.); - std::complex TMP2; - double P1[4]; - std::complex TMP0; - double P2[4]; - double P3[4]; - std::complex TMP6; - std::complex TMP5; - std::complex TMP4; - std::complex denom; - P2[0] = V2[0].real(); - P2[1] = V2[1].real(); - P2[2] = V2[1].imag(); - P2[3] = V2[0].imag(); - P3[0] = V3[0].real(); - P3[1] = V3[1].real(); - P3[2] = V3[1].imag(); - P3[3] = V3[0].imag(); - V1[0] = +V2[0] + V3[0]; - V1[1] = +V2[1] + V3[1]; - P1[0] = -V1[0].real(); - P1[1] = -V1[1].real(); - P1[2] = -V1[1].imag(); - P1[3] = -V1[0].imag(); - TMP5 = (V2[2] * P3[0] - V2[3] * P3[1] - V2[4] * P3[2] - V2[5] * P3[3]); - TMP4 = (P1[0] * V2[2] - P1[1] * V2[3] - P1[2] * V2[4] - P1[3] * V2[5]); - TMP6 = (V3[2] * V2[2] - V3[3] * V2[3] - V3[4] * V2[4] - V3[5] * V2[5]); - TMP0 = (V3[2] * P1[0] - V3[3] * P1[1] - V3[4] * P1[2] - V3[5] * P1[3]); - TMP2 = (V3[2] * P2[0] - V3[3] * P2[1] - V3[4] * P2[2] - V3[5] * P2[3]); - denom = COUP/((P1[0] * P1[0]) - (P1[1] * P1[1]) - (P1[2] * P1[2]) - (P1[3] * - P1[3]) - M1 * (M1 - cI * W1)); - V1[2] = denom * (TMP6 * (-cI * (P2[0]) + cI * (P3[0])) + (V2[2] * (-cI * - (TMP0) + cI * (TMP2)) + V3[2] * (-cI * (TMP5) + cI * (TMP4)))); - V1[3] = denom * (TMP6 * (-cI * (P2[1]) + cI * (P3[1])) + (V2[3] * (-cI * - (TMP0) + cI * (TMP2)) + V3[3] * (-cI * (TMP5) + cI * (TMP4)))); - V1[4] = denom * (TMP6 * (-cI * (P2[2]) + cI * (P3[2])) + (V2[4] * (-cI * - (TMP0) + cI * (TMP2)) + V3[4] * (-cI * (TMP5) + cI * (TMP4)))); - V1[5] = denom * (TMP6 * (-cI * (P2[3]) + cI * (P3[3])) + (V2[5] * (-cI * - (TMP0) + cI * (TMP2)) + V3[5] * (-cI * (TMP5) + cI * (TMP4)))); -} - - -} // end namespace MG5_sm_COLOREA - diff --git a/Shower/Dipole/Colorea/HelAmps_sm.h b/Shower/Dipole/Colorea/HelAmps_sm.h deleted file mode 100644 --- a/Shower/Dipole/Colorea/HelAmps_sm.h +++ /dev/null @@ -1,106 +0,0 @@ -//========================================================================== -// This file has been automatically generated for C++ Standalone -// MadGraph5_aMC@NLO v. 2.5.4, 2017-03-28 -// By the MadGraph5_aMC@NLO Development Team -// Visit launchpad.net/madgraph5 and amcatnlo.web.cern.ch -//========================================================================== - -#ifndef HelAmps_sm_H -#define HelAmps_sm_H - -#include -#include - -using namespace std; - -namespace MG5_sm_COLOREA -{ -double Sgn(double e, double f); - -void oxxxxx(double p[4], double fmass, int nhel, int nsf, std::complex - fo[6]); - -void sxxxxx(double p[4], int nss, std::complex sc[3]); - -void ixxxxx(double p[4], double fmass, int nhel, int nsf, std::complex - fi[6]); - -void txxxxx(double p[4], double tmass, int nhel, int nst, std::complex - fi[18]); - -void vxxxxx(double p[4], double vmass, int nhel, int nsv, std::complex - v[6]); - -void FFV1P0_3(std::complex F1[], std::complex F2[], - std::complex COUP, double M3, double W3, std::complex V3[]); - -void FFV2_2(std::complex F1[], std::complex V3[], - std::complex COUP, double M2, double W2, std::complex F2[]); -void FFV2_5_2(std::complex F1[], std::complex V3[], - std::complex COUP1, std::complex COUP2, double M2, double - W2, std::complex F2[]); - -void FFV1_2(std::complex F1[], std::complex V3[], - std::complex COUP, double M2, double W2, std::complex F2[]); - -void FFV2_0(std::complex F1[], std::complex F2[], - std::complex V3[], std::complex COUP, std::complex - & vertex); -void FFV2_5_0(std::complex F1[], std::complex F2[], - std::complex V3[], std::complex COUP1, std::complex - COUP2, std::complex & vertex); - -void FFV5_1(std::complex F2[], std::complex V3[], - std::complex COUP, double M1, double W1, std::complex F1[]); - -void FFV1_0(std::complex F1[], std::complex F2[], - std::complex V3[], std::complex COUP, std::complex - & vertex); - -void VVVV4P0_1(std::complex V2[], std::complex V3[], - std::complex V4[], std::complex COUP, double M1, double W1, - std::complex V1[]); - -void VVVV3P0_1(std::complex V2[], std::complex V3[], - std::complex V4[], std::complex COUP, double M1, double W1, - std::complex V1[]); - -void VVV1_0(std::complex V1[], std::complex V2[], - std::complex V3[], std::complex COUP, std::complex - & vertex); - -void FFV2_3(std::complex F1[], std::complex F2[], - std::complex COUP, double M3, double W3, std::complex V3[]); -void FFV2_4_3(std::complex F1[], std::complex F2[], - std::complex COUP1, std::complex COUP2, double M3, double - W3, std::complex V3[]); - -void FFV5_2(std::complex F1[], std::complex V3[], - std::complex COUP, double M2, double W2, std::complex F2[]); - -void FFV2_1(std::complex F2[], std::complex V3[], - std::complex COUP, double M1, double W1, std::complex F1[]); -void FFV2_5_1(std::complex F2[], std::complex V3[], - std::complex COUP1, std::complex COUP2, double M1, double - W1, std::complex F1[]); - -void FFV5_0(std::complex F1[], std::complex F2[], - std::complex V3[], std::complex COUP, std::complex - & vertex); - -void FFV1_1(std::complex F2[], std::complex V3[], - std::complex COUP, double M1, double W1, std::complex F1[]); - -void FFV4_3(std::complex F1[], std::complex F2[], - std::complex COUP, double M3, double W3, std::complex V3[]); - -void VVVV1P0_1(std::complex V2[], std::complex V3[], - std::complex V4[], std::complex COUP, double M1, double W1, - std::complex V1[]); - -void VVV1P0_1(std::complex V2[], std::complex V3[], - std::complex COUP, double M1, double W1, std::complex V1[]); - -} // end namespace MG5_sm_COLOREA - -#endif // HelAmps_sm_H diff --git a/Shower/Dipole/Colorea/Makefile.am b/Shower/Dipole/Colorea/Makefile.am deleted file mode 100644 --- a/Shower/Dipole/Colorea/Makefile.am +++ /dev/null @@ -1,19 +0,0 @@ -noinst_LTLIBRARIES = libHwDipoleShowerColorea.la - -libHwDipoleShowerColorea_la_SOURCES = \ - Colorea.fh \ - Colorea.cc \ - Colorea.h \ - HelAmps_sm.cc \ - HelAmps_sm.h \ - Parameters_sm.cc \ - Parameters_sm.h \ - read_slha_COLOREA.cc \ - read_slha_COLOREA.h \ - eeuugg.h \ - eeuugg.cc \ - eeuuggg.h \ - eeuuggg.cc \ - eeuugggg.h \ - eeuugggg.cc - diff --git a/Shower/Dipole/Colorea/Parameters_sm.cc b/Shower/Dipole/Colorea/Parameters_sm.cc deleted file mode 100644 --- a/Shower/Dipole/Colorea/Parameters_sm.cc +++ /dev/null @@ -1,241 +0,0 @@ -//========================================================================== -// This file has been automatically generated for C++ by -// MadGraph5_aMC@NLO v. 2.5.4, 2017-03-28 -// By the MadGraph5_aMC@NLO Development Team -// Visit launchpad.net/madgraph5 and amcatnlo.web.cern.ch -//========================================================================== - -#include -#include -#include "Parameters_sm.h" - -// Initialize static instance -Parameters_sm * Parameters_sm::instance = 0; - -// Function to get static instance - only one instance per program -Parameters_sm * Parameters_sm::getInstance() -{ - if (instance == 0) - instance = new Parameters_sm(); - - return instance; -} - -void Parameters_sm::setIndependentParameters(SLHAReader_COLOREA& slha) -{ - // Define "zero" - zero = 0; - ZERO = 0; - // Prepare a vector for indices - vector indices(2, 0); - mdl_WH = slha.get_block_entry("decay", 25, 6.382339e-03); - mdl_WW = slha.get_block_entry("decay", 24, 2.047600e+00); - mdl_WZ = slha.get_block_entry("decay", 23, 2.441404e+00); - mdl_WT = slha.get_block_entry("decay", 6, 1.491500e+00); - mdl_ymtau = slha.get_block_entry("yukawa", 15, 1.777000e+00); - mdl_ymt = slha.get_block_entry("yukawa", 6, 1.730000e+02); - mdl_ymb = slha.get_block_entry("yukawa", 5, 4.700000e+00); - aS = slha.get_block_entry("sminputs", 3, 1.180000e-01); - mdl_Gf = slha.get_block_entry("sminputs", 2, 1.166390e-05); - aEWM1 = slha.get_block_entry("sminputs", 1, 1.325070e+02); - mdl_MH = slha.get_block_entry("mass", 25, 1.250000e+02); - mdl_MZ = slha.get_block_entry("mass", 23, 9.118800e+01); - mdl_MTA = slha.get_block_entry("mass", 15, 1.777000e+00); - mdl_MT = slha.get_block_entry("mass", 6, 1.730000e+02); - mdl_MB = slha.get_block_entry("mass", 5, 4.700000e+00); - mdl_conjg__CKM3x3 = 1.; - mdl_CKM3x3 = 1.; - mdl_conjg__CKM1x1 = 1.; - mdl_complexi = std::complex (0., 1.); - mdl_MZ__exp__2 = ((mdl_MZ) * (mdl_MZ)); - mdl_MZ__exp__4 = ((mdl_MZ) * (mdl_MZ) * (mdl_MZ) * (mdl_MZ)); - mdl_sqrt__2 = sqrt(2.); - mdl_MH__exp__2 = ((mdl_MH) * (mdl_MH)); - mdl_aEW = 1./aEWM1; - mdl_MW = sqrt(mdl_MZ__exp__2/2. + sqrt(mdl_MZ__exp__4/4. - (mdl_aEW * M_PI * - mdl_MZ__exp__2)/(mdl_Gf * mdl_sqrt__2))); - mdl_sqrt__aEW = sqrt(mdl_aEW); - mdl_ee = 2. * mdl_sqrt__aEW * sqrt(M_PI); - mdl_MW__exp__2 = ((mdl_MW) * (mdl_MW)); - mdl_sw2 = 1. - mdl_MW__exp__2/mdl_MZ__exp__2; - mdl_cw = sqrt(1. - mdl_sw2); - mdl_sqrt__sw2 = sqrt(mdl_sw2); - mdl_sw = mdl_sqrt__sw2; - mdl_g1 = mdl_ee/mdl_cw; - mdl_gw = mdl_ee/mdl_sw; - mdl_vev = (2. * mdl_MW * mdl_sw)/mdl_ee; - mdl_vev__exp__2 = ((mdl_vev) * (mdl_vev)); - mdl_lam = mdl_MH__exp__2/(2. * mdl_vev__exp__2); - mdl_yb = (mdl_ymb * mdl_sqrt__2)/mdl_vev; - mdl_yt = (mdl_ymt * mdl_sqrt__2)/mdl_vev; - mdl_ytau = (mdl_ymtau * mdl_sqrt__2)/mdl_vev; - mdl_muH = sqrt(mdl_lam * mdl_vev__exp__2); - mdl_I1x33 = mdl_yb * mdl_conjg__CKM3x3; - mdl_I2x33 = mdl_yt * mdl_conjg__CKM3x3; - mdl_I3x33 = mdl_CKM3x3 * mdl_yt; - mdl_I4x33 = mdl_CKM3x3 * mdl_yb; - mdl_ee__exp__2 = ((mdl_ee) * (mdl_ee)); - mdl_sw__exp__2 = ((mdl_sw) * (mdl_sw)); - mdl_cw__exp__2 = ((mdl_cw) * (mdl_cw)); -} -void Parameters_sm::setIndependentCouplings() -{ - GC_2 = (2. * mdl_ee * mdl_complexi)/3.; - GC_3 = -(mdl_ee * mdl_complexi); - GC_50 = -(mdl_cw * mdl_ee * mdl_complexi)/(2. * mdl_sw); - GC_51 = (mdl_cw * mdl_ee * mdl_complexi)/(2. * mdl_sw); - GC_58 = -(mdl_ee * mdl_complexi * mdl_sw)/(6. * mdl_cw); - GC_59 = (mdl_ee * mdl_complexi * mdl_sw)/(2. * mdl_cw); -} -void Parameters_sm::setDependentParameters() -{ - mdl_sqrt__aS = sqrt(aS); - G = 2. * mdl_sqrt__aS * sqrt(M_PI); - mdl_G__exp__2 = ((G) * (G)); -} -void Parameters_sm::setDependentCouplings() -{ - GC_12 = mdl_complexi * mdl_G__exp__2; - GC_11 = mdl_complexi * G; - GC_10 = -G; -} - -// Routines for printing out parameters -void Parameters_sm::printIndependentParameters() -{ - cout << "sm model parameters independent of event kinematics:" << endl; - cout << setw(20) << "mdl_WH " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_WH << endl; - cout << setw(20) << "mdl_WW " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_WW << endl; - cout << setw(20) << "mdl_WZ " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_WZ << endl; - cout << setw(20) << "mdl_WT " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_WT << endl; - cout << setw(20) << "mdl_ymtau " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_ymtau << endl; - cout << setw(20) << "mdl_ymt " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_ymt << endl; - cout << setw(20) << "mdl_ymb " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_ymb << endl; - cout << setw(20) << "aS " << "= " << setiosflags(ios::scientific) << - setw(10) << aS << endl; - cout << setw(20) << "mdl_Gf " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_Gf << endl; - cout << setw(20) << "aEWM1 " << "= " << setiosflags(ios::scientific) << - setw(10) << aEWM1 << endl; - cout << setw(20) << "mdl_MH " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_MH << endl; - cout << setw(20) << "mdl_MZ " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_MZ << endl; - cout << setw(20) << "mdl_MTA " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_MTA << endl; - cout << setw(20) << "mdl_MT " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_MT << endl; - cout << setw(20) << "mdl_MB " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_MB << endl; - cout << setw(20) << "mdl_conjg__CKM3x3 " << "= " << - setiosflags(ios::scientific) << setw(10) << mdl_conjg__CKM3x3 << endl; - cout << setw(20) << "mdl_CKM3x3 " << "= " << setiosflags(ios::scientific) - << setw(10) << mdl_CKM3x3 << endl; - cout << setw(20) << "mdl_conjg__CKM1x1 " << "= " << - setiosflags(ios::scientific) << setw(10) << mdl_conjg__CKM1x1 << endl; - cout << setw(20) << "mdl_complexi " << "= " << setiosflags(ios::scientific) - << setw(10) << mdl_complexi << endl; - cout << setw(20) << "mdl_MZ__exp__2 " << "= " << - setiosflags(ios::scientific) << setw(10) << mdl_MZ__exp__2 << endl; - cout << setw(20) << "mdl_MZ__exp__4 " << "= " << - setiosflags(ios::scientific) << setw(10) << mdl_MZ__exp__4 << endl; - cout << setw(20) << "mdl_sqrt__2 " << "= " << setiosflags(ios::scientific) - << setw(10) << mdl_sqrt__2 << endl; - cout << setw(20) << "mdl_MH__exp__2 " << "= " << - setiosflags(ios::scientific) << setw(10) << mdl_MH__exp__2 << endl; - cout << setw(20) << "mdl_aEW " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_aEW << endl; - cout << setw(20) << "mdl_MW " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_MW << endl; - cout << setw(20) << "mdl_sqrt__aEW " << "= " << - setiosflags(ios::scientific) << setw(10) << mdl_sqrt__aEW << endl; - cout << setw(20) << "mdl_ee " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_ee << endl; - cout << setw(20) << "mdl_MW__exp__2 " << "= " << - setiosflags(ios::scientific) << setw(10) << mdl_MW__exp__2 << endl; - cout << setw(20) << "mdl_sw2 " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_sw2 << endl; - cout << setw(20) << "mdl_cw " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_cw << endl; - cout << setw(20) << "mdl_sqrt__sw2 " << "= " << - setiosflags(ios::scientific) << setw(10) << mdl_sqrt__sw2 << endl; - cout << setw(20) << "mdl_sw " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_sw << endl; - cout << setw(20) << "mdl_g1 " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_g1 << endl; - cout << setw(20) << "mdl_gw " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_gw << endl; - cout << setw(20) << "mdl_vev " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_vev << endl; - cout << setw(20) << "mdl_vev__exp__2 " << "= " << - setiosflags(ios::scientific) << setw(10) << mdl_vev__exp__2 << endl; - cout << setw(20) << "mdl_lam " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_lam << endl; - cout << setw(20) << "mdl_yb " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_yb << endl; - cout << setw(20) << "mdl_yt " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_yt << endl; - cout << setw(20) << "mdl_ytau " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_ytau << endl; - cout << setw(20) << "mdl_muH " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_muH << endl; - cout << setw(20) << "mdl_I1x33 " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_I1x33 << endl; - cout << setw(20) << "mdl_I2x33 " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_I2x33 << endl; - cout << setw(20) << "mdl_I3x33 " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_I3x33 << endl; - cout << setw(20) << "mdl_I4x33 " << "= " << setiosflags(ios::scientific) << - setw(10) << mdl_I4x33 << endl; - cout << setw(20) << "mdl_ee__exp__2 " << "= " << - setiosflags(ios::scientific) << setw(10) << mdl_ee__exp__2 << endl; - cout << setw(20) << "mdl_sw__exp__2 " << "= " << - setiosflags(ios::scientific) << setw(10) << mdl_sw__exp__2 << endl; - cout << setw(20) << "mdl_cw__exp__2 " << "= " << - setiosflags(ios::scientific) << setw(10) << mdl_cw__exp__2 << endl; -} -void Parameters_sm::printIndependentCouplings() -{ - cout << "sm model couplings independent of event kinematics:" << endl; - cout << setw(20) << "GC_2 " << "= " << setiosflags(ios::scientific) << - setw(10) << GC_2 << endl; - cout << setw(20) << "GC_3 " << "= " << setiosflags(ios::scientific) << - setw(10) << GC_3 << endl; - cout << setw(20) << "GC_50 " << "= " << setiosflags(ios::scientific) << - setw(10) << GC_50 << endl; - cout << setw(20) << "GC_51 " << "= " << setiosflags(ios::scientific) << - setw(10) << GC_51 << endl; - cout << setw(20) << "GC_58 " << "= " << setiosflags(ios::scientific) << - setw(10) << GC_58 << endl; - cout << setw(20) << "GC_59 " << "= " << setiosflags(ios::scientific) << - setw(10) << GC_59 << endl; -} -void Parameters_sm::printDependentParameters() -{ - cout << "sm model parameters dependent on event kinematics:" << endl; - cout << setw(20) << "mdl_sqrt__aS " << "= " << setiosflags(ios::scientific) - << setw(10) << mdl_sqrt__aS << endl; - cout << setw(20) << "G " << "= " << setiosflags(ios::scientific) << - setw(10) << G << endl; - cout << setw(20) << "mdl_G__exp__2 " << "= " << - setiosflags(ios::scientific) << setw(10) << mdl_G__exp__2 << endl; -} -void Parameters_sm::printDependentCouplings() -{ - cout << "sm model couplings dependent on event kinematics:" << endl; - cout << setw(20) << "GC_12 " << "= " << setiosflags(ios::scientific) << - setw(10) << GC_12 << endl; - cout << setw(20) << "GC_11 " << "= " << setiosflags(ios::scientific) << - setw(10) << GC_11 << endl; - cout << setw(20) << "GC_10 " << "= " << setiosflags(ios::scientific) << - setw(10) << GC_10 << endl; -} - - diff --git a/Shower/Dipole/Colorea/Parameters_sm.h b/Shower/Dipole/Colorea/Parameters_sm.h deleted file mode 100644 --- a/Shower/Dipole/Colorea/Parameters_sm.h +++ /dev/null @@ -1,66 +0,0 @@ -//========================================================================== -// This file has been automatically generated for C++ -// MadGraph5_aMC@NLO v. 2.5.4, 2017-03-28 -// By the MadGraph5_aMC@NLO Development Team -// Visit launchpad.net/madgraph5 and amcatnlo.web.cern.ch -//========================================================================== - -#ifndef Parameters_sm_H -#define Parameters_sm_H - -#include - -#include "read_slha_COLOREA.h" -using namespace std; - -class Parameters_sm -{ - public: - - static Parameters_sm * getInstance(); - - // Define "zero" - double zero, ZERO; - // Model parameters independent of aS - double mdl_WH, mdl_WW, mdl_WZ, mdl_WT, mdl_ymtau, mdl_ymt, mdl_ymb, aS, - mdl_Gf, aEWM1, mdl_MH, mdl_MZ, mdl_MTA, mdl_MT, mdl_MB, - mdl_conjg__CKM3x3, mdl_CKM3x3, mdl_conjg__CKM1x1, mdl_MZ__exp__2, - mdl_MZ__exp__4, mdl_sqrt__2, mdl_MH__exp__2, mdl_aEW, mdl_MW, - mdl_sqrt__aEW, mdl_ee, mdl_MW__exp__2, mdl_sw2, mdl_cw, mdl_sqrt__sw2, - mdl_sw, mdl_g1, mdl_gw, mdl_vev, mdl_vev__exp__2, mdl_lam, mdl_yb, - mdl_yt, mdl_ytau, mdl_muH, mdl_ee__exp__2, mdl_sw__exp__2, - mdl_cw__exp__2; - std::complex mdl_complexi, mdl_I1x33, mdl_I2x33, mdl_I3x33, - mdl_I4x33; - // Model parameters dependent on aS - double mdl_sqrt__aS, G, mdl_G__exp__2; - // Model couplings independent of aS - std::complex GC_2, GC_3, GC_50, GC_51, GC_58, GC_59; - // Model couplings dependent on aS - std::complex GC_12, GC_11, GC_10; - - // Set parameters that are unchanged during the run - void setIndependentParameters(SLHAReader_COLOREA& slha); - // Set couplings that are unchanged during the run - void setIndependentCouplings(); - // Set parameters that are changed event by event - void setDependentParameters(); - // Set couplings that are changed event by event - void setDependentCouplings(); - - // Print parameters that are unchanged during the run - void printIndependentParameters(); - // Print couplings that are unchanged during the run - void printIndependentCouplings(); - // Print parameters that are changed event by event - void printDependentParameters(); - // Print couplings that are changed event by event - void printDependentCouplings(); - - - private: - static Parameters_sm * instance; -}; - -#endif // Parameters_sm_H - diff --git a/Shower/Dipole/Colorea/eeuugg.cc b/Shower/Dipole/Colorea/eeuugg.cc deleted file mode 100644 --- a/Shower/Dipole/Colorea/eeuugg.cc +++ /dev/null @@ -1,292 +0,0 @@ -//========================================================================== -// This file has been automatically generated for C++ Standalone by -// MadGraph5_aMC@NLO v. 2.5.4, 2017-03-28 -// By the MadGraph5_aMC@NLO Development Team -// Visit launchpad.net/madgraph5 and amcatnlo.web.cern.ch -//========================================================================== -// and was then modified by J. Bellm. -#include "eeuugg.h" -#include "HelAmps_sm.h" -#include - -using namespace MG5_sm_COLOREA; - -//========================================================================== -// Class member functions for calculating the matrix elements for -// Process: e+ e- > u u~ g g WEIGHTED<=6 @1 - -//-------------------------------------------------------------------------- -// Initialize process. - -vector eeuugg::producePermutation(double r,vector < double * > & momenta){ - - setMomenta(momenta); - sigmaKin(); - - static const int res[2][5] = { - {5, 6, 3, 4, 0}, - {6, 5, 3, 4, 0}}; - - double jampsum=0.; - for( int i=0;i<2;i++) jampsum+=jamp2[0][i]; -// std::cout<<"\njampsum "< r )return std::vector(res[i], res[i] + sizeof res[i] / sizeof res[i][0]); - } - std::cerr<<"\nproducePermutation: Upps.. Something went wrong!!\n"<(); -} - - - -void eeuugg::initProc(string param_card_name) -{ - cout<<"\nColorea: Init process eeuugg for rearrangement (arXiv:1801.06113)."; - // Instantiate the model class and set parameters that stay fixed during run - pars = Parameters_sm::getInstance(); - SLHAReader_COLOREA slha(param_card_name); - pars->setIndependentParameters(slha); - pars->setIndependentCouplings(); -// pars->printIndependentParameters(); -// pars->printIndependentCouplings(); - // Set external particle masses for this matrix element - mME.push_back(pars->ZERO); - mME.push_back(pars->ZERO); - mME.push_back(pars->ZERO); - mME.push_back(pars->ZERO); - mME.push_back(pars->ZERO); - mME.push_back(pars->ZERO); - jamp2[0] = new double[2]; -} - -//-------------------------------------------------------------------------- -// Evaluate |M|^2, part independent of incoming flavour. - -void eeuugg::sigmaKin() -{ - // Set the parameters which change event by event - pars->setDependentParameters(); - pars->setDependentCouplings(); - static bool firsttime = true; - if (firsttime) - { -// pars->printDependentParameters(); -// pars->printDependentCouplings(); - firsttime = false; - } - - // Reset color flows - for(int i = 0; i < 2; i++ ) - jamp2[0][i] = 0.; - - // Local variables and constants - const int ncomb = 64; - static bool goodhel[ncomb] = {ncomb * false}; - static int ntry = 0, sum_hel = 0, ngood = 0; - static int igood[ncomb]; - static int jhel; - double t[nprocesses]; - // Helicities for the process - static const int helicities[ncomb][nexternal] = {{-1, -1, -1, -1, -1, -1}, - {-1, -1, -1, -1, -1, 1}, {-1, -1, -1, -1, 1, -1}, {-1, -1, -1, -1, 1, 1}, - {-1, -1, -1, 1, -1, -1}, {-1, -1, -1, 1, -1, 1}, {-1, -1, -1, 1, 1, -1}, - {-1, -1, -1, 1, 1, 1}, {-1, -1, 1, -1, -1, -1}, {-1, -1, 1, -1, -1, 1}, - {-1, -1, 1, -1, 1, -1}, {-1, -1, 1, -1, 1, 1}, {-1, -1, 1, 1, -1, -1}, - {-1, -1, 1, 1, -1, 1}, {-1, -1, 1, 1, 1, -1}, {-1, -1, 1, 1, 1, 1}, {-1, - 1, -1, -1, -1, -1}, {-1, 1, -1, -1, -1, 1}, {-1, 1, -1, -1, 1, -1}, {-1, - 1, -1, -1, 1, 1}, {-1, 1, -1, 1, -1, -1}, {-1, 1, -1, 1, -1, 1}, {-1, 1, - -1, 1, 1, -1}, {-1, 1, -1, 1, 1, 1}, {-1, 1, 1, -1, -1, -1}, {-1, 1, 1, - -1, -1, 1}, {-1, 1, 1, -1, 1, -1}, {-1, 1, 1, -1, 1, 1}, {-1, 1, 1, 1, - -1, -1}, {-1, 1, 1, 1, -1, 1}, {-1, 1, 1, 1, 1, -1}, {-1, 1, 1, 1, 1, 1}, - {1, -1, -1, -1, -1, -1}, {1, -1, -1, -1, -1, 1}, {1, -1, -1, -1, 1, -1}, - {1, -1, -1, -1, 1, 1}, {1, -1, -1, 1, -1, -1}, {1, -1, -1, 1, -1, 1}, {1, - -1, -1, 1, 1, -1}, {1, -1, -1, 1, 1, 1}, {1, -1, 1, -1, -1, -1}, {1, -1, - 1, -1, -1, 1}, {1, -1, 1, -1, 1, -1}, {1, -1, 1, -1, 1, 1}, {1, -1, 1, 1, - -1, -1}, {1, -1, 1, 1, -1, 1}, {1, -1, 1, 1, 1, -1}, {1, -1, 1, 1, 1, 1}, - {1, 1, -1, -1, -1, -1}, {1, 1, -1, -1, -1, 1}, {1, 1, -1, -1, 1, -1}, {1, - 1, -1, -1, 1, 1}, {1, 1, -1, 1, -1, -1}, {1, 1, -1, 1, -1, 1}, {1, 1, -1, - 1, 1, -1}, {1, 1, -1, 1, 1, 1}, {1, 1, 1, -1, -1, -1}, {1, 1, 1, -1, -1, - 1}, {1, 1, 1, -1, 1, -1}, {1, 1, 1, -1, 1, 1}, {1, 1, 1, 1, -1, -1}, {1, - 1, 1, 1, -1, 1}, {1, 1, 1, 1, 1, -1}, {1, 1, 1, 1, 1, 1}}; - // Denominators: spins, colors and identical particles - const int denominators[nprocesses] = {8}; - - ntry = ntry + 1; - - // Reset the matrix elements - for(int i = 0; i < nprocesses; i++ ) - { - matrix_element[i] = 0.; - } - // Define permutation - int perm[nexternal]; - for(int i = 0; i < nexternal; i++ ) - { - perm[i] = i; - } - - if (sum_hel == 0 || ntry < 10) - { - // Calculate the matrix element for all helicities - for(int ihel = 0; ihel < ncomb; ihel++ ) - { - if (goodhel[ihel] || ntry < 2) - { - calculate_wavefunctions(perm, helicities[ihel]); - t[0] = matrix_1_epem_uuxgg(); - - double tsum = 0; - for(int iproc = 0; iproc < nprocesses; iproc++ ) - { - matrix_element[iproc] += t[iproc]; - tsum += t[iproc]; - } - // Store which helicities give non-zero result - if (tsum != 0. && !goodhel[ihel]) - { - goodhel[ihel] = true; - ngood++; - igood[ngood] = ihel; - } - } - } - jhel = 0; - sum_hel = min(sum_hel, ngood); - } - else - { - // Only use the "good" helicities - for(int j = 0; j < sum_hel; j++ ) - { - jhel++; - if (jhel >= ngood) - jhel = 0; - double hwgt = double(ngood)/double(sum_hel); - int ihel = igood[jhel]; - calculate_wavefunctions(perm, helicities[ihel]); - t[0] = matrix_1_epem_uuxgg(); - - for(int iproc = 0; iproc < nprocesses; iproc++ ) - { - matrix_element[iproc] += t[iproc] * hwgt; - } - } - } - - for (int i = 0; i < nprocesses; i++ ) - matrix_element[i] /= denominators[i]; - - - -} - - -//-------------------------------------------------------------------------- -// Evaluate |M|^2 for each subprocess - -void eeuugg::calculate_wavefunctions(const int perm[], const int hel[]) -{ - // Calculate wavefunctions for all processes - - - // Calculate all wavefunctions - oxxxxx(p[perm[0]], mME[0], hel[0], -1, w[0]); - ixxxxx(p[perm[1]], mME[1], hel[1], +1, w[1]); - oxxxxx(p[perm[2]], mME[2], hel[2], +1, w[2]); - ixxxxx(p[perm[3]], mME[3], hel[3], -1, w[3]); - vxxxxx(p[perm[4]], mME[4], hel[4], +1, w[4]); - vxxxxx(p[perm[5]], mME[5], hel[5], +1, w[5]); - FFV1P0_3(w[1], w[0], pars->GC_3, pars->ZERO, pars->ZERO, w[6]); - FFV1_1(w[2], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[7]); - FFV1_2(w[3], w[6], pars->GC_2, pars->ZERO, pars->ZERO, w[8]); - FFV2_4_3(w[1], w[0], pars->GC_50, pars->GC_59, pars->mdl_MZ, pars->mdl_WZ, - w[9]); - FFV2_5_2(w[3], w[9], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[10]); - FFV1_2(w[3], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[11]); - FFV1_1(w[2], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[12]); - FFV1_2(w[3], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[13]); - FFV1_1(w[2], w[6], pars->GC_2, pars->ZERO, pars->ZERO, w[14]); - FFV2_5_1(w[2], w[9], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[15]); - VVV1P0_1(w[4], w[5], pars->GC_10, pars->ZERO, pars->ZERO, w[16]); - - // Calculate all amplitudes - // Amplitude(s) for diagram number 0 - FFV1_0(w[8], w[7], w[5], pars->GC_11, amp[0]); - FFV1_0(w[10], w[7], w[5], pars->GC_11, amp[1]); - FFV1_0(w[11], w[7], w[6], pars->GC_2, amp[2]); - FFV2_5_0(w[11], w[7], w[9], pars->GC_51, pars->GC_58, amp[3]); - FFV1_0(w[8], w[12], w[4], pars->GC_11, amp[4]); - FFV1_0(w[10], w[12], w[4], pars->GC_11, amp[5]); - FFV1_0(w[13], w[12], w[6], pars->GC_2, amp[6]); - FFV2_5_0(w[13], w[12], w[9], pars->GC_51, pars->GC_58, amp[7]); - FFV1_0(w[13], w[14], w[5], pars->GC_11, amp[8]); - FFV1_0(w[13], w[15], w[5], pars->GC_11, amp[9]); - FFV1_0(w[11], w[14], w[4], pars->GC_11, amp[10]); - FFV1_0(w[11], w[15], w[4], pars->GC_11, amp[11]); - FFV1_0(w[3], w[14], w[16], pars->GC_11, amp[12]); - FFV1_0(w[8], w[2], w[16], pars->GC_11, amp[13]); - FFV1_0(w[3], w[15], w[16], pars->GC_11, amp[14]); - FFV1_0(w[10], w[2], w[16], pars->GC_11, amp[15]); - -} -double eeuugg::matrix_1_epem_uuxgg() -{ - //int i, j; - // Local variables - //const int ngraphs = 16; - //const int ncolor = 2; - std::complex ztemp; - std::complex jamp[2]; - // The color matrix; - //static const double denom[ncolor] = {3, 3}; - //static const double cf[ncolor][ncolor] = {{16, -2}, {-2, 16}}; - - // Calculate color flows - jamp[0] = +amp[0] + amp[1] + amp[2] + amp[3] + amp[10] + amp[11] - - std::complex (0, 1) * amp[12] - std::complex (0, 1) * - amp[13] - std::complex (0, 1) * amp[14] - std::complex - (0, 1) * amp[15]; - jamp[1] = +amp[4] + amp[5] + amp[6] + amp[7] + amp[8] + amp[9] + - std::complex (0, 1) * amp[12] + std::complex (0, 1) * - amp[13] + std::complex (0, 1) * amp[14] + std::complex - (0, 1) * amp[15]; - - // Store the leading color flows for choice of color - for(int i = 0; i < 2; i++ ) - jamp2[0][i] += real(jamp[i] * conj(jamp[i])); - - return -1.; -} - - -double eeuugg::get_jamp2(int i) -{ - return jamp2[0][i]; -} - -int eeuugg::colorstring(int i, int j) -{ - static const double res[2][5] = { - {5, 6, 3, 4, 0}, - {6, 5, 3, 4, 0}}; - return res[i][j]; -} - - -int eeuugg::NCol() -{ - const int ncolor = 2; - return ncolor; -} - - - - - - diff --git a/Shower/Dipole/Colorea/eeuugg.h b/Shower/Dipole/Colorea/eeuugg.h deleted file mode 100644 --- a/Shower/Dipole/Colorea/eeuugg.h +++ /dev/null @@ -1,52 +0,0 @@ - //========================================================================== - // This file has been automatically generated for C++ Standalone by - // MadGraph5_aMC@NLO v. 2.5.4, 2017-03-28 - // By the MadGraph5_aMC@NLO Development Team - // Visit launchpad.net/madgraph5 and amcatnlo.web.cern.ch - //========================================================================== - // and was then modified by J. Bellm. -#ifndef MG5_Sigma_sm_epem_uuxgg_H -#define MG5_Sigma_sm_epem_uuxgg_H -#include -#include -#include "Parameters_sm.h" -using namespace std; -class eeuugg -{ - public: - eeuugg() { - initProc("param_card.dat"); - } - // Retrun the prefered gluon order - vector producePermutation(double r,vector < double * > & momenta); - void setMass(int i,double M){mME[i]=M;} - private: - ///////// Process Dependent - static const int ninitial = 2; - static const int nexternal = 6; - static const int nprocesses = 1; - static const int nwavefuncs = 17; - static const int namplitudes = 16; - std::complex w[nwavefuncs][18]; - double matrix_1_epem_uuxgg(); - ///////// Generic - double matrix_element[nprocesses]; - std::complex amp[namplitudes]; - double * jamp2[nprocesses]; - Parameters_sm * pars; - vector mME; - vector < double * > p; - int id1, id2; - void initProc(string param_card_name); - void sigmaKin(); - const vector & getMasses() const {return mME;} - vector < double * > getMomenta(){return p;} - void setMomenta(vector < double * > & momenta){p = momenta;} - void setInitial(int inid1, int inid2){id1 = inid1; id2 = inid2;} - void calculate_wavefunctions(const int perm[], const int hel[]); - // New function - double get_jamp2(int i); - int colorstring(int i, int j); - int NCol(); -}; -#endif // MG5_Sigma_sm_epem_uuxgg_H diff --git a/Shower/Dipole/Colorea/eeuuggg.cc b/Shower/Dipole/Colorea/eeuuggg.cc deleted file mode 100644 --- a/Shower/Dipole/Colorea/eeuuggg.cc +++ /dev/null @@ -1,532 +0,0 @@ -//========================================================================== -// This file has been automatically generated for C++ Standalone by -// MadGraph5_aMC@NLO v. 2.5.4, 2017-03-28 -// By the MadGraph5_aMC@NLO Development Team -// Visit launchpad.net/madgraph5 and amcatnlo.web.cern.ch -//========================================================================== -// and was then modified by J. Bellm. -#include "eeuuggg.h" -#include "HelAmps_sm.h" -#include - -using namespace MG5_sm_COLOREA; - -//========================================================================== -// Class member functions for calculating the matrix elements for -// Process: e+ e- > u u~ g g g WEIGHTED<=7 @1 - -//-------------------------------------------------------------------------- -// Initialize process. - -vector eeuuggg::producePermutation(double r,vector < double * > & momenta){ - static bool initialized=false; - if (!initialized){ - initProc("param_card.dat"); - initialized=true; - } - setMomenta(momenta); - sigmaKin(); - - static const int res[6][6] = { - {5, 6, 7, 3, 4, 0}, - {5, 7, 6, 3, 4, 0}, - {6, 5, 7, 3, 4, 0}, - {6, 7, 5, 3, 4, 0}, - {7, 5, 6, 3, 4, 0}, - {7, 6, 5, 3, 4, 0}}; - - double jampsum=0.; - for( int i=0;i<6;i++) jampsum+=jamp2[0][i]; - double cur=0.; - for(int i=0;i<6;i++){ - cur+=jamp2[0][i]; - if( cur/jampsum > r )return std::vector(res[i], res[i] + sizeof res[i] / sizeof res[i][0]); - } - //std::cout<<"producePermutation: Upps.. Something went wrong!!"; - return std::vector(); -} - - -void eeuuggg::initProc(string param_card_name) -{ - // Instantiate the model class and set parameters that stay fixed during run - cout<<"\nColorea: Init process eeuuggg for rearrangement (arXiv:1801.06113)."; - pars = Parameters_sm::getInstance(); - SLHAReader_COLOREA slha(param_card_name); - pars->setIndependentParameters(slha); - pars->setIndependentCouplings(); -// pars->printIndependentParameters(); -// pars->printIndependentCouplings(); - // Set external particle masses for this matrix element - mME.push_back(pars->ZERO); - mME.push_back(pars->ZERO); - mME.push_back(pars->ZERO); - mME.push_back(pars->ZERO); - mME.push_back(pars->ZERO); - mME.push_back(pars->ZERO); - mME.push_back(pars->ZERO); - jamp2[0] = new double[6]; -} - -//-------------------------------------------------------------------------- -// Evaluate |M|^2, part independent of incoming flavour. - -void eeuuggg::sigmaKin() -{ - // Set the parameters which change event by event - pars->setDependentParameters(); - pars->setDependentCouplings(); - static bool firsttime = true; - if (firsttime) - { -// pars->printDependentParameters(); -// pars->printDependentCouplings(); - firsttime = false; - } - - // Reset color flows - for(int i = 0; i < 6; i++ ) - jamp2[0][i] = 0.; - - // Local variables and constants - const int ncomb = 128; - static bool goodhel[ncomb] = {ncomb * false}; - static int ntry = 0, sum_hel = 0, ngood = 0; - static int igood[ncomb]; - static int jhel; -// std::complex * * wfs; - double t[nprocesses]; - // Helicities for the process - static const int helicities[ncomb][nexternal] = {{-1, -1, -1, -1, -1, -1, - -1}, {-1, -1, -1, -1, -1, -1, 1}, {-1, -1, -1, -1, -1, 1, -1}, {-1, -1, - -1, -1, -1, 1, 1}, {-1, -1, -1, -1, 1, -1, -1}, {-1, -1, -1, -1, 1, -1, - 1}, {-1, -1, -1, -1, 1, 1, -1}, {-1, -1, -1, -1, 1, 1, 1}, {-1, -1, -1, - 1, -1, -1, -1}, {-1, -1, -1, 1, -1, -1, 1}, {-1, -1, -1, 1, -1, 1, -1}, - {-1, -1, -1, 1, -1, 1, 1}, {-1, -1, -1, 1, 1, -1, -1}, {-1, -1, -1, 1, 1, - -1, 1}, {-1, -1, -1, 1, 1, 1, -1}, {-1, -1, -1, 1, 1, 1, 1}, {-1, -1, 1, - -1, -1, -1, -1}, {-1, -1, 1, -1, -1, -1, 1}, {-1, -1, 1, -1, -1, 1, -1}, - {-1, -1, 1, -1, -1, 1, 1}, {-1, -1, 1, -1, 1, -1, -1}, {-1, -1, 1, -1, 1, - -1, 1}, {-1, -1, 1, -1, 1, 1, -1}, {-1, -1, 1, -1, 1, 1, 1}, {-1, -1, 1, - 1, -1, -1, -1}, {-1, -1, 1, 1, -1, -1, 1}, {-1, -1, 1, 1, -1, 1, -1}, - {-1, -1, 1, 1, -1, 1, 1}, {-1, -1, 1, 1, 1, -1, -1}, {-1, -1, 1, 1, 1, - -1, 1}, {-1, -1, 1, 1, 1, 1, -1}, {-1, -1, 1, 1, 1, 1, 1}, {-1, 1, -1, - -1, -1, -1, -1}, {-1, 1, -1, -1, -1, -1, 1}, {-1, 1, -1, -1, -1, 1, -1}, - {-1, 1, -1, -1, -1, 1, 1}, {-1, 1, -1, -1, 1, -1, -1}, {-1, 1, -1, -1, 1, - -1, 1}, {-1, 1, -1, -1, 1, 1, -1}, {-1, 1, -1, -1, 1, 1, 1}, {-1, 1, -1, - 1, -1, -1, -1}, {-1, 1, -1, 1, -1, -1, 1}, {-1, 1, -1, 1, -1, 1, -1}, - {-1, 1, -1, 1, -1, 1, 1}, {-1, 1, -1, 1, 1, -1, -1}, {-1, 1, -1, 1, 1, - -1, 1}, {-1, 1, -1, 1, 1, 1, -1}, {-1, 1, -1, 1, 1, 1, 1}, {-1, 1, 1, -1, - -1, -1, -1}, {-1, 1, 1, -1, -1, -1, 1}, {-1, 1, 1, -1, -1, 1, -1}, {-1, - 1, 1, -1, -1, 1, 1}, {-1, 1, 1, -1, 1, -1, -1}, {-1, 1, 1, -1, 1, -1, 1}, - {-1, 1, 1, -1, 1, 1, -1}, {-1, 1, 1, -1, 1, 1, 1}, {-1, 1, 1, 1, -1, -1, - -1}, {-1, 1, 1, 1, -1, -1, 1}, {-1, 1, 1, 1, -1, 1, -1}, {-1, 1, 1, 1, - -1, 1, 1}, {-1, 1, 1, 1, 1, -1, -1}, {-1, 1, 1, 1, 1, -1, 1}, {-1, 1, 1, - 1, 1, 1, -1}, {-1, 1, 1, 1, 1, 1, 1}, {1, -1, -1, -1, -1, -1, -1}, {1, - -1, -1, -1, -1, -1, 1}, {1, -1, -1, -1, -1, 1, -1}, {1, -1, -1, -1, -1, - 1, 1}, {1, -1, -1, -1, 1, -1, -1}, {1, -1, -1, -1, 1, -1, 1}, {1, -1, -1, - -1, 1, 1, -1}, {1, -1, -1, -1, 1, 1, 1}, {1, -1, -1, 1, -1, -1, -1}, {1, - -1, -1, 1, -1, -1, 1}, {1, -1, -1, 1, -1, 1, -1}, {1, -1, -1, 1, -1, 1, - 1}, {1, -1, -1, 1, 1, -1, -1}, {1, -1, -1, 1, 1, -1, 1}, {1, -1, -1, 1, - 1, 1, -1}, {1, -1, -1, 1, 1, 1, 1}, {1, -1, 1, -1, -1, -1, -1}, {1, -1, - 1, -1, -1, -1, 1}, {1, -1, 1, -1, -1, 1, -1}, {1, -1, 1, -1, -1, 1, 1}, - {1, -1, 1, -1, 1, -1, -1}, {1, -1, 1, -1, 1, -1, 1}, {1, -1, 1, -1, 1, 1, - -1}, {1, -1, 1, -1, 1, 1, 1}, {1, -1, 1, 1, -1, -1, -1}, {1, -1, 1, 1, - -1, -1, 1}, {1, -1, 1, 1, -1, 1, -1}, {1, -1, 1, 1, -1, 1, 1}, {1, -1, 1, - 1, 1, -1, -1}, {1, -1, 1, 1, 1, -1, 1}, {1, -1, 1, 1, 1, 1, -1}, {1, -1, - 1, 1, 1, 1, 1}, {1, 1, -1, -1, -1, -1, -1}, {1, 1, -1, -1, -1, -1, 1}, - {1, 1, -1, -1, -1, 1, -1}, {1, 1, -1, -1, -1, 1, 1}, {1, 1, -1, -1, 1, - -1, -1}, {1, 1, -1, -1, 1, -1, 1}, {1, 1, -1, -1, 1, 1, -1}, {1, 1, -1, - -1, 1, 1, 1}, {1, 1, -1, 1, -1, -1, -1}, {1, 1, -1, 1, -1, -1, 1}, {1, 1, - -1, 1, -1, 1, -1}, {1, 1, -1, 1, -1, 1, 1}, {1, 1, -1, 1, 1, -1, -1}, {1, - 1, -1, 1, 1, -1, 1}, {1, 1, -1, 1, 1, 1, -1}, {1, 1, -1, 1, 1, 1, 1}, {1, - 1, 1, -1, -1, -1, -1}, {1, 1, 1, -1, -1, -1, 1}, {1, 1, 1, -1, -1, 1, - -1}, {1, 1, 1, -1, -1, 1, 1}, {1, 1, 1, -1, 1, -1, -1}, {1, 1, 1, -1, 1, - -1, 1}, {1, 1, 1, -1, 1, 1, -1}, {1, 1, 1, -1, 1, 1, 1}, {1, 1, 1, 1, -1, - -1, -1}, {1, 1, 1, 1, -1, -1, 1}, {1, 1, 1, 1, -1, 1, -1}, {1, 1, 1, 1, - -1, 1, 1}, {1, 1, 1, 1, 1, -1, -1}, {1, 1, 1, 1, 1, -1, 1}, {1, 1, 1, 1, - 1, 1, -1}, {1, 1, 1, 1, 1, 1, 1}}; - // Denominators: spins, colors and identical particles - const int denominators[nprocesses] = {24}; - - ntry = ntry + 1; - - // Reset the matrix elements - for(int i = 0; i < nprocesses; i++ ) - { - matrix_element[i] = 0.; - } - // Define permutation - int perm[nexternal]; - for(int i = 0; i < nexternal; i++ ) - { - perm[i] = i; - } - - if (sum_hel == 0 || ntry < 10) - { - // Calculate the matrix element for all helicities - for(int ihel = 0; ihel < ncomb; ihel++ ) - { - if (goodhel[ihel] || ntry < 2) - { - calculate_wavefunctions(perm, helicities[ihel]); - t[0] = matrix_1_epem_uuxggg(); - - double tsum = 0; - for(int iproc = 0; iproc < nprocesses; iproc++ ) - { - matrix_element[iproc] += t[iproc]; - tsum += t[iproc]; - } - // Store which helicities give non-zero result - if (tsum != 0. && !goodhel[ihel]) - { - goodhel[ihel] = true; - ngood++; - igood[ngood] = ihel; - } - } - } - jhel = 0; - sum_hel = min(sum_hel, ngood); - } - else - { - // Only use the "good" helicities - for(int j = 0; j < sum_hel; j++ ) - { - jhel++; - if (jhel >= ngood) - jhel = 0; - double hwgt = double(ngood)/double(sum_hel); - int ihel = igood[jhel]; - calculate_wavefunctions(perm, helicities[ihel]); - t[0] = matrix_1_epem_uuxggg(); - - for(int iproc = 0; iproc < nprocesses; iproc++ ) - { - matrix_element[iproc] += t[iproc] * hwgt; - } - } - } - - for (int i = 0; i < nprocesses; i++ ) - matrix_element[i] /= denominators[i]; - - - -} - - -//========================================================================== -// Private class member functions - -//-------------------------------------------------------------------------- -// Evaluate |M|^2 for each subprocess - -void eeuuggg::calculate_wavefunctions(const int perm[], const int hel[]) -{ - // Calculate wavefunctions for all processes -// int i;//, j; - - // Calculate all wavefunctions - oxxxxx(p[perm[0]], mME[0], hel[0], -1, w[0]); - ixxxxx(p[perm[1]], mME[1], hel[1], +1, w[1]); - oxxxxx(p[perm[2]], mME[2], hel[2], +1, w[2]); - ixxxxx(p[perm[3]], mME[3], hel[3], -1, w[3]); - vxxxxx(p[perm[4]], mME[4], hel[4], +1, w[4]); - vxxxxx(p[perm[5]], mME[5], hel[5], +1, w[5]); - vxxxxx(p[perm[6]], mME[6], hel[6], +1, w[6]); - FFV1P0_3(w[1], w[0], pars->GC_3, pars->ZERO, pars->ZERO, w[7]); - FFV1_1(w[2], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[8]); - FFV1_2(w[3], w[7], pars->GC_2, pars->ZERO, pars->ZERO, w[9]); - FFV1_1(w[8], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[10]); - FFV1_1(w[8], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[11]); - FFV2_4_3(w[1], w[0], pars->GC_50, pars->GC_59, pars->mdl_MZ, pars->mdl_WZ, - w[12]); - FFV2_5_2(w[3], w[12], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[13]); - FFV1_2(w[3], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[14]); - FFV1_1(w[8], w[7], pars->GC_2, pars->ZERO, pars->ZERO, w[15]); - FFV1_2(w[14], w[7], pars->GC_2, pars->ZERO, pars->ZERO, w[16]); - FFV2_5_1(w[8], w[12], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[17]); - FFV2_5_2(w[14], w[12], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[18]); - FFV1_2(w[3], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[19]); - FFV1_2(w[19], w[7], pars->GC_2, pars->ZERO, pars->ZERO, w[20]); - FFV2_5_2(w[19], w[12], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[21]); - VVV1P0_1(w[5], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[22]); - FFV1_1(w[2], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[23]); - FFV1_1(w[23], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[24]); - FFV1_1(w[23], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[25]); - FFV1_2(w[3], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[26]); - FFV1_1(w[23], w[7], pars->GC_2, pars->ZERO, pars->ZERO, w[27]); - FFV1_2(w[26], w[7], pars->GC_2, pars->ZERO, pars->ZERO, w[28]); - FFV2_5_1(w[23], w[12], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[29]); - FFV2_5_2(w[26], w[12], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[30]); - VVV1P0_1(w[4], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[31]); - FFV1_1(w[2], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[32]); - FFV1_1(w[32], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[33]); - FFV1_1(w[32], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[34]); - FFV1_1(w[32], w[7], pars->GC_2, pars->ZERO, pars->ZERO, w[35]); - FFV2_5_1(w[32], w[12], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[36]); - VVV1P0_1(w[4], w[5], pars->GC_10, pars->ZERO, pars->ZERO, w[37]); - FFV1_1(w[2], w[7], pars->GC_2, pars->ZERO, pars->ZERO, w[38]); - FFV1_2(w[26], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[39]); - FFV1_2(w[26], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[40]); - FFV2_5_1(w[2], w[12], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[41]); - FFV1_2(w[14], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[42]); - FFV1_2(w[14], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[43]); - FFV1_2(w[19], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[44]); - FFV1_2(w[19], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[45]); - FFV1_2(w[3], w[37], pars->GC_11, pars->ZERO, pars->ZERO, w[46]); - VVV1P0_1(w[37], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[47]); - FFV1_1(w[2], w[37], pars->GC_11, pars->ZERO, pars->ZERO, w[48]); - FFV1_2(w[3], w[31], pars->GC_11, pars->ZERO, pars->ZERO, w[49]); - VVV1P0_1(w[31], w[5], pars->GC_10, pars->ZERO, pars->ZERO, w[50]); - FFV1_1(w[2], w[31], pars->GC_11, pars->ZERO, pars->ZERO, w[51]); - FFV1_2(w[3], w[22], pars->GC_11, pars->ZERO, pars->ZERO, w[52]); - VVV1P0_1(w[4], w[22], pars->GC_10, pars->ZERO, pars->ZERO, w[53]); - FFV1_1(w[2], w[22], pars->GC_11, pars->ZERO, pars->ZERO, w[54]); - VVVV1P0_1(w[4], w[5], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[55]); - VVVV3P0_1(w[4], w[5], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[56]); - VVVV4P0_1(w[4], w[5], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[57]); - - // Calculate all amplitudes - // Amplitude(s) for diagram number 0 - FFV1_0(w[9], w[10], w[6], pars->GC_11, amp[0]); - FFV1_0(w[9], w[11], w[5], pars->GC_11, amp[1]); - FFV1_0(w[13], w[10], w[6], pars->GC_11, amp[2]); - FFV1_0(w[13], w[11], w[5], pars->GC_11, amp[3]); - FFV1_0(w[14], w[15], w[6], pars->GC_11, amp[4]); - FFV1_0(w[16], w[8], w[6], pars->GC_11, amp[5]); - FFV1_0(w[14], w[17], w[6], pars->GC_11, amp[6]); - FFV1_0(w[18], w[8], w[6], pars->GC_11, amp[7]); - FFV1_0(w[19], w[15], w[5], pars->GC_11, amp[8]); - FFV1_0(w[20], w[8], w[5], pars->GC_11, amp[9]); - FFV1_0(w[19], w[17], w[5], pars->GC_11, amp[10]); - FFV1_0(w[21], w[8], w[5], pars->GC_11, amp[11]); - FFV1_0(w[3], w[15], w[22], pars->GC_11, amp[12]); - FFV1_0(w[9], w[8], w[22], pars->GC_11, amp[13]); - FFV1_0(w[3], w[17], w[22], pars->GC_11, amp[14]); - FFV1_0(w[13], w[8], w[22], pars->GC_11, amp[15]); - FFV1_0(w[9], w[24], w[6], pars->GC_11, amp[16]); - FFV1_0(w[9], w[25], w[4], pars->GC_11, amp[17]); - FFV1_0(w[13], w[24], w[6], pars->GC_11, amp[18]); - FFV1_0(w[13], w[25], w[4], pars->GC_11, amp[19]); - FFV1_0(w[26], w[27], w[6], pars->GC_11, amp[20]); - FFV1_0(w[28], w[23], w[6], pars->GC_11, amp[21]); - FFV1_0(w[26], w[29], w[6], pars->GC_11, amp[22]); - FFV1_0(w[30], w[23], w[6], pars->GC_11, amp[23]); - FFV1_0(w[19], w[27], w[4], pars->GC_11, amp[24]); - FFV1_0(w[20], w[23], w[4], pars->GC_11, amp[25]); - FFV1_0(w[19], w[29], w[4], pars->GC_11, amp[26]); - FFV1_0(w[21], w[23], w[4], pars->GC_11, amp[27]); - FFV1_0(w[3], w[27], w[31], pars->GC_11, amp[28]); - FFV1_0(w[9], w[23], w[31], pars->GC_11, amp[29]); - FFV1_0(w[3], w[29], w[31], pars->GC_11, amp[30]); - FFV1_0(w[13], w[23], w[31], pars->GC_11, amp[31]); - FFV1_0(w[9], w[33], w[5], pars->GC_11, amp[32]); - FFV1_0(w[9], w[34], w[4], pars->GC_11, amp[33]); - FFV1_0(w[13], w[33], w[5], pars->GC_11, amp[34]); - FFV1_0(w[13], w[34], w[4], pars->GC_11, amp[35]); - FFV1_0(w[26], w[35], w[5], pars->GC_11, amp[36]); - FFV1_0(w[28], w[32], w[5], pars->GC_11, amp[37]); - FFV1_0(w[26], w[36], w[5], pars->GC_11, amp[38]); - FFV1_0(w[30], w[32], w[5], pars->GC_11, amp[39]); - FFV1_0(w[14], w[35], w[4], pars->GC_11, amp[40]); - FFV1_0(w[16], w[32], w[4], pars->GC_11, amp[41]); - FFV1_0(w[14], w[36], w[4], pars->GC_11, amp[42]); - FFV1_0(w[18], w[32], w[4], pars->GC_11, amp[43]); - FFV1_0(w[3], w[35], w[37], pars->GC_11, amp[44]); - FFV1_0(w[9], w[32], w[37], pars->GC_11, amp[45]); - FFV1_0(w[3], w[36], w[37], pars->GC_11, amp[46]); - FFV1_0(w[13], w[32], w[37], pars->GC_11, amp[47]); - FFV1_0(w[39], w[38], w[6], pars->GC_11, amp[48]); - FFV1_0(w[40], w[38], w[5], pars->GC_11, amp[49]); - FFV1_0(w[39], w[41], w[6], pars->GC_11, amp[50]); - FFV1_0(w[40], w[41], w[5], pars->GC_11, amp[51]); - FFV1_0(w[26], w[38], w[22], pars->GC_11, amp[52]); - FFV1_0(w[28], w[2], w[22], pars->GC_11, amp[53]); - FFV1_0(w[26], w[41], w[22], pars->GC_11, amp[54]); - FFV1_0(w[30], w[2], w[22], pars->GC_11, amp[55]); - FFV1_0(w[42], w[38], w[6], pars->GC_11, amp[56]); - FFV1_0(w[43], w[38], w[4], pars->GC_11, amp[57]); - FFV1_0(w[42], w[41], w[6], pars->GC_11, amp[58]); - FFV1_0(w[43], w[41], w[4], pars->GC_11, amp[59]); - FFV1_0(w[14], w[38], w[31], pars->GC_11, amp[60]); - FFV1_0(w[16], w[2], w[31], pars->GC_11, amp[61]); - FFV1_0(w[14], w[41], w[31], pars->GC_11, amp[62]); - FFV1_0(w[18], w[2], w[31], pars->GC_11, amp[63]); - FFV1_0(w[44], w[38], w[5], pars->GC_11, amp[64]); - FFV1_0(w[45], w[38], w[4], pars->GC_11, amp[65]); - FFV1_0(w[44], w[41], w[5], pars->GC_11, amp[66]); - FFV1_0(w[45], w[41], w[4], pars->GC_11, amp[67]); - FFV1_0(w[19], w[38], w[37], pars->GC_11, amp[68]); - FFV1_0(w[20], w[2], w[37], pars->GC_11, amp[69]); - FFV1_0(w[19], w[41], w[37], pars->GC_11, amp[70]); - FFV1_0(w[21], w[2], w[37], pars->GC_11, amp[71]); - FFV1_0(w[46], w[38], w[6], pars->GC_11, amp[72]); - FFV1_0(w[3], w[38], w[47], pars->GC_11, amp[73]); - FFV1_0(w[9], w[48], w[6], pars->GC_11, amp[74]); - FFV1_0(w[9], w[2], w[47], pars->GC_11, amp[75]); - FFV1_0(w[46], w[41], w[6], pars->GC_11, amp[76]); - FFV1_0(w[3], w[41], w[47], pars->GC_11, amp[77]); - FFV1_0(w[13], w[48], w[6], pars->GC_11, amp[78]); - FFV1_0(w[13], w[2], w[47], pars->GC_11, amp[79]); - FFV1_0(w[49], w[38], w[5], pars->GC_11, amp[80]); - FFV1_0(w[3], w[38], w[50], pars->GC_11, amp[81]); - FFV1_0(w[9], w[51], w[5], pars->GC_11, amp[82]); - FFV1_0(w[9], w[2], w[50], pars->GC_11, amp[83]); - FFV1_0(w[49], w[41], w[5], pars->GC_11, amp[84]); - FFV1_0(w[3], w[41], w[50], pars->GC_11, amp[85]); - FFV1_0(w[13], w[51], w[5], pars->GC_11, amp[86]); - FFV1_0(w[13], w[2], w[50], pars->GC_11, amp[87]); - FFV1_0(w[52], w[38], w[4], pars->GC_11, amp[88]); - FFV1_0(w[3], w[38], w[53], pars->GC_11, amp[89]); - FFV1_0(w[9], w[54], w[4], pars->GC_11, amp[90]); - FFV1_0(w[9], w[2], w[53], pars->GC_11, amp[91]); - FFV1_0(w[52], w[41], w[4], pars->GC_11, amp[92]); - FFV1_0(w[3], w[41], w[53], pars->GC_11, amp[93]); - FFV1_0(w[13], w[54], w[4], pars->GC_11, amp[94]); - FFV1_0(w[13], w[2], w[53], pars->GC_11, amp[95]); - FFV1_0(w[3], w[38], w[55], pars->GC_11, amp[96]); - FFV1_0(w[3], w[38], w[56], pars->GC_11, amp[97]); - FFV1_0(w[3], w[38], w[57], pars->GC_11, amp[98]); - FFV1_0(w[9], w[2], w[55], pars->GC_11, amp[99]); - FFV1_0(w[9], w[2], w[56], pars->GC_11, amp[100]); - FFV1_0(w[9], w[2], w[57], pars->GC_11, amp[101]); - FFV1_0(w[3], w[41], w[55], pars->GC_11, amp[102]); - FFV1_0(w[3], w[41], w[56], pars->GC_11, amp[103]); - FFV1_0(w[3], w[41], w[57], pars->GC_11, amp[104]); - FFV1_0(w[13], w[2], w[55], pars->GC_11, amp[105]); - FFV1_0(w[13], w[2], w[56], pars->GC_11, amp[106]); - FFV1_0(w[13], w[2], w[57], pars->GC_11, amp[107]); - -} -double eeuuggg::matrix_1_epem_uuxggg() -{ - int i;//, j; - // Local variables -// const int ngraphs = 108; - const int ncolor = 6; - std::complex ztemp; - std::complex jamp[ncolor]; - // The color matrix; -// static const double denom[ncolor] = {9, 9, 9, 9, 9, 9}; -// static const double cf[ncolor][ncolor] = {{64, -8, -8, 1, 1, 10}, {-8, 64, 1, -// 10, -8, 1}, {-8, 1, 64, -8, 10, 1}, {1, 10, -8, 64, 1, -8}, {1, -8, 10, -// 1, 64, -8}, {10, 1, 1, -8, -8, 64}}; - - // Calculate color flows - jamp[0] = +amp[0] + amp[2] + amp[8] + amp[9] + amp[10] + amp[11] - - std::complex (0, 1) * amp[12] - std::complex (0, 1) * - amp[13] - std::complex (0, 1) * amp[14] - std::complex - (0, 1) * amp[15] + amp[65] + amp[67] - std::complex (0, 1) * - amp[68] - std::complex (0, 1) * amp[69] - std::complex - (0, 1) * amp[70] - std::complex (0, 1) * amp[71] - amp[73] - - std::complex (0, 1) * amp[74] - amp[75] - amp[77] - - std::complex (0, 1) * amp[78] - amp[79] - std::complex - (0, 1) * amp[88] - amp[89] - amp[91] - std::complex (0, 1) * - amp[92] - amp[93] - amp[95] + amp[98] - amp[96] + amp[101] - amp[99] + - amp[104] - amp[102] + amp[107] - amp[105]; - jamp[1] = +amp[1] + amp[3] + amp[4] + amp[5] + amp[6] + amp[7] + - std::complex (0, 1) * amp[12] + std::complex (0, 1) * - amp[13] + std::complex (0, 1) * amp[14] + std::complex - (0, 1) * amp[15] + amp[57] + amp[59] - std::complex (0, 1) * - amp[60] - std::complex (0, 1) * amp[61] - std::complex - (0, 1) * amp[62] - std::complex (0, 1) * amp[63] - amp[81] - - std::complex (0, 1) * amp[82] - amp[83] - amp[85] - - std::complex (0, 1) * amp[86] - amp[87] + std::complex - (0, 1) * amp[88] + amp[89] + amp[91] + std::complex (0, 1) * - amp[92] + amp[93] + amp[95] + amp[96] + amp[97] + amp[99] + amp[100] + - amp[102] + amp[103] + amp[105] + amp[106]; - jamp[2] = +amp[16] + amp[18] + amp[24] + amp[25] + amp[26] + amp[27] - - std::complex (0, 1) * amp[28] - std::complex (0, 1) * - amp[29] - std::complex (0, 1) * amp[30] - std::complex - (0, 1) * amp[31] + amp[64] + amp[66] + std::complex (0, 1) * - amp[68] + std::complex (0, 1) * amp[69] + std::complex - (0, 1) * amp[70] + std::complex (0, 1) * amp[71] + amp[73] + - std::complex (0, 1) * amp[74] + amp[75] + amp[77] + - std::complex (0, 1) * amp[78] + amp[79] - std::complex - (0, 1) * amp[80] + amp[81] + amp[83] - std::complex (0, 1) * - amp[84] + amp[85] + amp[87] - amp[98] - amp[97] - amp[101] - amp[100] - - amp[104] - amp[103] - amp[107] - amp[106]; - jamp[3] = +amp[17] + amp[19] + amp[20] + amp[21] + amp[22] + amp[23] + - std::complex (0, 1) * amp[28] + std::complex (0, 1) * - amp[29] + std::complex (0, 1) * amp[30] + std::complex - (0, 1) * amp[31] + amp[49] + amp[51] - std::complex (0, 1) * - amp[52] - std::complex (0, 1) * amp[53] - std::complex - (0, 1) * amp[54] - std::complex (0, 1) * amp[55] + - std::complex (0, 1) * amp[80] - amp[81] - amp[83] + - std::complex (0, 1) * amp[84] - amp[85] - amp[87] + amp[89] - - std::complex (0, 1) * amp[90] + amp[91] + amp[93] - - std::complex (0, 1) * amp[94] + amp[95] + amp[96] + amp[97] + - amp[99] + amp[100] + amp[102] + amp[103] + amp[105] + amp[106]; - jamp[4] = +amp[32] + amp[34] + amp[40] + amp[41] + amp[42] + amp[43] - - std::complex (0, 1) * amp[44] - std::complex (0, 1) * - amp[45] - std::complex (0, 1) * amp[46] - std::complex - (0, 1) * amp[47] + amp[56] + amp[58] + std::complex (0, 1) * - amp[60] + std::complex (0, 1) * amp[61] + std::complex - (0, 1) * amp[62] + std::complex (0, 1) * amp[63] - - std::complex (0, 1) * amp[72] + amp[73] + amp[75] - - std::complex (0, 1) * amp[76] + amp[77] + amp[79] + amp[81] + - std::complex (0, 1) * amp[82] + amp[83] + amp[85] + - std::complex (0, 1) * amp[86] + amp[87] - amp[98] - amp[97] - - amp[101] - amp[100] - amp[104] - amp[103] - amp[107] - amp[106]; - jamp[5] = +amp[33] + amp[35] + amp[36] + amp[37] + amp[38] + amp[39] + - std::complex (0, 1) * amp[44] + std::complex (0, 1) * - amp[45] + std::complex (0, 1) * amp[46] + std::complex - (0, 1) * amp[47] + amp[48] + amp[50] + std::complex (0, 1) * - amp[52] + std::complex (0, 1) * amp[53] + std::complex - (0, 1) * amp[54] + std::complex (0, 1) * amp[55] + - std::complex (0, 1) * amp[72] - amp[73] - amp[75] + - std::complex (0, 1) * amp[76] - amp[77] - amp[79] - amp[89] + - std::complex (0, 1) * amp[90] - amp[91] - amp[93] + - std::complex (0, 1) * amp[94] - amp[95] + amp[98] - amp[96] + - amp[101] - amp[99] + amp[104] - amp[102] + amp[107] - amp[105]; - - - - // Store the leading color flows for choice of color - for(i = 0; i < ncolor; i++ ) - jamp2[0][i] += real(jamp[i] * conj(jamp[i])); - - return -1.; -} - - -double eeuuggg::get_jamp2(int i) -{ - return jamp2[0][i]; -} - -int eeuuggg::colorstring(int i, int j) -{ - static const double res[6][6] = { - {5, 6, 7, 3, 4, 0}, - {5, 7, 6, 3, 4, 0}, - {6, 5, 7, 3, 4, 0}, - {6, 7, 5, 3, 4, 0}, - {7, 5, 6, 3, 4, 0}, - {7, 6, 5, 3, 4, 0}}; - return res[i][j]; -} - - -int eeuuggg::NCol() -{ - const int ncolor = 6; - return ncolor; -} - - - - - diff --git a/Shower/Dipole/Colorea/eeuuggg.h b/Shower/Dipole/Colorea/eeuuggg.h deleted file mode 100644 --- a/Shower/Dipole/Colorea/eeuuggg.h +++ /dev/null @@ -1,52 +0,0 @@ - //========================================================================== - // This file has been automatically generated for C++ Standalone by - // MadGraph5_aMC@NLO v. 2.5.4, 2017-03-28 - // By the MadGraph5_aMC@NLO Development Team - // Visit launchpad.net/madgraph5 and amcatnlo.web.cern.ch - //========================================================================== - // and was then modified by J. Bellm. -#ifndef MG5_Sigma_sm_epem_uuxggg_H -#define MG5_Sigma_sm_epem_uuxggg_H -#include -#include -#include "Parameters_sm.h" -using namespace std; -class eeuuggg -{ - public: - eeuuggg() { - initProc("param_card.dat"); - } - // Retrun the prefered gluon order - vector producePermutation(double r,vector < double * > & momenta); - void setMass(int i,double M){mME[i]=M;} - private: - ///////// Process Dependent - static const int ninitial = 2; - static const int nexternal = 7; - static const int nprocesses = 1; - static const int nwavefuncs = 58; - static const int namplitudes = 108; - std::complex w[nwavefuncs][18]; - double matrix_1_epem_uuxggg(); - ///////// Generic - double matrix_element[nprocesses]; - std::complex amp[namplitudes]; - double * jamp2[nprocesses]; - Parameters_sm * pars; - vector mME; - vector < double * > p; - int id1, id2; - void initProc(string param_card_name); - void sigmaKin(); - const vector & getMasses() const {return mME;} - vector < double * > getMomenta(){return p;} - void setMomenta(vector < double * > & momenta){p = momenta;} - void setInitial(int inid1, int inid2){id1 = inid1; id2 = inid2;} - void calculate_wavefunctions(const int perm[], const int hel[]); - // New function - double get_jamp2(int i); - int colorstring(int i, int j); - int NCol(); -}; -#endif // MG5_Sigma_sm_epem_uuxggg_H diff --git a/Shower/Dipole/Colorea/eeuugggg.cc b/Shower/Dipole/Colorea/eeuugggg.cc deleted file mode 100644 --- a/Shower/Dipole/Colorea/eeuugggg.cc +++ /dev/null @@ -1,3120 +0,0 @@ -//========================================================================== -// This file has been automatically generated for C++ Standalone by -// MadGraph5_aMC@NLO v. 2.5.4, 2017-03-28 -// By the MadGraph5_aMC@NLO Development Team -// Visit launchpad.net/madgraph5 and amcatnlo.web.cern.ch -//========================================================================== -// and was then modified by J. Bellm. -#include "eeuugggg.h" -#include "HelAmps_sm.h" -#include - -using namespace MG5_sm_COLOREA; - -//========================================================================== -// Class member functions for calculating the matrix elements for -// Process: e+ e- > u u~ g g g g WEIGHTED<=8 @1 - -//-------------------------------------------------------------------------- -// Initialize process. - -vector eeuugggg::producePermutation(double r,vector < double * > & momenta){ - static bool initialized=false; - if (!initialized){ - initProc("param_card.dat"); - initialized=true; - } - setMomenta(momenta); - sigmaKin(); - - - static const int res[24][8] = { - {5, 6, 7, 8, 3, 4, 0, 0}, - {5, 6, 8, 7, 3, 4, 0, 0}, - {5, 7, 6, 8, 3, 4, 0, 0}, - {5, 7, 8, 6, 3, 4, 0, 0}, - {5, 8, 6, 7, 3, 4, 0, 0}, - {5, 8, 7, 6, 3, 4, 0, 0}, - {6, 5, 7, 8, 3, 4, 0, 0}, - {6, 5, 8, 7, 3, 4, 0, 0}, - {6, 7, 5, 8, 3, 4, 0, 0}, - {6, 7, 8, 5, 3, 4, 0, 0}, - {6, 8, 5, 7, 3, 4, 0, 0}, - {6, 8, 7, 5, 3, 4, 0, 0}, - {7, 5, 6, 8, 3, 4, 0, 0}, - {7, 5, 8, 6, 3, 4, 0, 0}, - {7, 6, 5, 8, 3, 4, 0, 0}, - {7, 6, 8, 5, 3, 4, 0, 0}, - {7, 8, 5, 6, 3, 4, 0, 0}, - {7, 8, 6, 5, 3, 4, 0, 0}, - {8, 5, 6, 7, 3, 4, 0, 0}, - {8, 5, 7, 6, 3, 4, 0, 0}, - {8, 6, 5, 7, 3, 4, 0, 0}, - {8, 6, 7, 5, 3, 4, 0, 0}, - {8, 7, 5, 6, 3, 4, 0, 0}, - {8, 7, 6, 5, 3, 4, 0, 0}}; - - double jampsum=0.; - for( int i=0;i<24;i++) jampsum+=jamp2[0][i]; - double cur=0.; - for(int i=0;i<24;i++){ - cur+=jamp2[0][i]; - if( cur/jampsum > r )return std::vector(res[i], res[i] + sizeof res[i] / sizeof res[i][0]); - } - //std::cout<<"producePermutation: Upps.. Something went wrong!!"; - return std::vector(); -} - - - -void eeuugggg::initProc(string param_card_name) -{ - cout<<"\nColorea: Init process eeuugggg for rearrangement (arXiv:1801.06113)."; - // Instantiate the model class and set parameters that stay fixed during run - pars = Parameters_sm::getInstance(); - SLHAReader_COLOREA slha(param_card_name); - pars->setIndependentParameters(slha); - pars->setIndependentCouplings(); -// pars->printIndependentParameters(); -// pars->printIndependentCouplings(); - // Set external particle masses for this matrix element - mME.push_back(pars->ZERO); - mME.push_back(pars->ZERO); - mME.push_back(pars->ZERO); - mME.push_back(pars->ZERO); - mME.push_back(pars->ZERO); - mME.push_back(pars->ZERO); - mME.push_back(pars->ZERO); - mME.push_back(pars->ZERO); - jamp2[0] = new double[24]; -} - -//-------------------------------------------------------------------------- -// Evaluate |M|^2, part independent of incoming flavour. - -void eeuugggg::sigmaKin() -{ - // Set the parameters which change event by event - pars->setDependentParameters(); - pars->setDependentCouplings(); - static bool firsttime = true; - if (firsttime) - { -// pars->printDependentParameters(); -// pars->printDependentCouplings(); - firsttime = false; - } - - // Reset color flows - for(int i = 0; i < 24; i++ ) - jamp2[0][i] = 0.; - - // Local variables and constants - const int ncomb = 256; - static bool goodhel[ncomb] = {ncomb * false}; - static int ntry = 0, sum_hel = 0, ngood = 0; - static int igood[ncomb]; - static int jhel; -// std::complex * * wfs; - double t[nprocesses]; - // Helicities for the process - static const int helicities[ncomb][nexternal] = {{-1, -1, -1, -1, -1, -1, -1, - -1}, {-1, -1, -1, -1, -1, -1, -1, 1}, {-1, -1, -1, -1, -1, -1, 1, -1}, - {-1, -1, -1, -1, -1, -1, 1, 1}, {-1, -1, -1, -1, -1, 1, -1, -1}, {-1, -1, - -1, -1, -1, 1, -1, 1}, {-1, -1, -1, -1, -1, 1, 1, -1}, {-1, -1, -1, -1, - -1, 1, 1, 1}, {-1, -1, -1, -1, 1, -1, -1, -1}, {-1, -1, -1, -1, 1, -1, - -1, 1}, {-1, -1, -1, -1, 1, -1, 1, -1}, {-1, -1, -1, -1, 1, -1, 1, 1}, - {-1, -1, -1, -1, 1, 1, -1, -1}, {-1, -1, -1, -1, 1, 1, -1, 1}, {-1, -1, - -1, -1, 1, 1, 1, -1}, {-1, -1, -1, -1, 1, 1, 1, 1}, {-1, -1, -1, 1, -1, - -1, -1, -1}, {-1, -1, -1, 1, -1, -1, -1, 1}, {-1, -1, -1, 1, -1, -1, 1, - -1}, {-1, -1, -1, 1, -1, -1, 1, 1}, {-1, -1, -1, 1, -1, 1, -1, -1}, {-1, - -1, -1, 1, -1, 1, -1, 1}, {-1, -1, -1, 1, -1, 1, 1, -1}, {-1, -1, -1, 1, - -1, 1, 1, 1}, {-1, -1, -1, 1, 1, -1, -1, -1}, {-1, -1, -1, 1, 1, -1, -1, - 1}, {-1, -1, -1, 1, 1, -1, 1, -1}, {-1, -1, -1, 1, 1, -1, 1, 1}, {-1, -1, - -1, 1, 1, 1, -1, -1}, {-1, -1, -1, 1, 1, 1, -1, 1}, {-1, -1, -1, 1, 1, 1, - 1, -1}, {-1, -1, -1, 1, 1, 1, 1, 1}, {-1, -1, 1, -1, -1, -1, -1, -1}, - {-1, -1, 1, -1, -1, -1, -1, 1}, {-1, -1, 1, -1, -1, -1, 1, -1}, {-1, -1, - 1, -1, -1, -1, 1, 1}, {-1, -1, 1, -1, -1, 1, -1, -1}, {-1, -1, 1, -1, -1, - 1, -1, 1}, {-1, -1, 1, -1, -1, 1, 1, -1}, {-1, -1, 1, -1, -1, 1, 1, 1}, - {-1, -1, 1, -1, 1, -1, -1, -1}, {-1, -1, 1, -1, 1, -1, -1, 1}, {-1, -1, - 1, -1, 1, -1, 1, -1}, {-1, -1, 1, -1, 1, -1, 1, 1}, {-1, -1, 1, -1, 1, 1, - -1, -1}, {-1, -1, 1, -1, 1, 1, -1, 1}, {-1, -1, 1, -1, 1, 1, 1, -1}, {-1, - -1, 1, -1, 1, 1, 1, 1}, {-1, -1, 1, 1, -1, -1, -1, -1}, {-1, -1, 1, 1, - -1, -1, -1, 1}, {-1, -1, 1, 1, -1, -1, 1, -1}, {-1, -1, 1, 1, -1, -1, 1, - 1}, {-1, -1, 1, 1, -1, 1, -1, -1}, {-1, -1, 1, 1, -1, 1, -1, 1}, {-1, -1, - 1, 1, -1, 1, 1, -1}, {-1, -1, 1, 1, -1, 1, 1, 1}, {-1, -1, 1, 1, 1, -1, - -1, -1}, {-1, -1, 1, 1, 1, -1, -1, 1}, {-1, -1, 1, 1, 1, -1, 1, -1}, {-1, - -1, 1, 1, 1, -1, 1, 1}, {-1, -1, 1, 1, 1, 1, -1, -1}, {-1, -1, 1, 1, 1, - 1, -1, 1}, {-1, -1, 1, 1, 1, 1, 1, -1}, {-1, -1, 1, 1, 1, 1, 1, 1}, {-1, - 1, -1, -1, -1, -1, -1, -1}, {-1, 1, -1, -1, -1, -1, -1, 1}, {-1, 1, -1, - -1, -1, -1, 1, -1}, {-1, 1, -1, -1, -1, -1, 1, 1}, {-1, 1, -1, -1, -1, 1, - -1, -1}, {-1, 1, -1, -1, -1, 1, -1, 1}, {-1, 1, -1, -1, -1, 1, 1, -1}, - {-1, 1, -1, -1, -1, 1, 1, 1}, {-1, 1, -1, -1, 1, -1, -1, -1}, {-1, 1, -1, - -1, 1, -1, -1, 1}, {-1, 1, -1, -1, 1, -1, 1, -1}, {-1, 1, -1, -1, 1, -1, - 1, 1}, {-1, 1, -1, -1, 1, 1, -1, -1}, {-1, 1, -1, -1, 1, 1, -1, 1}, {-1, - 1, -1, -1, 1, 1, 1, -1}, {-1, 1, -1, -1, 1, 1, 1, 1}, {-1, 1, -1, 1, -1, - -1, -1, -1}, {-1, 1, -1, 1, -1, -1, -1, 1}, {-1, 1, -1, 1, -1, -1, 1, - -1}, {-1, 1, -1, 1, -1, -1, 1, 1}, {-1, 1, -1, 1, -1, 1, -1, -1}, {-1, 1, - -1, 1, -1, 1, -1, 1}, {-1, 1, -1, 1, -1, 1, 1, -1}, {-1, 1, -1, 1, -1, 1, - 1, 1}, {-1, 1, -1, 1, 1, -1, -1, -1}, {-1, 1, -1, 1, 1, -1, -1, 1}, {-1, - 1, -1, 1, 1, -1, 1, -1}, {-1, 1, -1, 1, 1, -1, 1, 1}, {-1, 1, -1, 1, 1, - 1, -1, -1}, {-1, 1, -1, 1, 1, 1, -1, 1}, {-1, 1, -1, 1, 1, 1, 1, -1}, - {-1, 1, -1, 1, 1, 1, 1, 1}, {-1, 1, 1, -1, -1, -1, -1, -1}, {-1, 1, 1, - -1, -1, -1, -1, 1}, {-1, 1, 1, -1, -1, -1, 1, -1}, {-1, 1, 1, -1, -1, -1, - 1, 1}, {-1, 1, 1, -1, -1, 1, -1, -1}, {-1, 1, 1, -1, -1, 1, -1, 1}, {-1, - 1, 1, -1, -1, 1, 1, -1}, {-1, 1, 1, -1, -1, 1, 1, 1}, {-1, 1, 1, -1, 1, - -1, -1, -1}, {-1, 1, 1, -1, 1, -1, -1, 1}, {-1, 1, 1, -1, 1, -1, 1, -1}, - {-1, 1, 1, -1, 1, -1, 1, 1}, {-1, 1, 1, -1, 1, 1, -1, -1}, {-1, 1, 1, -1, - 1, 1, -1, 1}, {-1, 1, 1, -1, 1, 1, 1, -1}, {-1, 1, 1, -1, 1, 1, 1, 1}, - {-1, 1, 1, 1, -1, -1, -1, -1}, {-1, 1, 1, 1, -1, -1, -1, 1}, {-1, 1, 1, - 1, -1, -1, 1, -1}, {-1, 1, 1, 1, -1, -1, 1, 1}, {-1, 1, 1, 1, -1, 1, -1, - -1}, {-1, 1, 1, 1, -1, 1, -1, 1}, {-1, 1, 1, 1, -1, 1, 1, -1}, {-1, 1, 1, - 1, -1, 1, 1, 1}, {-1, 1, 1, 1, 1, -1, -1, -1}, {-1, 1, 1, 1, 1, -1, -1, - 1}, {-1, 1, 1, 1, 1, -1, 1, -1}, {-1, 1, 1, 1, 1, -1, 1, 1}, {-1, 1, 1, - 1, 1, 1, -1, -1}, {-1, 1, 1, 1, 1, 1, -1, 1}, {-1, 1, 1, 1, 1, 1, 1, -1}, - {-1, 1, 1, 1, 1, 1, 1, 1}, {1, -1, -1, -1, -1, -1, -1, -1}, {1, -1, -1, - -1, -1, -1, -1, 1}, {1, -1, -1, -1, -1, -1, 1, -1}, {1, -1, -1, -1, -1, - -1, 1, 1}, {1, -1, -1, -1, -1, 1, -1, -1}, {1, -1, -1, -1, -1, 1, -1, 1}, - {1, -1, -1, -1, -1, 1, 1, -1}, {1, -1, -1, -1, -1, 1, 1, 1}, {1, -1, -1, - -1, 1, -1, -1, -1}, {1, -1, -1, -1, 1, -1, -1, 1}, {1, -1, -1, -1, 1, -1, - 1, -1}, {1, -1, -1, -1, 1, -1, 1, 1}, {1, -1, -1, -1, 1, 1, -1, -1}, {1, - -1, -1, -1, 1, 1, -1, 1}, {1, -1, -1, -1, 1, 1, 1, -1}, {1, -1, -1, -1, - 1, 1, 1, 1}, {1, -1, -1, 1, -1, -1, -1, -1}, {1, -1, -1, 1, -1, -1, -1, - 1}, {1, -1, -1, 1, -1, -1, 1, -1}, {1, -1, -1, 1, -1, -1, 1, 1}, {1, -1, - -1, 1, -1, 1, -1, -1}, {1, -1, -1, 1, -1, 1, -1, 1}, {1, -1, -1, 1, -1, - 1, 1, -1}, {1, -1, -1, 1, -1, 1, 1, 1}, {1, -1, -1, 1, 1, -1, -1, -1}, - {1, -1, -1, 1, 1, -1, -1, 1}, {1, -1, -1, 1, 1, -1, 1, -1}, {1, -1, -1, - 1, 1, -1, 1, 1}, {1, -1, -1, 1, 1, 1, -1, -1}, {1, -1, -1, 1, 1, 1, -1, - 1}, {1, -1, -1, 1, 1, 1, 1, -1}, {1, -1, -1, 1, 1, 1, 1, 1}, {1, -1, 1, - -1, -1, -1, -1, -1}, {1, -1, 1, -1, -1, -1, -1, 1}, {1, -1, 1, -1, -1, - -1, 1, -1}, {1, -1, 1, -1, -1, -1, 1, 1}, {1, -1, 1, -1, -1, 1, -1, -1}, - {1, -1, 1, -1, -1, 1, -1, 1}, {1, -1, 1, -1, -1, 1, 1, -1}, {1, -1, 1, - -1, -1, 1, 1, 1}, {1, -1, 1, -1, 1, -1, -1, -1}, {1, -1, 1, -1, 1, -1, - -1, 1}, {1, -1, 1, -1, 1, -1, 1, -1}, {1, -1, 1, -1, 1, -1, 1, 1}, {1, - -1, 1, -1, 1, 1, -1, -1}, {1, -1, 1, -1, 1, 1, -1, 1}, {1, -1, 1, -1, 1, - 1, 1, -1}, {1, -1, 1, -1, 1, 1, 1, 1}, {1, -1, 1, 1, -1, -1, -1, -1}, {1, - -1, 1, 1, -1, -1, -1, 1}, {1, -1, 1, 1, -1, -1, 1, -1}, {1, -1, 1, 1, -1, - -1, 1, 1}, {1, -1, 1, 1, -1, 1, -1, -1}, {1, -1, 1, 1, -1, 1, -1, 1}, {1, - -1, 1, 1, -1, 1, 1, -1}, {1, -1, 1, 1, -1, 1, 1, 1}, {1, -1, 1, 1, 1, -1, - -1, -1}, {1, -1, 1, 1, 1, -1, -1, 1}, {1, -1, 1, 1, 1, -1, 1, -1}, {1, - -1, 1, 1, 1, -1, 1, 1}, {1, -1, 1, 1, 1, 1, -1, -1}, {1, -1, 1, 1, 1, 1, - -1, 1}, {1, -1, 1, 1, 1, 1, 1, -1}, {1, -1, 1, 1, 1, 1, 1, 1}, {1, 1, -1, - -1, -1, -1, -1, -1}, {1, 1, -1, -1, -1, -1, -1, 1}, {1, 1, -1, -1, -1, - -1, 1, -1}, {1, 1, -1, -1, -1, -1, 1, 1}, {1, 1, -1, -1, -1, 1, -1, -1}, - {1, 1, -1, -1, -1, 1, -1, 1}, {1, 1, -1, -1, -1, 1, 1, -1}, {1, 1, -1, - -1, -1, 1, 1, 1}, {1, 1, -1, -1, 1, -1, -1, -1}, {1, 1, -1, -1, 1, -1, - -1, 1}, {1, 1, -1, -1, 1, -1, 1, -1}, {1, 1, -1, -1, 1, -1, 1, 1}, {1, 1, - -1, -1, 1, 1, -1, -1}, {1, 1, -1, -1, 1, 1, -1, 1}, {1, 1, -1, -1, 1, 1, - 1, -1}, {1, 1, -1, -1, 1, 1, 1, 1}, {1, 1, -1, 1, -1, -1, -1, -1}, {1, 1, - -1, 1, -1, -1, -1, 1}, {1, 1, -1, 1, -1, -1, 1, -1}, {1, 1, -1, 1, -1, - -1, 1, 1}, {1, 1, -1, 1, -1, 1, -1, -1}, {1, 1, -1, 1, -1, 1, -1, 1}, {1, - 1, -1, 1, -1, 1, 1, -1}, {1, 1, -1, 1, -1, 1, 1, 1}, {1, 1, -1, 1, 1, -1, - -1, -1}, {1, 1, -1, 1, 1, -1, -1, 1}, {1, 1, -1, 1, 1, -1, 1, -1}, {1, 1, - -1, 1, 1, -1, 1, 1}, {1, 1, -1, 1, 1, 1, -1, -1}, {1, 1, -1, 1, 1, 1, -1, - 1}, {1, 1, -1, 1, 1, 1, 1, -1}, {1, 1, -1, 1, 1, 1, 1, 1}, {1, 1, 1, -1, - -1, -1, -1, -1}, {1, 1, 1, -1, -1, -1, -1, 1}, {1, 1, 1, -1, -1, -1, 1, - -1}, {1, 1, 1, -1, -1, -1, 1, 1}, {1, 1, 1, -1, -1, 1, -1, -1}, {1, 1, 1, - -1, -1, 1, -1, 1}, {1, 1, 1, -1, -1, 1, 1, -1}, {1, 1, 1, -1, -1, 1, 1, - 1}, {1, 1, 1, -1, 1, -1, -1, -1}, {1, 1, 1, -1, 1, -1, -1, 1}, {1, 1, 1, - -1, 1, -1, 1, -1}, {1, 1, 1, -1, 1, -1, 1, 1}, {1, 1, 1, -1, 1, 1, -1, - -1}, {1, 1, 1, -1, 1, 1, -1, 1}, {1, 1, 1, -1, 1, 1, 1, -1}, {1, 1, 1, - -1, 1, 1, 1, 1}, {1, 1, 1, 1, -1, -1, -1, -1}, {1, 1, 1, 1, -1, -1, -1, - 1}, {1, 1, 1, 1, -1, -1, 1, -1}, {1, 1, 1, 1, -1, -1, 1, 1}, {1, 1, 1, 1, - -1, 1, -1, -1}, {1, 1, 1, 1, -1, 1, -1, 1}, {1, 1, 1, 1, -1, 1, 1, -1}, - {1, 1, 1, 1, -1, 1, 1, 1}, {1, 1, 1, 1, 1, -1, -1, -1}, {1, 1, 1, 1, 1, - -1, -1, 1}, {1, 1, 1, 1, 1, -1, 1, -1}, {1, 1, 1, 1, 1, -1, 1, 1}, {1, 1, - 1, 1, 1, 1, -1, -1}, {1, 1, 1, 1, 1, 1, -1, 1}, {1, 1, 1, 1, 1, 1, 1, - -1}, {1, 1, 1, 1, 1, 1, 1, 1}}; - // Denominators: spins, colors and identical particles - const int denominators[nprocesses] = {96}; - - ntry = ntry + 1; - - // Reset the matrix elements - for(int i = 0; i < nprocesses; i++ ) - { - matrix_element[i] = 0.; - } - // Define permutation - int perm[nexternal]; - for(int i = 0; i < nexternal; i++ ) - { - perm[i] = i; - } - - if (sum_hel == 0 || ntry < 10) - { - // Calculate the matrix element for all helicities - for(int ihel = 0; ihel < ncomb; ihel++ ) - { - if (goodhel[ihel] || ntry < 2) - { - calculate_wavefunctions(perm, helicities[ihel]); - t[0] = matrix_1_epem_uuxgggg(); - - double tsum = 0; - for(int iproc = 0; iproc < nprocesses; iproc++ ) - { - matrix_element[iproc] += t[iproc]; - tsum += t[iproc]; - } - // Store which helicities give non-zero result - if (tsum != 0. && !goodhel[ihel]) - { - goodhel[ihel] = true; - ngood++; - igood[ngood] = ihel; - } - } - } - jhel = 0; - sum_hel = min(sum_hel, ngood); - } - else - { - // Only use the "good" helicities - for(int j = 0; j < sum_hel; j++ ) - { - jhel++; - if (jhel >= ngood) - jhel = 0; - double hwgt = double(ngood)/double(sum_hel); - int ihel = igood[jhel]; - calculate_wavefunctions(perm, helicities[ihel]); - t[0] = matrix_1_epem_uuxgggg(); - - for(int iproc = 0; iproc < nprocesses; iproc++ ) - { - matrix_element[iproc] += t[iproc] * hwgt; - } - } - } - - for (int i = 0; i < nprocesses; i++ ) - matrix_element[i] /= denominators[i]; - - - -} - - -//-------------------------------------------------------------------------- -// Evaluate |M|^2 for each subprocess - -void eeuugggg::calculate_wavefunctions(const int perm[], const int hel[]) -{ - - // Calculate all wavefunctions - oxxxxx(p[perm[0]], mME[0], hel[0], -1, w[0]); - ixxxxx(p[perm[1]], mME[1], hel[1], +1, w[1]); - oxxxxx(p[perm[2]], mME[2], hel[2], +1, w[2]); - ixxxxx(p[perm[3]], mME[3], hel[3], -1, w[3]); - vxxxxx(p[perm[4]], mME[4], hel[4], +1, w[4]); - vxxxxx(p[perm[5]], mME[5], hel[5], +1, w[5]); - vxxxxx(p[perm[6]], mME[6], hel[6], +1, w[6]); - vxxxxx(p[perm[7]], mME[7], hel[7], +1, w[7]); - FFV1P0_3(w[1], w[0], pars->GC_3, pars->ZERO, pars->ZERO, w[8]); - FFV1_1(w[2], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[9]); - FFV1_2(w[3], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[10]); - FFV1_1(w[9], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[11]); - FFV1_2(w[10], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[12]); - FFV1_2(w[10], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[13]); - FFV1_1(w[9], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[14]); - FFV1_2(w[10], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[15]); - FFV1_1(w[9], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[16]); - FFV2_4_3(w[1], w[0], pars->GC_50, pars->GC_59, pars->mdl_MZ, pars->mdl_WZ, - w[17]); - FFV2_5_2(w[3], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[18]); - FFV1_2(w[18], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[19]); - FFV1_2(w[18], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[20]); - FFV1_2(w[18], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[21]); - FFV1_2(w[3], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[22]); - FFV1_1(w[9], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[23]); - FFV1_2(w[22], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[24]); - FFV1_2(w[22], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[25]); - FFV1_2(w[22], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[26]); - FFV2_5_1(w[9], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[27]); - FFV2_5_2(w[22], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[28]); - VVV1P0_1(w[6], w[7], pars->GC_10, pars->ZERO, pars->ZERO, w[29]); - FFV1_2(w[3], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[30]); - FFV1_2(w[30], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[31]); - FFV1_2(w[30], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[32]); - FFV1_2(w[30], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[33]); - FFV2_5_2(w[30], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[34]); - VVV1P0_1(w[5], w[7], pars->GC_10, pars->ZERO, pars->ZERO, w[35]); - FFV1_2(w[3], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[36]); - FFV1_2(w[36], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[37]); - FFV1_2(w[36], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[38]); - FFV1_2(w[36], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[39]); - FFV2_5_2(w[36], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[40]); - VVV1P0_1(w[5], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[41]); - FFV1_2(w[3], w[41], pars->GC_11, pars->ZERO, pars->ZERO, w[42]); - VVV1P0_1(w[41], w[7], pars->GC_10, pars->ZERO, pars->ZERO, w[43]); - FFV1_1(w[9], w[41], pars->GC_11, pars->ZERO, pars->ZERO, w[44]); - FFV1_2(w[3], w[35], pars->GC_11, pars->ZERO, pars->ZERO, w[45]); - VVV1P0_1(w[35], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[46]); - FFV1_1(w[9], w[35], pars->GC_11, pars->ZERO, pars->ZERO, w[47]); - FFV1_2(w[3], w[29], pars->GC_11, pars->ZERO, pars->ZERO, w[48]); - VVV1P0_1(w[5], w[29], pars->GC_10, pars->ZERO, pars->ZERO, w[49]); - FFV1_1(w[9], w[29], pars->GC_11, pars->ZERO, pars->ZERO, w[50]); - VVVV1P0_1(w[5], w[6], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[51]); - VVVV3P0_1(w[5], w[6], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[52]); - VVVV4P0_1(w[5], w[6], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[53]); - FFV1_1(w[2], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[54]); - FFV1_1(w[54], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[55]); - FFV1_1(w[54], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[56]); - FFV1_2(w[10], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[57]); - FFV1_1(w[54], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[58]); - FFV1_2(w[18], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[59]); - FFV1_2(w[3], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[60]); - FFV1_1(w[54], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[61]); - FFV1_2(w[60], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[62]); - FFV1_2(w[60], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[63]); - FFV1_2(w[60], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[64]); - FFV2_5_1(w[54], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[65]); - FFV2_5_2(w[60], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[66]); - FFV1_2(w[30], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[67]); - VVV1P0_1(w[4], w[7], pars->GC_10, pars->ZERO, pars->ZERO, w[68]); - FFV1_2(w[36], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[69]); - VVV1P0_1(w[4], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[70]); - FFV1_2(w[3], w[70], pars->GC_11, pars->ZERO, pars->ZERO, w[71]); - VVV1P0_1(w[70], w[7], pars->GC_10, pars->ZERO, pars->ZERO, w[72]); - FFV1_1(w[54], w[70], pars->GC_11, pars->ZERO, pars->ZERO, w[73]); - FFV1_2(w[3], w[68], pars->GC_11, pars->ZERO, pars->ZERO, w[74]); - VVV1P0_1(w[68], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[75]); - FFV1_1(w[54], w[68], pars->GC_11, pars->ZERO, pars->ZERO, w[76]); - VVV1P0_1(w[4], w[29], pars->GC_10, pars->ZERO, pars->ZERO, w[77]); - FFV1_1(w[54], w[29], pars->GC_11, pars->ZERO, pars->ZERO, w[78]); - VVVV1P0_1(w[4], w[6], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[79]); - VVVV3P0_1(w[4], w[6], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[80]); - VVVV4P0_1(w[4], w[6], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[81]); - FFV1_1(w[2], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[82]); - FFV1_1(w[82], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[83]); - FFV1_1(w[82], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[84]); - FFV1_1(w[82], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[85]); - FFV1_1(w[82], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[86]); - FFV1_2(w[60], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[87]); - FFV2_5_1(w[82], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[88]); - FFV1_2(w[22], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[89]); - VVV1P0_1(w[4], w[5], pars->GC_10, pars->ZERO, pars->ZERO, w[90]); - FFV1_2(w[3], w[90], pars->GC_11, pars->ZERO, pars->ZERO, w[91]); - VVV1P0_1(w[90], w[7], pars->GC_10, pars->ZERO, pars->ZERO, w[92]); - FFV1_1(w[82], w[90], pars->GC_11, pars->ZERO, pars->ZERO, w[93]); - VVV1P0_1(w[68], w[5], pars->GC_10, pars->ZERO, pars->ZERO, w[94]); - FFV1_1(w[82], w[68], pars->GC_11, pars->ZERO, pars->ZERO, w[95]); - VVV1P0_1(w[4], w[35], pars->GC_10, pars->ZERO, pars->ZERO, w[96]); - FFV1_1(w[82], w[35], pars->GC_11, pars->ZERO, pars->ZERO, w[97]); - VVVV1P0_1(w[4], w[5], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[98]); - VVVV3P0_1(w[4], w[5], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[99]); - VVVV4P0_1(w[4], w[5], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[100]); - FFV1_1(w[2], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[101]); - FFV1_1(w[101], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[102]); - FFV1_1(w[101], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[103]); - FFV1_1(w[101], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[104]); - FFV1_1(w[101], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[105]); - FFV2_5_1(w[101], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[106]); - VVV1P0_1(w[90], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[107]); - FFV1_1(w[101], w[90], pars->GC_11, pars->ZERO, pars->ZERO, w[108]); - VVV1P0_1(w[70], w[5], pars->GC_10, pars->ZERO, pars->ZERO, w[109]); - FFV1_1(w[101], w[70], pars->GC_11, pars->ZERO, pars->ZERO, w[110]); - VVV1P0_1(w[4], w[41], pars->GC_10, pars->ZERO, pars->ZERO, w[111]); - FFV1_1(w[101], w[41], pars->GC_11, pars->ZERO, pars->ZERO, w[112]); - VVVV1P0_1(w[4], w[5], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[113]); - VVVV3P0_1(w[4], w[5], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[114]); - VVVV4P0_1(w[4], w[5], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[115]); - FFV1_1(w[2], w[8], pars->GC_2, pars->ZERO, pars->ZERO, w[116]); - FFV1_1(w[116], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[117]); - FFV1_1(w[116], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[118]); - FFV1_1(w[116], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[119]); - FFV2_5_1(w[2], w[17], pars->GC_51, pars->GC_58, pars->ZERO, pars->ZERO, - w[120]); - FFV1_1(w[120], w[6], pars->GC_11, pars->ZERO, pars->ZERO, w[121]); - FFV1_1(w[120], w[7], pars->GC_11, pars->ZERO, pars->ZERO, w[122]); - FFV1_1(w[120], w[5], pars->GC_11, pars->ZERO, pars->ZERO, w[123]); - FFV1_2(w[60], w[41], pars->GC_11, pars->ZERO, pars->ZERO, w[124]); - FFV1_1(w[2], w[41], pars->GC_11, pars->ZERO, pars->ZERO, w[125]); - FFV1_2(w[60], w[35], pars->GC_11, pars->ZERO, pars->ZERO, w[126]); - FFV1_1(w[2], w[35], pars->GC_11, pars->ZERO, pars->ZERO, w[127]); - FFV1_2(w[60], w[29], pars->GC_11, pars->ZERO, pars->ZERO, w[128]); - FFV1_1(w[2], w[29], pars->GC_11, pars->ZERO, pars->ZERO, w[129]); - FFV1_1(w[116], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[130]); - FFV1_1(w[120], w[4], pars->GC_11, pars->ZERO, pars->ZERO, w[131]); - FFV1_2(w[22], w[70], pars->GC_11, pars->ZERO, pars->ZERO, w[132]); - FFV1_1(w[2], w[70], pars->GC_11, pars->ZERO, pars->ZERO, w[133]); - FFV1_2(w[22], w[68], pars->GC_11, pars->ZERO, pars->ZERO, w[134]); - FFV1_1(w[2], w[68], pars->GC_11, pars->ZERO, pars->ZERO, w[135]); - FFV1_2(w[22], w[29], pars->GC_11, pars->ZERO, pars->ZERO, w[136]); - FFV1_2(w[30], w[90], pars->GC_11, pars->ZERO, pars->ZERO, w[137]); - FFV1_1(w[2], w[90], pars->GC_11, pars->ZERO, pars->ZERO, w[138]); - FFV1_2(w[30], w[68], pars->GC_11, pars->ZERO, pars->ZERO, w[139]); - FFV1_2(w[30], w[35], pars->GC_11, pars->ZERO, pars->ZERO, w[140]); - FFV1_2(w[36], w[90], pars->GC_11, pars->ZERO, pars->ZERO, w[141]); - FFV1_2(w[36], w[70], pars->GC_11, pars->ZERO, pars->ZERO, w[142]); - FFV1_2(w[36], w[41], pars->GC_11, pars->ZERO, pars->ZERO, w[143]); - FFV1P0_3(w[3], w[116], pars->GC_11, pars->ZERO, pars->ZERO, w[144]); - VVVV1P0_1(w[90], w[6], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[145]); - VVVV3P0_1(w[90], w[6], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[146]); - VVVV4P0_1(w[90], w[6], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[147]); - FFV1P0_3(w[10], w[2], pars->GC_11, pars->ZERO, pars->ZERO, w[148]); - FFV1P0_3(w[3], w[120], pars->GC_11, pars->ZERO, pars->ZERO, w[149]); - FFV1P0_3(w[18], w[2], pars->GC_11, pars->ZERO, pars->ZERO, w[150]); - VVV1P0_1(w[90], w[29], pars->GC_10, pars->ZERO, pars->ZERO, w[151]); - VVVV1P0_1(w[70], w[5], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[152]); - VVVV3P0_1(w[70], w[5], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[153]); - VVVV4P0_1(w[70], w[5], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[154]); - VVV1P0_1(w[70], w[35], pars->GC_10, pars->ZERO, pars->ZERO, w[155]); - VVVV1P0_1(w[68], w[5], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[156]); - VVVV3P0_1(w[68], w[5], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[157]); - VVVV4P0_1(w[68], w[5], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[158]); - VVV1P0_1(w[68], w[41], pars->GC_10, pars->ZERO, pars->ZERO, w[159]); - VVVV1P0_1(w[4], w[41], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[160]); - VVVV3P0_1(w[4], w[41], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[161]); - VVVV4P0_1(w[4], w[41], w[7], pars->GC_12, pars->ZERO, pars->ZERO, w[162]); - VVVV1P0_1(w[4], w[35], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[163]); - VVVV3P0_1(w[4], w[35], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[164]); - VVVV4P0_1(w[4], w[35], w[6], pars->GC_12, pars->ZERO, pars->ZERO, w[165]); - VVVV1P0_1(w[4], w[5], w[29], pars->GC_12, pars->ZERO, pars->ZERO, w[166]); - VVVV3P0_1(w[4], w[5], w[29], pars->GC_12, pars->ZERO, pars->ZERO, w[167]); - VVVV4P0_1(w[4], w[5], w[29], pars->GC_12, pars->ZERO, pars->ZERO, w[168]); - FFV1_2(w[3], w[113], pars->GC_11, pars->ZERO, pars->ZERO, w[169]); - FFV1_2(w[3], w[114], pars->GC_11, pars->ZERO, pars->ZERO, w[170]); - FFV1_2(w[3], w[115], pars->GC_11, pars->ZERO, pars->ZERO, w[171]); - VVV1P0_1(w[113], w[7], pars->GC_10, pars->ZERO, pars->ZERO, w[172]); - VVV1P0_1(w[114], w[7], pars->GC_10, pars->ZERO, pars->ZERO, w[173]); - VVV1P0_1(w[115], w[7], pars->GC_10, pars->ZERO, pars->ZERO, w[174]); - FFV1_1(w[2], w[113], pars->GC_11, pars->ZERO, pars->ZERO, w[175]); - FFV1_1(w[2], w[114], pars->GC_11, pars->ZERO, pars->ZERO, w[176]); - FFV1_1(w[2], w[115], pars->GC_11, pars->ZERO, pars->ZERO, w[177]); - FFV1_2(w[3], w[98], pars->GC_11, pars->ZERO, pars->ZERO, w[178]); - FFV1_2(w[3], w[99], pars->GC_11, pars->ZERO, pars->ZERO, w[179]); - FFV1_2(w[3], w[100], pars->GC_11, pars->ZERO, pars->ZERO, w[180]); - VVV1P0_1(w[98], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[181]); - VVV1P0_1(w[99], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[182]); - VVV1P0_1(w[100], w[6], pars->GC_10, pars->ZERO, pars->ZERO, w[183]); - FFV1_1(w[2], w[98], pars->GC_11, pars->ZERO, pars->ZERO, w[184]); - FFV1_1(w[2], w[99], pars->GC_11, pars->ZERO, pars->ZERO, w[185]); - FFV1_1(w[2], w[100], pars->GC_11, pars->ZERO, pars->ZERO, w[186]); - FFV1_2(w[3], w[79], pars->GC_11, pars->ZERO, pars->ZERO, w[187]); - FFV1_2(w[3], w[80], pars->GC_11, pars->ZERO, pars->ZERO, w[188]); - FFV1_2(w[3], w[81], pars->GC_11, pars->ZERO, pars->ZERO, w[189]); - VVV1P0_1(w[79], w[5], pars->GC_10, pars->ZERO, pars->ZERO, w[190]); - VVV1P0_1(w[80], w[5], pars->GC_10, pars->ZERO, pars->ZERO, w[191]); - VVV1P0_1(w[81], w[5], pars->GC_10, pars->ZERO, pars->ZERO, w[192]); - FFV1_1(w[2], w[79], pars->GC_11, pars->ZERO, pars->ZERO, w[193]); - FFV1_1(w[2], w[80], pars->GC_11, pars->ZERO, pars->ZERO, w[194]); - FFV1_1(w[2], w[81], pars->GC_11, pars->ZERO, pars->ZERO, w[195]); - FFV1_2(w[3], w[51], pars->GC_11, pars->ZERO, pars->ZERO, w[196]); - FFV1_2(w[3], w[52], pars->GC_11, pars->ZERO, pars->ZERO, w[197]); - FFV1_2(w[3], w[53], pars->GC_11, pars->ZERO, pars->ZERO, w[198]); - VVV1P0_1(w[4], w[51], pars->GC_10, pars->ZERO, pars->ZERO, w[199]); - VVV1P0_1(w[4], w[52], pars->GC_10, pars->ZERO, pars->ZERO, w[200]); - VVV1P0_1(w[4], w[53], pars->GC_10, pars->ZERO, pars->ZERO, w[201]); - FFV1_1(w[2], w[51], pars->GC_11, pars->ZERO, pars->ZERO, w[202]); - FFV1_1(w[2], w[52], pars->GC_11, pars->ZERO, pars->ZERO, w[203]); - FFV1_1(w[2], w[53], pars->GC_11, pars->ZERO, pars->ZERO, w[204]); - - // Calculate all amplitudes - // Amplitude(s) for diagram number 0 - FFV1_0(w[12], w[11], w[7], pars->GC_11, amp[0]); - FFV1_0(w[13], w[11], w[6], pars->GC_11, amp[1]); - FFV1_0(w[15], w[14], w[7], pars->GC_11, amp[2]); - FFV1_0(w[13], w[14], w[5], pars->GC_11, amp[3]); - FFV1_0(w[15], w[16], w[6], pars->GC_11, amp[4]); - FFV1_0(w[12], w[16], w[5], pars->GC_11, amp[5]); - FFV1_0(w[19], w[11], w[7], pars->GC_11, amp[6]); - FFV1_0(w[20], w[11], w[6], pars->GC_11, amp[7]); - FFV1_0(w[21], w[14], w[7], pars->GC_11, amp[8]); - FFV1_0(w[20], w[14], w[5], pars->GC_11, amp[9]); - FFV1_0(w[21], w[16], w[6], pars->GC_11, amp[10]); - FFV1_0(w[19], w[16], w[5], pars->GC_11, amp[11]); - FFV1_0(w[24], w[23], w[7], pars->GC_11, amp[12]); - FFV1_0(w[25], w[23], w[6], pars->GC_11, amp[13]); - FFV1_0(w[26], w[14], w[7], pars->GC_11, amp[14]); - FFV1_0(w[26], w[16], w[6], pars->GC_11, amp[15]); - FFV1_0(w[25], w[14], w[8], pars->GC_2, amp[16]); - FFV1_0(w[24], w[16], w[8], pars->GC_2, amp[17]); - FFV1_0(w[24], w[27], w[7], pars->GC_11, amp[18]); - FFV1_0(w[25], w[27], w[6], pars->GC_11, amp[19]); - FFV1_0(w[28], w[14], w[7], pars->GC_11, amp[20]); - FFV1_0(w[28], w[16], w[6], pars->GC_11, amp[21]); - FFV2_5_0(w[25], w[14], w[17], pars->GC_51, pars->GC_58, amp[22]); - FFV2_5_0(w[24], w[16], w[17], pars->GC_51, pars->GC_58, amp[23]); - FFV1_0(w[22], w[23], w[29], pars->GC_11, amp[24]); - FFV1_0(w[26], w[9], w[29], pars->GC_11, amp[25]); - FFV1_0(w[22], w[27], w[29], pars->GC_11, amp[26]); - FFV1_0(w[28], w[9], w[29], pars->GC_11, amp[27]); - FFV1_0(w[31], w[23], w[7], pars->GC_11, amp[28]); - FFV1_0(w[32], w[23], w[5], pars->GC_11, amp[29]); - FFV1_0(w[33], w[11], w[7], pars->GC_11, amp[30]); - FFV1_0(w[33], w[16], w[5], pars->GC_11, amp[31]); - FFV1_0(w[32], w[11], w[8], pars->GC_2, amp[32]); - FFV1_0(w[31], w[16], w[8], pars->GC_2, amp[33]); - FFV1_0(w[31], w[27], w[7], pars->GC_11, amp[34]); - FFV1_0(w[32], w[27], w[5], pars->GC_11, amp[35]); - FFV1_0(w[34], w[11], w[7], pars->GC_11, amp[36]); - FFV1_0(w[34], w[16], w[5], pars->GC_11, amp[37]); - FFV2_5_0(w[32], w[11], w[17], pars->GC_51, pars->GC_58, amp[38]); - FFV2_5_0(w[31], w[16], w[17], pars->GC_51, pars->GC_58, amp[39]); - FFV1_0(w[30], w[23], w[35], pars->GC_11, amp[40]); - FFV1_0(w[33], w[9], w[35], pars->GC_11, amp[41]); - FFV1_0(w[30], w[27], w[35], pars->GC_11, amp[42]); - FFV1_0(w[34], w[9], w[35], pars->GC_11, amp[43]); - FFV1_0(w[37], w[23], w[6], pars->GC_11, amp[44]); - FFV1_0(w[38], w[23], w[5], pars->GC_11, amp[45]); - FFV1_0(w[39], w[11], w[6], pars->GC_11, amp[46]); - FFV1_0(w[39], w[14], w[5], pars->GC_11, amp[47]); - FFV1_0(w[38], w[11], w[8], pars->GC_2, amp[48]); - FFV1_0(w[37], w[14], w[8], pars->GC_2, amp[49]); - FFV1_0(w[37], w[27], w[6], pars->GC_11, amp[50]); - FFV1_0(w[38], w[27], w[5], pars->GC_11, amp[51]); - FFV1_0(w[40], w[11], w[6], pars->GC_11, amp[52]); - FFV1_0(w[40], w[14], w[5], pars->GC_11, amp[53]); - FFV2_5_0(w[38], w[11], w[17], pars->GC_51, pars->GC_58, amp[54]); - FFV2_5_0(w[37], w[14], w[17], pars->GC_51, pars->GC_58, amp[55]); - FFV1_0(w[36], w[23], w[41], pars->GC_11, amp[56]); - FFV1_0(w[39], w[9], w[41], pars->GC_11, amp[57]); - FFV1_0(w[36], w[27], w[41], pars->GC_11, amp[58]); - FFV1_0(w[40], w[9], w[41], pars->GC_11, amp[59]); - FFV1_0(w[42], w[23], w[7], pars->GC_11, amp[60]); - FFV1_0(w[3], w[23], w[43], pars->GC_11, amp[61]); - FFV1_0(w[10], w[44], w[7], pars->GC_11, amp[62]); - FFV1_0(w[10], w[16], w[41], pars->GC_11, amp[63]); - FFV1_0(w[10], w[9], w[43], pars->GC_11, amp[64]); - FFV1_0(w[42], w[16], w[8], pars->GC_2, amp[65]); - FFV1_0(w[42], w[27], w[7], pars->GC_11, amp[66]); - FFV1_0(w[3], w[27], w[43], pars->GC_11, amp[67]); - FFV1_0(w[18], w[44], w[7], pars->GC_11, amp[68]); - FFV1_0(w[18], w[16], w[41], pars->GC_11, amp[69]); - FFV1_0(w[18], w[9], w[43], pars->GC_11, amp[70]); - FFV2_5_0(w[42], w[16], w[17], pars->GC_51, pars->GC_58, amp[71]); - FFV1_0(w[45], w[23], w[6], pars->GC_11, amp[72]); - FFV1_0(w[3], w[23], w[46], pars->GC_11, amp[73]); - FFV1_0(w[10], w[47], w[6], pars->GC_11, amp[74]); - FFV1_0(w[10], w[14], w[35], pars->GC_11, amp[75]); - FFV1_0(w[10], w[9], w[46], pars->GC_11, amp[76]); - FFV1_0(w[45], w[14], w[8], pars->GC_2, amp[77]); - FFV1_0(w[45], w[27], w[6], pars->GC_11, amp[78]); - FFV1_0(w[3], w[27], w[46], pars->GC_11, amp[79]); - FFV1_0(w[18], w[47], w[6], pars->GC_11, amp[80]); - FFV1_0(w[18], w[14], w[35], pars->GC_11, amp[81]); - FFV1_0(w[18], w[9], w[46], pars->GC_11, amp[82]); - FFV2_5_0(w[45], w[14], w[17], pars->GC_51, pars->GC_58, amp[83]); - FFV1_0(w[48], w[23], w[5], pars->GC_11, amp[84]); - FFV1_0(w[3], w[23], w[49], pars->GC_11, amp[85]); - FFV1_0(w[10], w[11], w[29], pars->GC_11, amp[86]); - FFV1_0(w[10], w[50], w[5], pars->GC_11, amp[87]); - FFV1_0(w[10], w[9], w[49], pars->GC_11, amp[88]); - FFV1_0(w[48], w[11], w[8], pars->GC_2, amp[89]); - FFV1_0(w[48], w[27], w[5], pars->GC_11, amp[90]); - FFV1_0(w[3], w[27], w[49], pars->GC_11, amp[91]); - FFV1_0(w[18], w[11], w[29], pars->GC_11, amp[92]); - FFV1_0(w[18], w[50], w[5], pars->GC_11, amp[93]); - FFV1_0(w[18], w[9], w[49], pars->GC_11, amp[94]); - FFV2_5_0(w[48], w[11], w[17], pars->GC_51, pars->GC_58, amp[95]); - FFV1_0(w[3], w[23], w[51], pars->GC_11, amp[96]); - FFV1_0(w[3], w[23], w[52], pars->GC_11, amp[97]); - FFV1_0(w[3], w[23], w[53], pars->GC_11, amp[98]); - FFV1_0(w[10], w[9], w[51], pars->GC_11, amp[99]); - FFV1_0(w[10], w[9], w[52], pars->GC_11, amp[100]); - FFV1_0(w[10], w[9], w[53], pars->GC_11, amp[101]); - FFV1_0(w[3], w[27], w[51], pars->GC_11, amp[102]); - FFV1_0(w[3], w[27], w[52], pars->GC_11, amp[103]); - FFV1_0(w[3], w[27], w[53], pars->GC_11, amp[104]); - FFV1_0(w[18], w[9], w[51], pars->GC_11, amp[105]); - FFV1_0(w[18], w[9], w[52], pars->GC_11, amp[106]); - FFV1_0(w[18], w[9], w[53], pars->GC_11, amp[107]); - FFV1_0(w[12], w[55], w[7], pars->GC_11, amp[108]); - FFV1_0(w[13], w[55], w[6], pars->GC_11, amp[109]); - FFV1_0(w[57], w[56], w[7], pars->GC_11, amp[110]); - FFV1_0(w[13], w[56], w[4], pars->GC_11, amp[111]); - FFV1_0(w[57], w[58], w[6], pars->GC_11, amp[112]); - FFV1_0(w[12], w[58], w[4], pars->GC_11, amp[113]); - FFV1_0(w[19], w[55], w[7], pars->GC_11, amp[114]); - FFV1_0(w[20], w[55], w[6], pars->GC_11, amp[115]); - FFV1_0(w[59], w[56], w[7], pars->GC_11, amp[116]); - FFV1_0(w[20], w[56], w[4], pars->GC_11, amp[117]); - FFV1_0(w[59], w[58], w[6], pars->GC_11, amp[118]); - FFV1_0(w[19], w[58], w[4], pars->GC_11, amp[119]); - FFV1_0(w[62], w[61], w[7], pars->GC_11, amp[120]); - FFV1_0(w[63], w[61], w[6], pars->GC_11, amp[121]); - FFV1_0(w[64], w[56], w[7], pars->GC_11, amp[122]); - FFV1_0(w[64], w[58], w[6], pars->GC_11, amp[123]); - FFV1_0(w[63], w[56], w[8], pars->GC_2, amp[124]); - FFV1_0(w[62], w[58], w[8], pars->GC_2, amp[125]); - FFV1_0(w[62], w[65], w[7], pars->GC_11, amp[126]); - FFV1_0(w[63], w[65], w[6], pars->GC_11, amp[127]); - FFV1_0(w[66], w[56], w[7], pars->GC_11, amp[128]); - FFV1_0(w[66], w[58], w[6], pars->GC_11, amp[129]); - FFV2_5_0(w[63], w[56], w[17], pars->GC_51, pars->GC_58, amp[130]); - FFV2_5_0(w[62], w[58], w[17], pars->GC_51, pars->GC_58, amp[131]); - FFV1_0(w[60], w[61], w[29], pars->GC_11, amp[132]); - FFV1_0(w[64], w[54], w[29], pars->GC_11, amp[133]); - FFV1_0(w[60], w[65], w[29], pars->GC_11, amp[134]); - FFV1_0(w[66], w[54], w[29], pars->GC_11, amp[135]); - FFV1_0(w[67], w[61], w[7], pars->GC_11, amp[136]); - FFV1_0(w[32], w[61], w[4], pars->GC_11, amp[137]); - FFV1_0(w[33], w[55], w[7], pars->GC_11, amp[138]); - FFV1_0(w[33], w[58], w[4], pars->GC_11, amp[139]); - FFV1_0(w[32], w[55], w[8], pars->GC_2, amp[140]); - FFV1_0(w[67], w[58], w[8], pars->GC_2, amp[141]); - FFV1_0(w[67], w[65], w[7], pars->GC_11, amp[142]); - FFV1_0(w[32], w[65], w[4], pars->GC_11, amp[143]); - FFV1_0(w[34], w[55], w[7], pars->GC_11, amp[144]); - FFV1_0(w[34], w[58], w[4], pars->GC_11, amp[145]); - FFV2_5_0(w[32], w[55], w[17], pars->GC_51, pars->GC_58, amp[146]); - FFV2_5_0(w[67], w[58], w[17], pars->GC_51, pars->GC_58, amp[147]); - FFV1_0(w[30], w[61], w[68], pars->GC_11, amp[148]); - FFV1_0(w[33], w[54], w[68], pars->GC_11, amp[149]); - FFV1_0(w[30], w[65], w[68], pars->GC_11, amp[150]); - FFV1_0(w[34], w[54], w[68], pars->GC_11, amp[151]); - FFV1_0(w[69], w[61], w[6], pars->GC_11, amp[152]); - FFV1_0(w[38], w[61], w[4], pars->GC_11, amp[153]); - FFV1_0(w[39], w[55], w[6], pars->GC_11, amp[154]); - FFV1_0(w[39], w[56], w[4], pars->GC_11, amp[155]); - FFV1_0(w[38], w[55], w[8], pars->GC_2, amp[156]); - FFV1_0(w[69], w[56], w[8], pars->GC_2, amp[157]); - FFV1_0(w[69], w[65], w[6], pars->GC_11, amp[158]); - FFV1_0(w[38], w[65], w[4], pars->GC_11, amp[159]); - FFV1_0(w[40], w[55], w[6], pars->GC_11, amp[160]); - FFV1_0(w[40], w[56], w[4], pars->GC_11, amp[161]); - FFV2_5_0(w[38], w[55], w[17], pars->GC_51, pars->GC_58, amp[162]); - FFV2_5_0(w[69], w[56], w[17], pars->GC_51, pars->GC_58, amp[163]); - FFV1_0(w[36], w[61], w[70], pars->GC_11, amp[164]); - FFV1_0(w[39], w[54], w[70], pars->GC_11, amp[165]); - FFV1_0(w[36], w[65], w[70], pars->GC_11, amp[166]); - FFV1_0(w[40], w[54], w[70], pars->GC_11, amp[167]); - FFV1_0(w[71], w[61], w[7], pars->GC_11, amp[168]); - FFV1_0(w[3], w[61], w[72], pars->GC_11, amp[169]); - FFV1_0(w[10], w[73], w[7], pars->GC_11, amp[170]); - FFV1_0(w[10], w[58], w[70], pars->GC_11, amp[171]); - FFV1_0(w[10], w[54], w[72], pars->GC_11, amp[172]); - FFV1_0(w[71], w[58], w[8], pars->GC_2, amp[173]); - FFV1_0(w[71], w[65], w[7], pars->GC_11, amp[174]); - FFV1_0(w[3], w[65], w[72], pars->GC_11, amp[175]); - FFV1_0(w[18], w[73], w[7], pars->GC_11, amp[176]); - FFV1_0(w[18], w[58], w[70], pars->GC_11, amp[177]); - FFV1_0(w[18], w[54], w[72], pars->GC_11, amp[178]); - FFV2_5_0(w[71], w[58], w[17], pars->GC_51, pars->GC_58, amp[179]); - FFV1_0(w[74], w[61], w[6], pars->GC_11, amp[180]); - FFV1_0(w[3], w[61], w[75], pars->GC_11, amp[181]); - FFV1_0(w[10], w[76], w[6], pars->GC_11, amp[182]); - FFV1_0(w[10], w[56], w[68], pars->GC_11, amp[183]); - FFV1_0(w[10], w[54], w[75], pars->GC_11, amp[184]); - FFV1_0(w[74], w[56], w[8], pars->GC_2, amp[185]); - FFV1_0(w[74], w[65], w[6], pars->GC_11, amp[186]); - FFV1_0(w[3], w[65], w[75], pars->GC_11, amp[187]); - FFV1_0(w[18], w[76], w[6], pars->GC_11, amp[188]); - FFV1_0(w[18], w[56], w[68], pars->GC_11, amp[189]); - FFV1_0(w[18], w[54], w[75], pars->GC_11, amp[190]); - FFV2_5_0(w[74], w[56], w[17], pars->GC_51, pars->GC_58, amp[191]); - FFV1_0(w[48], w[61], w[4], pars->GC_11, amp[192]); - FFV1_0(w[3], w[61], w[77], pars->GC_11, amp[193]); - FFV1_0(w[10], w[55], w[29], pars->GC_11, amp[194]); - FFV1_0(w[10], w[78], w[4], pars->GC_11, amp[195]); - FFV1_0(w[10], w[54], w[77], pars->GC_11, amp[196]); - FFV1_0(w[48], w[55], w[8], pars->GC_2, amp[197]); - FFV1_0(w[48], w[65], w[4], pars->GC_11, amp[198]); - FFV1_0(w[3], w[65], w[77], pars->GC_11, amp[199]); - FFV1_0(w[18], w[55], w[29], pars->GC_11, amp[200]); - FFV1_0(w[18], w[78], w[4], pars->GC_11, amp[201]); - FFV1_0(w[18], w[54], w[77], pars->GC_11, amp[202]); - FFV2_5_0(w[48], w[55], w[17], pars->GC_51, pars->GC_58, amp[203]); - FFV1_0(w[3], w[61], w[79], pars->GC_11, amp[204]); - FFV1_0(w[3], w[61], w[80], pars->GC_11, amp[205]); - FFV1_0(w[3], w[61], w[81], pars->GC_11, amp[206]); - FFV1_0(w[10], w[54], w[79], pars->GC_11, amp[207]); - FFV1_0(w[10], w[54], w[80], pars->GC_11, amp[208]); - FFV1_0(w[10], w[54], w[81], pars->GC_11, amp[209]); - FFV1_0(w[3], w[65], w[79], pars->GC_11, amp[210]); - FFV1_0(w[3], w[65], w[80], pars->GC_11, amp[211]); - FFV1_0(w[3], w[65], w[81], pars->GC_11, amp[212]); - FFV1_0(w[18], w[54], w[79], pars->GC_11, amp[213]); - FFV1_0(w[18], w[54], w[80], pars->GC_11, amp[214]); - FFV1_0(w[18], w[54], w[81], pars->GC_11, amp[215]); - FFV1_0(w[15], w[83], w[7], pars->GC_11, amp[216]); - FFV1_0(w[13], w[83], w[5], pars->GC_11, amp[217]); - FFV1_0(w[57], w[84], w[7], pars->GC_11, amp[218]); - FFV1_0(w[13], w[84], w[4], pars->GC_11, amp[219]); - FFV1_0(w[57], w[85], w[5], pars->GC_11, amp[220]); - FFV1_0(w[15], w[85], w[4], pars->GC_11, amp[221]); - FFV1_0(w[21], w[83], w[7], pars->GC_11, amp[222]); - FFV1_0(w[20], w[83], w[5], pars->GC_11, amp[223]); - FFV1_0(w[59], w[84], w[7], pars->GC_11, amp[224]); - FFV1_0(w[20], w[84], w[4], pars->GC_11, amp[225]); - FFV1_0(w[59], w[85], w[5], pars->GC_11, amp[226]); - FFV1_0(w[21], w[85], w[4], pars->GC_11, amp[227]); - FFV1_0(w[87], w[86], w[7], pars->GC_11, amp[228]); - FFV1_0(w[63], w[86], w[5], pars->GC_11, amp[229]); - FFV1_0(w[64], w[84], w[7], pars->GC_11, amp[230]); - FFV1_0(w[64], w[85], w[5], pars->GC_11, amp[231]); - FFV1_0(w[63], w[84], w[8], pars->GC_2, amp[232]); - FFV1_0(w[87], w[85], w[8], pars->GC_2, amp[233]); - FFV1_0(w[87], w[88], w[7], pars->GC_11, amp[234]); - FFV1_0(w[63], w[88], w[5], pars->GC_11, amp[235]); - FFV1_0(w[66], w[84], w[7], pars->GC_11, amp[236]); - FFV1_0(w[66], w[85], w[5], pars->GC_11, amp[237]); - FFV2_5_0(w[63], w[84], w[17], pars->GC_51, pars->GC_58, amp[238]); - FFV2_5_0(w[87], w[85], w[17], pars->GC_51, pars->GC_58, amp[239]); - FFV1_0(w[60], w[86], w[35], pars->GC_11, amp[240]); - FFV1_0(w[64], w[82], w[35], pars->GC_11, amp[241]); - FFV1_0(w[60], w[88], w[35], pars->GC_11, amp[242]); - FFV1_0(w[66], w[82], w[35], pars->GC_11, amp[243]); - FFV1_0(w[89], w[86], w[7], pars->GC_11, amp[244]); - FFV1_0(w[25], w[86], w[4], pars->GC_11, amp[245]); - FFV1_0(w[26], w[83], w[7], pars->GC_11, amp[246]); - FFV1_0(w[26], w[85], w[4], pars->GC_11, amp[247]); - FFV1_0(w[25], w[83], w[8], pars->GC_2, amp[248]); - FFV1_0(w[89], w[85], w[8], pars->GC_2, amp[249]); - FFV1_0(w[89], w[88], w[7], pars->GC_11, amp[250]); - FFV1_0(w[25], w[88], w[4], pars->GC_11, amp[251]); - FFV1_0(w[28], w[83], w[7], pars->GC_11, amp[252]); - FFV1_0(w[28], w[85], w[4], pars->GC_11, amp[253]); - FFV2_5_0(w[25], w[83], w[17], pars->GC_51, pars->GC_58, amp[254]); - FFV2_5_0(w[89], w[85], w[17], pars->GC_51, pars->GC_58, amp[255]); - FFV1_0(w[22], w[86], w[68], pars->GC_11, amp[256]); - FFV1_0(w[26], w[82], w[68], pars->GC_11, amp[257]); - FFV1_0(w[22], w[88], w[68], pars->GC_11, amp[258]); - FFV1_0(w[28], w[82], w[68], pars->GC_11, amp[259]); - FFV1_0(w[69], w[86], w[5], pars->GC_11, amp[260]); - FFV1_0(w[37], w[86], w[4], pars->GC_11, amp[261]); - FFV1_0(w[39], w[83], w[5], pars->GC_11, amp[262]); - FFV1_0(w[39], w[84], w[4], pars->GC_11, amp[263]); - FFV1_0(w[37], w[83], w[8], pars->GC_2, amp[264]); - FFV1_0(w[69], w[84], w[8], pars->GC_2, amp[265]); - FFV1_0(w[69], w[88], w[5], pars->GC_11, amp[266]); - FFV1_0(w[37], w[88], w[4], pars->GC_11, amp[267]); - FFV1_0(w[40], w[83], w[5], pars->GC_11, amp[268]); - FFV1_0(w[40], w[84], w[4], pars->GC_11, amp[269]); - FFV2_5_0(w[37], w[83], w[17], pars->GC_51, pars->GC_58, amp[270]); - FFV2_5_0(w[69], w[84], w[17], pars->GC_51, pars->GC_58, amp[271]); - FFV1_0(w[36], w[86], w[90], pars->GC_11, amp[272]); - FFV1_0(w[39], w[82], w[90], pars->GC_11, amp[273]); - FFV1_0(w[36], w[88], w[90], pars->GC_11, amp[274]); - FFV1_0(w[40], w[82], w[90], pars->GC_11, amp[275]); - FFV1_0(w[91], w[86], w[7], pars->GC_11, amp[276]); - FFV1_0(w[3], w[86], w[92], pars->GC_11, amp[277]); - FFV1_0(w[10], w[93], w[7], pars->GC_11, amp[278]); - FFV1_0(w[10], w[85], w[90], pars->GC_11, amp[279]); - FFV1_0(w[10], w[82], w[92], pars->GC_11, amp[280]); - FFV1_0(w[91], w[85], w[8], pars->GC_2, amp[281]); - FFV1_0(w[91], w[88], w[7], pars->GC_11, amp[282]); - FFV1_0(w[3], w[88], w[92], pars->GC_11, amp[283]); - FFV1_0(w[18], w[93], w[7], pars->GC_11, amp[284]); - FFV1_0(w[18], w[85], w[90], pars->GC_11, amp[285]); - FFV1_0(w[18], w[82], w[92], pars->GC_11, amp[286]); - FFV2_5_0(w[91], w[85], w[17], pars->GC_51, pars->GC_58, amp[287]); - FFV1_0(w[74], w[86], w[5], pars->GC_11, amp[288]); - FFV1_0(w[3], w[86], w[94], pars->GC_11, amp[289]); - FFV1_0(w[10], w[95], w[5], pars->GC_11, amp[290]); - FFV1_0(w[10], w[84], w[68], pars->GC_11, amp[291]); - FFV1_0(w[10], w[82], w[94], pars->GC_11, amp[292]); - FFV1_0(w[74], w[84], w[8], pars->GC_2, amp[293]); - FFV1_0(w[74], w[88], w[5], pars->GC_11, amp[294]); - FFV1_0(w[3], w[88], w[94], pars->GC_11, amp[295]); - FFV1_0(w[18], w[95], w[5], pars->GC_11, amp[296]); - FFV1_0(w[18], w[84], w[68], pars->GC_11, amp[297]); - FFV1_0(w[18], w[82], w[94], pars->GC_11, amp[298]); - FFV2_5_0(w[74], w[84], w[17], pars->GC_51, pars->GC_58, amp[299]); - FFV1_0(w[45], w[86], w[4], pars->GC_11, amp[300]); - FFV1_0(w[3], w[86], w[96], pars->GC_11, amp[301]); - FFV1_0(w[10], w[83], w[35], pars->GC_11, amp[302]); - FFV1_0(w[10], w[97], w[4], pars->GC_11, amp[303]); - FFV1_0(w[10], w[82], w[96], pars->GC_11, amp[304]); - FFV1_0(w[45], w[83], w[8], pars->GC_2, amp[305]); - FFV1_0(w[45], w[88], w[4], pars->GC_11, amp[306]); - FFV1_0(w[3], w[88], w[96], pars->GC_11, amp[307]); - FFV1_0(w[18], w[83], w[35], pars->GC_11, amp[308]); - FFV1_0(w[18], w[97], w[4], pars->GC_11, amp[309]); - FFV1_0(w[18], w[82], w[96], pars->GC_11, amp[310]); - FFV2_5_0(w[45], w[83], w[17], pars->GC_51, pars->GC_58, amp[311]); - FFV1_0(w[3], w[86], w[98], pars->GC_11, amp[312]); - FFV1_0(w[3], w[86], w[99], pars->GC_11, amp[313]); - FFV1_0(w[3], w[86], w[100], pars->GC_11, amp[314]); - FFV1_0(w[10], w[82], w[98], pars->GC_11, amp[315]); - FFV1_0(w[10], w[82], w[99], pars->GC_11, amp[316]); - FFV1_0(w[10], w[82], w[100], pars->GC_11, amp[317]); - FFV1_0(w[3], w[88], w[98], pars->GC_11, amp[318]); - FFV1_0(w[3], w[88], w[99], pars->GC_11, amp[319]); - FFV1_0(w[3], w[88], w[100], pars->GC_11, amp[320]); - FFV1_0(w[18], w[82], w[98], pars->GC_11, amp[321]); - FFV1_0(w[18], w[82], w[99], pars->GC_11, amp[322]); - FFV1_0(w[18], w[82], w[100], pars->GC_11, amp[323]); - FFV1_0(w[15], w[102], w[6], pars->GC_11, amp[324]); - FFV1_0(w[12], w[102], w[5], pars->GC_11, amp[325]); - FFV1_0(w[57], w[103], w[6], pars->GC_11, amp[326]); - FFV1_0(w[12], w[103], w[4], pars->GC_11, amp[327]); - FFV1_0(w[57], w[104], w[5], pars->GC_11, amp[328]); - FFV1_0(w[15], w[104], w[4], pars->GC_11, amp[329]); - FFV1_0(w[21], w[102], w[6], pars->GC_11, amp[330]); - FFV1_0(w[19], w[102], w[5], pars->GC_11, amp[331]); - FFV1_0(w[59], w[103], w[6], pars->GC_11, amp[332]); - FFV1_0(w[19], w[103], w[4], pars->GC_11, amp[333]); - FFV1_0(w[59], w[104], w[5], pars->GC_11, amp[334]); - FFV1_0(w[21], w[104], w[4], pars->GC_11, amp[335]); - FFV1_0(w[87], w[105], w[6], pars->GC_11, amp[336]); - FFV1_0(w[62], w[105], w[5], pars->GC_11, amp[337]); - FFV1_0(w[64], w[103], w[6], pars->GC_11, amp[338]); - FFV1_0(w[64], w[104], w[5], pars->GC_11, amp[339]); - FFV1_0(w[62], w[103], w[8], pars->GC_2, amp[340]); - FFV1_0(w[87], w[104], w[8], pars->GC_2, amp[341]); - FFV1_0(w[87], w[106], w[6], pars->GC_11, amp[342]); - FFV1_0(w[62], w[106], w[5], pars->GC_11, amp[343]); - FFV1_0(w[66], w[103], w[6], pars->GC_11, amp[344]); - FFV1_0(w[66], w[104], w[5], pars->GC_11, amp[345]); - FFV2_5_0(w[62], w[103], w[17], pars->GC_51, pars->GC_58, amp[346]); - FFV2_5_0(w[87], w[104], w[17], pars->GC_51, pars->GC_58, amp[347]); - FFV1_0(w[60], w[105], w[41], pars->GC_11, amp[348]); - FFV1_0(w[64], w[101], w[41], pars->GC_11, amp[349]); - FFV1_0(w[60], w[106], w[41], pars->GC_11, amp[350]); - FFV1_0(w[66], w[101], w[41], pars->GC_11, amp[351]); - FFV1_0(w[89], w[105], w[6], pars->GC_11, amp[352]); - FFV1_0(w[24], w[105], w[4], pars->GC_11, amp[353]); - FFV1_0(w[26], w[102], w[6], pars->GC_11, amp[354]); - FFV1_0(w[26], w[104], w[4], pars->GC_11, amp[355]); - FFV1_0(w[24], w[102], w[8], pars->GC_2, amp[356]); - FFV1_0(w[89], w[104], w[8], pars->GC_2, amp[357]); - FFV1_0(w[89], w[106], w[6], pars->GC_11, amp[358]); - FFV1_0(w[24], w[106], w[4], pars->GC_11, amp[359]); - FFV1_0(w[28], w[102], w[6], pars->GC_11, amp[360]); - FFV1_0(w[28], w[104], w[4], pars->GC_11, amp[361]); - FFV2_5_0(w[24], w[102], w[17], pars->GC_51, pars->GC_58, amp[362]); - FFV2_5_0(w[89], w[104], w[17], pars->GC_51, pars->GC_58, amp[363]); - FFV1_0(w[22], w[105], w[70], pars->GC_11, amp[364]); - FFV1_0(w[26], w[101], w[70], pars->GC_11, amp[365]); - FFV1_0(w[22], w[106], w[70], pars->GC_11, amp[366]); - FFV1_0(w[28], w[101], w[70], pars->GC_11, amp[367]); - FFV1_0(w[67], w[105], w[5], pars->GC_11, amp[368]); - FFV1_0(w[31], w[105], w[4], pars->GC_11, amp[369]); - FFV1_0(w[33], w[102], w[5], pars->GC_11, amp[370]); - FFV1_0(w[33], w[103], w[4], pars->GC_11, amp[371]); - FFV1_0(w[31], w[102], w[8], pars->GC_2, amp[372]); - FFV1_0(w[67], w[103], w[8], pars->GC_2, amp[373]); - FFV1_0(w[67], w[106], w[5], pars->GC_11, amp[374]); - FFV1_0(w[31], w[106], w[4], pars->GC_11, amp[375]); - FFV1_0(w[34], w[102], w[5], pars->GC_11, amp[376]); - FFV1_0(w[34], w[103], w[4], pars->GC_11, amp[377]); - FFV2_5_0(w[31], w[102], w[17], pars->GC_51, pars->GC_58, amp[378]); - FFV2_5_0(w[67], w[103], w[17], pars->GC_51, pars->GC_58, amp[379]); - FFV1_0(w[30], w[105], w[90], pars->GC_11, amp[380]); - FFV1_0(w[33], w[101], w[90], pars->GC_11, amp[381]); - FFV1_0(w[30], w[106], w[90], pars->GC_11, amp[382]); - FFV1_0(w[34], w[101], w[90], pars->GC_11, amp[383]); - FFV1_0(w[91], w[105], w[6], pars->GC_11, amp[384]); - FFV1_0(w[3], w[105], w[107], pars->GC_11, amp[385]); - FFV1_0(w[10], w[108], w[6], pars->GC_11, amp[386]); - FFV1_0(w[10], w[104], w[90], pars->GC_11, amp[387]); - FFV1_0(w[10], w[101], w[107], pars->GC_11, amp[388]); - FFV1_0(w[91], w[104], w[8], pars->GC_2, amp[389]); - FFV1_0(w[91], w[106], w[6], pars->GC_11, amp[390]); - FFV1_0(w[3], w[106], w[107], pars->GC_11, amp[391]); - FFV1_0(w[18], w[108], w[6], pars->GC_11, amp[392]); - FFV1_0(w[18], w[104], w[90], pars->GC_11, amp[393]); - FFV1_0(w[18], w[101], w[107], pars->GC_11, amp[394]); - FFV2_5_0(w[91], w[104], w[17], pars->GC_51, pars->GC_58, amp[395]); - FFV1_0(w[71], w[105], w[5], pars->GC_11, amp[396]); - FFV1_0(w[3], w[105], w[109], pars->GC_11, amp[397]); - FFV1_0(w[10], w[110], w[5], pars->GC_11, amp[398]); - FFV1_0(w[10], w[103], w[70], pars->GC_11, amp[399]); - FFV1_0(w[10], w[101], w[109], pars->GC_11, amp[400]); - FFV1_0(w[71], w[103], w[8], pars->GC_2, amp[401]); - FFV1_0(w[71], w[106], w[5], pars->GC_11, amp[402]); - FFV1_0(w[3], w[106], w[109], pars->GC_11, amp[403]); - FFV1_0(w[18], w[110], w[5], pars->GC_11, amp[404]); - FFV1_0(w[18], w[103], w[70], pars->GC_11, amp[405]); - FFV1_0(w[18], w[101], w[109], pars->GC_11, amp[406]); - FFV2_5_0(w[71], w[103], w[17], pars->GC_51, pars->GC_58, amp[407]); - FFV1_0(w[42], w[105], w[4], pars->GC_11, amp[408]); - FFV1_0(w[3], w[105], w[111], pars->GC_11, amp[409]); - FFV1_0(w[10], w[102], w[41], pars->GC_11, amp[410]); - FFV1_0(w[10], w[112], w[4], pars->GC_11, amp[411]); - FFV1_0(w[10], w[101], w[111], pars->GC_11, amp[412]); - FFV1_0(w[42], w[102], w[8], pars->GC_2, amp[413]); - FFV1_0(w[42], w[106], w[4], pars->GC_11, amp[414]); - FFV1_0(w[3], w[106], w[111], pars->GC_11, amp[415]); - FFV1_0(w[18], w[102], w[41], pars->GC_11, amp[416]); - FFV1_0(w[18], w[112], w[4], pars->GC_11, amp[417]); - FFV1_0(w[18], w[101], w[111], pars->GC_11, amp[418]); - FFV2_5_0(w[42], w[102], w[17], pars->GC_51, pars->GC_58, amp[419]); - FFV1_0(w[3], w[105], w[113], pars->GC_11, amp[420]); - FFV1_0(w[3], w[105], w[114], pars->GC_11, amp[421]); - FFV1_0(w[3], w[105], w[115], pars->GC_11, amp[422]); - FFV1_0(w[10], w[101], w[113], pars->GC_11, amp[423]); - FFV1_0(w[10], w[101], w[114], pars->GC_11, amp[424]); - FFV1_0(w[10], w[101], w[115], pars->GC_11, amp[425]); - FFV1_0(w[3], w[106], w[113], pars->GC_11, amp[426]); - FFV1_0(w[3], w[106], w[114], pars->GC_11, amp[427]); - FFV1_0(w[3], w[106], w[115], pars->GC_11, amp[428]); - FFV1_0(w[18], w[101], w[113], pars->GC_11, amp[429]); - FFV1_0(w[18], w[101], w[114], pars->GC_11, amp[430]); - FFV1_0(w[18], w[101], w[115], pars->GC_11, amp[431]); - FFV1_0(w[87], w[117], w[7], pars->GC_11, amp[432]); - FFV1_0(w[87], w[118], w[6], pars->GC_11, amp[433]); - FFV1_0(w[62], w[119], w[7], pars->GC_11, amp[434]); - FFV1_0(w[62], w[118], w[5], pars->GC_11, amp[435]); - FFV1_0(w[63], w[119], w[6], pars->GC_11, amp[436]); - FFV1_0(w[63], w[117], w[5], pars->GC_11, amp[437]); - FFV1_0(w[87], w[121], w[7], pars->GC_11, amp[438]); - FFV1_0(w[87], w[122], w[6], pars->GC_11, amp[439]); - FFV1_0(w[62], w[123], w[7], pars->GC_11, amp[440]); - FFV1_0(w[62], w[122], w[5], pars->GC_11, amp[441]); - FFV1_0(w[63], w[123], w[6], pars->GC_11, amp[442]); - FFV1_0(w[63], w[121], w[5], pars->GC_11, amp[443]); - FFV1_0(w[124], w[116], w[7], pars->GC_11, amp[444]); - FFV1_0(w[63], w[116], w[41], pars->GC_11, amp[445]); - FFV1_0(w[60], w[116], w[43], pars->GC_11, amp[446]); - FFV1_0(w[64], w[125], w[7], pars->GC_11, amp[447]); - FFV1_0(w[64], w[2], w[43], pars->GC_11, amp[448]); - FFV1_0(w[63], w[125], w[8], pars->GC_2, amp[449]); - FFV1_0(w[124], w[120], w[7], pars->GC_11, amp[450]); - FFV1_0(w[63], w[120], w[41], pars->GC_11, amp[451]); - FFV1_0(w[60], w[120], w[43], pars->GC_11, amp[452]); - FFV1_0(w[66], w[125], w[7], pars->GC_11, amp[453]); - FFV1_0(w[66], w[2], w[43], pars->GC_11, amp[454]); - FFV2_5_0(w[63], w[125], w[17], pars->GC_51, pars->GC_58, amp[455]); - FFV1_0(w[126], w[116], w[6], pars->GC_11, amp[456]); - FFV1_0(w[62], w[116], w[35], pars->GC_11, amp[457]); - FFV1_0(w[60], w[116], w[46], pars->GC_11, amp[458]); - FFV1_0(w[64], w[127], w[6], pars->GC_11, amp[459]); - FFV1_0(w[64], w[2], w[46], pars->GC_11, amp[460]); - FFV1_0(w[62], w[127], w[8], pars->GC_2, amp[461]); - FFV1_0(w[126], w[120], w[6], pars->GC_11, amp[462]); - FFV1_0(w[62], w[120], w[35], pars->GC_11, amp[463]); - FFV1_0(w[60], w[120], w[46], pars->GC_11, amp[464]); - FFV1_0(w[66], w[127], w[6], pars->GC_11, amp[465]); - FFV1_0(w[66], w[2], w[46], pars->GC_11, amp[466]); - FFV2_5_0(w[62], w[127], w[17], pars->GC_51, pars->GC_58, amp[467]); - FFV1_0(w[87], w[116], w[29], pars->GC_11, amp[468]); - FFV1_0(w[128], w[116], w[5], pars->GC_11, amp[469]); - FFV1_0(w[60], w[116], w[49], pars->GC_11, amp[470]); - FFV1_0(w[64], w[129], w[5], pars->GC_11, amp[471]); - FFV1_0(w[64], w[2], w[49], pars->GC_11, amp[472]); - FFV1_0(w[87], w[129], w[8], pars->GC_2, amp[473]); - FFV1_0(w[87], w[120], w[29], pars->GC_11, amp[474]); - FFV1_0(w[128], w[120], w[5], pars->GC_11, amp[475]); - FFV1_0(w[60], w[120], w[49], pars->GC_11, amp[476]); - FFV1_0(w[66], w[129], w[5], pars->GC_11, amp[477]); - FFV1_0(w[66], w[2], w[49], pars->GC_11, amp[478]); - FFV2_5_0(w[87], w[129], w[17], pars->GC_51, pars->GC_58, amp[479]); - FFV1_0(w[60], w[116], w[51], pars->GC_11, amp[480]); - FFV1_0(w[60], w[116], w[52], pars->GC_11, amp[481]); - FFV1_0(w[60], w[116], w[53], pars->GC_11, amp[482]); - FFV1_0(w[64], w[2], w[51], pars->GC_11, amp[483]); - FFV1_0(w[64], w[2], w[52], pars->GC_11, amp[484]); - FFV1_0(w[64], w[2], w[53], pars->GC_11, amp[485]); - FFV1_0(w[60], w[120], w[51], pars->GC_11, amp[486]); - FFV1_0(w[60], w[120], w[52], pars->GC_11, amp[487]); - FFV1_0(w[60], w[120], w[53], pars->GC_11, amp[488]); - FFV1_0(w[66], w[2], w[51], pars->GC_11, amp[489]); - FFV1_0(w[66], w[2], w[52], pars->GC_11, amp[490]); - FFV1_0(w[66], w[2], w[53], pars->GC_11, amp[491]); - FFV1_0(w[89], w[117], w[7], pars->GC_11, amp[492]); - FFV1_0(w[89], w[118], w[6], pars->GC_11, amp[493]); - FFV1_0(w[24], w[130], w[7], pars->GC_11, amp[494]); - FFV1_0(w[24], w[118], w[4], pars->GC_11, amp[495]); - FFV1_0(w[25], w[130], w[6], pars->GC_11, amp[496]); - FFV1_0(w[25], w[117], w[4], pars->GC_11, amp[497]); - FFV1_0(w[89], w[121], w[7], pars->GC_11, amp[498]); - FFV1_0(w[89], w[122], w[6], pars->GC_11, amp[499]); - FFV1_0(w[24], w[131], w[7], pars->GC_11, amp[500]); - FFV1_0(w[24], w[122], w[4], pars->GC_11, amp[501]); - FFV1_0(w[25], w[131], w[6], pars->GC_11, amp[502]); - FFV1_0(w[25], w[121], w[4], pars->GC_11, amp[503]); - FFV1_0(w[132], w[116], w[7], pars->GC_11, amp[504]); - FFV1_0(w[25], w[116], w[70], pars->GC_11, amp[505]); - FFV1_0(w[22], w[116], w[72], pars->GC_11, amp[506]); - FFV1_0(w[26], w[133], w[7], pars->GC_11, amp[507]); - FFV1_0(w[26], w[2], w[72], pars->GC_11, amp[508]); - FFV1_0(w[25], w[133], w[8], pars->GC_2, amp[509]); - FFV1_0(w[132], w[120], w[7], pars->GC_11, amp[510]); - FFV1_0(w[25], w[120], w[70], pars->GC_11, amp[511]); - FFV1_0(w[22], w[120], w[72], pars->GC_11, amp[512]); - FFV1_0(w[28], w[133], w[7], pars->GC_11, amp[513]); - FFV1_0(w[28], w[2], w[72], pars->GC_11, amp[514]); - FFV2_5_0(w[25], w[133], w[17], pars->GC_51, pars->GC_58, amp[515]); - FFV1_0(w[134], w[116], w[6], pars->GC_11, amp[516]); - FFV1_0(w[24], w[116], w[68], pars->GC_11, amp[517]); - FFV1_0(w[22], w[116], w[75], pars->GC_11, amp[518]); - FFV1_0(w[26], w[135], w[6], pars->GC_11, amp[519]); - FFV1_0(w[26], w[2], w[75], pars->GC_11, amp[520]); - FFV1_0(w[24], w[135], w[8], pars->GC_2, amp[521]); - FFV1_0(w[134], w[120], w[6], pars->GC_11, amp[522]); - FFV1_0(w[24], w[120], w[68], pars->GC_11, amp[523]); - FFV1_0(w[22], w[120], w[75], pars->GC_11, amp[524]); - FFV1_0(w[28], w[135], w[6], pars->GC_11, amp[525]); - FFV1_0(w[28], w[2], w[75], pars->GC_11, amp[526]); - FFV2_5_0(w[24], w[135], w[17], pars->GC_51, pars->GC_58, amp[527]); - FFV1_0(w[89], w[116], w[29], pars->GC_11, amp[528]); - FFV1_0(w[136], w[116], w[4], pars->GC_11, amp[529]); - FFV1_0(w[22], w[116], w[77], pars->GC_11, amp[530]); - FFV1_0(w[26], w[129], w[4], pars->GC_11, amp[531]); - FFV1_0(w[26], w[2], w[77], pars->GC_11, amp[532]); - FFV1_0(w[89], w[129], w[8], pars->GC_2, amp[533]); - FFV1_0(w[89], w[120], w[29], pars->GC_11, amp[534]); - FFV1_0(w[136], w[120], w[4], pars->GC_11, amp[535]); - FFV1_0(w[22], w[120], w[77], pars->GC_11, amp[536]); - FFV1_0(w[28], w[129], w[4], pars->GC_11, amp[537]); - FFV1_0(w[28], w[2], w[77], pars->GC_11, amp[538]); - FFV2_5_0(w[89], w[129], w[17], pars->GC_51, pars->GC_58, amp[539]); - FFV1_0(w[22], w[116], w[79], pars->GC_11, amp[540]); - FFV1_0(w[22], w[116], w[80], pars->GC_11, amp[541]); - FFV1_0(w[22], w[116], w[81], pars->GC_11, amp[542]); - FFV1_0(w[26], w[2], w[79], pars->GC_11, amp[543]); - FFV1_0(w[26], w[2], w[80], pars->GC_11, amp[544]); - FFV1_0(w[26], w[2], w[81], pars->GC_11, amp[545]); - FFV1_0(w[22], w[120], w[79], pars->GC_11, amp[546]); - FFV1_0(w[22], w[120], w[80], pars->GC_11, amp[547]); - FFV1_0(w[22], w[120], w[81], pars->GC_11, amp[548]); - FFV1_0(w[28], w[2], w[79], pars->GC_11, amp[549]); - FFV1_0(w[28], w[2], w[80], pars->GC_11, amp[550]); - FFV1_0(w[28], w[2], w[81], pars->GC_11, amp[551]); - FFV1_0(w[67], w[119], w[7], pars->GC_11, amp[552]); - FFV1_0(w[67], w[118], w[5], pars->GC_11, amp[553]); - FFV1_0(w[31], w[130], w[7], pars->GC_11, amp[554]); - FFV1_0(w[31], w[118], w[4], pars->GC_11, amp[555]); - FFV1_0(w[32], w[130], w[5], pars->GC_11, amp[556]); - FFV1_0(w[32], w[119], w[4], pars->GC_11, amp[557]); - FFV1_0(w[67], w[123], w[7], pars->GC_11, amp[558]); - FFV1_0(w[67], w[122], w[5], pars->GC_11, amp[559]); - FFV1_0(w[31], w[131], w[7], pars->GC_11, amp[560]); - FFV1_0(w[31], w[122], w[4], pars->GC_11, amp[561]); - FFV1_0(w[32], w[131], w[5], pars->GC_11, amp[562]); - FFV1_0(w[32], w[123], w[4], pars->GC_11, amp[563]); - FFV1_0(w[137], w[116], w[7], pars->GC_11, amp[564]); - FFV1_0(w[32], w[116], w[90], pars->GC_11, amp[565]); - FFV1_0(w[30], w[116], w[92], pars->GC_11, amp[566]); - FFV1_0(w[33], w[138], w[7], pars->GC_11, amp[567]); - FFV1_0(w[33], w[2], w[92], pars->GC_11, amp[568]); - FFV1_0(w[32], w[138], w[8], pars->GC_2, amp[569]); - FFV1_0(w[137], w[120], w[7], pars->GC_11, amp[570]); - FFV1_0(w[32], w[120], w[90], pars->GC_11, amp[571]); - FFV1_0(w[30], w[120], w[92], pars->GC_11, amp[572]); - FFV1_0(w[34], w[138], w[7], pars->GC_11, amp[573]); - FFV1_0(w[34], w[2], w[92], pars->GC_11, amp[574]); - FFV2_5_0(w[32], w[138], w[17], pars->GC_51, pars->GC_58, amp[575]); - FFV1_0(w[139], w[116], w[5], pars->GC_11, amp[576]); - FFV1_0(w[31], w[116], w[68], pars->GC_11, amp[577]); - FFV1_0(w[30], w[116], w[94], pars->GC_11, amp[578]); - FFV1_0(w[33], w[135], w[5], pars->GC_11, amp[579]); - FFV1_0(w[33], w[2], w[94], pars->GC_11, amp[580]); - FFV1_0(w[31], w[135], w[8], pars->GC_2, amp[581]); - FFV1_0(w[139], w[120], w[5], pars->GC_11, amp[582]); - FFV1_0(w[31], w[120], w[68], pars->GC_11, amp[583]); - FFV1_0(w[30], w[120], w[94], pars->GC_11, amp[584]); - FFV1_0(w[34], w[135], w[5], pars->GC_11, amp[585]); - FFV1_0(w[34], w[2], w[94], pars->GC_11, amp[586]); - FFV2_5_0(w[31], w[135], w[17], pars->GC_51, pars->GC_58, amp[587]); - FFV1_0(w[67], w[116], w[35], pars->GC_11, amp[588]); - FFV1_0(w[140], w[116], w[4], pars->GC_11, amp[589]); - FFV1_0(w[30], w[116], w[96], pars->GC_11, amp[590]); - FFV1_0(w[33], w[127], w[4], pars->GC_11, amp[591]); - FFV1_0(w[33], w[2], w[96], pars->GC_11, amp[592]); - FFV1_0(w[67], w[127], w[8], pars->GC_2, amp[593]); - FFV1_0(w[67], w[120], w[35], pars->GC_11, amp[594]); - FFV1_0(w[140], w[120], w[4], pars->GC_11, amp[595]); - FFV1_0(w[30], w[120], w[96], pars->GC_11, amp[596]); - FFV1_0(w[34], w[127], w[4], pars->GC_11, amp[597]); - FFV1_0(w[34], w[2], w[96], pars->GC_11, amp[598]); - FFV2_5_0(w[67], w[127], w[17], pars->GC_51, pars->GC_58, amp[599]); - FFV1_0(w[30], w[116], w[98], pars->GC_11, amp[600]); - FFV1_0(w[30], w[116], w[99], pars->GC_11, amp[601]); - FFV1_0(w[30], w[116], w[100], pars->GC_11, amp[602]); - FFV1_0(w[33], w[2], w[98], pars->GC_11, amp[603]); - FFV1_0(w[33], w[2], w[99], pars->GC_11, amp[604]); - FFV1_0(w[33], w[2], w[100], pars->GC_11, amp[605]); - FFV1_0(w[30], w[120], w[98], pars->GC_11, amp[606]); - FFV1_0(w[30], w[120], w[99], pars->GC_11, amp[607]); - FFV1_0(w[30], w[120], w[100], pars->GC_11, amp[608]); - FFV1_0(w[34], w[2], w[98], pars->GC_11, amp[609]); - FFV1_0(w[34], w[2], w[99], pars->GC_11, amp[610]); - FFV1_0(w[34], w[2], w[100], pars->GC_11, amp[611]); - FFV1_0(w[69], w[119], w[6], pars->GC_11, amp[612]); - FFV1_0(w[69], w[117], w[5], pars->GC_11, amp[613]); - FFV1_0(w[37], w[130], w[6], pars->GC_11, amp[614]); - FFV1_0(w[37], w[117], w[4], pars->GC_11, amp[615]); - FFV1_0(w[38], w[130], w[5], pars->GC_11, amp[616]); - FFV1_0(w[38], w[119], w[4], pars->GC_11, amp[617]); - FFV1_0(w[69], w[123], w[6], pars->GC_11, amp[618]); - FFV1_0(w[69], w[121], w[5], pars->GC_11, amp[619]); - FFV1_0(w[37], w[131], w[6], pars->GC_11, amp[620]); - FFV1_0(w[37], w[121], w[4], pars->GC_11, amp[621]); - FFV1_0(w[38], w[131], w[5], pars->GC_11, amp[622]); - FFV1_0(w[38], w[123], w[4], pars->GC_11, amp[623]); - FFV1_0(w[141], w[116], w[6], pars->GC_11, amp[624]); - FFV1_0(w[38], w[116], w[90], pars->GC_11, amp[625]); - FFV1_0(w[36], w[116], w[107], pars->GC_11, amp[626]); - FFV1_0(w[39], w[138], w[6], pars->GC_11, amp[627]); - FFV1_0(w[39], w[2], w[107], pars->GC_11, amp[628]); - FFV1_0(w[38], w[138], w[8], pars->GC_2, amp[629]); - FFV1_0(w[141], w[120], w[6], pars->GC_11, amp[630]); - FFV1_0(w[38], w[120], w[90], pars->GC_11, amp[631]); - FFV1_0(w[36], w[120], w[107], pars->GC_11, amp[632]); - FFV1_0(w[40], w[138], w[6], pars->GC_11, amp[633]); - FFV1_0(w[40], w[2], w[107], pars->GC_11, amp[634]); - FFV2_5_0(w[38], w[138], w[17], pars->GC_51, pars->GC_58, amp[635]); - FFV1_0(w[142], w[116], w[5], pars->GC_11, amp[636]); - FFV1_0(w[37], w[116], w[70], pars->GC_11, amp[637]); - FFV1_0(w[36], w[116], w[109], pars->GC_11, amp[638]); - FFV1_0(w[39], w[133], w[5], pars->GC_11, amp[639]); - FFV1_0(w[39], w[2], w[109], pars->GC_11, amp[640]); - FFV1_0(w[37], w[133], w[8], pars->GC_2, amp[641]); - FFV1_0(w[142], w[120], w[5], pars->GC_11, amp[642]); - FFV1_0(w[37], w[120], w[70], pars->GC_11, amp[643]); - FFV1_0(w[36], w[120], w[109], pars->GC_11, amp[644]); - FFV1_0(w[40], w[133], w[5], pars->GC_11, amp[645]); - FFV1_0(w[40], w[2], w[109], pars->GC_11, amp[646]); - FFV2_5_0(w[37], w[133], w[17], pars->GC_51, pars->GC_58, amp[647]); - FFV1_0(w[69], w[116], w[41], pars->GC_11, amp[648]); - FFV1_0(w[143], w[116], w[4], pars->GC_11, amp[649]); - FFV1_0(w[36], w[116], w[111], pars->GC_11, amp[650]); - FFV1_0(w[39], w[125], w[4], pars->GC_11, amp[651]); - FFV1_0(w[39], w[2], w[111], pars->GC_11, amp[652]); - FFV1_0(w[69], w[125], w[8], pars->GC_2, amp[653]); - FFV1_0(w[69], w[120], w[41], pars->GC_11, amp[654]); - FFV1_0(w[143], w[120], w[4], pars->GC_11, amp[655]); - FFV1_0(w[36], w[120], w[111], pars->GC_11, amp[656]); - FFV1_0(w[40], w[125], w[4], pars->GC_11, amp[657]); - FFV1_0(w[40], w[2], w[111], pars->GC_11, amp[658]); - FFV2_5_0(w[69], w[125], w[17], pars->GC_51, pars->GC_58, amp[659]); - FFV1_0(w[36], w[116], w[113], pars->GC_11, amp[660]); - FFV1_0(w[36], w[116], w[114], pars->GC_11, amp[661]); - FFV1_0(w[36], w[116], w[115], pars->GC_11, amp[662]); - FFV1_0(w[39], w[2], w[113], pars->GC_11, amp[663]); - FFV1_0(w[39], w[2], w[114], pars->GC_11, amp[664]); - FFV1_0(w[39], w[2], w[115], pars->GC_11, amp[665]); - FFV1_0(w[36], w[120], w[113], pars->GC_11, amp[666]); - FFV1_0(w[36], w[120], w[114], pars->GC_11, amp[667]); - FFV1_0(w[36], w[120], w[115], pars->GC_11, amp[668]); - FFV1_0(w[40], w[2], w[113], pars->GC_11, amp[669]); - FFV1_0(w[40], w[2], w[114], pars->GC_11, amp[670]); - FFV1_0(w[40], w[2], w[115], pars->GC_11, amp[671]); - FFV1_0(w[91], w[117], w[7], pars->GC_11, amp[672]); - FFV1_0(w[91], w[118], w[6], pars->GC_11, amp[673]); - VVV1_0(w[107], w[7], w[144], pars->GC_10, amp[674]); - FFV1_0(w[3], w[118], w[107], pars->GC_11, amp[675]); - VVV1_0(w[92], w[6], w[144], pars->GC_10, amp[676]); - FFV1_0(w[3], w[117], w[92], pars->GC_11, amp[677]); - FFV1_0(w[3], w[116], w[145], pars->GC_11, amp[678]); - FFV1_0(w[3], w[116], w[146], pars->GC_11, amp[679]); - FFV1_0(w[3], w[116], w[147], pars->GC_11, amp[680]); - FFV1_0(w[12], w[138], w[7], pars->GC_11, amp[681]); - FFV1_0(w[13], w[138], w[6], pars->GC_11, amp[682]); - VVV1_0(w[107], w[7], w[148], pars->GC_10, amp[683]); - FFV1_0(w[13], w[2], w[107], pars->GC_11, amp[684]); - VVV1_0(w[92], w[6], w[148], pars->GC_10, amp[685]); - FFV1_0(w[12], w[2], w[92], pars->GC_11, amp[686]); - FFV1_0(w[10], w[2], w[145], pars->GC_11, amp[687]); - FFV1_0(w[10], w[2], w[146], pars->GC_11, amp[688]); - FFV1_0(w[10], w[2], w[147], pars->GC_11, amp[689]); - FFV1_0(w[91], w[121], w[7], pars->GC_11, amp[690]); - FFV1_0(w[91], w[122], w[6], pars->GC_11, amp[691]); - VVV1_0(w[107], w[7], w[149], pars->GC_10, amp[692]); - FFV1_0(w[3], w[122], w[107], pars->GC_11, amp[693]); - VVV1_0(w[92], w[6], w[149], pars->GC_10, amp[694]); - FFV1_0(w[3], w[121], w[92], pars->GC_11, amp[695]); - FFV1_0(w[3], w[120], w[145], pars->GC_11, amp[696]); - FFV1_0(w[3], w[120], w[146], pars->GC_11, amp[697]); - FFV1_0(w[3], w[120], w[147], pars->GC_11, amp[698]); - FFV1_0(w[19], w[138], w[7], pars->GC_11, amp[699]); - FFV1_0(w[20], w[138], w[6], pars->GC_11, amp[700]); - VVV1_0(w[107], w[7], w[150], pars->GC_10, amp[701]); - FFV1_0(w[20], w[2], w[107], pars->GC_11, amp[702]); - VVV1_0(w[92], w[6], w[150], pars->GC_10, amp[703]); - FFV1_0(w[19], w[2], w[92], pars->GC_11, amp[704]); - FFV1_0(w[18], w[2], w[145], pars->GC_11, amp[705]); - FFV1_0(w[18], w[2], w[146], pars->GC_11, amp[706]); - FFV1_0(w[18], w[2], w[147], pars->GC_11, amp[707]); - FFV1_0(w[91], w[116], w[29], pars->GC_11, amp[708]); - FFV1_0(w[48], w[116], w[90], pars->GC_11, amp[709]); - FFV1_0(w[3], w[116], w[151], pars->GC_11, amp[710]); - FFV1_0(w[10], w[138], w[29], pars->GC_11, amp[711]); - FFV1_0(w[10], w[129], w[90], pars->GC_11, amp[712]); - FFV1_0(w[10], w[2], w[151], pars->GC_11, amp[713]); - FFV1_0(w[48], w[138], w[8], pars->GC_2, amp[714]); - FFV1_0(w[91], w[129], w[8], pars->GC_2, amp[715]); - FFV1_0(w[91], w[120], w[29], pars->GC_11, amp[716]); - FFV1_0(w[48], w[120], w[90], pars->GC_11, amp[717]); - FFV1_0(w[3], w[120], w[151], pars->GC_11, amp[718]); - FFV1_0(w[18], w[138], w[29], pars->GC_11, amp[719]); - FFV1_0(w[18], w[129], w[90], pars->GC_11, amp[720]); - FFV1_0(w[18], w[2], w[151], pars->GC_11, amp[721]); - FFV2_5_0(w[48], w[138], w[17], pars->GC_51, pars->GC_58, amp[722]); - FFV2_5_0(w[91], w[129], w[17], pars->GC_51, pars->GC_58, amp[723]); - FFV1_0(w[71], w[119], w[7], pars->GC_11, amp[724]); - FFV1_0(w[71], w[118], w[5], pars->GC_11, amp[725]); - VVV1_0(w[109], w[7], w[144], pars->GC_10, amp[726]); - FFV1_0(w[3], w[118], w[109], pars->GC_11, amp[727]); - VVV1_0(w[72], w[5], w[144], pars->GC_10, amp[728]); - FFV1_0(w[3], w[119], w[72], pars->GC_11, amp[729]); - FFV1_0(w[3], w[116], w[152], pars->GC_11, amp[730]); - FFV1_0(w[3], w[116], w[153], pars->GC_11, amp[731]); - FFV1_0(w[3], w[116], w[154], pars->GC_11, amp[732]); - FFV1_0(w[15], w[133], w[7], pars->GC_11, amp[733]); - FFV1_0(w[13], w[133], w[5], pars->GC_11, amp[734]); - VVV1_0(w[109], w[7], w[148], pars->GC_10, amp[735]); - FFV1_0(w[13], w[2], w[109], pars->GC_11, amp[736]); - VVV1_0(w[72], w[5], w[148], pars->GC_10, amp[737]); - FFV1_0(w[15], w[2], w[72], pars->GC_11, amp[738]); - FFV1_0(w[10], w[2], w[152], pars->GC_11, amp[739]); - FFV1_0(w[10], w[2], w[153], pars->GC_11, amp[740]); - FFV1_0(w[10], w[2], w[154], pars->GC_11, amp[741]); - FFV1_0(w[71], w[123], w[7], pars->GC_11, amp[742]); - FFV1_0(w[71], w[122], w[5], pars->GC_11, amp[743]); - VVV1_0(w[109], w[7], w[149], pars->GC_10, amp[744]); - FFV1_0(w[3], w[122], w[109], pars->GC_11, amp[745]); - VVV1_0(w[72], w[5], w[149], pars->GC_10, amp[746]); - FFV1_0(w[3], w[123], w[72], pars->GC_11, amp[747]); - FFV1_0(w[3], w[120], w[152], pars->GC_11, amp[748]); - FFV1_0(w[3], w[120], w[153], pars->GC_11, amp[749]); - FFV1_0(w[3], w[120], w[154], pars->GC_11, amp[750]); - FFV1_0(w[21], w[133], w[7], pars->GC_11, amp[751]); - FFV1_0(w[20], w[133], w[5], pars->GC_11, amp[752]); - VVV1_0(w[109], w[7], w[150], pars->GC_10, amp[753]); - FFV1_0(w[20], w[2], w[109], pars->GC_11, amp[754]); - VVV1_0(w[72], w[5], w[150], pars->GC_10, amp[755]); - FFV1_0(w[21], w[2], w[72], pars->GC_11, amp[756]); - FFV1_0(w[18], w[2], w[152], pars->GC_11, amp[757]); - FFV1_0(w[18], w[2], w[153], pars->GC_11, amp[758]); - FFV1_0(w[18], w[2], w[154], pars->GC_11, amp[759]); - FFV1_0(w[71], w[116], w[35], pars->GC_11, amp[760]); - FFV1_0(w[45], w[116], w[70], pars->GC_11, amp[761]); - FFV1_0(w[3], w[116], w[155], pars->GC_11, amp[762]); - FFV1_0(w[10], w[133], w[35], pars->GC_11, amp[763]); - FFV1_0(w[10], w[127], w[70], pars->GC_11, amp[764]); - FFV1_0(w[10], w[2], w[155], pars->GC_11, amp[765]); - FFV1_0(w[45], w[133], w[8], pars->GC_2, amp[766]); - FFV1_0(w[71], w[127], w[8], pars->GC_2, amp[767]); - FFV1_0(w[71], w[120], w[35], pars->GC_11, amp[768]); - FFV1_0(w[45], w[120], w[70], pars->GC_11, amp[769]); - FFV1_0(w[3], w[120], w[155], pars->GC_11, amp[770]); - FFV1_0(w[18], w[133], w[35], pars->GC_11, amp[771]); - FFV1_0(w[18], w[127], w[70], pars->GC_11, amp[772]); - FFV1_0(w[18], w[2], w[155], pars->GC_11, amp[773]); - FFV2_5_0(w[45], w[133], w[17], pars->GC_51, pars->GC_58, amp[774]); - FFV2_5_0(w[71], w[127], w[17], pars->GC_51, pars->GC_58, amp[775]); - FFV1_0(w[74], w[119], w[6], pars->GC_11, amp[776]); - FFV1_0(w[74], w[117], w[5], pars->GC_11, amp[777]); - VVV1_0(w[94], w[6], w[144], pars->GC_10, amp[778]); - FFV1_0(w[3], w[117], w[94], pars->GC_11, amp[779]); - VVV1_0(w[75], w[5], w[144], pars->GC_10, amp[780]); - FFV1_0(w[3], w[119], w[75], pars->GC_11, amp[781]); - FFV1_0(w[3], w[116], w[156], pars->GC_11, amp[782]); - FFV1_0(w[3], w[116], w[157], pars->GC_11, amp[783]); - FFV1_0(w[3], w[116], w[158], pars->GC_11, amp[784]); - FFV1_0(w[15], w[135], w[6], pars->GC_11, amp[785]); - FFV1_0(w[12], w[135], w[5], pars->GC_11, amp[786]); - VVV1_0(w[94], w[6], w[148], pars->GC_10, amp[787]); - FFV1_0(w[12], w[2], w[94], pars->GC_11, amp[788]); - VVV1_0(w[75], w[5], w[148], pars->GC_10, amp[789]); - FFV1_0(w[15], w[2], w[75], pars->GC_11, amp[790]); - FFV1_0(w[10], w[2], w[156], pars->GC_11, amp[791]); - FFV1_0(w[10], w[2], w[157], pars->GC_11, amp[792]); - FFV1_0(w[10], w[2], w[158], pars->GC_11, amp[793]); - FFV1_0(w[74], w[123], w[6], pars->GC_11, amp[794]); - FFV1_0(w[74], w[121], w[5], pars->GC_11, amp[795]); - VVV1_0(w[94], w[6], w[149], pars->GC_10, amp[796]); - FFV1_0(w[3], w[121], w[94], pars->GC_11, amp[797]); - VVV1_0(w[75], w[5], w[149], pars->GC_10, amp[798]); - FFV1_0(w[3], w[123], w[75], pars->GC_11, amp[799]); - FFV1_0(w[3], w[120], w[156], pars->GC_11, amp[800]); - FFV1_0(w[3], w[120], w[157], pars->GC_11, amp[801]); - FFV1_0(w[3], w[120], w[158], pars->GC_11, amp[802]); - FFV1_0(w[21], w[135], w[6], pars->GC_11, amp[803]); - FFV1_0(w[19], w[135], w[5], pars->GC_11, amp[804]); - VVV1_0(w[94], w[6], w[150], pars->GC_10, amp[805]); - FFV1_0(w[19], w[2], w[94], pars->GC_11, amp[806]); - VVV1_0(w[75], w[5], w[150], pars->GC_10, amp[807]); - FFV1_0(w[21], w[2], w[75], pars->GC_11, amp[808]); - FFV1_0(w[18], w[2], w[156], pars->GC_11, amp[809]); - FFV1_0(w[18], w[2], w[157], pars->GC_11, amp[810]); - FFV1_0(w[18], w[2], w[158], pars->GC_11, amp[811]); - FFV1_0(w[74], w[116], w[41], pars->GC_11, amp[812]); - FFV1_0(w[42], w[116], w[68], pars->GC_11, amp[813]); - FFV1_0(w[3], w[116], w[159], pars->GC_11, amp[814]); - FFV1_0(w[10], w[135], w[41], pars->GC_11, amp[815]); - FFV1_0(w[10], w[125], w[68], pars->GC_11, amp[816]); - FFV1_0(w[10], w[2], w[159], pars->GC_11, amp[817]); - FFV1_0(w[42], w[135], w[8], pars->GC_2, amp[818]); - FFV1_0(w[74], w[125], w[8], pars->GC_2, amp[819]); - FFV1_0(w[74], w[120], w[41], pars->GC_11, amp[820]); - FFV1_0(w[42], w[120], w[68], pars->GC_11, amp[821]); - FFV1_0(w[3], w[120], w[159], pars->GC_11, amp[822]); - FFV1_0(w[18], w[135], w[41], pars->GC_11, amp[823]); - FFV1_0(w[18], w[125], w[68], pars->GC_11, amp[824]); - FFV1_0(w[18], w[2], w[159], pars->GC_11, amp[825]); - FFV2_5_0(w[42], w[135], w[17], pars->GC_51, pars->GC_58, amp[826]); - FFV2_5_0(w[74], w[125], w[17], pars->GC_51, pars->GC_58, amp[827]); - FFV1_0(w[42], w[130], w[7], pars->GC_11, amp[828]); - FFV1_0(w[42], w[118], w[4], pars->GC_11, amp[829]); - VVV1_0(w[111], w[7], w[144], pars->GC_10, amp[830]); - FFV1_0(w[3], w[118], w[111], pars->GC_11, amp[831]); - VVV1_0(w[4], w[43], w[144], pars->GC_10, amp[832]); - FFV1_0(w[3], w[130], w[43], pars->GC_11, amp[833]); - FFV1_0(w[3], w[116], w[160], pars->GC_11, amp[834]); - FFV1_0(w[3], w[116], w[161], pars->GC_11, amp[835]); - FFV1_0(w[3], w[116], w[162], pars->GC_11, amp[836]); - FFV1_0(w[57], w[125], w[7], pars->GC_11, amp[837]); - FFV1_0(w[13], w[125], w[4], pars->GC_11, amp[838]); - VVV1_0(w[111], w[7], w[148], pars->GC_10, amp[839]); - FFV1_0(w[13], w[2], w[111], pars->GC_11, amp[840]); - VVV1_0(w[4], w[43], w[148], pars->GC_10, amp[841]); - FFV1_0(w[57], w[2], w[43], pars->GC_11, amp[842]); - FFV1_0(w[10], w[2], w[160], pars->GC_11, amp[843]); - FFV1_0(w[10], w[2], w[161], pars->GC_11, amp[844]); - FFV1_0(w[10], w[2], w[162], pars->GC_11, amp[845]); - FFV1_0(w[42], w[131], w[7], pars->GC_11, amp[846]); - FFV1_0(w[42], w[122], w[4], pars->GC_11, amp[847]); - VVV1_0(w[111], w[7], w[149], pars->GC_10, amp[848]); - FFV1_0(w[3], w[122], w[111], pars->GC_11, amp[849]); - VVV1_0(w[4], w[43], w[149], pars->GC_10, amp[850]); - FFV1_0(w[3], w[131], w[43], pars->GC_11, amp[851]); - FFV1_0(w[3], w[120], w[160], pars->GC_11, amp[852]); - FFV1_0(w[3], w[120], w[161], pars->GC_11, amp[853]); - FFV1_0(w[3], w[120], w[162], pars->GC_11, amp[854]); - FFV1_0(w[59], w[125], w[7], pars->GC_11, amp[855]); - FFV1_0(w[20], w[125], w[4], pars->GC_11, amp[856]); - VVV1_0(w[111], w[7], w[150], pars->GC_10, amp[857]); - FFV1_0(w[20], w[2], w[111], pars->GC_11, amp[858]); - VVV1_0(w[4], w[43], w[150], pars->GC_10, amp[859]); - FFV1_0(w[59], w[2], w[43], pars->GC_11, amp[860]); - FFV1_0(w[18], w[2], w[160], pars->GC_11, amp[861]); - FFV1_0(w[18], w[2], w[161], pars->GC_11, amp[862]); - FFV1_0(w[18], w[2], w[162], pars->GC_11, amp[863]); - FFV1_0(w[45], w[130], w[6], pars->GC_11, amp[864]); - FFV1_0(w[45], w[117], w[4], pars->GC_11, amp[865]); - VVV1_0(w[96], w[6], w[144], pars->GC_10, amp[866]); - FFV1_0(w[3], w[117], w[96], pars->GC_11, amp[867]); - VVV1_0(w[4], w[46], w[144], pars->GC_10, amp[868]); - FFV1_0(w[3], w[130], w[46], pars->GC_11, amp[869]); - FFV1_0(w[3], w[116], w[163], pars->GC_11, amp[870]); - FFV1_0(w[3], w[116], w[164], pars->GC_11, amp[871]); - FFV1_0(w[3], w[116], w[165], pars->GC_11, amp[872]); - FFV1_0(w[57], w[127], w[6], pars->GC_11, amp[873]); - FFV1_0(w[12], w[127], w[4], pars->GC_11, amp[874]); - VVV1_0(w[96], w[6], w[148], pars->GC_10, amp[875]); - FFV1_0(w[12], w[2], w[96], pars->GC_11, amp[876]); - VVV1_0(w[4], w[46], w[148], pars->GC_10, amp[877]); - FFV1_0(w[57], w[2], w[46], pars->GC_11, amp[878]); - FFV1_0(w[10], w[2], w[163], pars->GC_11, amp[879]); - FFV1_0(w[10], w[2], w[164], pars->GC_11, amp[880]); - FFV1_0(w[10], w[2], w[165], pars->GC_11, amp[881]); - FFV1_0(w[45], w[131], w[6], pars->GC_11, amp[882]); - FFV1_0(w[45], w[121], w[4], pars->GC_11, amp[883]); - VVV1_0(w[96], w[6], w[149], pars->GC_10, amp[884]); - FFV1_0(w[3], w[121], w[96], pars->GC_11, amp[885]); - VVV1_0(w[4], w[46], w[149], pars->GC_10, amp[886]); - FFV1_0(w[3], w[131], w[46], pars->GC_11, amp[887]); - FFV1_0(w[3], w[120], w[163], pars->GC_11, amp[888]); - FFV1_0(w[3], w[120], w[164], pars->GC_11, amp[889]); - FFV1_0(w[3], w[120], w[165], pars->GC_11, amp[890]); - FFV1_0(w[59], w[127], w[6], pars->GC_11, amp[891]); - FFV1_0(w[19], w[127], w[4], pars->GC_11, amp[892]); - VVV1_0(w[96], w[6], w[150], pars->GC_10, amp[893]); - FFV1_0(w[19], w[2], w[96], pars->GC_11, amp[894]); - VVV1_0(w[4], w[46], w[150], pars->GC_10, amp[895]); - FFV1_0(w[59], w[2], w[46], pars->GC_11, amp[896]); - FFV1_0(w[18], w[2], w[163], pars->GC_11, amp[897]); - FFV1_0(w[18], w[2], w[164], pars->GC_11, amp[898]); - FFV1_0(w[18], w[2], w[165], pars->GC_11, amp[899]); - FFV1_0(w[48], w[130], w[5], pars->GC_11, amp[900]); - FFV1_0(w[48], w[119], w[4], pars->GC_11, amp[901]); - VVV1_0(w[77], w[5], w[144], pars->GC_10, amp[902]); - FFV1_0(w[3], w[119], w[77], pars->GC_11, amp[903]); - VVV1_0(w[4], w[49], w[144], pars->GC_10, amp[904]); - FFV1_0(w[3], w[130], w[49], pars->GC_11, amp[905]); - FFV1_0(w[3], w[116], w[166], pars->GC_11, amp[906]); - FFV1_0(w[3], w[116], w[167], pars->GC_11, amp[907]); - FFV1_0(w[3], w[116], w[168], pars->GC_11, amp[908]); - FFV1_0(w[57], w[129], w[5], pars->GC_11, amp[909]); - FFV1_0(w[15], w[129], w[4], pars->GC_11, amp[910]); - VVV1_0(w[77], w[5], w[148], pars->GC_10, amp[911]); - FFV1_0(w[15], w[2], w[77], pars->GC_11, amp[912]); - VVV1_0(w[4], w[49], w[148], pars->GC_10, amp[913]); - FFV1_0(w[57], w[2], w[49], pars->GC_11, amp[914]); - FFV1_0(w[10], w[2], w[166], pars->GC_11, amp[915]); - FFV1_0(w[10], w[2], w[167], pars->GC_11, amp[916]); - FFV1_0(w[10], w[2], w[168], pars->GC_11, amp[917]); - FFV1_0(w[48], w[131], w[5], pars->GC_11, amp[918]); - FFV1_0(w[48], w[123], w[4], pars->GC_11, amp[919]); - VVV1_0(w[77], w[5], w[149], pars->GC_10, amp[920]); - FFV1_0(w[3], w[123], w[77], pars->GC_11, amp[921]); - VVV1_0(w[4], w[49], w[149], pars->GC_10, amp[922]); - FFV1_0(w[3], w[131], w[49], pars->GC_11, amp[923]); - FFV1_0(w[3], w[120], w[166], pars->GC_11, amp[924]); - FFV1_0(w[3], w[120], w[167], pars->GC_11, amp[925]); - FFV1_0(w[3], w[120], w[168], pars->GC_11, amp[926]); - FFV1_0(w[59], w[129], w[5], pars->GC_11, amp[927]); - FFV1_0(w[21], w[129], w[4], pars->GC_11, amp[928]); - VVV1_0(w[77], w[5], w[150], pars->GC_10, amp[929]); - FFV1_0(w[21], w[2], w[77], pars->GC_11, amp[930]); - VVV1_0(w[4], w[49], w[150], pars->GC_10, amp[931]); - FFV1_0(w[59], w[2], w[49], pars->GC_11, amp[932]); - FFV1_0(w[18], w[2], w[166], pars->GC_11, amp[933]); - FFV1_0(w[18], w[2], w[167], pars->GC_11, amp[934]); - FFV1_0(w[18], w[2], w[168], pars->GC_11, amp[935]); - FFV1_0(w[169], w[116], w[7], pars->GC_11, amp[936]); - FFV1_0(w[170], w[116], w[7], pars->GC_11, amp[937]); - FFV1_0(w[171], w[116], w[7], pars->GC_11, amp[938]); - FFV1_0(w[3], w[116], w[172], pars->GC_11, amp[939]); - FFV1_0(w[3], w[116], w[173], pars->GC_11, amp[940]); - FFV1_0(w[3], w[116], w[174], pars->GC_11, amp[941]); - FFV1_0(w[10], w[175], w[7], pars->GC_11, amp[942]); - FFV1_0(w[10], w[176], w[7], pars->GC_11, amp[943]); - FFV1_0(w[10], w[177], w[7], pars->GC_11, amp[944]); - FFV1_0(w[10], w[2], w[172], pars->GC_11, amp[945]); - FFV1_0(w[10], w[2], w[173], pars->GC_11, amp[946]); - FFV1_0(w[10], w[2], w[174], pars->GC_11, amp[947]); - FFV1_0(w[169], w[120], w[7], pars->GC_11, amp[948]); - FFV1_0(w[170], w[120], w[7], pars->GC_11, amp[949]); - FFV1_0(w[171], w[120], w[7], pars->GC_11, amp[950]); - FFV1_0(w[3], w[120], w[172], pars->GC_11, amp[951]); - FFV1_0(w[3], w[120], w[173], pars->GC_11, amp[952]); - FFV1_0(w[3], w[120], w[174], pars->GC_11, amp[953]); - FFV1_0(w[18], w[175], w[7], pars->GC_11, amp[954]); - FFV1_0(w[18], w[176], w[7], pars->GC_11, amp[955]); - FFV1_0(w[18], w[177], w[7], pars->GC_11, amp[956]); - FFV1_0(w[18], w[2], w[172], pars->GC_11, amp[957]); - FFV1_0(w[18], w[2], w[173], pars->GC_11, amp[958]); - FFV1_0(w[18], w[2], w[174], pars->GC_11, amp[959]); - FFV1_0(w[178], w[116], w[6], pars->GC_11, amp[960]); - FFV1_0(w[179], w[116], w[6], pars->GC_11, amp[961]); - FFV1_0(w[180], w[116], w[6], pars->GC_11, amp[962]); - FFV1_0(w[3], w[116], w[181], pars->GC_11, amp[963]); - FFV1_0(w[3], w[116], w[182], pars->GC_11, amp[964]); - FFV1_0(w[3], w[116], w[183], pars->GC_11, amp[965]); - FFV1_0(w[10], w[184], w[6], pars->GC_11, amp[966]); - FFV1_0(w[10], w[185], w[6], pars->GC_11, amp[967]); - FFV1_0(w[10], w[186], w[6], pars->GC_11, amp[968]); - FFV1_0(w[10], w[2], w[181], pars->GC_11, amp[969]); - FFV1_0(w[10], w[2], w[182], pars->GC_11, amp[970]); - FFV1_0(w[10], w[2], w[183], pars->GC_11, amp[971]); - FFV1_0(w[178], w[120], w[6], pars->GC_11, amp[972]); - FFV1_0(w[179], w[120], w[6], pars->GC_11, amp[973]); - FFV1_0(w[180], w[120], w[6], pars->GC_11, amp[974]); - FFV1_0(w[3], w[120], w[181], pars->GC_11, amp[975]); - FFV1_0(w[3], w[120], w[182], pars->GC_11, amp[976]); - FFV1_0(w[3], w[120], w[183], pars->GC_11, amp[977]); - FFV1_0(w[18], w[184], w[6], pars->GC_11, amp[978]); - FFV1_0(w[18], w[185], w[6], pars->GC_11, amp[979]); - FFV1_0(w[18], w[186], w[6], pars->GC_11, amp[980]); - FFV1_0(w[18], w[2], w[181], pars->GC_11, amp[981]); - FFV1_0(w[18], w[2], w[182], pars->GC_11, amp[982]); - FFV1_0(w[18], w[2], w[183], pars->GC_11, amp[983]); - FFV1_0(w[187], w[116], w[5], pars->GC_11, amp[984]); - FFV1_0(w[188], w[116], w[5], pars->GC_11, amp[985]); - FFV1_0(w[189], w[116], w[5], pars->GC_11, amp[986]); - FFV1_0(w[3], w[116], w[190], pars->GC_11, amp[987]); - FFV1_0(w[3], w[116], w[191], pars->GC_11, amp[988]); - FFV1_0(w[3], w[116], w[192], pars->GC_11, amp[989]); - FFV1_0(w[10], w[193], w[5], pars->GC_11, amp[990]); - FFV1_0(w[10], w[194], w[5], pars->GC_11, amp[991]); - FFV1_0(w[10], w[195], w[5], pars->GC_11, amp[992]); - FFV1_0(w[10], w[2], w[190], pars->GC_11, amp[993]); - FFV1_0(w[10], w[2], w[191], pars->GC_11, amp[994]); - FFV1_0(w[10], w[2], w[192], pars->GC_11, amp[995]); - FFV1_0(w[187], w[120], w[5], pars->GC_11, amp[996]); - FFV1_0(w[188], w[120], w[5], pars->GC_11, amp[997]); - FFV1_0(w[189], w[120], w[5], pars->GC_11, amp[998]); - FFV1_0(w[3], w[120], w[190], pars->GC_11, amp[999]); - FFV1_0(w[3], w[120], w[191], pars->GC_11, amp[1000]); - FFV1_0(w[3], w[120], w[192], pars->GC_11, amp[1001]); - FFV1_0(w[18], w[193], w[5], pars->GC_11, amp[1002]); - FFV1_0(w[18], w[194], w[5], pars->GC_11, amp[1003]); - FFV1_0(w[18], w[195], w[5], pars->GC_11, amp[1004]); - FFV1_0(w[18], w[2], w[190], pars->GC_11, amp[1005]); - FFV1_0(w[18], w[2], w[191], pars->GC_11, amp[1006]); - FFV1_0(w[18], w[2], w[192], pars->GC_11, amp[1007]); - FFV1_0(w[196], w[116], w[4], pars->GC_11, amp[1008]); - FFV1_0(w[197], w[116], w[4], pars->GC_11, amp[1009]); - FFV1_0(w[198], w[116], w[4], pars->GC_11, amp[1010]); - FFV1_0(w[3], w[116], w[199], pars->GC_11, amp[1011]); - FFV1_0(w[3], w[116], w[200], pars->GC_11, amp[1012]); - FFV1_0(w[3], w[116], w[201], pars->GC_11, amp[1013]); - FFV1_0(w[10], w[202], w[4], pars->GC_11, amp[1014]); - FFV1_0(w[10], w[203], w[4], pars->GC_11, amp[1015]); - FFV1_0(w[10], w[204], w[4], pars->GC_11, amp[1016]); - FFV1_0(w[10], w[2], w[199], pars->GC_11, amp[1017]); - FFV1_0(w[10], w[2], w[200], pars->GC_11, amp[1018]); - FFV1_0(w[10], w[2], w[201], pars->GC_11, amp[1019]); - FFV1_0(w[196], w[120], w[4], pars->GC_11, amp[1020]); - FFV1_0(w[197], w[120], w[4], pars->GC_11, amp[1021]); - FFV1_0(w[198], w[120], w[4], pars->GC_11, amp[1022]); - FFV1_0(w[3], w[120], w[199], pars->GC_11, amp[1023]); - FFV1_0(w[3], w[120], w[200], pars->GC_11, amp[1024]); - FFV1_0(w[3], w[120], w[201], pars->GC_11, amp[1025]); - FFV1_0(w[18], w[202], w[4], pars->GC_11, amp[1026]); - FFV1_0(w[18], w[203], w[4], pars->GC_11, amp[1027]); - FFV1_0(w[18], w[204], w[4], pars->GC_11, amp[1028]); - FFV1_0(w[18], w[2], w[199], pars->GC_11, amp[1029]); - FFV1_0(w[18], w[2], w[200], pars->GC_11, amp[1030]); - FFV1_0(w[18], w[2], w[201], pars->GC_11, amp[1031]); - -} -double eeuugggg::matrix_1_epem_uuxgggg() -{ -// int i, j; - // Local variables -// const int ngraphs = 1032; - const int ncolor = 24; - std::complex ztemp; - std::complex jamp[ncolor]; - // The color matrix; - //static const double denom[ncolor] = {54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - // 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54}; - /*static const double cf[ncolor][ncolor] = {{512, -64, -64, 8, 8, 80, -64, 8, - 8, -1, -1, -10, 8, -1, 80, -10, 71, 62, -1, -10, -10, 62, 62, -28}, {-64, - 512, 8, 80, -64, 8, 8, -64, -1, -10, 8, -1, -1, -10, -10, 62, 62, -28, 8, - -1, 80, -10, 71, 62}, {-64, 8, 512, -64, 80, 8, 8, -1, 80, -10, 71, 62, - -64, 8, 8, -1, -1, -10, -10, -1, 62, -28, -10, 62}, {8, 80, -64, 512, 8, - -64, -1, -10, -10, 62, 62, -28, 8, -64, -1, -10, 8, -1, -1, 8, 71, 62, - 80, -10}, {8, -64, 80, 8, 512, -64, -1, 8, 71, 62, 80, -10, -10, -1, 62, - -28, -10, 62, -64, 8, 8, -1, -1, -10}, {80, 8, 8, -64, -64, 512, -10, -1, - 62, -28, -10, 62, -1, 8, 71, 62, 80, -10, 8, -64, -1, -10, 8, -1}, {-64, - 8, 8, -1, -1, -10, 512, -64, -64, 8, 8, 80, 80, -10, 8, -1, 62, 71, -10, - 62, -1, -10, -28, 62}, {8, -64, -1, -10, 8, -1, -64, 512, 8, 80, -64, 8, - -10, 62, -1, -10, -28, 62, 80, -10, 8, -1, 62, 71}, {8, -1, 80, -10, 71, - 62, -64, 8, 512, -64, 80, 8, 8, -1, -64, 8, -10, -1, 62, -28, -10, -1, - 62, -10}, {-1, -10, -10, 62, 62, -28, 8, 80, -64, 512, 8, -64, -1, -10, - 8, -64, -1, 8, 71, 62, -1, 8, -10, 80}, {-1, 8, 71, 62, 80, -10, 8, -64, - 80, 8, 512, -64, 62, -28, -10, -1, 62, -10, 8, -1, -64, 8, -10, -1}, - {-10, -1, 62, -28, -10, 62, 80, 8, 8, -64, -64, 512, 71, 62, -1, 8, -10, - 80, -1, -10, 8, -64, -1, 8}, {8, -1, -64, 8, -10, -1, 80, -10, 8, -1, 62, - 71, 512, -64, -64, 8, 8, 80, 62, -10, -28, 62, -1, -10}, {-1, -10, 8, - -64, -1, 8, -10, 62, -1, -10, -28, 62, -64, 512, 8, 80, -64, 8, -10, 80, - 62, 71, 8, -1}, {80, -10, 8, -1, 62, 71, 8, -1, -64, 8, -10, -1, -64, 8, - 512, -64, 80, 8, -28, 62, 62, -10, -10, -1}, {-10, 62, -1, -10, -28, 62, - -1, -10, 8, -64, -1, 8, 8, 80, -64, 512, 8, -64, 62, 71, -10, 80, -1, 8}, - {71, 62, -1, 8, -10, 80, 62, -28, -10, -1, 62, -10, 8, -64, 80, 8, 512, - -64, -1, 8, -10, -1, -64, 8}, {62, -28, -10, -1, 62, -10, 71, 62, -1, 8, - -10, 80, 80, 8, 8, -64, -64, 512, -10, -1, -1, 8, 8, -64}, {-1, 8, -10, - -1, -64, 8, -10, 80, 62, 71, 8, -1, 62, -10, -28, 62, -1, -10, 512, -64, - -64, 8, 8, 80}, {-10, -1, -1, 8, 8, -64, 62, -10, -28, 62, -1, -10, -10, - 80, 62, 71, 8, -1, -64, 512, 8, 80, -64, 8}, {-10, 80, 62, 71, 8, -1, -1, - 8, -10, -1, -64, 8, -28, 62, 62, -10, -10, -1, -64, 8, 512, -64, 80, 8}, - {62, -10, -28, 62, -1, -10, -10, -1, -1, 8, 8, -64, 62, 71, -10, 80, -1, - 8, 8, 80, -64, 512, 8, -64}, {62, 71, -10, 80, -1, 8, -28, 62, 62, -10, - -10, -1, -1, 8, -10, -1, -64, 8, 8, -64, 80, 8, 512, -64}, {-28, 62, 62, - -10, -10, -1, 62, 71, -10, 80, -1, 8, -10, -1, -1, 8, 8, -64, 80, 8, 8, - -64, -64, 512}}; - */ - - // Calculate color flows - jamp[0] = +amp[1] + amp[7] + amp[45] + amp[46] + amp[48] + amp[51] + amp[52] - + amp[54] - std::complex (0, 1) * amp[56] - std::complex - (0, 1) * amp[57] - std::complex (0, 1) * amp[58] - - std::complex (0, 1) * amp[59] - amp[61] - std::complex - (0, 1) * amp[62] - amp[64] - amp[67] - std::complex (0, 1) * - amp[68] - amp[70] - std::complex (0, 1) * amp[84] - amp[85] - - std::complex (0, 1) * amp[86] - amp[88] - std::complex - (0, 1) * amp[89] - std::complex (0, 1) * amp[90] - amp[91] - - std::complex (0, 1) * amp[92] - amp[94] - std::complex - (0, 1) * amp[95] + amp[98] - amp[96] + amp[101] - amp[99] + amp[104] - - amp[102] + amp[107] - amp[105] + amp[616] + amp[622] - - std::complex (0, 1) * amp[625] - amp[626] - std::complex - (0, 1) * amp[627] - amp[628] - std::complex (0, 1) * amp[629] - - std::complex (0, 1) * amp[631] - amp[632] - std::complex - (0, 1) * amp[633] - amp[634] - std::complex (0, 1) * amp[635] - - std::complex (0, 1) * amp[649] - amp[650] - amp[652] - - std::complex (0, 1) * amp[655] - amp[656] - amp[658] + amp[662] - - amp[660] + amp[665] - amp[663] + amp[668] - amp[666] + amp[671] - - amp[669] + std::complex (0, 1) * amp[674] - std::complex - (0, 1) * amp[680] + std::complex (0, 1) * amp[678] - - std::complex (0, 1) * amp[682] + std::complex (0, 1) * - amp[683] - amp[684] - std::complex (0, 1) * amp[689] + - std::complex (0, 1) * amp[687] + std::complex (0, 1) * - amp[692] - std::complex (0, 1) * amp[698] + std::complex - (0, 1) * amp[696] - std::complex (0, 1) * amp[700] + - std::complex (0, 1) * amp[701] - amp[702] - std::complex - (0, 1) * amp[707] + std::complex (0, 1) * amp[705] - amp[709] + - std::complex (0, 1) * amp[710] - amp[711] + std::complex - (0, 1) * amp[713] - amp[714] - amp[717] + std::complex (0, 1) * - amp[718] - amp[719] + std::complex (0, 1) * amp[721] - amp[722] + - std::complex (0, 1) * amp[830] + std::complex (0, 1) * - amp[832] - amp[833] - std::complex (0, 1) * amp[836] + - std::complex (0, 1) * amp[834] + std::complex (0, 1) * - amp[839] - amp[840] + std::complex (0, 1) * amp[841] - - std::complex (0, 1) * amp[845] + std::complex (0, 1) * - amp[843] + std::complex (0, 1) * amp[848] + std::complex - (0, 1) * amp[850] - amp[851] - std::complex (0, 1) * amp[854] + - std::complex (0, 1) * amp[852] + std::complex (0, 1) * - amp[857] - amp[858] + std::complex (0, 1) * amp[859] - - std::complex (0, 1) * amp[863] + std::complex (0, 1) * - amp[861] - std::complex (0, 1) * amp[900] + std::complex - (0, 1) * amp[904] - amp[905] - std::complex (0, 1) * amp[908] + - std::complex (0, 1) * amp[906] + std::complex (0, 1) * - amp[913] - std::complex (0, 1) * amp[917] + std::complex - (0, 1) * amp[915] - std::complex (0, 1) * amp[918] + - std::complex (0, 1) * amp[922] - amp[923] - std::complex - (0, 1) * amp[926] + std::complex (0, 1) * amp[924] + - std::complex (0, 1) * amp[931] - std::complex (0, 1) * - amp[935] + std::complex (0, 1) * amp[933] - std::complex - (0, 1) * amp[941] + std::complex (0, 1) * amp[939] + amp[944] - - amp[942] - std::complex (0, 1) * amp[947] + std::complex - (0, 1) * amp[945] - std::complex (0, 1) * amp[953] + - std::complex (0, 1) * amp[951] + amp[956] - amp[954] - - std::complex (0, 1) * amp[959] + std::complex (0, 1) * - amp[957] + amp[1010] - amp[1008] - std::complex (0, 1) * - amp[1013] + std::complex (0, 1) * amp[1011] - - std::complex (0, 1) * amp[1019] + std::complex (0, 1) * - amp[1017] + amp[1022] - amp[1020] - std::complex (0, 1) * - amp[1025] + std::complex (0, 1) * amp[1023] - - std::complex (0, 1) * amp[1031] + std::complex (0, 1) * - amp[1029]; - jamp[1] = +amp[0] + amp[6] + amp[29] + amp[30] + amp[32] + amp[35] + amp[36] - + amp[38] - std::complex (0, 1) * amp[40] - std::complex - (0, 1) * amp[41] - std::complex (0, 1) * amp[42] - - std::complex (0, 1) * amp[43] - amp[73] - std::complex - (0, 1) * amp[74] - amp[76] - amp[79] - std::complex (0, 1) * - amp[80] - amp[82] + std::complex (0, 1) * amp[84] + amp[85] + - std::complex (0, 1) * amp[86] + amp[88] + std::complex - (0, 1) * amp[89] + std::complex (0, 1) * amp[90] + amp[91] + - std::complex (0, 1) * amp[92] + amp[94] + std::complex - (0, 1) * amp[95] + amp[96] + amp[97] + amp[99] + amp[100] + amp[102] + - amp[103] + amp[105] + amp[106] + amp[556] + amp[562] - - std::complex (0, 1) * amp[565] - amp[566] - std::complex - (0, 1) * amp[567] - amp[568] - std::complex (0, 1) * amp[569] - - std::complex (0, 1) * amp[571] - amp[572] - std::complex - (0, 1) * amp[573] - amp[574] - std::complex (0, 1) * amp[575] - - std::complex (0, 1) * amp[589] - amp[590] - amp[592] - - std::complex (0, 1) * amp[595] - amp[596] - amp[598] + amp[602] - - amp[600] + amp[605] - amp[603] + amp[608] - amp[606] + amp[611] - - amp[609] + std::complex (0, 1) * amp[676] - std::complex - (0, 1) * amp[678] - std::complex (0, 1) * amp[679] - - std::complex (0, 1) * amp[681] + std::complex (0, 1) * - amp[685] - amp[686] - std::complex (0, 1) * amp[687] - - std::complex (0, 1) * amp[688] + std::complex (0, 1) * - amp[694] - std::complex (0, 1) * amp[696] - std::complex - (0, 1) * amp[697] - std::complex (0, 1) * amp[699] + - std::complex (0, 1) * amp[703] - amp[704] - std::complex - (0, 1) * amp[705] - std::complex (0, 1) * amp[706] + amp[709] - - std::complex (0, 1) * amp[710] + amp[711] - std::complex - (0, 1) * amp[713] + amp[714] + amp[717] - std::complex (0, 1) * - amp[718] + amp[719] - std::complex (0, 1) * amp[721] + amp[722] + - std::complex (0, 1) * amp[866] + std::complex (0, 1) * - amp[868] - amp[869] - std::complex (0, 1) * amp[872] + - std::complex (0, 1) * amp[870] + std::complex (0, 1) * - amp[875] - amp[876] + std::complex (0, 1) * amp[877] - - std::complex (0, 1) * amp[881] + std::complex (0, 1) * - amp[879] + std::complex (0, 1) * amp[884] + std::complex - (0, 1) * amp[886] - amp[887] - std::complex (0, 1) * amp[890] + - std::complex (0, 1) * amp[888] + std::complex (0, 1) * - amp[893] - amp[894] + std::complex (0, 1) * amp[895] - - std::complex (0, 1) * amp[899] + std::complex (0, 1) * - amp[897] + std::complex (0, 1) * amp[900] - std::complex - (0, 1) * amp[904] + amp[905] + std::complex (0, 1) * amp[908] - - std::complex (0, 1) * amp[906] - std::complex (0, 1) * - amp[913] + std::complex (0, 1) * amp[917] - std::complex - (0, 1) * amp[915] + std::complex (0, 1) * amp[918] - - std::complex (0, 1) * amp[922] + amp[923] + std::complex - (0, 1) * amp[926] - std::complex (0, 1) * amp[924] - - std::complex (0, 1) * amp[931] + std::complex (0, 1) * - amp[935] - std::complex (0, 1) * amp[933] - std::complex - (0, 1) * amp[965] + std::complex (0, 1) * amp[963] + amp[968] - - amp[966] - std::complex (0, 1) * amp[971] + std::complex - (0, 1) * amp[969] - std::complex (0, 1) * amp[977] + - std::complex (0, 1) * amp[975] + amp[980] - amp[978] - - std::complex (0, 1) * amp[983] + std::complex (0, 1) * - amp[981] + amp[1008] + amp[1009] - std::complex (0, 1) * - amp[1011] - std::complex (0, 1) * amp[1012] - - std::complex (0, 1) * amp[1017] - std::complex (0, 1) * - amp[1018] + amp[1020] + amp[1021] - std::complex (0, 1) * - amp[1023] - std::complex (0, 1) * amp[1024] - - std::complex (0, 1) * amp[1029] - std::complex (0, 1) * - amp[1030]; - jamp[2] = +amp[3] + amp[9] + amp[44] + amp[47] + amp[49] + amp[50] + amp[53] - + amp[55] + std::complex (0, 1) * amp[56] + std::complex - (0, 1) * amp[57] + std::complex (0, 1) * amp[58] + - std::complex (0, 1) * amp[59] + amp[61] + std::complex - (0, 1) * amp[62] + amp[64] + amp[67] + std::complex (0, 1) * - amp[68] + amp[70] - std::complex (0, 1) * amp[72] + amp[73] - - std::complex (0, 1) * amp[75] + amp[76] - std::complex - (0, 1) * amp[77] - std::complex (0, 1) * amp[78] + amp[79] - - std::complex (0, 1) * amp[81] + amp[82] - std::complex - (0, 1) * amp[83] - amp[98] - amp[97] - amp[101] - amp[100] - amp[104] - - amp[103] - amp[107] - amp[106] + amp[614] + amp[620] - - std::complex (0, 1) * amp[637] - amp[638] - std::complex - (0, 1) * amp[639] - amp[640] - std::complex (0, 1) * amp[641] - - std::complex (0, 1) * amp[643] - amp[644] - std::complex - (0, 1) * amp[645] - amp[646] - std::complex (0, 1) * amp[647] + - std::complex (0, 1) * amp[649] + amp[650] + amp[652] + - std::complex (0, 1) * amp[655] + amp[656] + amp[658] + amp[660] + - amp[661] + amp[663] + amp[664] + amp[666] + amp[667] + amp[669] + - amp[670] + std::complex (0, 1) * amp[726] - std::complex - (0, 1) * amp[732] + std::complex (0, 1) * amp[730] - - std::complex (0, 1) * amp[734] + std::complex (0, 1) * - amp[735] - amp[736] - std::complex (0, 1) * amp[741] + - std::complex (0, 1) * amp[739] + std::complex (0, 1) * - amp[744] - std::complex (0, 1) * amp[750] + std::complex - (0, 1) * amp[748] - std::complex (0, 1) * amp[752] + - std::complex (0, 1) * amp[753] - amp[754] - std::complex - (0, 1) * amp[759] + std::complex (0, 1) * amp[757] - amp[761] + - std::complex (0, 1) * amp[762] - amp[763] + std::complex - (0, 1) * amp[765] - amp[766] - amp[769] + std::complex (0, 1) * - amp[770] - amp[771] + std::complex (0, 1) * amp[773] - amp[774] - - std::complex (0, 1) * amp[830] - std::complex (0, 1) * - amp[832] + amp[833] + std::complex (0, 1) * amp[836] - - std::complex (0, 1) * amp[834] - std::complex (0, 1) * - amp[839] + amp[840] - std::complex (0, 1) * amp[841] + - std::complex (0, 1) * amp[845] - std::complex (0, 1) * - amp[843] - std::complex (0, 1) * amp[848] - std::complex - (0, 1) * amp[850] + amp[851] + std::complex (0, 1) * amp[854] - - std::complex (0, 1) * amp[852] - std::complex (0, 1) * - amp[857] + amp[858] - std::complex (0, 1) * amp[859] + - std::complex (0, 1) * amp[863] - std::complex (0, 1) * - amp[861] - std::complex (0, 1) * amp[864] - std::complex - (0, 1) * amp[868] + amp[869] - std::complex (0, 1) * amp[870] - - std::complex (0, 1) * amp[871] - std::complex (0, 1) * - amp[877] - std::complex (0, 1) * amp[879] - std::complex - (0, 1) * amp[880] - std::complex (0, 1) * amp[882] - - std::complex (0, 1) * amp[886] + amp[887] - std::complex - (0, 1) * amp[888] - std::complex (0, 1) * amp[889] - - std::complex (0, 1) * amp[895] - std::complex (0, 1) * - amp[897] - std::complex (0, 1) * amp[898] - std::complex - (0, 1) * amp[939] - std::complex (0, 1) * amp[940] + amp[942] + - amp[943] - std::complex (0, 1) * amp[945] - std::complex - (0, 1) * amp[946] - std::complex (0, 1) * amp[951] - - std::complex (0, 1) * amp[952] + amp[954] + amp[955] - - std::complex (0, 1) * amp[957] - std::complex (0, 1) * - amp[958] - amp[1010] - amp[1009] + std::complex (0, 1) * - amp[1013] + std::complex (0, 1) * amp[1012] + - std::complex (0, 1) * amp[1019] + std::complex (0, 1) * - amp[1018] - amp[1022] - amp[1021] + std::complex (0, 1) * - amp[1025] + std::complex (0, 1) * amp[1024] + - std::complex (0, 1) * amp[1031] + std::complex (0, 1) * - amp[1030]; - jamp[3] = +amp[2] + amp[8] + amp[13] + amp[14] + amp[16] + amp[19] + amp[20] - + amp[22] - std::complex (0, 1) * amp[24] - std::complex - (0, 1) * amp[25] - std::complex (0, 1) * amp[26] - - std::complex (0, 1) * amp[27] + std::complex (0, 1) * - amp[72] - amp[73] + std::complex (0, 1) * amp[75] - amp[76] + - std::complex (0, 1) * amp[77] + std::complex (0, 1) * - amp[78] - amp[79] + std::complex (0, 1) * amp[81] - amp[82] + - std::complex (0, 1) * amp[83] + amp[85] - std::complex - (0, 1) * amp[87] + amp[88] + amp[91] - std::complex (0, 1) * - amp[93] + amp[94] + amp[96] + amp[97] + amp[99] + amp[100] + amp[102] + - amp[103] + amp[105] + amp[106] + amp[496] + amp[502] - - std::complex (0, 1) * amp[505] - amp[506] - std::complex - (0, 1) * amp[507] - amp[508] - std::complex (0, 1) * amp[509] - - std::complex (0, 1) * amp[511] - amp[512] - std::complex - (0, 1) * amp[513] - amp[514] - std::complex (0, 1) * amp[515] - - std::complex (0, 1) * amp[529] - amp[530] - amp[532] - - std::complex (0, 1) * amp[535] - amp[536] - amp[538] + amp[542] - - amp[540] + amp[545] - amp[543] + amp[548] - amp[546] + amp[551] - - amp[549] + std::complex (0, 1) * amp[728] - std::complex - (0, 1) * amp[730] - std::complex (0, 1) * amp[731] - - std::complex (0, 1) * amp[733] + std::complex (0, 1) * - amp[737] - amp[738] - std::complex (0, 1) * amp[739] - - std::complex (0, 1) * amp[740] + std::complex (0, 1) * - amp[746] - std::complex (0, 1) * amp[748] - std::complex - (0, 1) * amp[749] - std::complex (0, 1) * amp[751] + - std::complex (0, 1) * amp[755] - amp[756] - std::complex - (0, 1) * amp[757] - std::complex (0, 1) * amp[758] + amp[761] - - std::complex (0, 1) * amp[762] + amp[763] - std::complex - (0, 1) * amp[765] + amp[766] + amp[769] - std::complex (0, 1) * - amp[770] + amp[771] - std::complex (0, 1) * amp[773] + amp[774] + - std::complex (0, 1) * amp[864] + std::complex (0, 1) * - amp[868] - amp[869] + std::complex (0, 1) * amp[870] + - std::complex (0, 1) * amp[871] + std::complex (0, 1) * - amp[877] + std::complex (0, 1) * amp[879] + std::complex - (0, 1) * amp[880] + std::complex (0, 1) * amp[882] + - std::complex (0, 1) * amp[886] - amp[887] + std::complex - (0, 1) * amp[888] + std::complex (0, 1) * amp[889] + - std::complex (0, 1) * amp[895] + std::complex (0, 1) * - amp[897] + std::complex (0, 1) * amp[898] + std::complex - (0, 1) * amp[902] - std::complex (0, 1) * amp[904] + amp[905] - - std::complex (0, 1) * amp[906] - std::complex (0, 1) * - amp[907] + std::complex (0, 1) * amp[911] - amp[912] - - std::complex (0, 1) * amp[913] - std::complex (0, 1) * - amp[915] - std::complex (0, 1) * amp[916] + std::complex - (0, 1) * amp[920] - std::complex (0, 1) * amp[922] + amp[923] - - std::complex (0, 1) * amp[924] - std::complex (0, 1) * - amp[925] + std::complex (0, 1) * amp[929] - amp[930] - - std::complex (0, 1) * amp[931] - std::complex (0, 1) * - amp[933] - std::complex (0, 1) * amp[934] - std::complex - (0, 1) * amp[989] + std::complex (0, 1) * amp[987] + amp[992] - - amp[990] - std::complex (0, 1) * amp[995] + std::complex - (0, 1) * amp[993] - std::complex (0, 1) * amp[1001] + - std::complex (0, 1) * amp[999] + amp[1004] - amp[1002] - - std::complex (0, 1) * amp[1007] + std::complex (0, 1) * - amp[1005] + amp[1008] + amp[1009] - std::complex (0, 1) * - amp[1011] - std::complex (0, 1) * amp[1012] - - std::complex (0, 1) * amp[1017] - std::complex (0, 1) * - amp[1018] + amp[1020] + amp[1021] - std::complex (0, 1) * - amp[1023] - std::complex (0, 1) * amp[1024] - - std::complex (0, 1) * amp[1029] - std::complex (0, 1) * - amp[1030]; - jamp[4] = +amp[5] + amp[11] + amp[28] + amp[31] + amp[33] + amp[34] + amp[37] - + amp[39] + std::complex (0, 1) * amp[40] + std::complex - (0, 1) * amp[41] + std::complex (0, 1) * amp[42] + - std::complex (0, 1) * amp[43] - std::complex (0, 1) * - amp[60] + amp[61] - std::complex (0, 1) * amp[63] + amp[64] - - std::complex (0, 1) * amp[65] - std::complex (0, 1) * - amp[66] + amp[67] - std::complex (0, 1) * amp[69] + amp[70] - - std::complex (0, 1) * amp[71] + amp[73] + std::complex - (0, 1) * amp[74] + amp[76] + amp[79] + std::complex (0, 1) * - amp[80] + amp[82] - amp[98] - amp[97] - amp[101] - amp[100] - amp[104] - - amp[103] - amp[107] - amp[106] + amp[554] + amp[560] - - std::complex (0, 1) * amp[577] - amp[578] - std::complex - (0, 1) * amp[579] - amp[580] - std::complex (0, 1) * amp[581] - - std::complex (0, 1) * amp[583] - amp[584] - std::complex - (0, 1) * amp[585] - amp[586] - std::complex (0, 1) * amp[587] + - std::complex (0, 1) * amp[589] + amp[590] + amp[592] + - std::complex (0, 1) * amp[595] + amp[596] + amp[598] + amp[600] + - amp[601] + amp[603] + amp[604] + amp[606] + amp[607] + amp[609] + - amp[610] + std::complex (0, 1) * amp[778] - std::complex - (0, 1) * amp[784] + std::complex (0, 1) * amp[782] - - std::complex (0, 1) * amp[786] + std::complex (0, 1) * - amp[787] - amp[788] - std::complex (0, 1) * amp[793] + - std::complex (0, 1) * amp[791] + std::complex (0, 1) * - amp[796] - std::complex (0, 1) * amp[802] + std::complex - (0, 1) * amp[800] - std::complex (0, 1) * amp[804] + - std::complex (0, 1) * amp[805] - amp[806] - std::complex - (0, 1) * amp[811] + std::complex (0, 1) * amp[809] - amp[813] + - std::complex (0, 1) * amp[814] - amp[815] + std::complex - (0, 1) * amp[817] - amp[818] - amp[821] + std::complex (0, 1) * - amp[822] - amp[823] + std::complex (0, 1) * amp[825] - amp[826] - - std::complex (0, 1) * amp[828] - std::complex (0, 1) * - amp[832] + amp[833] - std::complex (0, 1) * amp[834] - - std::complex (0, 1) * amp[835] - std::complex (0, 1) * - amp[841] - std::complex (0, 1) * amp[843] - std::complex - (0, 1) * amp[844] - std::complex (0, 1) * amp[846] - - std::complex (0, 1) * amp[850] + amp[851] - std::complex - (0, 1) * amp[852] - std::complex (0, 1) * amp[853] - - std::complex (0, 1) * amp[859] - std::complex (0, 1) * - amp[861] - std::complex (0, 1) * amp[862] - std::complex - (0, 1) * amp[866] - std::complex (0, 1) * amp[868] + amp[869] + - std::complex (0, 1) * amp[872] - std::complex (0, 1) * - amp[870] - std::complex (0, 1) * amp[875] + amp[876] - - std::complex (0, 1) * amp[877] + std::complex (0, 1) * - amp[881] - std::complex (0, 1) * amp[879] - std::complex - (0, 1) * amp[884] - std::complex (0, 1) * amp[886] + amp[887] + - std::complex (0, 1) * amp[890] - std::complex (0, 1) * - amp[888] - std::complex (0, 1) * amp[893] + amp[894] - - std::complex (0, 1) * amp[895] + std::complex (0, 1) * - amp[899] - std::complex (0, 1) * amp[897] - std::complex - (0, 1) * amp[963] - std::complex (0, 1) * amp[964] + amp[966] + - amp[967] - std::complex (0, 1) * amp[969] - std::complex - (0, 1) * amp[970] - std::complex (0, 1) * amp[975] - - std::complex (0, 1) * amp[976] + amp[978] + amp[979] - - std::complex (0, 1) * amp[981] - std::complex (0, 1) * - amp[982] - amp[1010] - amp[1009] + std::complex (0, 1) * - amp[1013] + std::complex (0, 1) * amp[1012] + - std::complex (0, 1) * amp[1019] + std::complex (0, 1) * - amp[1018] - amp[1022] - amp[1021] + std::complex (0, 1) * - amp[1025] + std::complex (0, 1) * amp[1024] + - std::complex (0, 1) * amp[1031] + std::complex (0, 1) * - amp[1030]; - jamp[5] = +amp[4] + amp[10] + amp[12] + amp[15] + amp[17] + amp[18] + amp[21] - + amp[23] + std::complex (0, 1) * amp[24] + std::complex - (0, 1) * amp[25] + std::complex (0, 1) * amp[26] + - std::complex (0, 1) * amp[27] + std::complex (0, 1) * - amp[60] - amp[61] + std::complex (0, 1) * amp[63] - amp[64] + - std::complex (0, 1) * amp[65] + std::complex (0, 1) * - amp[66] - amp[67] + std::complex (0, 1) * amp[69] - amp[70] + - std::complex (0, 1) * amp[71] - amp[85] + std::complex - (0, 1) * amp[87] - amp[88] - amp[91] + std::complex (0, 1) * - amp[93] - amp[94] + amp[98] - amp[96] + amp[101] - amp[99] + amp[104] - - amp[102] + amp[107] - amp[105] + amp[494] + amp[500] - - std::complex (0, 1) * amp[517] - amp[518] - std::complex - (0, 1) * amp[519] - amp[520] - std::complex (0, 1) * amp[521] - - std::complex (0, 1) * amp[523] - amp[524] - std::complex - (0, 1) * amp[525] - amp[526] - std::complex (0, 1) * amp[527] + - std::complex (0, 1) * amp[529] + amp[530] + amp[532] + - std::complex (0, 1) * amp[535] + amp[536] + amp[538] + amp[540] + - amp[541] + amp[543] + amp[544] + amp[546] + amp[547] + amp[549] + - amp[550] + std::complex (0, 1) * amp[780] - std::complex - (0, 1) * amp[782] - std::complex (0, 1) * amp[783] - - std::complex (0, 1) * amp[785] + std::complex (0, 1) * - amp[789] - amp[790] - std::complex (0, 1) * amp[791] - - std::complex (0, 1) * amp[792] + std::complex (0, 1) * - amp[798] - std::complex (0, 1) * amp[800] - std::complex - (0, 1) * amp[801] - std::complex (0, 1) * amp[803] + - std::complex (0, 1) * amp[807] - amp[808] - std::complex - (0, 1) * amp[809] - std::complex (0, 1) * amp[810] + amp[813] - - std::complex (0, 1) * amp[814] + amp[815] - std::complex - (0, 1) * amp[817] + amp[818] + amp[821] - std::complex (0, 1) * - amp[822] + amp[823] - std::complex (0, 1) * amp[825] + amp[826] + - std::complex (0, 1) * amp[828] + std::complex (0, 1) * - amp[832] - amp[833] + std::complex (0, 1) * amp[834] + - std::complex (0, 1) * amp[835] + std::complex (0, 1) * - amp[841] + std::complex (0, 1) * amp[843] + std::complex - (0, 1) * amp[844] + std::complex (0, 1) * amp[846] + - std::complex (0, 1) * amp[850] - amp[851] + std::complex - (0, 1) * amp[852] + std::complex (0, 1) * amp[853] + - std::complex (0, 1) * amp[859] + std::complex (0, 1) * - amp[861] + std::complex (0, 1) * amp[862] - std::complex - (0, 1) * amp[902] + std::complex (0, 1) * amp[904] - amp[905] + - std::complex (0, 1) * amp[906] + std::complex (0, 1) * - amp[907] - std::complex (0, 1) * amp[911] + amp[912] + - std::complex (0, 1) * amp[913] + std::complex (0, 1) * - amp[915] + std::complex (0, 1) * amp[916] - std::complex - (0, 1) * amp[920] + std::complex (0, 1) * amp[922] - amp[923] + - std::complex (0, 1) * amp[924] + std::complex (0, 1) * - amp[925] - std::complex (0, 1) * amp[929] + amp[930] + - std::complex (0, 1) * amp[931] + std::complex (0, 1) * - amp[933] + std::complex (0, 1) * amp[934] - std::complex - (0, 1) * amp[987] - std::complex (0, 1) * amp[988] + amp[990] + - amp[991] - std::complex (0, 1) * amp[993] - std::complex - (0, 1) * amp[994] - std::complex (0, 1) * amp[999] - - std::complex (0, 1) * amp[1000] + amp[1002] + amp[1003] - - std::complex (0, 1) * amp[1005] - std::complex (0, 1) * - amp[1006] + amp[1010] - amp[1008] - std::complex (0, 1) * - amp[1013] + std::complex (0, 1) * amp[1011] - - std::complex (0, 1) * amp[1019] + std::complex (0, 1) * - amp[1017] + amp[1022] - amp[1020] - std::complex (0, 1) * - amp[1025] + std::complex (0, 1) * amp[1023] - - std::complex (0, 1) * amp[1031] + std::complex (0, 1) * - amp[1029]; - jamp[6] = +amp[109] + amp[115] + amp[153] + amp[154] + amp[156] + amp[159] + - amp[160] + amp[162] - std::complex (0, 1) * amp[164] - - std::complex (0, 1) * amp[165] - std::complex (0, 1) * - amp[166] - std::complex (0, 1) * amp[167] - amp[169] - - std::complex (0, 1) * amp[170] - amp[172] - amp[175] - - std::complex (0, 1) * amp[176] - amp[178] - std::complex - (0, 1) * amp[192] - amp[193] - std::complex (0, 1) * amp[194] - - amp[196] - std::complex (0, 1) * amp[197] - std::complex - (0, 1) * amp[198] - amp[199] - std::complex (0, 1) * amp[200] - - amp[202] - std::complex (0, 1) * amp[203] + amp[206] - amp[204] + - amp[209] - amp[207] + amp[212] - amp[210] + amp[215] - amp[213] + - amp[617] + amp[623] + std::complex (0, 1) * amp[625] + amp[626] + - std::complex (0, 1) * amp[627] + amp[628] + std::complex - (0, 1) * amp[629] + std::complex (0, 1) * amp[631] + amp[632] + - std::complex (0, 1) * amp[633] + amp[634] + std::complex - (0, 1) * amp[635] - std::complex (0, 1) * amp[636] + amp[638] + - amp[640] - std::complex (0, 1) * amp[642] + amp[644] + amp[646] - - amp[662] - amp[661] - amp[665] - amp[664] - amp[668] - amp[667] - - amp[671] - amp[670] - std::complex (0, 1) * amp[674] + - std::complex (0, 1) * amp[680] - std::complex (0, 1) * - amp[678] + std::complex (0, 1) * amp[682] - std::complex - (0, 1) * amp[683] + amp[684] + std::complex (0, 1) * amp[689] - - std::complex (0, 1) * amp[687] - std::complex (0, 1) * - amp[692] + std::complex (0, 1) * amp[698] - std::complex - (0, 1) * amp[696] + std::complex (0, 1) * amp[700] - - std::complex (0, 1) * amp[701] + amp[702] + std::complex - (0, 1) * amp[707] - std::complex (0, 1) * amp[705] + amp[709] - - std::complex (0, 1) * amp[710] + amp[711] - std::complex - (0, 1) * amp[713] + amp[714] + amp[717] - std::complex (0, 1) * - amp[718] + amp[719] - std::complex (0, 1) * amp[721] + amp[722] - - std::complex (0, 1) * amp[726] - std::complex (0, 1) * - amp[728] - amp[729] + std::complex (0, 1) * amp[732] + - std::complex (0, 1) * amp[731] - std::complex (0, 1) * - amp[735] + amp[736] - std::complex (0, 1) * amp[737] + - std::complex (0, 1) * amp[741] + std::complex (0, 1) * - amp[740] - std::complex (0, 1) * amp[744] - std::complex - (0, 1) * amp[746] - amp[747] + std::complex (0, 1) * amp[750] + - std::complex (0, 1) * amp[749] - std::complex (0, 1) * - amp[753] + amp[754] - std::complex (0, 1) * amp[755] + - std::complex (0, 1) * amp[759] + std::complex (0, 1) * - amp[758] - std::complex (0, 1) * amp[901] - std::complex - (0, 1) * amp[902] - amp[903] + std::complex (0, 1) * amp[908] + - std::complex (0, 1) * amp[907] - std::complex (0, 1) * - amp[911] + std::complex (0, 1) * amp[917] + std::complex - (0, 1) * amp[916] - std::complex (0, 1) * amp[919] - - std::complex (0, 1) * amp[920] - amp[921] + std::complex - (0, 1) * amp[926] + std::complex (0, 1) * amp[925] - - std::complex (0, 1) * amp[929] + std::complex (0, 1) * - amp[935] + std::complex (0, 1) * amp[934] + std::complex - (0, 1) * amp[941] + std::complex (0, 1) * amp[940] - amp[944] - - amp[943] + std::complex (0, 1) * amp[947] + std::complex - (0, 1) * amp[946] + std::complex (0, 1) * amp[953] + - std::complex (0, 1) * amp[952] - amp[956] - amp[955] + - std::complex (0, 1) * amp[959] + std::complex (0, 1) * - amp[958] + amp[986] - amp[984] + std::complex (0, 1) * amp[989] - - std::complex (0, 1) * amp[987] + std::complex (0, 1) * - amp[995] - std::complex (0, 1) * amp[993] + amp[998] - amp[996] + - std::complex (0, 1) * amp[1001] - std::complex (0, 1) * - amp[999] + std::complex (0, 1) * amp[1007] - std::complex - (0, 1) * amp[1005]; - jamp[7] = +amp[108] + amp[114] + amp[137] + amp[138] + amp[140] + amp[143] + - amp[144] + amp[146] - std::complex (0, 1) * amp[148] - - std::complex (0, 1) * amp[149] - std::complex (0, 1) * - amp[150] - std::complex (0, 1) * amp[151] - amp[181] - - std::complex (0, 1) * amp[182] - amp[184] - amp[187] - - std::complex (0, 1) * amp[188] - amp[190] + std::complex - (0, 1) * amp[192] + amp[193] + std::complex (0, 1) * amp[194] + - amp[196] + std::complex (0, 1) * amp[197] + std::complex - (0, 1) * amp[198] + amp[199] + std::complex (0, 1) * amp[200] + - amp[202] + std::complex (0, 1) * amp[203] + amp[204] + amp[205] + - amp[207] + amp[208] + amp[210] + amp[211] + amp[213] + amp[214] + - amp[557] + amp[563] + std::complex (0, 1) * amp[565] + amp[566] + - std::complex (0, 1) * amp[567] + amp[568] + std::complex - (0, 1) * amp[569] + std::complex (0, 1) * amp[571] + amp[572] + - std::complex (0, 1) * amp[573] + amp[574] + std::complex - (0, 1) * amp[575] - std::complex (0, 1) * amp[576] + amp[578] + - amp[580] - std::complex (0, 1) * amp[582] + amp[584] + amp[586] - - amp[602] - amp[601] - amp[605] - amp[604] - amp[608] - amp[607] - - amp[611] - amp[610] - std::complex (0, 1) * amp[676] + - std::complex (0, 1) * amp[678] + std::complex (0, 1) * - amp[679] + std::complex (0, 1) * amp[681] - std::complex - (0, 1) * amp[685] + amp[686] + std::complex (0, 1) * amp[687] + - std::complex (0, 1) * amp[688] - std::complex (0, 1) * - amp[694] + std::complex (0, 1) * amp[696] + std::complex - (0, 1) * amp[697] + std::complex (0, 1) * amp[699] - - std::complex (0, 1) * amp[703] + amp[704] + std::complex - (0, 1) * amp[705] + std::complex (0, 1) * amp[706] - amp[709] + - std::complex (0, 1) * amp[710] - amp[711] + std::complex - (0, 1) * amp[713] - amp[714] - amp[717] + std::complex (0, 1) * - amp[718] - amp[719] + std::complex (0, 1) * amp[721] - amp[722] - - std::complex (0, 1) * amp[778] - std::complex (0, 1) * - amp[780] - amp[781] + std::complex (0, 1) * amp[784] + - std::complex (0, 1) * amp[783] - std::complex (0, 1) * - amp[787] + amp[788] - std::complex (0, 1) * amp[789] + - std::complex (0, 1) * amp[793] + std::complex (0, 1) * - amp[792] - std::complex (0, 1) * amp[796] - std::complex - (0, 1) * amp[798] - amp[799] + std::complex (0, 1) * amp[802] + - std::complex (0, 1) * amp[801] - std::complex (0, 1) * - amp[805] + amp[806] - std::complex (0, 1) * amp[807] + - std::complex (0, 1) * amp[811] + std::complex (0, 1) * - amp[810] + std::complex (0, 1) * amp[901] + std::complex - (0, 1) * amp[902] + amp[903] - std::complex (0, 1) * amp[908] - - std::complex (0, 1) * amp[907] + std::complex (0, 1) * - amp[911] - std::complex (0, 1) * amp[917] - std::complex - (0, 1) * amp[916] + std::complex (0, 1) * amp[919] + - std::complex (0, 1) * amp[920] + amp[921] - std::complex - (0, 1) * amp[926] - std::complex (0, 1) * amp[925] + - std::complex (0, 1) * amp[929] - std::complex (0, 1) * - amp[935] - std::complex (0, 1) * amp[934] + std::complex - (0, 1) * amp[965] + std::complex (0, 1) * amp[964] - amp[968] - - amp[967] + std::complex (0, 1) * amp[971] + std::complex - (0, 1) * amp[970] + std::complex (0, 1) * amp[977] + - std::complex (0, 1) * amp[976] - amp[980] - amp[979] + - std::complex (0, 1) * amp[983] + std::complex (0, 1) * - amp[982] + amp[984] + amp[985] + std::complex (0, 1) * amp[987] + - std::complex (0, 1) * amp[988] + std::complex (0, 1) * - amp[993] + std::complex (0, 1) * amp[994] + amp[996] + amp[997] + - std::complex (0, 1) * amp[999] + std::complex (0, 1) * - amp[1000] + std::complex (0, 1) * amp[1005] + - std::complex (0, 1) * amp[1006]; - jamp[8] = +amp[111] + amp[117] + amp[152] + amp[155] + amp[157] + amp[158] + - amp[161] + amp[163] + std::complex (0, 1) * amp[164] + - std::complex (0, 1) * amp[165] + std::complex (0, 1) * - amp[166] + std::complex (0, 1) * amp[167] + amp[169] + - std::complex (0, 1) * amp[170] + amp[172] + amp[175] + - std::complex (0, 1) * amp[176] + amp[178] - std::complex - (0, 1) * amp[180] + amp[181] - std::complex (0, 1) * amp[183] + - amp[184] - std::complex (0, 1) * amp[185] - std::complex - (0, 1) * amp[186] + amp[187] - std::complex (0, 1) * amp[189] + - amp[190] - std::complex (0, 1) * amp[191] - amp[206] - amp[205] - - amp[209] - amp[208] - amp[212] - amp[211] - amp[215] - amp[214] + - amp[612] + amp[618] + std::complex (0, 1) * amp[636] - amp[638] - - amp[640] + std::complex (0, 1) * amp[642] - amp[644] - amp[646] - - std::complex (0, 1) * amp[648] + amp[650] - std::complex - (0, 1) * amp[651] + amp[652] - std::complex (0, 1) * amp[653] - - std::complex (0, 1) * amp[654] + amp[656] - std::complex - (0, 1) * amp[657] + amp[658] - std::complex (0, 1) * amp[659] + - amp[660] + amp[661] + amp[663] + amp[664] + amp[666] + amp[667] + - amp[669] + amp[670] + std::complex (0, 1) * amp[726] + - std::complex (0, 1) * amp[728] + amp[729] - std::complex - (0, 1) * amp[732] - std::complex (0, 1) * amp[731] + - std::complex (0, 1) * amp[735] - amp[736] + std::complex - (0, 1) * amp[737] - std::complex (0, 1) * amp[741] - - std::complex (0, 1) * amp[740] + std::complex (0, 1) * - amp[744] + std::complex (0, 1) * amp[746] + amp[747] - - std::complex (0, 1) * amp[750] - std::complex (0, 1) * - amp[749] + std::complex (0, 1) * amp[753] - amp[754] + - std::complex (0, 1) * amp[755] - std::complex (0, 1) * - amp[759] - std::complex (0, 1) * amp[758] - std::complex - (0, 1) * amp[776] + std::complex (0, 1) * amp[780] + amp[781] - - std::complex (0, 1) * amp[782] - std::complex (0, 1) * - amp[783] + std::complex (0, 1) * amp[789] - std::complex - (0, 1) * amp[791] - std::complex (0, 1) * amp[792] - - std::complex (0, 1) * amp[794] + std::complex (0, 1) * - amp[798] + amp[799] - std::complex (0, 1) * amp[800] - - std::complex (0, 1) * amp[801] + std::complex (0, 1) * - amp[807] - std::complex (0, 1) * amp[809] - std::complex - (0, 1) * amp[810] - amp[812] - std::complex (0, 1) * amp[814] - - amp[816] - std::complex (0, 1) * amp[817] - amp[819] - amp[820] - - std::complex (0, 1) * amp[822] - amp[824] - std::complex - (0, 1) * amp[825] - amp[827] - std::complex (0, 1) * amp[830] + - std::complex (0, 1) * amp[836] + std::complex (0, 1) * - amp[835] - std::complex (0, 1) * amp[838] - std::complex - (0, 1) * amp[839] + amp[840] + std::complex (0, 1) * amp[845] + - std::complex (0, 1) * amp[844] - std::complex (0, 1) * - amp[848] + std::complex (0, 1) * amp[854] + std::complex - (0, 1) * amp[853] - std::complex (0, 1) * amp[856] - - std::complex (0, 1) * amp[857] + amp[858] + std::complex - (0, 1) * amp[863] + std::complex (0, 1) * amp[862] - - std::complex (0, 1) * amp[939] - std::complex (0, 1) * - amp[940] + amp[942] + amp[943] - std::complex (0, 1) * amp[945] - - std::complex (0, 1) * amp[946] - std::complex (0, 1) * - amp[951] - std::complex (0, 1) * amp[952] + amp[954] + amp[955] - - std::complex (0, 1) * amp[957] - std::complex (0, 1) * - amp[958] - amp[986] - amp[985] - std::complex (0, 1) * amp[989] - - std::complex (0, 1) * amp[988] - std::complex (0, 1) * - amp[995] - std::complex (0, 1) * amp[994] - amp[998] - amp[997] - - std::complex (0, 1) * amp[1001] - std::complex (0, 1) * - amp[1000] - std::complex (0, 1) * amp[1007] - - std::complex (0, 1) * amp[1006]; - jamp[9] = +amp[110] + amp[116] + amp[121] + amp[122] + amp[124] + amp[127] + - amp[128] + amp[130] - std::complex (0, 1) * amp[132] - - std::complex (0, 1) * amp[133] - std::complex (0, 1) * - amp[134] - std::complex (0, 1) * amp[135] + std::complex - (0, 1) * amp[180] - amp[181] + std::complex (0, 1) * amp[183] - - amp[184] + std::complex (0, 1) * amp[185] + std::complex - (0, 1) * amp[186] - amp[187] + std::complex (0, 1) * amp[189] - - amp[190] + std::complex (0, 1) * amp[191] + amp[193] - - std::complex (0, 1) * amp[195] + amp[196] + amp[199] - - std::complex (0, 1) * amp[201] + amp[202] + amp[204] + amp[205] + - amp[207] + amp[208] + amp[210] + amp[211] + amp[213] + amp[214] + - amp[436] + amp[442] - std::complex (0, 1) * amp[445] - amp[446] - - std::complex (0, 1) * amp[447] - amp[448] - std::complex - (0, 1) * amp[449] - std::complex (0, 1) * amp[451] - amp[452] - - std::complex (0, 1) * amp[453] - amp[454] - std::complex - (0, 1) * amp[455] - std::complex (0, 1) * amp[469] - amp[470] - - amp[472] - std::complex (0, 1) * amp[475] - amp[476] - amp[478] + - amp[482] - amp[480] + amp[485] - amp[483] + amp[488] - amp[486] + - amp[491] - amp[489] + std::complex (0, 1) * amp[776] - - std::complex (0, 1) * amp[780] - amp[781] + std::complex - (0, 1) * amp[782] + std::complex (0, 1) * amp[783] - - std::complex (0, 1) * amp[789] + std::complex (0, 1) * - amp[791] + std::complex (0, 1) * amp[792] + std::complex - (0, 1) * amp[794] - std::complex (0, 1) * amp[798] - amp[799] + - std::complex (0, 1) * amp[800] + std::complex (0, 1) * - amp[801] - std::complex (0, 1) * amp[807] + std::complex - (0, 1) * amp[809] + std::complex (0, 1) * amp[810] + amp[812] + - std::complex (0, 1) * amp[814] + amp[816] + std::complex - (0, 1) * amp[817] + amp[819] + amp[820] + std::complex (0, 1) * - amp[822] + amp[824] + std::complex (0, 1) * amp[825] + amp[827] - - std::complex (0, 1) * amp[832] - std::complex (0, 1) * - amp[834] - std::complex (0, 1) * amp[835] - std::complex - (0, 1) * amp[837] - std::complex (0, 1) * amp[841] - amp[842] - - std::complex (0, 1) * amp[843] - std::complex (0, 1) * - amp[844] - std::complex (0, 1) * amp[850] - std::complex - (0, 1) * amp[852] - std::complex (0, 1) * amp[853] - - std::complex (0, 1) * amp[855] - std::complex (0, 1) * - amp[859] - amp[860] - std::complex (0, 1) * amp[861] - - std::complex (0, 1) * amp[862] + std::complex (0, 1) * - amp[902] + amp[903] - std::complex (0, 1) * amp[904] - - std::complex (0, 1) * amp[906] - std::complex (0, 1) * - amp[907] + std::complex (0, 1) * amp[911] - std::complex - (0, 1) * amp[913] - amp[914] - std::complex (0, 1) * amp[915] - - std::complex (0, 1) * amp[916] + std::complex (0, 1) * - amp[920] + amp[921] - std::complex (0, 1) * amp[922] - - std::complex (0, 1) * amp[924] - std::complex (0, 1) * - amp[925] + std::complex (0, 1) * amp[929] - std::complex - (0, 1) * amp[931] - amp[932] - std::complex (0, 1) * amp[933] - - std::complex (0, 1) * amp[934] + amp[984] + amp[985] + - std::complex (0, 1) * amp[987] + std::complex (0, 1) * - amp[988] + std::complex (0, 1) * amp[993] + std::complex - (0, 1) * amp[994] + amp[996] + amp[997] + std::complex (0, 1) * - amp[999] + std::complex (0, 1) * amp[1000] + std::complex - (0, 1) * amp[1005] + std::complex (0, 1) * amp[1006] + - std::complex (0, 1) * amp[1013] - std::complex (0, 1) * - amp[1011] + amp[1016] - amp[1014] + std::complex (0, 1) * - amp[1019] - std::complex (0, 1) * amp[1017] + - std::complex (0, 1) * amp[1025] - std::complex (0, 1) * - amp[1023] + amp[1028] - amp[1026] + std::complex (0, 1) * - amp[1031] - std::complex (0, 1) * amp[1029]; - jamp[10] = +amp[113] + amp[119] + amp[136] + amp[139] + amp[141] + amp[142] + - amp[145] + amp[147] + std::complex (0, 1) * amp[148] + - std::complex (0, 1) * amp[149] + std::complex (0, 1) * - amp[150] + std::complex (0, 1) * amp[151] - std::complex - (0, 1) * amp[168] + amp[169] - std::complex (0, 1) * amp[171] + - amp[172] - std::complex (0, 1) * amp[173] - std::complex - (0, 1) * amp[174] + amp[175] - std::complex (0, 1) * amp[177] + - amp[178] - std::complex (0, 1) * amp[179] + amp[181] + - std::complex (0, 1) * amp[182] + amp[184] + amp[187] + - std::complex (0, 1) * amp[188] + amp[190] - amp[206] - amp[205] - - amp[209] - amp[208] - amp[212] - amp[211] - amp[215] - amp[214] + - amp[552] + amp[558] + std::complex (0, 1) * amp[576] - amp[578] - - amp[580] + std::complex (0, 1) * amp[582] - amp[584] - amp[586] - - std::complex (0, 1) * amp[588] + amp[590] - std::complex - (0, 1) * amp[591] + amp[592] - std::complex (0, 1) * amp[593] - - std::complex (0, 1) * amp[594] + amp[596] - std::complex - (0, 1) * amp[597] + amp[598] - std::complex (0, 1) * amp[599] + - amp[600] + amp[601] + amp[603] + amp[604] + amp[606] + amp[607] + - amp[609] + amp[610] - std::complex (0, 1) * amp[724] + - std::complex (0, 1) * amp[728] + amp[729] - std::complex - (0, 1) * amp[730] - std::complex (0, 1) * amp[731] + - std::complex (0, 1) * amp[737] - std::complex (0, 1) * - amp[739] - std::complex (0, 1) * amp[740] - std::complex - (0, 1) * amp[742] + std::complex (0, 1) * amp[746] + amp[747] - - std::complex (0, 1) * amp[748] - std::complex (0, 1) * - amp[749] + std::complex (0, 1) * amp[755] - std::complex - (0, 1) * amp[757] - std::complex (0, 1) * amp[758] - amp[760] - - std::complex (0, 1) * amp[762] - amp[764] - std::complex - (0, 1) * amp[765] - amp[767] - amp[768] - std::complex (0, 1) * - amp[770] - amp[772] - std::complex (0, 1) * amp[773] - amp[775] + - std::complex (0, 1) * amp[778] + std::complex (0, 1) * - amp[780] + amp[781] - std::complex (0, 1) * amp[784] - - std::complex (0, 1) * amp[783] + std::complex (0, 1) * - amp[787] - amp[788] + std::complex (0, 1) * amp[789] - - std::complex (0, 1) * amp[793] - std::complex (0, 1) * - amp[792] + std::complex (0, 1) * amp[796] + std::complex - (0, 1) * amp[798] + amp[799] - std::complex (0, 1) * amp[802] - - std::complex (0, 1) * amp[801] + std::complex (0, 1) * - amp[805] - amp[806] + std::complex (0, 1) * amp[807] - - std::complex (0, 1) * amp[811] - std::complex (0, 1) * - amp[810] - std::complex (0, 1) * amp[866] + std::complex - (0, 1) * amp[872] + std::complex (0, 1) * amp[871] - - std::complex (0, 1) * amp[874] - std::complex (0, 1) * - amp[875] + amp[876] + std::complex (0, 1) * amp[881] + - std::complex (0, 1) * amp[880] - std::complex (0, 1) * - amp[884] + std::complex (0, 1) * amp[890] + std::complex - (0, 1) * amp[889] - std::complex (0, 1) * amp[892] - - std::complex (0, 1) * amp[893] + amp[894] + std::complex - (0, 1) * amp[899] + std::complex (0, 1) * amp[898] - - std::complex (0, 1) * amp[963] - std::complex (0, 1) * - amp[964] + amp[966] + amp[967] - std::complex (0, 1) * amp[969] - - std::complex (0, 1) * amp[970] - std::complex (0, 1) * - amp[975] - std::complex (0, 1) * amp[976] + amp[978] + amp[979] - - std::complex (0, 1) * amp[981] - std::complex (0, 1) * - amp[982] - amp[986] - amp[985] - std::complex (0, 1) * amp[989] - - std::complex (0, 1) * amp[988] - std::complex (0, 1) * - amp[995] - std::complex (0, 1) * amp[994] - amp[998] - amp[997] - - std::complex (0, 1) * amp[1001] - std::complex (0, 1) * - amp[1000] - std::complex (0, 1) * amp[1007] - - std::complex (0, 1) * amp[1006]; - jamp[11] = +amp[112] + amp[118] + amp[120] + amp[123] + amp[125] + amp[126] + - amp[129] + amp[131] + std::complex (0, 1) * amp[132] + - std::complex (0, 1) * amp[133] + std::complex (0, 1) * - amp[134] + std::complex (0, 1) * amp[135] + std::complex - (0, 1) * amp[168] - amp[169] + std::complex (0, 1) * amp[171] - - amp[172] + std::complex (0, 1) * amp[173] + std::complex - (0, 1) * amp[174] - amp[175] + std::complex (0, 1) * amp[177] - - amp[178] + std::complex (0, 1) * amp[179] - amp[193] + - std::complex (0, 1) * amp[195] - amp[196] - amp[199] + - std::complex (0, 1) * amp[201] - amp[202] + amp[206] - amp[204] + - amp[209] - amp[207] + amp[212] - amp[210] + amp[215] - amp[213] + - amp[434] + amp[440] - std::complex (0, 1) * amp[457] - amp[458] - - std::complex (0, 1) * amp[459] - amp[460] - std::complex - (0, 1) * amp[461] - std::complex (0, 1) * amp[463] - amp[464] - - std::complex (0, 1) * amp[465] - amp[466] - std::complex - (0, 1) * amp[467] + std::complex (0, 1) * amp[469] + amp[470] + - amp[472] + std::complex (0, 1) * amp[475] + amp[476] + amp[478] + - amp[480] + amp[481] + amp[483] + amp[484] + amp[486] + amp[487] + - amp[489] + amp[490] + std::complex (0, 1) * amp[724] - - std::complex (0, 1) * amp[728] - amp[729] + std::complex - (0, 1) * amp[730] + std::complex (0, 1) * amp[731] - - std::complex (0, 1) * amp[737] + std::complex (0, 1) * - amp[739] + std::complex (0, 1) * amp[740] + std::complex - (0, 1) * amp[742] - std::complex (0, 1) * amp[746] - amp[747] + - std::complex (0, 1) * amp[748] + std::complex (0, 1) * - amp[749] - std::complex (0, 1) * amp[755] + std::complex - (0, 1) * amp[757] + std::complex (0, 1) * amp[758] + amp[760] + - std::complex (0, 1) * amp[762] + amp[764] + std::complex - (0, 1) * amp[765] + amp[767] + amp[768] + std::complex (0, 1) * - amp[770] + amp[772] + std::complex (0, 1) * amp[773] + amp[775] - - std::complex (0, 1) * amp[868] - std::complex (0, 1) * - amp[870] - std::complex (0, 1) * amp[871] - std::complex - (0, 1) * amp[873] - std::complex (0, 1) * amp[877] - amp[878] - - std::complex (0, 1) * amp[879] - std::complex (0, 1) * - amp[880] - std::complex (0, 1) * amp[886] - std::complex - (0, 1) * amp[888] - std::complex (0, 1) * amp[889] - - std::complex (0, 1) * amp[891] - std::complex (0, 1) * - amp[895] - amp[896] - std::complex (0, 1) * amp[897] - - std::complex (0, 1) * amp[898] - std::complex (0, 1) * - amp[902] - amp[903] + std::complex (0, 1) * amp[904] + - std::complex (0, 1) * amp[906] + std::complex (0, 1) * - amp[907] - std::complex (0, 1) * amp[911] + std::complex - (0, 1) * amp[913] + amp[914] + std::complex (0, 1) * amp[915] + - std::complex (0, 1) * amp[916] - std::complex (0, 1) * - amp[920] - amp[921] + std::complex (0, 1) * amp[922] + - std::complex (0, 1) * amp[924] + std::complex (0, 1) * - amp[925] - std::complex (0, 1) * amp[929] + std::complex - (0, 1) * amp[931] + amp[932] + std::complex (0, 1) * amp[933] + - std::complex (0, 1) * amp[934] + amp[986] - amp[984] + - std::complex (0, 1) * amp[989] - std::complex (0, 1) * - amp[987] + std::complex (0, 1) * amp[995] - std::complex - (0, 1) * amp[993] + amp[998] - amp[996] + std::complex (0, 1) * - amp[1001] - std::complex (0, 1) * amp[999] + std::complex - (0, 1) * amp[1007] - std::complex (0, 1) * amp[1005] + - std::complex (0, 1) * amp[1011] + std::complex (0, 1) * - amp[1012] + amp[1014] + amp[1015] + std::complex (0, 1) * - amp[1017] + std::complex (0, 1) * amp[1018] + - std::complex (0, 1) * amp[1023] + std::complex (0, 1) * - amp[1024] + amp[1026] + amp[1027] + std::complex (0, 1) * - amp[1029] + std::complex (0, 1) * amp[1030]; - jamp[12] = +amp[217] + amp[223] + amp[261] + amp[262] + amp[264] + amp[267] + - amp[268] + amp[270] - std::complex (0, 1) * amp[272] - - std::complex (0, 1) * amp[273] - std::complex (0, 1) * - amp[274] - std::complex (0, 1) * amp[275] - amp[277] - - std::complex (0, 1) * amp[278] - amp[280] - amp[283] - - std::complex (0, 1) * amp[284] - amp[286] - std::complex - (0, 1) * amp[300] - amp[301] - std::complex (0, 1) * amp[302] - - amp[304] - std::complex (0, 1) * amp[305] - std::complex - (0, 1) * amp[306] - amp[307] - std::complex (0, 1) * amp[308] - - amp[310] - std::complex (0, 1) * amp[311] + amp[314] - amp[312] + - amp[317] - amp[315] + amp[320] - amp[318] + amp[323] - amp[321] + - amp[615] + amp[621] - std::complex (0, 1) * amp[624] + amp[626] + - amp[628] - std::complex (0, 1) * amp[630] + amp[632] + amp[634] + - std::complex (0, 1) * amp[637] + amp[638] + std::complex - (0, 1) * amp[639] + amp[640] + std::complex (0, 1) * amp[641] + - std::complex (0, 1) * amp[643] + amp[644] + std::complex - (0, 1) * amp[645] + amp[646] + std::complex (0, 1) * amp[647] - - amp[662] - amp[661] - amp[665] - amp[664] - amp[668] - amp[667] - - amp[671] - amp[670] - std::complex (0, 1) * amp[674] - - std::complex (0, 1) * amp[676] - amp[677] + std::complex - (0, 1) * amp[680] + std::complex (0, 1) * amp[679] - - std::complex (0, 1) * amp[683] + amp[684] - std::complex - (0, 1) * amp[685] + std::complex (0, 1) * amp[689] + - std::complex (0, 1) * amp[688] - std::complex (0, 1) * - amp[692] - std::complex (0, 1) * amp[694] - amp[695] + - std::complex (0, 1) * amp[698] + std::complex (0, 1) * - amp[697] - std::complex (0, 1) * amp[701] + amp[702] - - std::complex (0, 1) * amp[703] + std::complex (0, 1) * - amp[707] + std::complex (0, 1) * amp[706] - std::complex - (0, 1) * amp[726] + std::complex (0, 1) * amp[732] - - std::complex (0, 1) * amp[730] + std::complex (0, 1) * - amp[734] - std::complex (0, 1) * amp[735] + amp[736] + - std::complex (0, 1) * amp[741] - std::complex (0, 1) * - amp[739] - std::complex (0, 1) * amp[744] + std::complex - (0, 1) * amp[750] - std::complex (0, 1) * amp[748] + - std::complex (0, 1) * amp[752] - std::complex (0, 1) * - amp[753] + amp[754] + std::complex (0, 1) * amp[759] - - std::complex (0, 1) * amp[757] + amp[761] - std::complex - (0, 1) * amp[762] + amp[763] - std::complex (0, 1) * amp[765] + - amp[766] + amp[769] - std::complex (0, 1) * amp[770] + amp[771] - - std::complex (0, 1) * amp[773] + amp[774] - std::complex - (0, 1) * amp[865] - std::complex (0, 1) * amp[866] - amp[867] + - std::complex (0, 1) * amp[872] + std::complex (0, 1) * - amp[871] - std::complex (0, 1) * amp[875] + std::complex - (0, 1) * amp[881] + std::complex (0, 1) * amp[880] - - std::complex (0, 1) * amp[883] - std::complex (0, 1) * - amp[884] - amp[885] + std::complex (0, 1) * amp[890] + - std::complex (0, 1) * amp[889] - std::complex (0, 1) * - amp[893] + std::complex (0, 1) * amp[899] + std::complex - (0, 1) * amp[898] + std::complex (0, 1) * amp[941] + - std::complex (0, 1) * amp[940] - amp[944] - amp[943] + - std::complex (0, 1) * amp[947] + std::complex (0, 1) * - amp[946] + std::complex (0, 1) * amp[953] + std::complex - (0, 1) * amp[952] - amp[956] - amp[955] + std::complex (0, 1) * - amp[959] + std::complex (0, 1) * amp[958] + amp[962] - amp[960] + - std::complex (0, 1) * amp[965] - std::complex (0, 1) * - amp[963] + std::complex (0, 1) * amp[971] - std::complex - (0, 1) * amp[969] + amp[974] - amp[972] + std::complex (0, 1) * - amp[977] - std::complex (0, 1) * amp[975] + std::complex - (0, 1) * amp[983] - std::complex (0, 1) * amp[981]; - jamp[13] = +amp[216] + amp[222] + amp[245] + amp[246] + amp[248] + amp[251] + - amp[252] + amp[254] - std::complex (0, 1) * amp[256] - - std::complex (0, 1) * amp[257] - std::complex (0, 1) * - amp[258] - std::complex (0, 1) * amp[259] - amp[289] - - std::complex (0, 1) * amp[290] - amp[292] - amp[295] - - std::complex (0, 1) * amp[296] - amp[298] + std::complex - (0, 1) * amp[300] + amp[301] + std::complex (0, 1) * amp[302] + - amp[304] + std::complex (0, 1) * amp[305] + std::complex - (0, 1) * amp[306] + amp[307] + std::complex (0, 1) * amp[308] + - amp[310] + std::complex (0, 1) * amp[311] + amp[312] + amp[313] + - amp[315] + amp[316] + amp[318] + amp[319] + amp[321] + amp[322] + - amp[497] + amp[503] + std::complex (0, 1) * amp[505] + amp[506] + - std::complex (0, 1) * amp[507] + amp[508] + std::complex - (0, 1) * amp[509] + std::complex (0, 1) * amp[511] + amp[512] + - std::complex (0, 1) * amp[513] + amp[514] + std::complex - (0, 1) * amp[515] - std::complex (0, 1) * amp[516] + amp[518] + - amp[520] - std::complex (0, 1) * amp[522] + amp[524] + amp[526] - - amp[542] - amp[541] - amp[545] - amp[544] - amp[548] - amp[547] - - amp[551] - amp[550] - std::complex (0, 1) * amp[728] + - std::complex (0, 1) * amp[730] + std::complex (0, 1) * - amp[731] + std::complex (0, 1) * amp[733] - std::complex - (0, 1) * amp[737] + amp[738] + std::complex (0, 1) * amp[739] + - std::complex (0, 1) * amp[740] - std::complex (0, 1) * - amp[746] + std::complex (0, 1) * amp[748] + std::complex - (0, 1) * amp[749] + std::complex (0, 1) * amp[751] - - std::complex (0, 1) * amp[755] + amp[756] + std::complex - (0, 1) * amp[757] + std::complex (0, 1) * amp[758] - amp[761] + - std::complex (0, 1) * amp[762] - amp[763] + std::complex - (0, 1) * amp[765] - amp[766] - amp[769] + std::complex (0, 1) * - amp[770] - amp[771] + std::complex (0, 1) * amp[773] - amp[774] - - std::complex (0, 1) * amp[778] - amp[779] - std::complex - (0, 1) * amp[780] + std::complex (0, 1) * amp[784] + - std::complex (0, 1) * amp[783] - std::complex (0, 1) * - amp[787] - std::complex (0, 1) * amp[789] + amp[790] + - std::complex (0, 1) * amp[793] + std::complex (0, 1) * - amp[792] - std::complex (0, 1) * amp[796] - amp[797] - - std::complex (0, 1) * amp[798] + std::complex (0, 1) * - amp[802] + std::complex (0, 1) * amp[801] - std::complex - (0, 1) * amp[805] - std::complex (0, 1) * amp[807] + amp[808] + - std::complex (0, 1) * amp[811] + std::complex (0, 1) * - amp[810] + std::complex (0, 1) * amp[865] + std::complex - (0, 1) * amp[866] + amp[867] - std::complex (0, 1) * amp[872] - - std::complex (0, 1) * amp[871] + std::complex (0, 1) * - amp[875] - std::complex (0, 1) * amp[881] - std::complex - (0, 1) * amp[880] + std::complex (0, 1) * amp[883] + - std::complex (0, 1) * amp[884] + amp[885] - std::complex - (0, 1) * amp[890] - std::complex (0, 1) * amp[889] + - std::complex (0, 1) * amp[893] - std::complex (0, 1) * - amp[899] - std::complex (0, 1) * amp[898] + amp[960] + amp[961] + - std::complex (0, 1) * amp[963] + std::complex (0, 1) * - amp[964] + std::complex (0, 1) * amp[969] + std::complex - (0, 1) * amp[970] + amp[972] + amp[973] + std::complex (0, 1) * - amp[975] + std::complex (0, 1) * amp[976] + std::complex - (0, 1) * amp[981] + std::complex (0, 1) * amp[982] + - std::complex (0, 1) * amp[989] + std::complex (0, 1) * - amp[988] - amp[992] - amp[991] + std::complex (0, 1) * amp[995] + - std::complex (0, 1) * amp[994] + std::complex (0, 1) * - amp[1001] + std::complex (0, 1) * amp[1000] - amp[1004] - - amp[1003] + std::complex (0, 1) * amp[1007] + - std::complex (0, 1) * amp[1006]; - jamp[14] = +amp[219] + amp[225] + amp[260] + amp[263] + amp[265] + amp[266] + - amp[269] + amp[271] + std::complex (0, 1) * amp[272] + - std::complex (0, 1) * amp[273] + std::complex (0, 1) * - amp[274] + std::complex (0, 1) * amp[275] + amp[277] + - std::complex (0, 1) * amp[278] + amp[280] + amp[283] + - std::complex (0, 1) * amp[284] + amp[286] - std::complex - (0, 1) * amp[288] + amp[289] - std::complex (0, 1) * amp[291] + - amp[292] - std::complex (0, 1) * amp[293] - std::complex - (0, 1) * amp[294] + amp[295] - std::complex (0, 1) * amp[297] + - amp[298] - std::complex (0, 1) * amp[299] - amp[314] - amp[313] - - amp[317] - amp[316] - amp[320] - amp[319] - amp[323] - amp[322] + - amp[613] + amp[619] + std::complex (0, 1) * amp[624] - amp[626] - - amp[628] + std::complex (0, 1) * amp[630] - amp[632] - amp[634] + - std::complex (0, 1) * amp[648] - amp[650] + std::complex - (0, 1) * amp[651] - amp[652] + std::complex (0, 1) * amp[653] + - std::complex (0, 1) * amp[654] - amp[656] + std::complex - (0, 1) * amp[657] - amp[658] + std::complex (0, 1) * amp[659] + - amp[662] - amp[660] + amp[665] - amp[663] + amp[668] - amp[666] + - amp[671] - amp[669] + std::complex (0, 1) * amp[674] + - std::complex (0, 1) * amp[676] + amp[677] - std::complex - (0, 1) * amp[680] - std::complex (0, 1) * amp[679] + - std::complex (0, 1) * amp[683] - amp[684] + std::complex - (0, 1) * amp[685] - std::complex (0, 1) * amp[689] - - std::complex (0, 1) * amp[688] + std::complex (0, 1) * - amp[692] + std::complex (0, 1) * amp[694] + amp[695] - - std::complex (0, 1) * amp[698] - std::complex (0, 1) * - amp[697] + std::complex (0, 1) * amp[701] - amp[702] + - std::complex (0, 1) * amp[703] - std::complex (0, 1) * - amp[707] - std::complex (0, 1) * amp[706] - std::complex - (0, 1) * amp[777] + std::complex (0, 1) * amp[778] + amp[779] - - std::complex (0, 1) * amp[784] + std::complex (0, 1) * - amp[782] + std::complex (0, 1) * amp[787] - std::complex - (0, 1) * amp[793] + std::complex (0, 1) * amp[791] - - std::complex (0, 1) * amp[795] + std::complex (0, 1) * - amp[796] + amp[797] - std::complex (0, 1) * amp[802] + - std::complex (0, 1) * amp[800] + std::complex (0, 1) * - amp[805] - std::complex (0, 1) * amp[811] + std::complex - (0, 1) * amp[809] + amp[812] + std::complex (0, 1) * amp[814] + - amp[816] + std::complex (0, 1) * amp[817] + amp[819] + amp[820] + - std::complex (0, 1) * amp[822] + amp[824] + std::complex - (0, 1) * amp[825] + amp[827] + std::complex (0, 1) * amp[830] - - std::complex (0, 1) * amp[836] - std::complex (0, 1) * - amp[835] + std::complex (0, 1) * amp[838] + std::complex - (0, 1) * amp[839] - amp[840] - std::complex (0, 1) * amp[845] - - std::complex (0, 1) * amp[844] + std::complex (0, 1) * - amp[848] - std::complex (0, 1) * amp[854] - std::complex - (0, 1) * amp[853] + std::complex (0, 1) * amp[856] + - std::complex (0, 1) * amp[857] - amp[858] - std::complex - (0, 1) * amp[863] - std::complex (0, 1) * amp[862] - - std::complex (0, 1) * amp[941] + std::complex (0, 1) * - amp[939] + amp[944] - amp[942] - std::complex (0, 1) * amp[947] + - std::complex (0, 1) * amp[945] - std::complex (0, 1) * - amp[953] + std::complex (0, 1) * amp[951] + amp[956] - amp[954] - - std::complex (0, 1) * amp[959] + std::complex (0, 1) * - amp[957] - amp[962] - amp[961] - std::complex (0, 1) * amp[965] - - std::complex (0, 1) * amp[964] - std::complex (0, 1) * - amp[971] - std::complex (0, 1) * amp[970] - amp[974] - amp[973] - - std::complex (0, 1) * amp[977] - std::complex (0, 1) * - amp[976] - std::complex (0, 1) * amp[983] - std::complex - (0, 1) * amp[982]; - jamp[15] = +amp[218] + amp[224] + amp[229] + amp[230] + amp[232] + amp[235] + - amp[236] + amp[238] - std::complex (0, 1) * amp[240] - - std::complex (0, 1) * amp[241] - std::complex (0, 1) * - amp[242] - std::complex (0, 1) * amp[243] + std::complex - (0, 1) * amp[288] - amp[289] + std::complex (0, 1) * amp[291] - - amp[292] + std::complex (0, 1) * amp[293] + std::complex - (0, 1) * amp[294] - amp[295] + std::complex (0, 1) * amp[297] - - amp[298] + std::complex (0, 1) * amp[299] + amp[301] - - std::complex (0, 1) * amp[303] + amp[304] + amp[307] - - std::complex (0, 1) * amp[309] + amp[310] + amp[312] + amp[313] + - amp[315] + amp[316] + amp[318] + amp[319] + amp[321] + amp[322] + - amp[437] + amp[443] + std::complex (0, 1) * amp[445] + amp[446] + - std::complex (0, 1) * amp[447] + amp[448] + std::complex - (0, 1) * amp[449] + std::complex (0, 1) * amp[451] + amp[452] + - std::complex (0, 1) * amp[453] + amp[454] + std::complex - (0, 1) * amp[455] - std::complex (0, 1) * amp[456] + amp[458] + - amp[460] - std::complex (0, 1) * amp[462] + amp[464] + amp[466] - - amp[482] - amp[481] - amp[485] - amp[484] - amp[488] - amp[487] - - amp[491] - amp[490] + std::complex (0, 1) * amp[777] - - std::complex (0, 1) * amp[778] - amp[779] + std::complex - (0, 1) * amp[784] - std::complex (0, 1) * amp[782] - - std::complex (0, 1) * amp[787] + std::complex (0, 1) * - amp[793] - std::complex (0, 1) * amp[791] + std::complex - (0, 1) * amp[795] - std::complex (0, 1) * amp[796] - amp[797] + - std::complex (0, 1) * amp[802] - std::complex (0, 1) * - amp[800] - std::complex (0, 1) * amp[805] + std::complex - (0, 1) * amp[811] - std::complex (0, 1) * amp[809] - amp[812] - - std::complex (0, 1) * amp[814] - amp[816] - std::complex - (0, 1) * amp[817] - amp[819] - amp[820] - std::complex (0, 1) * - amp[822] - amp[824] - std::complex (0, 1) * amp[825] - amp[827] + - std::complex (0, 1) * amp[832] + std::complex (0, 1) * - amp[834] + std::complex (0, 1) * amp[835] + std::complex - (0, 1) * amp[837] + std::complex (0, 1) * amp[841] + amp[842] + - std::complex (0, 1) * amp[843] + std::complex (0, 1) * - amp[844] + std::complex (0, 1) * amp[850] + std::complex - (0, 1) * amp[852] + std::complex (0, 1) * amp[853] + - std::complex (0, 1) * amp[855] + std::complex (0, 1) * - amp[859] + amp[860] + std::complex (0, 1) * amp[861] + - std::complex (0, 1) * amp[862] + std::complex (0, 1) * - amp[866] + amp[867] + std::complex (0, 1) * amp[868] - - std::complex (0, 1) * amp[872] + std::complex (0, 1) * - amp[870] + std::complex (0, 1) * amp[875] + std::complex - (0, 1) * amp[877] + amp[878] - std::complex (0, 1) * amp[881] + - std::complex (0, 1) * amp[879] + std::complex (0, 1) * - amp[884] + amp[885] + std::complex (0, 1) * amp[886] - - std::complex (0, 1) * amp[890] + std::complex (0, 1) * - amp[888] + std::complex (0, 1) * amp[893] + std::complex - (0, 1) * amp[895] + amp[896] - std::complex (0, 1) * amp[899] + - std::complex (0, 1) * amp[897] + amp[960] + amp[961] + - std::complex (0, 1) * amp[963] + std::complex (0, 1) * - amp[964] + std::complex (0, 1) * amp[969] + std::complex - (0, 1) * amp[970] + amp[972] + amp[973] + std::complex (0, 1) * - amp[975] + std::complex (0, 1) * amp[976] + std::complex - (0, 1) * amp[981] + std::complex (0, 1) * amp[982] - - std::complex (0, 1) * amp[1013] - std::complex (0, 1) * - amp[1012] - amp[1016] - amp[1015] - std::complex (0, 1) * - amp[1019] - std::complex (0, 1) * amp[1018] - - std::complex (0, 1) * amp[1025] - std::complex (0, 1) * - amp[1024] - amp[1028] - amp[1027] - std::complex (0, 1) * - amp[1031] - std::complex (0, 1) * amp[1030]; - jamp[16] = +amp[221] + amp[227] + amp[244] + amp[247] + amp[249] + amp[250] + - amp[253] + amp[255] + std::complex (0, 1) * amp[256] + - std::complex (0, 1) * amp[257] + std::complex (0, 1) * - amp[258] + std::complex (0, 1) * amp[259] - std::complex - (0, 1) * amp[276] + amp[277] - std::complex (0, 1) * amp[279] + - amp[280] - std::complex (0, 1) * amp[281] - std::complex - (0, 1) * amp[282] + amp[283] - std::complex (0, 1) * amp[285] + - amp[286] - std::complex (0, 1) * amp[287] + amp[289] + - std::complex (0, 1) * amp[290] + amp[292] + amp[295] + - std::complex (0, 1) * amp[296] + amp[298] - amp[314] - amp[313] - - amp[317] - amp[316] - amp[320] - amp[319] - amp[323] - amp[322] + - amp[492] + amp[498] + std::complex (0, 1) * amp[516] - amp[518] - - amp[520] + std::complex (0, 1) * amp[522] - amp[524] - amp[526] - - std::complex (0, 1) * amp[528] + amp[530] - std::complex - (0, 1) * amp[531] + amp[532] - std::complex (0, 1) * amp[533] - - std::complex (0, 1) * amp[534] + amp[536] - std::complex - (0, 1) * amp[537] + amp[538] - std::complex (0, 1) * amp[539] + - amp[540] + amp[541] + amp[543] + amp[544] + amp[546] + amp[547] + - amp[549] + amp[550] - std::complex (0, 1) * amp[672] + - std::complex (0, 1) * amp[676] + amp[677] - std::complex - (0, 1) * amp[678] - std::complex (0, 1) * amp[679] + - std::complex (0, 1) * amp[685] - std::complex (0, 1) * - amp[687] - std::complex (0, 1) * amp[688] - std::complex - (0, 1) * amp[690] + std::complex (0, 1) * amp[694] + amp[695] - - std::complex (0, 1) * amp[696] - std::complex (0, 1) * - amp[697] + std::complex (0, 1) * amp[703] - std::complex - (0, 1) * amp[705] - std::complex (0, 1) * amp[706] - amp[708] - - std::complex (0, 1) * amp[710] - amp[712] - std::complex - (0, 1) * amp[713] - amp[715] - amp[716] - std::complex (0, 1) * - amp[718] - amp[720] - std::complex (0, 1) * amp[721] - amp[723] + - std::complex (0, 1) * amp[778] + amp[779] + std::complex - (0, 1) * amp[780] - std::complex (0, 1) * amp[784] - - std::complex (0, 1) * amp[783] + std::complex (0, 1) * - amp[787] + std::complex (0, 1) * amp[789] - amp[790] - - std::complex (0, 1) * amp[793] - std::complex (0, 1) * - amp[792] + std::complex (0, 1) * amp[796] + amp[797] + - std::complex (0, 1) * amp[798] - std::complex (0, 1) * - amp[802] - std::complex (0, 1) * amp[801] + std::complex - (0, 1) * amp[805] + std::complex (0, 1) * amp[807] - amp[808] - - std::complex (0, 1) * amp[811] - std::complex (0, 1) * - amp[810] - std::complex (0, 1) * amp[902] + std::complex - (0, 1) * amp[908] + std::complex (0, 1) * amp[907] - - std::complex (0, 1) * amp[910] - std::complex (0, 1) * - amp[911] + amp[912] + std::complex (0, 1) * amp[917] + - std::complex (0, 1) * amp[916] - std::complex (0, 1) * - amp[920] + std::complex (0, 1) * amp[926] + std::complex - (0, 1) * amp[925] - std::complex (0, 1) * amp[928] - - std::complex (0, 1) * amp[929] + amp[930] + std::complex - (0, 1) * amp[935] + std::complex (0, 1) * amp[934] - amp[962] - - amp[961] - std::complex (0, 1) * amp[965] - std::complex - (0, 1) * amp[964] - std::complex (0, 1) * amp[971] - - std::complex (0, 1) * amp[970] - amp[974] - amp[973] - - std::complex (0, 1) * amp[977] - std::complex (0, 1) * - amp[976] - std::complex (0, 1) * amp[983] - std::complex - (0, 1) * amp[982] - std::complex (0, 1) * amp[987] - - std::complex (0, 1) * amp[988] + amp[990] + amp[991] - - std::complex (0, 1) * amp[993] - std::complex (0, 1) * - amp[994] - std::complex (0, 1) * amp[999] - std::complex - (0, 1) * amp[1000] + amp[1002] + amp[1003] - std::complex (0, 1) - * amp[1005] - std::complex (0, 1) * amp[1006]; - jamp[17] = +amp[220] + amp[226] + amp[228] + amp[231] + amp[233] + amp[234] + - amp[237] + amp[239] + std::complex (0, 1) * amp[240] + - std::complex (0, 1) * amp[241] + std::complex (0, 1) * - amp[242] + std::complex (0, 1) * amp[243] + std::complex - (0, 1) * amp[276] - amp[277] + std::complex (0, 1) * amp[279] - - amp[280] + std::complex (0, 1) * amp[281] + std::complex - (0, 1) * amp[282] - amp[283] + std::complex (0, 1) * amp[285] - - amp[286] + std::complex (0, 1) * amp[287] - amp[301] + - std::complex (0, 1) * amp[303] - amp[304] - amp[307] + - std::complex (0, 1) * amp[309] - amp[310] + amp[314] - amp[312] + - amp[317] - amp[315] + amp[320] - amp[318] + amp[323] - amp[321] + - amp[432] + amp[438] + std::complex (0, 1) * amp[456] - amp[458] - - amp[460] + std::complex (0, 1) * amp[462] - amp[464] - amp[466] - - std::complex (0, 1) * amp[468] + amp[470] - std::complex - (0, 1) * amp[471] + amp[472] - std::complex (0, 1) * amp[473] - - std::complex (0, 1) * amp[474] + amp[476] - std::complex - (0, 1) * amp[477] + amp[478] - std::complex (0, 1) * amp[479] + - amp[480] + amp[481] + amp[483] + amp[484] + amp[486] + amp[487] + - amp[489] + amp[490] + std::complex (0, 1) * amp[672] - - std::complex (0, 1) * amp[676] - amp[677] + std::complex - (0, 1) * amp[678] + std::complex (0, 1) * amp[679] - - std::complex (0, 1) * amp[685] + std::complex (0, 1) * - amp[687] + std::complex (0, 1) * amp[688] + std::complex - (0, 1) * amp[690] - std::complex (0, 1) * amp[694] - amp[695] + - std::complex (0, 1) * amp[696] + std::complex (0, 1) * - amp[697] - std::complex (0, 1) * amp[703] + std::complex - (0, 1) * amp[705] + std::complex (0, 1) * amp[706] + amp[708] + - std::complex (0, 1) * amp[710] + amp[712] + std::complex - (0, 1) * amp[713] + amp[715] + amp[716] + std::complex (0, 1) * - amp[718] + amp[720] + std::complex (0, 1) * amp[721] + amp[723] - - std::complex (0, 1) * amp[866] - amp[867] - std::complex - (0, 1) * amp[868] + std::complex (0, 1) * amp[872] - - std::complex (0, 1) * amp[870] - std::complex (0, 1) * - amp[875] - std::complex (0, 1) * amp[877] - amp[878] + - std::complex (0, 1) * amp[881] - std::complex (0, 1) * - amp[879] - std::complex (0, 1) * amp[884] - amp[885] - - std::complex (0, 1) * amp[886] + std::complex (0, 1) * - amp[890] - std::complex (0, 1) * amp[888] - std::complex - (0, 1) * amp[893] - std::complex (0, 1) * amp[895] - amp[896] + - std::complex (0, 1) * amp[899] - std::complex (0, 1) * - amp[897] + std::complex (0, 1) * amp[904] - std::complex - (0, 1) * amp[908] + std::complex (0, 1) * amp[906] - - std::complex (0, 1) * amp[909] + std::complex (0, 1) * - amp[913] + amp[914] - std::complex (0, 1) * amp[917] + - std::complex (0, 1) * amp[915] + std::complex (0, 1) * - amp[922] - std::complex (0, 1) * amp[926] + std::complex - (0, 1) * amp[924] - std::complex (0, 1) * amp[927] + - std::complex (0, 1) * amp[931] + amp[932] - std::complex - (0, 1) * amp[935] + std::complex (0, 1) * amp[933] + amp[962] - - amp[960] + std::complex (0, 1) * amp[965] - std::complex - (0, 1) * amp[963] + std::complex (0, 1) * amp[971] - - std::complex (0, 1) * amp[969] + amp[974] - amp[972] + - std::complex (0, 1) * amp[977] - std::complex (0, 1) * - amp[975] + std::complex (0, 1) * amp[983] - std::complex - (0, 1) * amp[981] + std::complex (0, 1) * amp[1011] + - std::complex (0, 1) * amp[1012] + amp[1014] + amp[1015] + - std::complex (0, 1) * amp[1017] + std::complex (0, 1) * - amp[1018] + std::complex (0, 1) * amp[1023] + - std::complex (0, 1) * amp[1024] + amp[1026] + amp[1027] + - std::complex (0, 1) * amp[1029] + std::complex (0, 1) * - amp[1030]; - jamp[18] = +amp[325] + amp[331] + amp[369] + amp[370] + amp[372] + amp[375] + - amp[376] + amp[378] - std::complex (0, 1) * amp[380] - - std::complex (0, 1) * amp[381] - std::complex (0, 1) * - amp[382] - std::complex (0, 1) * amp[383] - amp[385] - - std::complex (0, 1) * amp[386] - amp[388] - amp[391] - - std::complex (0, 1) * amp[392] - amp[394] - std::complex - (0, 1) * amp[408] - amp[409] - std::complex (0, 1) * amp[410] - - amp[412] - std::complex (0, 1) * amp[413] - std::complex - (0, 1) * amp[414] - amp[415] - std::complex (0, 1) * amp[416] - - amp[418] - std::complex (0, 1) * amp[419] + amp[422] - amp[420] + - amp[425] - amp[423] + amp[428] - amp[426] + amp[431] - amp[429] + - amp[555] + amp[561] - std::complex (0, 1) * amp[564] + amp[566] + - amp[568] - std::complex (0, 1) * amp[570] + amp[572] + amp[574] + - std::complex (0, 1) * amp[577] + amp[578] + std::complex - (0, 1) * amp[579] + amp[580] + std::complex (0, 1) * amp[581] + - std::complex (0, 1) * amp[583] + amp[584] + std::complex - (0, 1) * amp[585] + amp[586] + std::complex (0, 1) * amp[587] - - amp[602] - amp[601] - amp[605] - amp[604] - amp[608] - amp[607] - - amp[611] - amp[610] - std::complex (0, 1) * amp[674] - amp[675] - - std::complex (0, 1) * amp[676] + std::complex (0, 1) * - amp[680] + std::complex (0, 1) * amp[679] - std::complex - (0, 1) * amp[683] - std::complex (0, 1) * amp[685] + amp[686] + - std::complex (0, 1) * amp[689] + std::complex (0, 1) * - amp[688] - std::complex (0, 1) * amp[692] - amp[693] - - std::complex (0, 1) * amp[694] + std::complex (0, 1) * - amp[698] + std::complex (0, 1) * amp[697] - std::complex - (0, 1) * amp[701] - std::complex (0, 1) * amp[703] + amp[704] + - std::complex (0, 1) * amp[707] + std::complex (0, 1) * - amp[706] - std::complex (0, 1) * amp[778] + std::complex - (0, 1) * amp[784] - std::complex (0, 1) * amp[782] + - std::complex (0, 1) * amp[786] - std::complex (0, 1) * - amp[787] + amp[788] + std::complex (0, 1) * amp[793] - - std::complex (0, 1) * amp[791] - std::complex (0, 1) * - amp[796] + std::complex (0, 1) * amp[802] - std::complex - (0, 1) * amp[800] + std::complex (0, 1) * amp[804] - - std::complex (0, 1) * amp[805] + amp[806] + std::complex - (0, 1) * amp[811] - std::complex (0, 1) * amp[809] + amp[813] - - std::complex (0, 1) * amp[814] + amp[815] - std::complex - (0, 1) * amp[817] + amp[818] + amp[821] - std::complex (0, 1) * - amp[822] + amp[823] - std::complex (0, 1) * amp[825] + amp[826] - - std::complex (0, 1) * amp[829] - std::complex (0, 1) * - amp[830] - amp[831] + std::complex (0, 1) * amp[836] + - std::complex (0, 1) * amp[835] - std::complex (0, 1) * - amp[839] + std::complex (0, 1) * amp[845] + std::complex - (0, 1) * amp[844] - std::complex (0, 1) * amp[847] - - std::complex (0, 1) * amp[848] - amp[849] + std::complex - (0, 1) * amp[854] + std::complex (0, 1) * amp[853] - - std::complex (0, 1) * amp[857] + std::complex (0, 1) * - amp[863] + std::complex (0, 1) * amp[862] + amp[938] - amp[936] + - std::complex (0, 1) * amp[941] - std::complex (0, 1) * - amp[939] + std::complex (0, 1) * amp[947] - std::complex - (0, 1) * amp[945] + amp[950] - amp[948] + std::complex (0, 1) * - amp[953] - std::complex (0, 1) * amp[951] + std::complex - (0, 1) * amp[959] - std::complex (0, 1) * amp[957] + - std::complex (0, 1) * amp[965] + std::complex (0, 1) * - amp[964] - amp[968] - amp[967] + std::complex (0, 1) * amp[971] + - std::complex (0, 1) * amp[970] + std::complex (0, 1) * - amp[977] + std::complex (0, 1) * amp[976] - amp[980] - amp[979] + - std::complex (0, 1) * amp[983] + std::complex (0, 1) * - amp[982]; - jamp[19] = +amp[324] + amp[330] + amp[353] + amp[354] + amp[356] + amp[359] + - amp[360] + amp[362] - std::complex (0, 1) * amp[364] - - std::complex (0, 1) * amp[365] - std::complex (0, 1) * - amp[366] - std::complex (0, 1) * amp[367] - amp[397] - - std::complex (0, 1) * amp[398] - amp[400] - amp[403] - - std::complex (0, 1) * amp[404] - amp[406] + std::complex - (0, 1) * amp[408] + amp[409] + std::complex (0, 1) * amp[410] + - amp[412] + std::complex (0, 1) * amp[413] + std::complex - (0, 1) * amp[414] + amp[415] + std::complex (0, 1) * amp[416] + - amp[418] + std::complex (0, 1) * amp[419] + amp[420] + amp[421] + - amp[423] + amp[424] + amp[426] + amp[427] + amp[429] + amp[430] + - amp[495] + amp[501] - std::complex (0, 1) * amp[504] + amp[506] + - amp[508] - std::complex (0, 1) * amp[510] + amp[512] + amp[514] + - std::complex (0, 1) * amp[517] + amp[518] + std::complex - (0, 1) * amp[519] + amp[520] + std::complex (0, 1) * amp[521] + - std::complex (0, 1) * amp[523] + amp[524] + std::complex - (0, 1) * amp[525] + amp[526] + std::complex (0, 1) * amp[527] - - amp[542] - amp[541] - amp[545] - amp[544] - amp[548] - amp[547] - - amp[551] - amp[550] - std::complex (0, 1) * amp[726] - amp[727] - - std::complex (0, 1) * amp[728] + std::complex (0, 1) * - amp[732] + std::complex (0, 1) * amp[731] - std::complex - (0, 1) * amp[735] - std::complex (0, 1) * amp[737] + amp[738] + - std::complex (0, 1) * amp[741] + std::complex (0, 1) * - amp[740] - std::complex (0, 1) * amp[744] - amp[745] - - std::complex (0, 1) * amp[746] + std::complex (0, 1) * - amp[750] + std::complex (0, 1) * amp[749] - std::complex - (0, 1) * amp[753] - std::complex (0, 1) * amp[755] + amp[756] + - std::complex (0, 1) * amp[759] + std::complex (0, 1) * - amp[758] - std::complex (0, 1) * amp[780] + std::complex - (0, 1) * amp[782] + std::complex (0, 1) * amp[783] + - std::complex (0, 1) * amp[785] - std::complex (0, 1) * - amp[789] + amp[790] + std::complex (0, 1) * amp[791] + - std::complex (0, 1) * amp[792] - std::complex (0, 1) * - amp[798] + std::complex (0, 1) * amp[800] + std::complex - (0, 1) * amp[801] + std::complex (0, 1) * amp[803] - - std::complex (0, 1) * amp[807] + amp[808] + std::complex - (0, 1) * amp[809] + std::complex (0, 1) * amp[810] - amp[813] + - std::complex (0, 1) * amp[814] - amp[815] + std::complex - (0, 1) * amp[817] - amp[818] - amp[821] + std::complex (0, 1) * - amp[822] - amp[823] + std::complex (0, 1) * amp[825] - amp[826] + - std::complex (0, 1) * amp[829] + std::complex (0, 1) * - amp[830] + amp[831] - std::complex (0, 1) * amp[836] - - std::complex (0, 1) * amp[835] + std::complex (0, 1) * - amp[839] - std::complex (0, 1) * amp[845] - std::complex - (0, 1) * amp[844] + std::complex (0, 1) * amp[847] + - std::complex (0, 1) * amp[848] + amp[849] - std::complex - (0, 1) * amp[854] - std::complex (0, 1) * amp[853] + - std::complex (0, 1) * amp[857] - std::complex (0, 1) * - amp[863] - std::complex (0, 1) * amp[862] + amp[936] + amp[937] + - std::complex (0, 1) * amp[939] + std::complex (0, 1) * - amp[940] + std::complex (0, 1) * amp[945] + std::complex - (0, 1) * amp[946] + amp[948] + amp[949] + std::complex (0, 1) * - amp[951] + std::complex (0, 1) * amp[952] + std::complex - (0, 1) * amp[957] + std::complex (0, 1) * amp[958] + - std::complex (0, 1) * amp[989] + std::complex (0, 1) * - amp[988] - amp[992] - amp[991] + std::complex (0, 1) * amp[995] + - std::complex (0, 1) * amp[994] + std::complex (0, 1) * - amp[1001] + std::complex (0, 1) * amp[1000] - amp[1004] - - amp[1003] + std::complex (0, 1) * amp[1007] + - std::complex (0, 1) * amp[1006]; - jamp[20] = +amp[327] + amp[333] + amp[368] + amp[371] + amp[373] + amp[374] + - amp[377] + amp[379] + std::complex (0, 1) * amp[380] + - std::complex (0, 1) * amp[381] + std::complex (0, 1) * - amp[382] + std::complex (0, 1) * amp[383] + amp[385] + - std::complex (0, 1) * amp[386] + amp[388] + amp[391] + - std::complex (0, 1) * amp[392] + amp[394] - std::complex - (0, 1) * amp[396] + amp[397] - std::complex (0, 1) * amp[399] + - amp[400] - std::complex (0, 1) * amp[401] - std::complex - (0, 1) * amp[402] + amp[403] - std::complex (0, 1) * amp[405] + - amp[406] - std::complex (0, 1) * amp[407] - amp[422] - amp[421] - - amp[425] - amp[424] - amp[428] - amp[427] - amp[431] - amp[430] + - amp[553] + amp[559] + std::complex (0, 1) * amp[564] - amp[566] - - amp[568] + std::complex (0, 1) * amp[570] - amp[572] - amp[574] + - std::complex (0, 1) * amp[588] - amp[590] + std::complex - (0, 1) * amp[591] - amp[592] + std::complex (0, 1) * amp[593] + - std::complex (0, 1) * amp[594] - amp[596] + std::complex - (0, 1) * amp[597] - amp[598] + std::complex (0, 1) * amp[599] + - amp[602] - amp[600] + amp[605] - amp[603] + amp[608] - amp[606] + - amp[611] - amp[609] + std::complex (0, 1) * amp[674] + amp[675] + - std::complex (0, 1) * amp[676] - std::complex (0, 1) * - amp[680] - std::complex (0, 1) * amp[679] + std::complex - (0, 1) * amp[683] + std::complex (0, 1) * amp[685] - amp[686] - - std::complex (0, 1) * amp[689] - std::complex (0, 1) * - amp[688] + std::complex (0, 1) * amp[692] + amp[693] + - std::complex (0, 1) * amp[694] - std::complex (0, 1) * - amp[698] - std::complex (0, 1) * amp[697] + std::complex - (0, 1) * amp[701] + std::complex (0, 1) * amp[703] - amp[704] - - std::complex (0, 1) * amp[707] - std::complex (0, 1) * - amp[706] - std::complex (0, 1) * amp[725] + std::complex - (0, 1) * amp[726] + amp[727] - std::complex (0, 1) * amp[732] + - std::complex (0, 1) * amp[730] + std::complex (0, 1) * - amp[735] - std::complex (0, 1) * amp[741] + std::complex - (0, 1) * amp[739] - std::complex (0, 1) * amp[743] + - std::complex (0, 1) * amp[744] + amp[745] - std::complex - (0, 1) * amp[750] + std::complex (0, 1) * amp[748] + - std::complex (0, 1) * amp[753] - std::complex (0, 1) * - amp[759] + std::complex (0, 1) * amp[757] + amp[760] + - std::complex (0, 1) * amp[762] + amp[764] + std::complex - (0, 1) * amp[765] + amp[767] + amp[768] + std::complex (0, 1) * - amp[770] + amp[772] + std::complex (0, 1) * amp[773] + amp[775] + - std::complex (0, 1) * amp[866] - std::complex (0, 1) * - amp[872] - std::complex (0, 1) * amp[871] + std::complex - (0, 1) * amp[874] + std::complex (0, 1) * amp[875] - amp[876] - - std::complex (0, 1) * amp[881] - std::complex (0, 1) * - amp[880] + std::complex (0, 1) * amp[884] - std::complex - (0, 1) * amp[890] - std::complex (0, 1) * amp[889] + - std::complex (0, 1) * amp[892] + std::complex (0, 1) * - amp[893] - amp[894] - std::complex (0, 1) * amp[899] - - std::complex (0, 1) * amp[898] - amp[938] - amp[937] - - std::complex (0, 1) * amp[941] - std::complex (0, 1) * - amp[940] - std::complex (0, 1) * amp[947] - std::complex - (0, 1) * amp[946] - amp[950] - amp[949] - std::complex (0, 1) * - amp[953] - std::complex (0, 1) * amp[952] - std::complex - (0, 1) * amp[959] - std::complex (0, 1) * amp[958] - - std::complex (0, 1) * amp[965] + std::complex (0, 1) * - amp[963] + amp[968] - amp[966] - std::complex (0, 1) * amp[971] + - std::complex (0, 1) * amp[969] - std::complex (0, 1) * - amp[977] + std::complex (0, 1) * amp[975] + amp[980] - amp[978] - - std::complex (0, 1) * amp[983] + std::complex (0, 1) * - amp[981]; - jamp[21] = +amp[326] + amp[332] + amp[337] + amp[338] + amp[340] + amp[343] + - amp[344] + amp[346] - std::complex (0, 1) * amp[348] - - std::complex (0, 1) * amp[349] - std::complex (0, 1) * - amp[350] - std::complex (0, 1) * amp[351] + std::complex - (0, 1) * amp[396] - amp[397] + std::complex (0, 1) * amp[399] - - amp[400] + std::complex (0, 1) * amp[401] + std::complex - (0, 1) * amp[402] - amp[403] + std::complex (0, 1) * amp[405] - - amp[406] + std::complex (0, 1) * amp[407] + amp[409] - - std::complex (0, 1) * amp[411] + amp[412] + amp[415] - - std::complex (0, 1) * amp[417] + amp[418] + amp[420] + amp[421] + - amp[423] + amp[424] + amp[426] + amp[427] + amp[429] + amp[430] + - amp[435] + amp[441] - std::complex (0, 1) * amp[444] + amp[446] + - amp[448] - std::complex (0, 1) * amp[450] + amp[452] + amp[454] + - std::complex (0, 1) * amp[457] + amp[458] + std::complex - (0, 1) * amp[459] + amp[460] + std::complex (0, 1) * amp[461] + - std::complex (0, 1) * amp[463] + amp[464] + std::complex - (0, 1) * amp[465] + amp[466] + std::complex (0, 1) * amp[467] - - amp[482] - amp[481] - amp[485] - amp[484] - amp[488] - amp[487] - - amp[491] - amp[490] + std::complex (0, 1) * amp[725] - - std::complex (0, 1) * amp[726] - amp[727] + std::complex - (0, 1) * amp[732] - std::complex (0, 1) * amp[730] - - std::complex (0, 1) * amp[735] + std::complex (0, 1) * - amp[741] - std::complex (0, 1) * amp[739] + std::complex - (0, 1) * amp[743] - std::complex (0, 1) * amp[744] - amp[745] + - std::complex (0, 1) * amp[750] - std::complex (0, 1) * - amp[748] - std::complex (0, 1) * amp[753] + std::complex - (0, 1) * amp[759] - std::complex (0, 1) * amp[757] - amp[760] - - std::complex (0, 1) * amp[762] - amp[764] - std::complex - (0, 1) * amp[765] - amp[767] - amp[768] - std::complex (0, 1) * - amp[770] - amp[772] - std::complex (0, 1) * amp[773] - amp[775] + - std::complex (0, 1) * amp[830] + amp[831] + std::complex - (0, 1) * amp[832] - std::complex (0, 1) * amp[836] + - std::complex (0, 1) * amp[834] + std::complex (0, 1) * - amp[839] + std::complex (0, 1) * amp[841] + amp[842] - - std::complex (0, 1) * amp[845] + std::complex (0, 1) * - amp[843] + std::complex (0, 1) * amp[848] + amp[849] + - std::complex (0, 1) * amp[850] - std::complex (0, 1) * - amp[854] + std::complex (0, 1) * amp[852] + std::complex - (0, 1) * amp[857] + std::complex (0, 1) * amp[859] + amp[860] - - std::complex (0, 1) * amp[863] + std::complex (0, 1) * - amp[861] + std::complex (0, 1) * amp[868] + std::complex - (0, 1) * amp[870] + std::complex (0, 1) * amp[871] + - std::complex (0, 1) * amp[873] + std::complex (0, 1) * - amp[877] + amp[878] + std::complex (0, 1) * amp[879] + - std::complex (0, 1) * amp[880] + std::complex (0, 1) * - amp[886] + std::complex (0, 1) * amp[888] + std::complex - (0, 1) * amp[889] + std::complex (0, 1) * amp[891] + - std::complex (0, 1) * amp[895] + amp[896] + std::complex - (0, 1) * amp[897] + std::complex (0, 1) * amp[898] + amp[936] + - amp[937] + std::complex (0, 1) * amp[939] + std::complex - (0, 1) * amp[940] + std::complex (0, 1) * amp[945] + - std::complex (0, 1) * amp[946] + amp[948] + amp[949] + - std::complex (0, 1) * amp[951] + std::complex (0, 1) * - amp[952] + std::complex (0, 1) * amp[957] + std::complex - (0, 1) * amp[958] - std::complex (0, 1) * amp[1013] - - std::complex (0, 1) * amp[1012] - amp[1016] - amp[1015] - - std::complex (0, 1) * amp[1019] - std::complex (0, 1) * - amp[1018] - std::complex (0, 1) * amp[1025] - - std::complex (0, 1) * amp[1024] - amp[1028] - amp[1027] - - std::complex (0, 1) * amp[1031] - std::complex (0, 1) * - amp[1030]; - jamp[22] = +amp[329] + amp[335] + amp[352] + amp[355] + amp[357] + amp[358] + - amp[361] + amp[363] + std::complex (0, 1) * amp[364] + - std::complex (0, 1) * amp[365] + std::complex (0, 1) * - amp[366] + std::complex (0, 1) * amp[367] - std::complex - (0, 1) * amp[384] + amp[385] - std::complex (0, 1) * amp[387] + - amp[388] - std::complex (0, 1) * amp[389] - std::complex - (0, 1) * amp[390] + amp[391] - std::complex (0, 1) * amp[393] + - amp[394] - std::complex (0, 1) * amp[395] + amp[397] + - std::complex (0, 1) * amp[398] + amp[400] + amp[403] + - std::complex (0, 1) * amp[404] + amp[406] - amp[422] - amp[421] - - amp[425] - amp[424] - amp[428] - amp[427] - amp[431] - amp[430] + - amp[493] + amp[499] + std::complex (0, 1) * amp[504] - amp[506] - - amp[508] + std::complex (0, 1) * amp[510] - amp[512] - amp[514] + - std::complex (0, 1) * amp[528] - amp[530] + std::complex - (0, 1) * amp[531] - amp[532] + std::complex (0, 1) * amp[533] + - std::complex (0, 1) * amp[534] - amp[536] + std::complex - (0, 1) * amp[537] - amp[538] + std::complex (0, 1) * amp[539] + - amp[542] - amp[540] + amp[545] - amp[543] + amp[548] - amp[546] + - amp[551] - amp[549] - std::complex (0, 1) * amp[673] + - std::complex (0, 1) * amp[674] + amp[675] - std::complex - (0, 1) * amp[680] + std::complex (0, 1) * amp[678] + - std::complex (0, 1) * amp[683] - std::complex (0, 1) * - amp[689] + std::complex (0, 1) * amp[687] - std::complex - (0, 1) * amp[691] + std::complex (0, 1) * amp[692] + amp[693] - - std::complex (0, 1) * amp[698] + std::complex (0, 1) * - amp[696] + std::complex (0, 1) * amp[701] - std::complex - (0, 1) * amp[707] + std::complex (0, 1) * amp[705] + amp[708] + - std::complex (0, 1) * amp[710] + amp[712] + std::complex - (0, 1) * amp[713] + amp[715] + amp[716] + std::complex (0, 1) * - amp[718] + amp[720] + std::complex (0, 1) * amp[721] + amp[723] + - std::complex (0, 1) * amp[726] + amp[727] + std::complex - (0, 1) * amp[728] - std::complex (0, 1) * amp[732] - - std::complex (0, 1) * amp[731] + std::complex (0, 1) * - amp[735] + std::complex (0, 1) * amp[737] - amp[738] - - std::complex (0, 1) * amp[741] - std::complex (0, 1) * - amp[740] + std::complex (0, 1) * amp[744] + amp[745] + - std::complex (0, 1) * amp[746] - std::complex (0, 1) * - amp[750] - std::complex (0, 1) * amp[749] + std::complex - (0, 1) * amp[753] + std::complex (0, 1) * amp[755] - amp[756] - - std::complex (0, 1) * amp[759] - std::complex (0, 1) * - amp[758] + std::complex (0, 1) * amp[902] - std::complex - (0, 1) * amp[908] - std::complex (0, 1) * amp[907] + - std::complex (0, 1) * amp[910] + std::complex (0, 1) * - amp[911] - amp[912] - std::complex (0, 1) * amp[917] - - std::complex (0, 1) * amp[916] + std::complex (0, 1) * - amp[920] - std::complex (0, 1) * amp[926] - std::complex - (0, 1) * amp[925] + std::complex (0, 1) * amp[928] + - std::complex (0, 1) * amp[929] - amp[930] - std::complex - (0, 1) * amp[935] - std::complex (0, 1) * amp[934] - amp[938] - - amp[937] - std::complex (0, 1) * amp[941] - std::complex - (0, 1) * amp[940] - std::complex (0, 1) * amp[947] - - std::complex (0, 1) * amp[946] - amp[950] - amp[949] - - std::complex (0, 1) * amp[953] - std::complex (0, 1) * - amp[952] - std::complex (0, 1) * amp[959] - std::complex - (0, 1) * amp[958] - std::complex (0, 1) * amp[989] + - std::complex (0, 1) * amp[987] + amp[992] - amp[990] - - std::complex (0, 1) * amp[995] + std::complex (0, 1) * - amp[993] - std::complex (0, 1) * amp[1001] + std::complex - (0, 1) * amp[999] + amp[1004] - amp[1002] - std::complex (0, 1) * - amp[1007] + std::complex (0, 1) * amp[1005]; - jamp[23] = +amp[328] + amp[334] + amp[336] + amp[339] + amp[341] + amp[342] + - amp[345] + amp[347] + std::complex (0, 1) * amp[348] + - std::complex (0, 1) * amp[349] + std::complex (0, 1) * - amp[350] + std::complex (0, 1) * amp[351] + std::complex - (0, 1) * amp[384] - amp[385] + std::complex (0, 1) * amp[387] - - amp[388] + std::complex (0, 1) * amp[389] + std::complex - (0, 1) * amp[390] - amp[391] + std::complex (0, 1) * amp[393] - - amp[394] + std::complex (0, 1) * amp[395] - amp[409] + - std::complex (0, 1) * amp[411] - amp[412] - amp[415] + - std::complex (0, 1) * amp[417] - amp[418] + amp[422] - amp[420] + - amp[425] - amp[423] + amp[428] - amp[426] + amp[431] - amp[429] + - amp[433] + amp[439] + std::complex (0, 1) * amp[444] - amp[446] - - amp[448] + std::complex (0, 1) * amp[450] - amp[452] - amp[454] + - std::complex (0, 1) * amp[468] - amp[470] + std::complex - (0, 1) * amp[471] - amp[472] + std::complex (0, 1) * amp[473] + - std::complex (0, 1) * amp[474] - amp[476] + std::complex - (0, 1) * amp[477] - amp[478] + std::complex (0, 1) * amp[479] + - amp[482] - amp[480] + amp[485] - amp[483] + amp[488] - amp[486] + - amp[491] - amp[489] + std::complex (0, 1) * amp[673] - - std::complex (0, 1) * amp[674] - amp[675] + std::complex - (0, 1) * amp[680] - std::complex (0, 1) * amp[678] - - std::complex (0, 1) * amp[683] + std::complex (0, 1) * - amp[689] - std::complex (0, 1) * amp[687] + std::complex - (0, 1) * amp[691] - std::complex (0, 1) * amp[692] - amp[693] + - std::complex (0, 1) * amp[698] - std::complex (0, 1) * - amp[696] - std::complex (0, 1) * amp[701] + std::complex - (0, 1) * amp[707] - std::complex (0, 1) * amp[705] - amp[708] - - std::complex (0, 1) * amp[710] - amp[712] - std::complex - (0, 1) * amp[713] - amp[715] - amp[716] - std::complex (0, 1) * - amp[718] - amp[720] - std::complex (0, 1) * amp[721] - amp[723] - - std::complex (0, 1) * amp[830] - amp[831] - std::complex - (0, 1) * amp[832] + std::complex (0, 1) * amp[836] - - std::complex (0, 1) * amp[834] - std::complex (0, 1) * - amp[839] - std::complex (0, 1) * amp[841] - amp[842] + - std::complex (0, 1) * amp[845] - std::complex (0, 1) * - amp[843] - std::complex (0, 1) * amp[848] - amp[849] - - std::complex (0, 1) * amp[850] + std::complex (0, 1) * - amp[854] - std::complex (0, 1) * amp[852] - std::complex - (0, 1) * amp[857] - std::complex (0, 1) * amp[859] - amp[860] + - std::complex (0, 1) * amp[863] - std::complex (0, 1) * - amp[861] - std::complex (0, 1) * amp[904] + std::complex - (0, 1) * amp[908] - std::complex (0, 1) * amp[906] + - std::complex (0, 1) * amp[909] - std::complex (0, 1) * - amp[913] - amp[914] + std::complex (0, 1) * amp[917] - - std::complex (0, 1) * amp[915] - std::complex (0, 1) * - amp[922] + std::complex (0, 1) * amp[926] - std::complex - (0, 1) * amp[924] + std::complex (0, 1) * amp[927] - - std::complex (0, 1) * amp[931] - amp[932] + std::complex - (0, 1) * amp[935] - std::complex (0, 1) * amp[933] + amp[938] - - amp[936] + std::complex (0, 1) * amp[941] - std::complex - (0, 1) * amp[939] + std::complex (0, 1) * amp[947] - - std::complex (0, 1) * amp[945] + amp[950] - amp[948] + - std::complex (0, 1) * amp[953] - std::complex (0, 1) * - amp[951] + std::complex (0, 1) * amp[959] - std::complex - (0, 1) * amp[957] + std::complex (0, 1) * amp[1013] - - std::complex (0, 1) * amp[1011] + amp[1016] - amp[1014] + - std::complex (0, 1) * amp[1019] - std::complex (0, 1) * - amp[1017] + std::complex (0, 1) * amp[1025] - - std::complex (0, 1) * amp[1023] + amp[1028] - amp[1026] + - std::complex (0, 1) * amp[1031] - std::complex (0, 1) * - amp[1029]; - - // Store the leading color flows for choice of color - for(int i = 0; i < ncolor; i++ ) - jamp2[0][i] += real(jamp[i] * conj(jamp[i])); - - return -1.; -} - - -double eeuugggg::get_jamp2(int i) -{ - return jamp2[0][i]; -} - -int eeuugggg::colorstring(int i, int j) -{ - static const int res[24][8] = { - {5, 6, 7, 8, 3, 4, 0, 0}, - {5, 6, 8, 7, 3, 4, 0, 0}, - {5, 7, 6, 8, 3, 4, 0, 0}, - {5, 7, 8, 6, 3, 4, 0, 0}, - {5, 8, 6, 7, 3, 4, 0, 0}, - {5, 8, 7, 6, 3, 4, 0, 0}, - {6, 5, 7, 8, 3, 4, 0, 0}, - {6, 5, 8, 7, 3, 4, 0, 0}, - {6, 7, 5, 8, 3, 4, 0, 0}, - {6, 7, 8, 5, 3, 4, 0, 0}, - {6, 8, 5, 7, 3, 4, 0, 0}, - {6, 8, 7, 5, 3, 4, 0, 0}, - {7, 5, 6, 8, 3, 4, 0, 0}, - {7, 5, 8, 6, 3, 4, 0, 0}, - {7, 6, 5, 8, 3, 4, 0, 0}, - {7, 6, 8, 5, 3, 4, 0, 0}, - {7, 8, 5, 6, 3, 4, 0, 0}, - {7, 8, 6, 5, 3, 4, 0, 0}, - {8, 5, 6, 7, 3, 4, 0, 0}, - {8, 5, 7, 6, 3, 4, 0, 0}, - {8, 6, 5, 7, 3, 4, 0, 0}, - {8, 6, 7, 5, 3, 4, 0, 0}, - {8, 7, 5, 6, 3, 4, 0, 0}, - {8, 7, 6, 5, 3, 4, 0, 0}}; - return res[i][j]; -} - - -int eeuugggg::NCol() -{ - static const int ncolor = 24; - return ncolor; -} - - - - - - - - - - - - diff --git a/Shower/Dipole/Colorea/eeuugggg.h b/Shower/Dipole/Colorea/eeuugggg.h deleted file mode 100644 --- a/Shower/Dipole/Colorea/eeuugggg.h +++ /dev/null @@ -1,52 +0,0 @@ - //========================================================================== - // This file has been automatically generated for C++ Standalone by - // MadGraph5_aMC@NLO v. 2.5.4, 2017-03-28 - // By the MadGraph5_aMC@NLO Development Team - // Visit launchpad.net/madgraph5 and amcatnlo.web.cern.ch - //========================================================================== - // and was then modified by J. Bellm. -#ifndef MG5_Sigma_sm_epem_uuxgggg_H -#define MG5_Sigma_sm_epem_uuxgggg_H -#include -#include -#include "Parameters_sm.h" -using namespace std; -class eeuugggg -{ - public: - eeuugggg(){ - initProc("param_card.dat"); - } - // Retrun the prefered gluon order - vector producePermutation(double r,vector < double * > & momenta); - void setMass(int i,double M){mME[i]=M;} - private: - ///////// Process Dependent - static const int ninitial = 2; - static const int nexternal = 8; - static const int nprocesses = 1; - static const int nwavefuncs = 205; - static const int namplitudes = 1032; - std::complex w[nwavefuncs][18]; - double matrix_1_epem_uuxgggg(); - ///////// Generic - double matrix_element[nprocesses]; - std::complex amp[namplitudes]; - double * jamp2[nprocesses]; - Parameters_sm * pars; - vector mME; - vector < double * > p; - int id1, id2; - void initProc(string param_card_name); - void sigmaKin(); - const vector & getMasses() const {return mME;} - vector < double * > getMomenta(){return p;} - void setMomenta(vector < double * > & momenta){p = momenta;} - void setInitial(int inid1, int inid2){id1 = inid1; id2 = inid2;} - void calculate_wavefunctions(const int perm[], const int hel[]); - // New function - double get_jamp2(int i); - int colorstring(int i, int j); - int NCol(); -}; -#endif // MG5_Sigma_sm_epem_uuxgggg_H diff --git a/Shower/Dipole/Colorea/read_slha_COLOREA.cc b/Shower/Dipole/Colorea/read_slha_COLOREA.cc deleted file mode 100644 --- a/Shower/Dipole/Colorea/read_slha_COLOREA.cc +++ /dev/null @@ -1,144 +0,0 @@ -#include -#include -#include -#include "read_slha_COLOREA.h" - -void SLHABlock_COLOREA::set_entry(std::vector indices, double value) -{ - if (_entries.size() == 0) - _indices = indices.size(); - else if(indices.size() != _indices) - throw "Wrong number of indices in set_entry"; - - _entries[indices] = value; -} - -double SLHABlock_COLOREA::get_entry(std::vector indices, double def_val) -{ - if (_entries.find(indices) == _entries.end()){ - std::cout << "Warning: No such entry in " << _name << ", using default value " - << def_val << std::endl; - return def_val; - } - return _entries[indices]; -} - -void SLHAReader_COLOREA::read_slha_file(std::string file_name) -{ - std::ifstream param_card; - param_card.open(file_name.c_str(), std::ifstream::in); - if(!param_card.good()) - throw "Error while opening param card"; - std::cout << "\nColorea: Opened slha file " << file_name << " for reading" << std::endl; - char buf[200]; - std::string line; - std::string block(""); - - while(param_card.good()){ - param_card.getline(buf, 200); - line = buf; - // Change to lowercase - transform(line.begin(), line.end(), line.begin(), (int(*)(int)) tolower); - if(line != "" && line[0] != '#'){ - if(block != ""){ - // Look for double index blocks - double dindex1, dindex2; - double value; - std::stringstream linestr2(line); - if (linestr2 >> dindex1 >> dindex2 >> value && - dindex1 == int(dindex1) and dindex2 == int(dindex2)) - { - std::vector indices; - indices.push_back(int(dindex1)); - indices.push_back(int(dindex2)); - set_block_entry(block, indices, value); - // Done with this line, read next - continue; - } - std::stringstream linestr1(line); - // Look for single index blocks - if(linestr1 >> dindex1 >> value && dindex1 == int(dindex1)) - { - std::vector indices; - indices.push_back(int(dindex1)); - set_block_entry(block, indices, value); - // Done with this line, read next - continue; - } - } - // Look for block - if(line.find("block ") != line.npos){ - line = line.substr(6); - // Get rid of spaces between block and block name - while (line[0] == ' ') - line = line.substr(1); - // Now find end of block name - std::string::size_type space_pos = line.find(' '); - if(space_pos != line.npos) - line = line.substr(0, space_pos); - block = line; - continue; - } - // Look for decay - if(line.find("decay ") == 0){ - line = line.substr(6); - block = ""; - std::stringstream linestr(line); - int pdg_code; - double value; - if(linestr >> pdg_code >> value) - set_block_entry("decay", pdg_code, value); - else - std::cout << "Warning: Wrong format for decay block " << line << std::endl; - continue; - } - } - } - - if (_blocks.size() == 0) - throw "No information read from SLHA card"; - - param_card.close(); -} - -double SLHAReader_COLOREA::get_block_entry(std::string block_name, std::vector indices, - double def_val) -{ - if (_blocks.find(block_name) == _blocks.end()){ - std::cout << "No such block " << block_name << ", using default value " - << def_val << std::endl; - return def_val; - } - return _blocks[block_name].get_entry(indices); -} - -double SLHAReader_COLOREA::get_block_entry(std::string block_name, int index, - double def_val) -{ - std::vector indices; - indices.push_back(index); - return get_block_entry(block_name, indices, def_val); -} - - -void SLHAReader_COLOREA::set_block_entry(std::string block_name, std::vector indices, - double value) -{ - if (_blocks.find(block_name) == _blocks.end()){ - SLHABlock_COLOREA block(block_name); - _blocks[block_name] = block; - } - _blocks[block_name].set_entry(indices, value); - /* cout << "Set block " << block_name << " entry "; - for (int i=0;i < indices.size();i++) - cout << indices[i] << " "; - cout << "to " << _blocks[block_name].get_entry(indices) << endl;*/ -} - -void SLHAReader_COLOREA::set_block_entry(std::string block_name, int index, - double value) -{ - std::vector indices; - indices.push_back(index); - set_block_entry(block_name, indices, value); -} diff --git a/Shower/Dipole/Colorea/read_slha_COLOREA.h b/Shower/Dipole/Colorea/read_slha_COLOREA.h deleted file mode 100644 --- a/Shower/Dipole/Colorea/read_slha_COLOREA.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef READ_SLHA_H -#define READ_SLHA_H - -#include -#include -#include -#include - -class SLHABlock_COLOREA -{ - public: - SLHABlock_COLOREA(std::string name = ""){_name = name;} - ~SLHABlock_COLOREA(){} - - void set_entry(std::vector indices, double value); - double get_entry(std::vector indices, double def_val = 0); - void set_name(std::string name) {_name = name;} - std::string get_name(){return _name;} - int get_indices() { return _indices;} - - private: - std::string _name; - std::map, double> _entries; - unsigned int _indices; -}; - -class SLHAReader_COLOREA -{ - public: - SLHAReader_COLOREA(std::string file_name = "") - {if(file_name != "") read_slha_file(file_name);} - - void read_slha_file(std::string file_name); - double get_block_entry(std::string block_name, std::vector indices, - double def_val = 0); - double get_block_entry(std::string block_name, int index, - double def_val = 0); - void set_block_entry(std::string block_name, std::vector indices, - double value); - void set_block_entry(std::string block_name, int index, - double value); - private: - std::map _blocks; -}; - -#endif diff --git a/Shower/Dipole/DipoleShowerHandler.cc b/Shower/Dipole/DipoleShowerHandler.cc --- a/Shower/Dipole/DipoleShowerHandler.cc +++ b/Shower/Dipole/DipoleShowerHandler.cc @@ -1,1927 +1,1897 @@ // -*- C++ -*- // // DipoleShowerHandler.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 DipoleShowerHandler class. // #include #include "DipoleShowerHandler.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/RefVector.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/ParVector.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" // include theses to have complete types #include "Herwig/PDF/MPIPDF.h" #include "Herwig/PDF/MinBiasPDF.h" #include "Herwig/PDF/HwRemDecayer.h" #include "Herwig/Shower/Dipole/Utility/DipolePartonSplitter.h" #include "Herwig/MatrixElement/Matchbox/Base/MergerBase.h" #include "Herwig/MatrixElement/Matchbox/Base/SubtractedME.h" #include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h" #include using namespace Herwig; bool DipoleShowerHandler::firstWarn = true; DipoleShowerHandler::DipoleShowerHandler() : ShowerHandler(), chainOrderVetoScales(true), nEmissions(0), discardNoEmissions(false), firstMCatNLOEmission(false), thePowhegDecayEmission(true), //theAnalyseSpinCorrelations(false), realignmentScheme(0), doSubleadingNc(false),subleadingNcEmissionsLimit(0), densityOperatorEvolution(0),densityOperatorCutoff(1.0*GeV2), doPartialUnweightingAtEmission(false), doPartialUnweighting(false),referenceWeight(0.1), cmecReweightFactor(1.0),negCMECScaling(1.0), verbosity(0), printEvent(0), nTries(0), didRadiate(false), didRealign(false), theRenormalizationScaleFreeze(1.*GeV), theFactorizationScaleFreeze(2.*GeV), theDoCompensate(false), theFreezeGrid(500000), theDetuning(1.0), maxPt(ZERO), muPt(ZERO), theInputColouredOffShellInShower(), theZBoundaries(1) {} DipoleShowerHandler::~DipoleShowerHandler() {} IBPtr DipoleShowerHandler::clone() const { return new_ptr(*this); } IBPtr DipoleShowerHandler::fullclone() const { return new_ptr(*this); } void DipoleShowerHandler::cascade(tPVector ) { throw Exception() << "DipoleShowerHandler: Dipoleshower not implemented as second shower." << "Check your setup or contact Herwig authors." << Exception::runerror; } tPPair DipoleShowerHandler::cascade(tSubProPtr sub, XCombPtr, Energy optHardPt, Energy optCutoff) { useMe(); prepareCascade(sub); resetWeights(); if ( !doFSR() && ! doISR() ) return sub->incoming(); eventRecord().setSubleadingNc(doSubleadingNc, subleadingNcEmissionsLimit); eventRecord().clear(); eventRecord().prepare(sub,dynamic_ptr_cast(lastXCombPtr()),newStep(),pdfs(), ShowerHandler::currentHandler()->generator()->currentEvent()->incoming(), firstInteraction(), offShellPartons(), !doSubleadingNc); if ( doSubleadingNc ) { if ( !theSplittingReweight ) { throw Exception() << "No splitting reweight was found. " << "A ColourMatrixElementCorrection " << "splitting reweight is required " << "for the subleading colour shower." << Exception::runerror; } //Set the evolution scheme for the density operator eventRecord().setDensityOperatorEvolution( densityOperatorEvolution, densityOperatorCutoff ); //Set the CMEC reweight factor theSplittingReweight->reweightFactor(cmecReweightFactor); theSplittingReweight->negativeScaling(negCMECScaling); theSplittingReweight->updateCurrentHandler(); } // SW: Removed simple test on doFSR and doISR and moved // here to account for the case of a hard event involving // no coloured particles but with unstable outgoing particles if ( !doFSR() && ! doISR() && eventRecord().decays().empty() ) return sub->incoming(); if ( !doISR() && eventRecord().outgoing().empty() && eventRecord().decays().empty() ) return sub->incoming(); if ( !doFSR() && !eventRecord().incoming().first->coloured() && !eventRecord().incoming().second->coloured() && eventRecord().decays().empty() ) return sub->incoming(); nTries = 0; // Clear the vertex record for spin correlations if ( spinCorrelations() ) //|| theAnalyseSpinCorrelations ) vertexRecord().clear(); while ( true ) { try { didRadiate = false; didRealign = false; if ( eventRecord().truncatedShower() ) { throw Exception() << "Inconsistent hard emission set-up in DipoleShowerHandler::cascade. " << "No truncated shower needed with DipoleShowerHandler. Add " << "'set MEMatching:TruncatedShower No' to input file." << Exception::runerror; } hardScales(lastXCombPtr()->lastShowerScale()); if ( verbosity > 1 ) { generator()->log() << "DipoleShowerHandler starting off:\n"; eventRecord().debugLastEvent(generator()->log()); generator()->log() << flush; } unsigned int nEmitted = 0; if ( firstMCatNLOEmission ) { if ( !eventRecord().isMCatNLOHEvent() ) nEmissions = 1; else nEmissions = 0; } if ( !firstMCatNLOEmission ) { doCascade(nEmitted,optHardPt,optCutoff); if ( discardNoEmissions ) { if ( !didRadiate ) throw Veto(); if ( nEmissions ) if ( nEmissions < nEmitted ) throw Veto(); } } else { if ( nEmissions == 1 ) doCascade(nEmitted,optHardPt,optCutoff); } if ( intrinsicPtGenerator ) { if ( eventRecord().incoming().first->coloured() && eventRecord().incoming().second->coloured() ) { LorentzRotation rot = intrinsicPtGenerator->kick(eventRecord().incoming(), eventRecord().intermediates()); eventRecord().transform(rot); } } didRealign = realign(); constituentReshuffle(); // backup subleading switch if decays fail bool doneSubleadingNc = doSubleadingNc; // subleading N can't handle decays doSubleadingNc = false; try { // Decay and shower any particles that require decaying while ( !eventRecord().decays().empty() ) { map::const_iterator decayIt = eventRecord().decays().begin(); if ( eventRecord().nextDecay() ) { decayIt = eventRecord().decays().find(eventRecord().nextDecay() ); } else { // find the decay to do, one with greatest width and parent showered while(find(eventRecord().outgoing().begin(),eventRecord().outgoing().end(),decayIt->first)== eventRecord().outgoing().end() && find(eventRecord().hard().begin(),eventRecord().hard().end(),decayIt->first)== eventRecord().hard().end()) ++decayIt; } assert(decayIt!=eventRecord().decays().end()); PPtr incoming = decayIt->first; eventRecord().currentDecay(decayIt->second); // Use this to record if an emission actually happens bool powhegEmission = !( nEmissions && nEmitted==nEmissions) ? thePowhegDecayEmission : false; // Decay the particle / sort out its pert proc Energy showerScale = eventRecord().decay(incoming, powhegEmission); // Following the decay, the bool powheg emission is updated // to indicate whether or not an emission occurred if ( powhegEmission ) nEmitted += 1; // Check that there is only one particle incoming to the decay assert(eventRecord().currentDecay()->incoming().size()==1); // Prepare the event record for the showering of the decay bool needToShower = eventRecord().prepareDecay(eventRecord().currentDecay(), offShellPartons()); // Only need to shower if we have coloured outgoing particles if ( needToShower ) { // The decays currently considered produce a maximum of 2 chains (with powheg emission) // so all dipole should have the same scale as returned by the decay function. assert( eventRecord().chains().size() <= 2 ); for ( auto & ch : eventRecord().chains()) { for ( auto & dip : ch.dipoles()) { assert ( showerScale > ZERO ); dip.leftScale( showerScale ); dip.rightScale( showerScale ); } } // Prepare vertex record for spin correlations in decay shower if ( spinCorrelations() ) vertexRecord().prepareParticleDecay(incoming); // Perform the cascade doCascade(nEmitted,optHardPt,optCutoff,true); if ( spinCorrelations() ) vertexRecord().updateParticleDecay(); // Do the constituent mass shell reshuffling decayConstituentReshuffle(eventRecord().currentDecay()); } // Update the decays, adding any decays and updating momenta eventRecord().updateDecays(eventRecord().currentDecay()); eventRecord().decays().erase(decayIt); } } catch(...) { // reset flag doSubleadingNc = doneSubleadingNc; throw; } doSubleadingNc = doneSubleadingNc; break; } catch (RedoShower&) { resetWeights(); if ( ++nTries > maxtry() ) throw ShowerTriesVeto(maxtry()); eventRecord().clear(); eventRecord().prepare(sub, dynamic_ptr_cast(lastXCombPtr()), newStep(), pdfs(), ShowerHandler::currentHandler()->generator()->currentEvent()->incoming(), firstInteraction(), offShellPartons(), !doSubleadingNc); if ( doSubleadingNc ) { theSplittingReweight->updateCurrentHandler(); } continue; } catch (...) { throw; } } tPPair incoming=eventRecord().fillEventRecord(newStep(),firstInteraction(),didRealign); setDidRunCascade(true); return incoming; } // Reshuffle the outgoing partons from the hard process onto their constituent mass shells void DipoleShowerHandler::constituentReshuffle() { if ( constituentReshuffler && ShowerHandler::currentHandler()->retConstituentMasses() ) { if ( eventRecord().decays().empty() ) { constituentReshuffler->reshuffle(eventRecord().outgoing(), eventRecord().incoming(), eventRecord().intermediates()); return; } else { PList decaying; for(auto const & dec : eventRecord().decays()) decaying.push_back(dec.first); constituentReshuffler->hardProcDecayReshuffle( decaying, eventRecord().outgoing(), eventRecord().hard(), eventRecord().incoming(), eventRecord().intermediates()); } } // After reshuffling the hard process, the decays need to be updated // as this is not done in reshuffle vector > decays; for(auto const & dec : eventRecord().decays() ) decays.push_back({dec.first,dec.second}); for(auto const & dec : decays) { PPtr unstable = dec.first; PList::iterator pos = find(eventRecord().intermediates().begin(), eventRecord().intermediates().end(), dec.first); // Update the PPtr in theDecays if(pos!=eventRecord().intermediates().end()) { unstable = *pos; while(!unstable->children().empty()) { unstable = unstable->children()[0]; } eventRecord().decays().erase(dec.first); eventRecord().decays()[unstable] = dec.second; // Update the momenta of any other particles in the decay chain // (for externally provided events) if ( !(eventRecord().decays()[unstable]->outgoing().empty()) ) eventRecord().updateDecayChainMom( unstable , eventRecord().decays()[unstable]); } else { if ( !(eventRecord().decays()[unstable]->outgoing().empty()) ) { // Update the momenta of any other particles in the decay chain // (for externally provided events) // Note this needs to be done for all decaying particles in the // outgoing/hard regardless of whether that particle radiated // or was involved in the reshuffling, this is due to the // transformation performed for IILightKinematics. if ( (find(eventRecord().outgoing().begin(), eventRecord().outgoing().end(), unstable) != eventRecord().outgoing().end()) || (find(eventRecord().hard().begin(), eventRecord().hard().end(), unstable) != eventRecord().hard().end()) ) eventRecord().updateDecayChainMom( unstable , eventRecord().decays()[unstable]); } } } eventRecord().currentDecay(PerturbativeProcessPtr()); } // Reshuffle outgoing partons from a decay process onto their constituent mass shells void DipoleShowerHandler::decayConstituentReshuffle(PerturbativeProcessPtr decayProc) { if ( Debug::level > 2 ){ // Test this function by comparing the // invariant mass of the outgoing decay // systems before and after reshuffling Lorentz5Momentum testOutMomBefore (ZERO,ZERO,ZERO,ZERO); Energy testInvMassBefore = ZERO; for ( auto const & testDecayOutItBefore : decayProc->outgoing() ) { testOutMomBefore += testDecayOutItBefore.first->momentum(); } testInvMassBefore = testOutMomBefore.m(); // decayReshuffle updates both the event record and the decay perturbative process if ( constituentReshuffler && ShowerHandler::currentHandler()->retConstituentMasses()) { constituentReshuffler->decayReshuffle(decayProc, eventRecord().outgoing(), eventRecord().hard(), eventRecord().intermediates()); } Lorentz5Momentum testOutMomAfter (ZERO,ZERO,ZERO,ZERO); Energy testInvMassAfter = ZERO; for ( auto const & testDecayOutItAfter : decayProc->outgoing() ) { testOutMomAfter += testDecayOutItAfter.first->momentum(); } testInvMassAfter = testOutMomAfter.m(); +#ifndef NDEBUG Energy incomingMass = decayProc->incoming()[0].first->momentum().m(); +#endif assert( abs(testInvMassBefore-incomingMass)/GeV < 1e-5 ); assert( abs(testInvMassBefore-testInvMassAfter)/GeV < 1e-5); }else{ // decayReshuffle updates both the event record and the decay perturbative process if ( constituentReshuffler && ShowerHandler::currentHandler()->retConstituentMasses() ) { constituentReshuffler->decayReshuffle(decayProc, eventRecord().outgoing(), eventRecord().hard(), eventRecord().intermediates()); } return; } } // Sets the scale of each particle in the dipole chains by finding the smallest //of several upper bound energy scales: the CMEnergy of the event, //the transverse mass of outgoing particles, the hardScale (maxPT or maxQ) //calculated for each dipole (in both configurations) and the veto scale for each particle void DipoleShowerHandler::hardScales(Energy2 muf) { // Initalise maximum pt as max CMEnergy of the event maxPt = generator()->maximumCMEnergy(); if ( restrictPhasespace() ) { // First interaction == hard collision (i.e. not a MPI collision) if ( !hardScaleIsMuF() || !firstInteraction() ) { if ( !eventRecord().outgoing().empty() ) { for ( auto const & p : eventRecord().outgoing() ) maxPt = min(maxPt,p->momentum().mt()); } //Look at any non-coloured outgoing particles in the current subprocess else { assert(!eventRecord().hard().empty()); Lorentz5Momentum phard(ZERO,ZERO,ZERO,ZERO); for ( auto const & p : eventRecord().hard()) phard += p->momentum(); Energy mhard = phard.m(); maxPt = mhard; } maxPt *= hardScaleFactor(); } else { maxPt = hardScaleFactor()*sqrt(muf); } muPt = maxPt; } else { muPt = hardScaleFactor()*sqrt(muf); } if ( doSubleadingNc ) { return; } for ( auto & ch : eventRecord().chains()) { // Note that minVetoScale is a value for each DipoleChain, not each dipole // It will contain the minimum veto scale from all of the dipoles in the chain Energy minVetoScale = -1.*GeV; for ( auto & dip : ch.dipoles()) { // max scale per config Energy maxFirst = ZERO; Energy maxSecond = ZERO; // Loop over the kernels for the given dipole. // For each dipole configuration, calculate ptMax (or QMax if virtuality ordering) // for each kernel and find the maximum for ( auto const & k : kernels) { pair conf = {true,false}; if ( k->canHandle(dip.index(conf)) ) { // Look in DipoleChainOrdering for this Energy scale = evolutionOrdering()->hardScale(dip.emitter(conf),dip.spectator(conf), dip.emitterX(conf),dip.spectatorX(conf), *k,dip.index(conf)); maxFirst = max(maxFirst,scale); } conf = {false,true}; if ( k->canHandle(dip.index(conf)) ) { Energy scale = evolutionOrdering()->hardScale(dip.emitter(conf),dip.spectator(conf), dip.emitterX(conf),dip.spectatorX(conf), *k,dip.index(conf)); maxSecond = max(maxSecond,scale); } } // Find the maximum value from comparing the maxScale found from maxPt and the vetoScale of the particle if ( dip.leftParticle()->vetoScale() >= ZERO ) { maxFirst = min(maxFirst,sqrt(dip.leftParticle()->vetoScale())); // minVetoScale is a value for each DipoleChain, not each dipole // It contains the minimum veto scale for all the dipoles in the entire DipoleChain if ( minVetoScale >= ZERO ) minVetoScale = min(minVetoScale,sqrt(dip.leftParticle()->vetoScale())); else minVetoScale = sqrt(dip.leftParticle()->vetoScale()); } if ( dip.rightParticle()->vetoScale() >= ZERO ) { maxSecond = min(maxSecond,sqrt(dip.rightParticle()->vetoScale())); if ( minVetoScale >= ZERO ) minVetoScale = min(minVetoScale,sqrt(dip.rightParticle()->vetoScale())); else minVetoScale = sqrt(dip.rightParticle()->vetoScale()); } // Set the emitterScale for both members of each dipole maxFirst = min(maxPt,maxFirst); dip.emitterScale({true,false},maxFirst); maxSecond = min(maxPt,maxSecond); dip.emitterScale({false,true},maxSecond); } // if the smallest veto scale (i.e. from all of the dipoles) // is smaller than the scale calculated for a particular // particle in a particular dipole, // replace the scale with the veto scale if ( !evolutionOrdering()->independentDipoles() && chainOrderVetoScales && minVetoScale >= ZERO ) { for ( auto & dip : ch.dipoles() ) { dip.leftScale(min(dip.leftScale(),minVetoScale)); dip.rightScale(min(dip.rightScale(),minVetoScale)); } } } } void DipoleShowerHandler::hardScalesSubleading(list candidates, Energy hardPt) { maxPt = hardPt;//generator()->maximumCMEnergy(); // Note that minVetoScale is a value for each competing dipole (i.e. all dipoles // for the subleading shower. // It will contain the minimum veto scale from all of the dipoles Energy minVetoScale = -1.*GeV; for ( list::iterator cand = candidates.begin(); cand != candidates.end(); ++cand ) { // max scale Energy maxScale = ZERO; // Loop over kernels for ( vector::ptr>::iterator k = kernels.begin(); k != kernels.end(); ++k ) { if ( (**k).canHandle(cand->index()) ) { Energy scale = evolutionOrdering()->hardScale(cand->emitter(),cand->spectator(), cand->emitterX(),cand->spectatorX(), **k,cand->index()); maxScale = max(maxScale,scale); } } if ( cand->emitter()->vetoScale() >= ZERO ) { maxScale = min(maxScale,sqrt(cand->emitter()->vetoScale())); if ( minVetoScale >= ZERO ) minVetoScale = min(minVetoScale,sqrt(cand->emitter()->vetoScale())); else minVetoScale = sqrt(cand->emitter()->vetoScale()); } maxScale = min(maxPt,maxScale); cand->scale(maxScale); } if ( !evolutionOrdering()->independentDipoles() && chainOrderVetoScales && minVetoScale >= ZERO ) { for ( list::iterator cand = candidates.begin(); cand != candidates.end(); ++cand ) { cand->scale(min(cand->scale(),minVetoScale)); } } } void DipoleShowerHandler::addCandidates(PPair particles, list& clist) const { DipoleSplittingInfo candidate; Energy2 scale = ZERO; pair is(particles.first == eventRecord().incoming().first, particles.second == eventRecord().incoming().second); if ( (is.first && !is.second) || (!is.first && is.second) ) { scale = -(particles.first->momentum() - particles.second->momentum()).m2(); } else { scale = (particles.first->momentum() + particles.second->momentum()).m2(); } DipoleIndex index(particles.first->dataPtr(),particles.second->dataPtr(), is.first ? eventRecord().pdfs().first : PDF(), is.second ? eventRecord().pdfs().second : PDF()); candidate.scale(sqrt(scale)); candidate.index(index); candidate.configuration(make_pair(true,false)); candidate.emitter(particles.first); candidate.emitterX(is.first ? eventRecord().fractions().first : 1.0); candidate.spectator(particles.second); candidate.spectatorX(is.second ? eventRecord().fractions().second : 1.0); clist.push_back(candidate); index.swap(); candidate.index(index); candidate.configuration(make_pair(false,true)); candidate.emitter(particles.second); candidate.emitterX(is.second ? eventRecord().fractions().second : 1.0); candidate.spectator(particles.first); candidate.spectatorX(is.first ? eventRecord().fractions().first : 1.0); clist.push_back(candidate); } void DipoleShowerHandler::getCandidates(list& clist) const { clist.clear(); for ( PList::const_iterator i = eventRecord().outgoing().begin(); i != eventRecord().outgoing().end(); ++i ) { PList::const_iterator j = i; ++j; for ( ; j != eventRecord().outgoing().end(); ++j ) { addCandidates(make_pair(*i,*j),clist); } // Changed order of *i and inc().first if ( eventRecord().incoming().first->coloured() ) addCandidates(make_pair(eventRecord().incoming().first,*i),clist); if ( eventRecord().incoming().second->coloured() ) addCandidates(make_pair(*i,eventRecord().incoming().second),clist); } if ( eventRecord().incoming().first->coloured() && eventRecord().incoming().second->coloured() ) { addCandidates(eventRecord().incoming(),clist); } } void DipoleShowerHandler::performSplitting(DipoleSplittingInfo& split) const { Ptr::tptr kinematics = split.splittingKinematics(); kinematics->generateKinematics(split.emitter()->momentum(), split.spectator()->momentum(), split); split.splitEmitter(split.emitterData()->produceParticle(kinematics->lastEmitterMomentum())); split.splitSpectator(split.spectatorData()->produceParticle(kinematics->lastSpectatorMomentum())); split.emission(split.emissionData()->produceParticle(kinematics->lastEmissionMomentum())); // Setting resolution scales for the particles split.emission()->scale(sqr(split.lastPt())); split.splitEmitter()->scale(sqr(split.lastPt())); split.splitSpectator()->scale(split.spectator()->scale()); PVector neighbours; if ( DipolePartonSplitter::colourConnected(split.emitter(), eventRecord().incoming().first) && split.emitter() != eventRecord().incoming().first ) neighbours.push_back(eventRecord().incoming().first); if ( DipolePartonSplitter::colourConnected(split.emitter(), eventRecord().incoming().second) && split.emitter() != eventRecord().incoming().second ) neighbours.push_back(eventRecord().incoming().second); for ( PList::const_iterator p = eventRecord().outgoing().begin(); p != eventRecord().outgoing().end(); ++p ) { if ( *p == split.emitter() ) continue; if ( DipolePartonSplitter::colourConnected(split.emitter(),*p) ) neighbours.push_back(*p); } assert(neighbours.size() == 1 || neighbours.size() == 2 ); if ( neighbours.size() == 2 ) { if ( UseRandom::rnd() < 0.5 ) swap(neighbours[0],neighbours[1]); } DipolePartonSplitter::split(split.emitter(),split.splitEmitter(),split.emission(), neighbours.front(),split.index().initialStateEmitter(),false); DipolePartonSplitter::change(split.spectator(),split.splitSpectator(), split.index().initialStateSpectator(),false); } Energy DipoleShowerHandler::nextSubleadingSplitting(Energy hardPt, Energy optHardPt, Energy optCutoff, const bool decay) { list candidates; getCandidates(candidates); hardScalesSubleading(candidates,hardPt); for ( list::iterator cand = candidates.begin(); cand != candidates.end(); cand++ ) { cand->scale(hardPt); } list::iterator split = candidates.end(); // Winner of all dipoles DipoleSplittingInfo winner; // Winner for the current iteration of the for loop DipoleSplittingInfo candWinner; Energy winnerScale = 0.0*GeV; Energy nextScale = 0.0*GeV; for ( list::iterator cand = candidates.begin(); cand != candidates.end(); cand++ ) { nextScale = getWinner(candWinner, cand->index(), cand->emitterX(),cand->spectatorX(), make_pair(true,false), cand->emitter(),cand->spectator(), hardPt, optHardPt, optCutoff); if ( nextScale > winnerScale ) { winnerScale = nextScale; winner = candWinner; split = cand; winnerIndex = winningKernelIndex;//check } } if ( split == candidates.end() ) return ZERO; if ( decay ) winner.isDecayProc( true ); split->fill(winner); performSplitting(*split); eventRecord().update(*split); for ( list::iterator dip = candidates.begin(); dip != candidates.end(); ++dip ) { if ( dip == split ) continue; dip->emission(split->emission()); if ( dip->emitter() == split->emitter() ) { dip->splitEmitter(split->splitEmitter()); } else { dip->splitEmitter(dip->emitter()); } if ( dip->spectator() == split->spectator() ) { dip->splitSpectator(split->splitSpectator()); } else { dip->splitSpectator(dip->spectator()); } } // Update the ShowerHandler of the splitting reweight. if ( doSubleadingNc ) { theSplittingReweight->updateCurrentHandler(); } return split->lastPt(); } Energy DipoleShowerHandler::getWinner(DipoleSplittingInfo& winner, const Dipole& dip, pair conf, Energy optHardPt, Energy optCutoff) { return getWinner(winner,dip.index(conf), dip.emitterX(conf),dip.spectatorX(conf), conf,dip.emitter(conf),dip.spectator(conf), dip.emitterScale(conf),optHardPt,optCutoff); } Energy DipoleShowerHandler::getWinner(SubleadingSplittingInfo& winner, Energy optHardPt, Energy optCutoff) { return getWinner(winner,winner.index(), winner.emitterX(),winner.spectatorX(), winner.configuration(), winner.emitter(),winner.spectator(), winner.startScale(),optHardPt,optCutoff); } Energy DipoleShowerHandler::getWinner(DipoleSplittingInfo& winner, const DipoleIndex& index, double emitterX, double spectatorX, pair conf, tPPtr emitter, tPPtr spectator, Energy startScale, Energy optHardPt, Energy optCutoff) { if ( !index.initialStateEmitter() && !doFSR() ) { winner.didStopEvolving(); return 0.0*GeV; } if ( index.initialStateEmitter() && !doISR() ) { winner.didStopEvolving(); return 0.0*GeV; } if ( index.incomingDecaySpectator() && !doFSR() ) { winner.didStopEvolving(); return 0.0*GeV; } // Currently do not split IF dipoles so // don't evaluate them in order to avoid // exceptions in the log if ( index.incomingDecayEmitter() ) { winner.didStopEvolving(); return 0.0*GeV; } DipoleSplittingInfo candidate; candidate.index(index); candidate.configuration(conf); candidate.emitterX(emitterX); candidate.spectatorX(spectatorX); candidate.emitter(emitter); candidate.spectator(spectator); if ( generators().find(candidate.index()) == generators().end() ) getGenerators(candidate.index(),theSplittingReweight); // // NOTE -- needs proper fixing at some point // // For some very strange reason, equal_range gives back // key ranges it hasn't been asked for. This particularly // happens e.g. for FI dipoles of the same kind, but different // PDF (hard vs MPI PDF). I can't see a reason for this, // as DipoleIndex properly implements comparison for equality // and (lexicographic) ordering; for the time being, we // use equal_range, extented by an explicit check for wether // the key is indeed what we wanted. See line after (*) comment // below. // // SW - Update 04/01/2016: Note - This caused a bug for me as I did not // include equality checks on the decay booleans in the == definition pair gens = generators().equal_range(candidate.index()); Energy winnerScale = 0.0*GeV; GeneratorMap::iterator winnerGen = generators().end(); for ( GeneratorMap::iterator gen = gens.first; gen != gens.second; ++gen ) { if ( doPartialUnweighting ) gen->second->doPartialUnweighting(referenceWeight); // (*) see NOTE above if ( !(gen->first == candidate.index()) ) continue; if ( startScale <= gen->second->splittingKinematics()->IRCutoff() ) continue; Energy dScale = gen->second->splittingKinematics()->dipoleScale(emitter->momentum(), spectator->momentum()); // in very exceptional cases happening in DIS if ( std::isnan( double(dScale/MeV) ) ) throw RedoShower(); candidate.scale(dScale); // Calculate the mass of the recoil system // for decay dipoles if ( candidate.index().incomingDecaySpectator() || candidate.index().incomingDecayEmitter() ) { Energy recoilMass = gen->second->splittingKinematics()->recoilMassKin(emitter->momentum(), spectator->momentum()); candidate.recoilMass(recoilMass); } // Store emitter and spectator masses, needed in kinematics if ( candidate.index().emitterData()->mass() != ZERO ) { if ( !candidate.index().offShellEmitter() ) candidate.emitterMass( emitter->nominalMass() ); else candidate.emitterMass( emitter->mass() ); } if ( candidate.index().spectatorData()->mass() != ZERO ) { if ( !candidate.index().offShellSpectator() ) candidate.spectatorMass( spectator->nominalMass() ); else candidate.spectatorMass( spectator->mass() ); } candidate.continuesEvolving(); Energy hardScale = evolutionOrdering()->maxPt(startScale,candidate,*(gen->second->splittingKernel())); Energy maxPossible = gen->second->splittingKinematics()->ptMax(candidate.scale(), candidate.emitterX(), candidate.spectatorX(), candidate, *gen->second->splittingKernel()); Energy ircutoff = optCutoff < gen->second->splittingKinematics()->IRCutoff() ? gen->second->splittingKinematics()->IRCutoff() : optCutoff; if ( maxPossible <= ircutoff ) { continue; } if ( maxPossible >= hardScale ){ candidate.hardPt(hardScale); } else { hardScale = maxPossible; candidate.hardPt(maxPossible); } gen->second->generate(candidate,currentWeights(),optHardPt,optCutoff); Energy nextScale = evolutionOrdering()->evolutionScale( gen->second->lastSplitting(),*(gen->second->splittingKernel())); if ( nextScale > winnerScale ) { winner.fill(candidate); gen->second->completeSplitting(winner); winnerGen = gen; winnerScale = nextScale; if ( continueSubleadingNc() ) winningKernelIndex = kernelIndex+1;//check } if ( continueSubleadingNc() ) { kernelIndex++;//check scales.push_back(nextScale);//check theWeightsVector.push_back(gen->second->splittingWeightVector()); } reweight(reweight() * gen->second->splittingWeight()); } if ( winnerGen == generators().end() ) { winner.didStopEvolving(); return 0.0*GeV; } if ( winner.stoppedEvolving() ) return 0.0*GeV; return winnerScale; } void DipoleShowerHandler::doCascade(unsigned int& emDone, Energy optHardPt, Energy optCutoff, const bool decay) { if ( nEmissions ) if ( emDone == nEmissions ) return; if ( doSubleadingNc ) { unsigned int subEmDone = 0; // Set the starting scale Energy hardPt = muPt; double wref = referenceWeight; while ( subEmDone < subleadingNcEmissionsLimit && hardPt != ZERO && continueSubleadingNc() ) { // Clear out the weights from the earlier step theWeightsVector.clear(); kernelIndex = 0;//check scales.clear();//check hardPt = nextSubleadingSplitting( hardPt, optHardPt, optCutoff, decay ); // Partial unweighting if ( doPartialUnweightingAtEmission ) { const double w = reweight(); if ( abs(w) < wref ) { if ( abs(w)/wref < UseRandom::rnd() ) { // Set weight to zero and end this event reweight(0.0); return; } else reweight( wref*w/abs(w) ); } // Update the reference weight after emission wref *= referenceWeight; } // When the winning scale is larger than the cutoff // remove the added weights that are under the winning scale if ( hardPt != ZERO ) { Energy maxq = 0.0*GeV; +#ifndef NDEBUG size_t iwinner = theWeightsVector.size();//check +#endif for ( size_t i = 0; i < theWeightsVector.size(); i++ ) { if ( theWeightsVector[i].size() > 0 ) { // get<2> is true for an accept step. if ( std::get<2>(theWeightsVector[i].back()) && std::get<0>(theWeightsVector[i].back()) > maxq) { maxq = std::get<0>(theWeightsVector[i].back()); +#ifndef NDEBUG iwinner = i;//check +#endif } } } assert(winnerIndex-1 == iwinner);//check double correctionWeight = 1.0; for ( size_t i = 0; i < theWeightsVector.size(); i++ ) { for ( size_t j = 0; j < theWeightsVector[i].size(); j++ ) { if ( std::get<0>(theWeightsVector[i][j]) < maxq ) correctionWeight *= std::get<1>(theWeightsVector[i][j]); } } reweight(reweight()/correctionWeight); } // Increment the number of subleading Nc emissions done subEmDone++; // Stop if the limit of emissions is reached if ( nEmissions ) if ( ++emDone == nEmissions ) return; } // Subleading shower done, prepare chains for the standard // dipole shower eventRecord().prepareChainsSubleading( decay ); // Set scales for ( list::iterator ch = eventRecord().chains().begin(); ch != eventRecord().chains().end(); ch++ ) { for ( list::iterator dp = ch->dipoles().begin(); dp != ch->dipoles().end(); dp++ ) { dp->emitterScale(make_pair(true,false),hardPt); dp->emitterScale(make_pair(false,true),hardPt); } } } DipoleSplittingInfo winner; DipoleSplittingInfo dipoleWinner; while ( eventRecord().haveChain() ) { - - // allow the dipole chain to be rearranged according to arXiv:1801.06113 - if( _rearrange && ( _rearrangeNEmissions < 0 || _rearrangeNEmissions >= int(emDone) ) ){ - eventRecord().currentChain().rearrange(_dipmax,_diplong); - } if ( verbosity > 2 ) { generator()->log() << "DipoleShowerHandler selecting splittings for the chain:\n" << eventRecord().currentChain() << flush; } list::iterator winnerDip = eventRecord().currentChain().dipoles().end(); Energy winnerScale = 0.0*GeV; Energy nextLeftScale = 0.0*GeV; Energy nextRightScale = 0.0*GeV; for ( list::iterator dip = eventRecord().currentChain().dipoles().begin(); dip != eventRecord().currentChain().dipoles().end(); ++dip ) { nextLeftScale = getWinner(dipoleWinner,*dip,{true,false},optHardPt,optCutoff); if ( nextLeftScale > winnerScale ) { winnerScale = nextLeftScale; winner = dipoleWinner; winnerDip = dip; } nextRightScale = getWinner(dipoleWinner,*dip,{false,true},optHardPt,optCutoff); if ( nextRightScale > winnerScale ) { winnerScale = nextRightScale; winner = dipoleWinner; winnerDip = dip; } if ( evolutionOrdering()->independentDipoles() ) { Energy dipScale = max(nextLeftScale,nextRightScale); if ( dip->leftScale() > dipScale ) dip->leftScale(dipScale); if ( dip->rightScale() > dipScale ) dip->rightScale(dipScale); } } if ( verbosity > 1 ) { if ( winnerDip != eventRecord().currentChain().dipoles().end() ) generator()->log() << "DipoleShowerHandler selected the splitting:\n" << winner << " for the dipole\n" << (*winnerDip) << flush; else generator()->log() << "DipoleShowerHandler could not select a splitting above the IR cutoff\n" << flush; } // pop the chain if no dipole did radiate if ( winnerDip == eventRecord().currentChain().dipoles().end() ) { eventRecord().popChain(); if ( theEventReweight && eventRecord().chains().empty() ) if ( (theEventReweight->firstInteraction() && firstInteraction()) || (theEventReweight->secondaryInteractions() && !firstInteraction()) ) { double w = theEventReweight->weightCascade(eventRecord().incoming(), eventRecord().outgoing(), eventRecord().hard(),theGlobalAlphaS); reweight(reweight()*w); } continue; } // Check if the produced splitting would be part // of a matrix element region in a multi jet merging. // If so, the optHardPt is set to the current winner scale and the slitting // is vetoed. Note: It is possible that the current scale is larger than the // merging scale but another shower configuration shows a scale that is // below the required scale. if(firstInteraction() && !decay){ if ( isMERegion( winnerScale , winner , winnerDip) ){ optHardPt=winnerScale; // Vetoed shower. continue; }else if( theMergingHelper ){ optHardPt=ZERO; } } // otherwise perform the splitting didRadiate = true; eventRecord().isMCatNLOSEvent(false); eventRecord().isMCatNLOHEvent(false); pair::iterator,list::iterator> children; DipoleChain* firstChain = nullptr; DipoleChain* secondChain = nullptr; // Generate the azimuthal angle if ( spinCorrelations() ) vertexRecord().generatePhi(winner,*winnerDip); if ( decay ) winner.isDecayProc( true ); // Note: the dipoles are updated in eventRecord().split(....) after the splitting, // hence the entire cascade is handled in doCascade // The dipole scales are updated in dip->split(....) if ( decay ) winner.isDecayProc( true ); eventRecord().split(winnerDip,winner,children,firstChain,secondChain); // Update the vertex record following the splitting if ( spinCorrelations() ) vertexRecord().update(winner); assert(firstChain && secondChain); evolutionOrdering()->setEvolutionScale(winnerScale,winner,*firstChain,children); if ( !secondChain->dipoles().empty() ) evolutionOrdering()->setEvolutionScale(winnerScale,winner,*secondChain,children); if ( verbosity > 1 ) { generator()->log() << "DipoleShowerHandler did split the last selected dipole into:\n" << (*children.first) << (*children.second) << flush; } if ( verbosity > 2 ) { generator()->log() << "After splitting the last selected dipole, " << "DipoleShowerHandler encountered the following chains:\n" << (*firstChain) << (*secondChain) << flush; } if ( theEventReweight ) if ( (theEventReweight->firstInteraction() && firstInteraction()) || (theEventReweight->secondaryInteractions() && !firstInteraction()) ) { double w = theEventReweight->weight(eventRecord().incoming(), eventRecord().outgoing(), eventRecord().hard(),theGlobalAlphaS); reweight(reweight()*w); } if ( nEmissions ) if ( ++emDone == nEmissions ) return; } } bool DipoleShowerHandler::isMERegion(const Energy winnerScale, const DipoleSplittingInfo & winner, list::iterator winnerDip ){ // First check if we have a merging setup adn additional conditions. if(!theMergingHelper)return false; if(!eventHandler()->currentCollision())return false; if(theMergingHelper->maxLegs()<=eventRecord().outgoing().size()+ eventRecord().hard().size() +2)//incoming return false; if( theMergingHelper->mergingScale() > winnerScale ) return false; // Now produce a temporary splitting to check if the final configuration is // part of the matrix element region pair::iterator,list::iterator> tmpchildren; DipoleSplittingInfo tmpwinner=winner; DipoleChain* tmpfirstChain = nullptr; DipoleChain* tmpsecondChain = nullptr; auto New=eventRecord().tmpsplit(winnerDip,tmpwinner, tmpchildren,tmpfirstChain, tmpsecondChain); // This is the same function that is used in the ME calculations of the // multi jet merging. if (theMergingHelper->matrixElementRegion(New.first, New.second, winnerScale, theMergingHelper->mergingScale())) { return true; }else return false; } bool DipoleShowerHandler::realign() { if ( !didRadiate && !intrinsicPtGenerator ) return false; if ( eventRecord().incoming().first->coloured() || eventRecord().incoming().second->coloured() ) { if ( eventRecord().incoming().first->momentum().perp2()/GeV2 < 1e-10 && eventRecord().incoming().second->momentum().perp2()/GeV2 < 1e-10 ) return false; pair inMomenta (eventRecord().incoming().first->momentum(), eventRecord().incoming().second->momentum()); LorentzRotation transform((inMomenta.first+inMomenta.second).findBoostToCM()); Axis dir = (transform * inMomenta.first).vect().unit(); Axis rot (-dir.y(),dir.x(),0); double theta = dir.theta(); if ( lastParticles().first->momentum().z() < ZERO ) theta = -theta; transform.rotate(-theta,rot); inMomenta.first = transform*inMomenta.first; inMomenta.second = transform*inMomenta.second; assert(inMomenta.first.z() > ZERO && inMomenta.second.z() < ZERO); Energy2 sHat = (eventRecord().incoming().first->momentum() + eventRecord().incoming().second->momentum()).m2(); pair masses(eventRecord().incoming().first->mass(), eventRecord().incoming().second->mass()); pair qs; if ( !eventRecord().incoming().first->coloured() ) { assert(masses.second == ZERO); qs.first = eventRecord().incoming().first->momentum().z(); qs.second = (sHat-sqr(masses.first))/(2.*(qs.first+sqrt(sqr(masses.first)+sqr(qs.first)))); } else if ( !eventRecord().incoming().second->coloured() ) { assert(masses.first == ZERO); qs.second = eventRecord().incoming().second->momentum().z(); qs.first = (sHat-sqr(masses.second))/(2.*(qs.second+sqrt(sqr(masses.second)+sqr(qs.second)))); } else { assert(masses.first == ZERO && masses.second == ZERO); if ( realignmentScheme == 0 ) { double yX = eventRecord().pX().rapidity(); double yInt = (transform*eventRecord().pX()).rapidity(); double dy = yX-yInt; qs.first = (sqrt(sHat)/2.)*exp(dy); qs.second = (sqrt(sHat)/2.)*exp(-dy); } else if ( realignmentScheme == 1 ) { Energy sS = sqrt((lastParticles().first->momentum() + lastParticles().second->momentum()).m2()); qs.first = eventRecord().fractions().first * sS / 2.; qs.second = eventRecord().fractions().second * sS / 2.; } } double beta = (qs.first-qs.second) / ( sqrt(sqr(masses.first)+sqr(qs.first)) + sqrt(sqr(masses.second)+sqr(qs.second)) ); transform.boostZ(beta); Lorentz5Momentum tmp; if ( eventRecord().incoming().first->coloured() ) { tmp = eventRecord().incoming().first->momentum(); tmp = transform * tmp; eventRecord().incoming().first->set5Momentum(tmp); } if ( eventRecord().incoming().second->coloured() ) { tmp = eventRecord().incoming().second->momentum(); tmp = transform * tmp; eventRecord().incoming().second->set5Momentum(tmp); } eventRecord().transform(transform); return true; } return false; } void DipoleShowerHandler::resetAlphaS(Ptr::tptr as) { for ( auto & k : kernels) { if ( !k->alphaS() ) k->alphaS(as); k->renormalizationScaleFreeze(theRenormalizationScaleFreeze); k->factorizationScaleFreeze(theFactorizationScaleFreeze); } // clear the generators to be rebuild // actually, there shouldn't be any generators // when this happens. generators().clear(); } void DipoleShowerHandler::resetReweight(Ptr::tptr rw) { for ( auto & g : generators() ) g.second->splittingReweight(rw); } void DipoleShowerHandler::getGenerators(const DipoleIndex& ind, Ptr::tptr rw) { bool gotone = false; for ( auto & k : kernels ) { if ( k->canHandle(ind) ) { if ( verbosity > 0 ) { generator()->log() << "DipoleShowerHandler encountered the dipole configuration\n" << ind << " in event number " << eventHandler()->currentEvent()->number() << "\nwhich can be handled by the splitting kernel '" << k->name() << "'.\n" << flush; } gotone = true; Ptr::ptr nGenerator = new_ptr(DipoleSplittingGenerator()); nGenerator->doCompensate(theDoCompensate); nGenerator->splittingKernel(k); if ( renormalizationScaleFactor() != 1. ) nGenerator->splittingKernel()->renormalizationScaleFactor(renormalizationScaleFactor()); if ( factorizationScaleFactor() != 1. ) nGenerator->splittingKernel()->factorizationScaleFactor(factorizationScaleFactor()); if ( !nGenerator->splittingReweight() ) nGenerator->splittingReweight(rw); nGenerator->splittingKernel()->freezeGrid(theFreezeGrid); nGenerator->splittingKernel()->detuning(theDetuning); GeneratorMap::const_iterator equivalent = generators().end(); for ( GeneratorMap::const_iterator eq = generators().begin(); eq != generators().end(); ++eq ) { if ( !eq->second->wrapping() ) if ( k->canHandleEquivalent(ind,*(eq->second->splittingKernel()),eq->first) ) { equivalent = eq; if ( verbosity > 0 ) { generator()->log() << "The dipole configuration " << ind << " can equivalently be handled by the existing\n" << "generator for configuration " << eq->first << " using the kernel '" << eq->second->splittingKernel()->name() << "'\n" << flush; } break; } } if ( equivalent != generators().end() ) { nGenerator->wrap(equivalent->second); } DipoleSplittingInfo dummy; dummy.index(ind); nGenerator->prepare(dummy); generators().insert({ind,nGenerator}); } } if ( !gotone ) { throw Exception() << "DipoleShowerHandler could not " << "find a splitting kernel which is able " << "to handle splittings off the dipole " << ind << ".\n" << "Please check the input files." << Exception::runerror; } } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void DipoleShowerHandler::doinit() { ShowerHandler::doinit(); if ( theGlobalAlphaS ) resetAlphaS(theGlobalAlphaS); // copy off-shell particle ids before showering from input vector to the // set used in the simulation if ( theColouredOffShellInShower.empty() ) { for(unsigned int ix=0;ixsplittingKinematics()->openZBoundaries() == 0 ) zChoice0 = true; else if ( k->splittingKinematics()->openZBoundaries() == 1 ) zChoice1 = true; else zChoiceOther = true; // either inconsistent or other option which cannot be handled by the matching if ( zChoice0 && zChoice1 ) { zChoiceOther = true; break; } } if ( zChoiceOther ) theZBoundaries = 2; else if ( zChoice1 ) theZBoundaries = 1; else if ( zChoice0 ) theZBoundaries = 0; } void DipoleShowerHandler::dofinish() { ShowerHandler::dofinish(); } void DipoleShowerHandler::doinitrun() { ShowerHandler::doinitrun(); } void DipoleShowerHandler::persistentOutput(PersistentOStream & os) const { os << kernels << theEvolutionOrdering << constituentReshuffler << intrinsicPtGenerator << theGlobalAlphaS << chainOrderVetoScales << nEmissions << discardNoEmissions << firstMCatNLOEmission << thePowhegDecayEmission //<< theAnalyseSpinCorrelations << doSubleadingNc << subleadingNcEmissionsLimit << densityOperatorEvolution << ounit(densityOperatorCutoff,GeV2) << doPartialUnweightingAtEmission << doPartialUnweighting << referenceWeight << cmecReweightFactor << negCMECScaling << realignmentScheme << verbosity << printEvent << ounit(theRenormalizationScaleFreeze,GeV) << ounit(theFactorizationScaleFreeze,GeV) << theShowerApproximation << theDoCompensate << theFreezeGrid << theDetuning << theEventReweight << theSplittingReweight << ounit(maxPt,GeV) << ounit(muPt,GeV)<< theMergingHelper << theColouredOffShellInShower << theInputColouredOffShellInShower - << _rearrange << _dipmax << _diplong << _rearrangeNEmissions << theZBoundaries; + << theZBoundaries; } void DipoleShowerHandler::persistentInput(PersistentIStream & is, int) { is >> kernels >> theEvolutionOrdering >> constituentReshuffler >> intrinsicPtGenerator >> theGlobalAlphaS >> chainOrderVetoScales >> nEmissions >> discardNoEmissions >> firstMCatNLOEmission >> thePowhegDecayEmission //>> theAnalyseSpinCorrelations >> doSubleadingNc >> subleadingNcEmissionsLimit >> densityOperatorEvolution >> iunit(densityOperatorCutoff,GeV2) >> doPartialUnweightingAtEmission >> doPartialUnweighting >> referenceWeight >> cmecReweightFactor >> negCMECScaling >> realignmentScheme >> verbosity >> printEvent >> iunit(theRenormalizationScaleFreeze,GeV) >> iunit(theFactorizationScaleFreeze,GeV) >> theShowerApproximation >> theDoCompensate >> theFreezeGrid >> theDetuning >> theEventReweight >> theSplittingReweight >> iunit(maxPt,GeV) >> iunit(muPt,GeV)>>theMergingHelper >> theColouredOffShellInShower >> theInputColouredOffShellInShower - >> _rearrange >> _dipmax >> _diplong >> _rearrangeNEmissions >> theZBoundaries; + >> theZBoundaries; } ClassDescription DipoleShowerHandler::initDipoleShowerHandler; // Definition of the static class description member. void DipoleShowerHandler::Init() { static ClassDocumentation documentation ("The DipoleShowerHandler class manages the showering using " "the dipole shower algorithm.", "The shower evolution was performed using the algorithm described in " "\\cite{Platzer:2009jq} and \\cite{Platzer:2011bc}.", "%\\cite{Platzer:2009jq}\n" "\\bibitem{Platzer:2009jq}\n" "S.~Platzer and S.~Gieseke,\n" "``Coherent Parton Showers with Local Recoils,''\n" " JHEP {\\bf 1101}, 024 (2011)\n" "arXiv:0909.5593 [hep-ph].\n" "%%CITATION = ARXIV:0909.5593;%%\n" "%\\cite{Platzer:2011bc}\n" "\\bibitem{Platzer:2011bc}\n" "S.~Platzer and S.~Gieseke,\n" "``Dipole Showers and Automated NLO Matching in Herwig,''\n" "arXiv:1109.6256 [hep-ph].\n" "%%CITATION = ARXIV:1109.6256;%%"); static RefVector interfaceKernels ("Kernels", "Set the splitting kernels to be used by the dipole shower.", &DipoleShowerHandler::kernels, -1, false, false, true, false, false); static Reference interfaceEvolutionOrdering ("EvolutionOrdering", "Set the evolution ordering to be used.", &DipoleShowerHandler::theEvolutionOrdering, false, false, true, false, false); static Reference interfaceConstituentReshuffler ("ConstituentReshuffler", "The object to be used to reshuffle partons to their constitutent mass shells.", &DipoleShowerHandler::constituentReshuffler, false, false, true, true, false); static Reference interfaceIntrinsicPtGenerator ("IntrinsicPtGenerator", "Set the object in charge to generate intrinsic pt for incoming partons.", &DipoleShowerHandler::intrinsicPtGenerator, false, false, true, true, false); static Reference interfaceGlobalAlphaS ("GlobalAlphaS", "Set a global strong coupling for all splitting kernels.", &DipoleShowerHandler::theGlobalAlphaS, false, false, true, true, false); // Start: Trying to add interface for the subleading Nc static Switch interfaceDoSubleadingNc ("DoSubleadingNc", "Switch on or off subleading Nc corrections.", &DipoleShowerHandler::doSubleadingNc, true, false, false); static SwitchOption interfaceDoSubleadingNcOn (interfaceDoSubleadingNc, "On", "Switch on subleading Nc corrections.", true); static SwitchOption interfaceDoSubleadingNcOff (interfaceDoSubleadingNc, "Off", "Switch off subleading Nc corrections.", false); // Limit for how many subleading Nc emissions should be calculated static Parameter interfaceSubleadingNcEmissionsLimit ("SubleadingNcEmissionsLimit", "Number of emissions to calculate subleading Nc corrections for.", &DipoleShowerHandler::subleadingNcEmissionsLimit,0,0,0, false, false, Interface::lowerlim); static Parameter interfaceDensityOperatorEvolution ("DensityOperatorEvolution", "Scheme for evolving the density operator.", &DipoleShowerHandler::densityOperatorEvolution,0,0,0, false, false, Interface::lowerlim); static Parameter interfaceDensityOperatorCutoff ("DensityOperatorCutoff", "Cutoff for momentum invariants for the density operator evolution.", &DipoleShowerHandler::densityOperatorCutoff,GeV2,1.0*GeV2,0.0*GeV2,0*GeV2, false, false, Interface::lowerlim); static Switch interfaceDoPartialUnweightingAtEmission ("DoPartialUnweightingAtEmission", "Switch on or off partial unweighting at the emission level.", &DipoleShowerHandler::doPartialUnweightingAtEmission,true,false,false); static SwitchOption interfaceDoPartialUnweightingAtEmissionOn (interfaceDoPartialUnweightingAtEmission, "On", "Switch on partial unweighting.", true); static SwitchOption interfaceDoPartialUnweightingAtEmissionOff (interfaceDoPartialUnweightingAtEmission, "Off", "Switch off partial unweighting.", false); static Switch interfaceDoPartialUnweighting ("DoPartialUnweighting", "Switch on or off partial unweighting at the dipole splitting level.", &DipoleShowerHandler::doPartialUnweighting,true,false,false); static SwitchOption interfaceDoPartialUnweightingOn (interfaceDoPartialUnweighting, "On", "Switch on partial unweighting.", true); static SwitchOption interfaceDoPartialUnweightingOff (interfaceDoPartialUnweighting, "Off", "Switch off partial unweighting.", false); static Parameter interfaceReferenceWeight ("ReferenceWeight", "Reference weight for the partial unweighting.", &DipoleShowerHandler::referenceWeight,0.1,0.0,0, false, false, Interface::lowerlim); static Parameter interfaceCMECReweightFactor ("CMECReweightFactor", "Factor used in the reweighting algorithm.", &DipoleShowerHandler::cmecReweightFactor,1.0,0.0,0, false, false, Interface::lowerlim); static Parameter interfaceNegCMECScaling ("NegCMECScaling", "Scaling factor for the negative colour matrix element corrections (CMECs).", &DipoleShowerHandler::negCMECScaling,0.0,0.0,0, false, false, Interface::lowerlim); static Switch interfaceRealignmentScheme ("RealignmentScheme", "The realignment scheme to use.", &DipoleShowerHandler::realignmentScheme, 0, false, false); static SwitchOption interfaceRealignmentSchemePreserveRapidity (interfaceRealignmentScheme, "PreserveRapidity", "Preserve the rapidity of non-coloured outgoing system.", 0); static SwitchOption interfaceRealignmentSchemeEvolutionFractions (interfaceRealignmentScheme, "EvolutionFractions", "Use momentum fractions as generated by the evolution.", 1); static SwitchOption interfaceRealignmentSchemeCollisionFrame (interfaceRealignmentScheme, "CollisionFrame", "Determine realignment from collision frame.", 2); static Switch interfaceChainOrderVetoScales ("ChainOrderVetoScales", "[experimental] Switch the chain ordering for veto scales on or off.", &DipoleShowerHandler::chainOrderVetoScales, true, false, false); static SwitchOption interfaceChainOrderVetoScalesYes (interfaceChainOrderVetoScales, "Yes", "Switch on chain ordering for veto scales.", true); static SwitchOption interfaceChainOrderVetoScalesNo (interfaceChainOrderVetoScales, "No", "Switch off chain ordering for veto scales.", false); interfaceChainOrderVetoScales.rank(-1); static Parameter interfaceNEmissions ("NEmissions", "[debug option] Limit the number of emissions to be generated. Zero does not limit the number of emissions.", &DipoleShowerHandler::nEmissions, 0, 0, 0, false, false, Interface::lowerlim); interfaceNEmissions.rank(-1); static Switch interfaceDiscardNoEmissions ("DiscardNoEmissions", "[debug option] Discard events without radiation.", &DipoleShowerHandler::discardNoEmissions, false, false, false); static SwitchOption interfaceDiscardNoEmissionsYes (interfaceDiscardNoEmissions, "Yes", "Discard events without radiation.", true); static SwitchOption interfaceDiscardNoEmissionsNo (interfaceDiscardNoEmissions, "No", "Do not discard events without radiation.", false); interfaceDiscardNoEmissions.rank(-1); static Switch interfaceFirstMCatNLOEmission ("FirstMCatNLOEmission", "[debug option] Only perform the first MC@NLO emission.", &DipoleShowerHandler::firstMCatNLOEmission, false, false, false); static SwitchOption interfaceFirstMCatNLOEmissionYes (interfaceFirstMCatNLOEmission, "Yes", "Perform only the first MC@NLO emission.", true); static SwitchOption interfaceFirstMCatNLOEmissionNo (interfaceFirstMCatNLOEmission, "No", "Produce all emissions.", false); interfaceFirstMCatNLOEmission.rank(-1); static Parameter interfaceVerbosity ("Verbosity", "[debug option] Set the level of debug information provided.", &DipoleShowerHandler::verbosity, 0, 0, 0, false, false, Interface::lowerlim); interfaceVerbosity.rank(-1); static Parameter interfacePrintEvent ("PrintEvent", "[debug option] The number of events for which debugging information should be provided.", &DipoleShowerHandler::printEvent, 0, 0, 0, false, false, Interface::lowerlim); interfacePrintEvent.rank(-1); static Parameter interfaceRenormalizationScaleFreeze ("RenormalizationScaleFreeze", "The freezing scale for the renormalization scale.", &DipoleShowerHandler::theRenormalizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter interfaceFactorizationScaleFreeze ("FactorizationScaleFreeze", "The freezing scale for the factorization scale.", &DipoleShowerHandler::theFactorizationScaleFreeze, GeV, 2.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Switch interfaceDoCompensate ("DoCompensate", "", &DipoleShowerHandler::theDoCompensate, false, false, false); static SwitchOption interfaceDoCompensateYes (interfaceDoCompensate, "Yes", "", true); static SwitchOption interfaceDoCompensateNo (interfaceDoCompensate, "No", "", false); static Parameter interfaceFreezeGrid ("FreezeGrid", "", &DipoleShowerHandler::theFreezeGrid, 500000, 1, 0, false, false, Interface::lowerlim); static Parameter interfaceDetuning ("Detuning", "A value to detune the overestimate kernel.", &DipoleShowerHandler::theDetuning, 1.0, 1.0, 0, false, false, Interface::lowerlim); static Reference interfaceEventReweight ("EventReweight", "", &DipoleShowerHandler::theEventReweight, false, false, true, true, false); static Reference interfaceSplittingReweight ("SplittingReweight", "Set the splitting reweight.", &DipoleShowerHandler::theSplittingReweight, false, false, true, true, false); static Switch interfacePowhegDecayEmission ("PowhegDecayEmission", "Use Powheg style emission for the decays", &DipoleShowerHandler::thePowhegDecayEmission, true, false, false); static SwitchOption interfacePowhegDecayEmissionYes (interfacePowhegDecayEmission,"Yes","Powheg decay emission on", true); static SwitchOption interfacePowhegDecayEmissionNo (interfacePowhegDecayEmission,"No","Powheg decay emission off", false); static ParVector interfaceOffShellInShower ("OffShellInShower", "PDG codes of the coloured particles that can be off-shell in the process.", &DipoleShowerHandler::theInputColouredOffShellInShower, -1, 0l, -10000000l, 10000000l, false, false, Interface::limited); /* static Switch interfaceAnalyseSpinCorrelations ("AnalyseSpinCorrelations", "Record the information required for the spin correlation analyis.", &DipoleShowerHandler::theAnalyseSpinCorrelations, false, false, false); static SwitchOption interfaceAnalyseSpinCorrelationsYes (interfaceAnalyseSpinCorrelations,"Yes","Record the information for analysing the spin correlations.", true); static SwitchOption interfaceAnalyseSpinCorrelationsNo (interfaceAnalyseSpinCorrelations,"No","Do not record extra information.", false); */ - static Switch interfacerearrange - ("Rearrange", - "Allow rearranging of dipole chains according to arXiv:1801.06113", - &DipoleShowerHandler::_rearrange, false, false, false); - - static SwitchOption interfacerearrangeYes - (interfacerearrange,"Yes","_rearrange on", true); - - static SwitchOption interfacerearrangeNo - (interfacerearrange,"No","_rearrange off", false); - - static Parameter interfacedipmax - ("DipMax", - "Allow rearrangment of color chains with ME including dipmax dipoles.", - &DipoleShowerHandler::_dipmax, 0, 0, 0, - false, false, Interface::lowerlim); - - static Parameter interfacediplong - ("DipLong", - "Dipole chains with more than dipmax dipoles are treated as long. \ - diplong=3 rearranges these chains with eeuugg MEs, \ - diplong=4 rearranges these chains with eeuuggg MEs (slower), \ - diplong=5 rearranges these chains with eeuugggg MEs (slow).\ - Note: Numerically there is no difference between the options. ", - &DipoleShowerHandler::_diplong, 0, 0, 0, - false, false, Interface::lowerlim); - - static Parameter interfacedcorrectNemissions - ("RearrangeNEmissions", - "Allow rearrangment of color chains up to the nth emission.", - &DipoleShowerHandler::_rearrangeNEmissions, 0, 0, 0, - false, false, Interface::lowerlim); + } diff --git a/Shower/Dipole/DipoleShowerHandler.h b/Shower/Dipole/DipoleShowerHandler.h --- a/Shower/Dipole/DipoleShowerHandler.h +++ b/Shower/Dipole/DipoleShowerHandler.h @@ -1,785 +1,764 @@ // -*- C++ -*- // // DipoleShowerHandler.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_DipoleShowerHandler_H #define HERWIG_DipoleShowerHandler_H // // This is the declaration of the DipoleShowerHandler class. // #include "Herwig/Shower/ShowerHandler.h" #include "Herwig/Shower/Dipole/DipoleShowerHandler.fh" #include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h" #include "Herwig/Shower/Dipole/Base/DipoleSplittingReweight.h" #include "Herwig/Shower/Dipole/Kernels/DipoleSplittingKernel.h" #include "Herwig/Shower/Dipole/Base/DipoleSplittingGenerator.h" #include "Herwig/Shower/Dipole/Base/DipoleEventRecord.h" #include "Herwig/Shower/Dipole/Base/DipoleEvolutionOrdering.h" #include "Herwig/Shower/Dipole/Base/DipoleEventReweight.h" #include "Herwig/Shower/Dipole/Utility/ConstituentReshuffler.h" #include "Herwig/Shower/Dipole/Utility/IntrinsicPtGenerator.h" #include "Herwig/MatrixElement/Matchbox/Base/MergerBase.h" #include "Herwig/MatrixElement/Matchbox/Matching/ShowerApproximation.h" #include "Herwig/Shower/Dipole/SpinCorrelations/DipoleVertexRecord.h" #include "Herwig/MatrixElement/Matchbox/Utility/DensityOperator.h" #include namespace Herwig { using namespace ThePEG; /** * \ingroup DipoleShower * \author Simon Platzer, Stephen Webster * * \brief The DipoleShowerHandler class manages the showering using * the dipole shower algorithm. * * @see \ref DipoleShowerHandlerInterfaces "The interfaces" * defined for DipoleShowerHandler. */ class DipoleShowerHandler: public ShowerHandler { friend class Merger; public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ DipoleShowerHandler(); /** * The destructor. */ virtual ~DipoleShowerHandler(); //@} public: inline void colourPrint(); /** * Indicate a problem in the shower. */ struct RedoShower {}; /** * Insert an additional splitting kernel. */ void addSplitting(Ptr::ptr sp) { kernels.push_back(sp); } /** * Reset the alpha_s for all splitting kernels. */ void resetAlphaS(Ptr::tptr); virtual void cascade(tPVector); /** * Reset the splitting reweight for all splitting kernels. */ void resetReweight(Ptr::tptr); /** * Return true, if the shower handler can generate a truncated * shower for POWHEG style events generated using Matchbox */ virtual bool canHandleMatchboxTrunc() const { return false; } /** * Return true, if this cascade handler will perform reshuffling from hard * process masses. */ virtual bool isReshuffling() const { return false; } /** * Return the relevant hard scale to be used in the profile scales */ virtual Energy hardScale() const { return muPt; } /** * Calculate the alpha_s value the shower uses for Q. */ double as(Energy Q)const{return theGlobalAlphaS->value(sqr(Q));} /** * Return the number of scale dependent active flavours from * the alpha_s object. */ double Nf(Energy Q)const{return theGlobalAlphaS->Nf(sqr(Q));} /* * Access the vertex record */ DipoleVertexRecord& vertexRecord() { return theVertexRecord; } /** * Return the event record */ const DipoleVertexRecord& vertexRecord() const { return theVertexRecord; } /** * Set the pointer to the Merging Helper. * Used by the merging factory. */ void setMerger(Ptr::ptr mh){theMergingHelper=mh;} public: /** * Return the dictionary for the incoming particles and outgoing partons * in the event, will be empty if subleading Nc is turned off. */ const map& particleIndices() const { return eventRecord().particleIndices(); } /** * Return the particle data vector of the particles in the event, will * be empty if subleading Nc is turned off. */ const cPDVector& particlesAfter() const { return eventRecord().particlesAfter(); } /** * Return the density operator from the event record. */ DensityOperator& densityOperator() { return eventRecord().densityOperator(); } /** * Return the colour matrix element correction map, will be empty if * subleading Nc is turned off. NOT USED, REMOVE */ const map,pair >,double>& correlatorMap() const { return eventRecord().densityOperator().correlatorMap(); } /** * Return the colour basis used in the density operator. NOT USED, REMOVE */ Ptr::tptr colourBasis() { return eventRecord().densityOperator().colourBasis(); } /** * Return the continue subleading Nc flag from the event record. */ bool continueSubleadingNc() const { return eventRecord().getContinueSubleadingNc(); } protected: /** * Add the possible splitting candidates given a pair of emitting particles */ void addCandidates(PPair particles, list& clist) const; /** * Get all possible radiating dipoles */ void getCandidates(list& clist) const; /** * Perform a splitting independent of any chains */ void performSplitting(DipoleSplittingInfo&) const; /** * Generate the next subleading Nc improved splitting and return the scale */ Energy nextSubleadingSplitting(Energy hardPt, Energy optHardPt, Energy optCutoff, const bool decay); protected: typedef multimap::ptr> GeneratorMap; /** * The main method which manages the showering of a subprocess. */ virtual tPPair cascade(tSubProPtr sub, XCombPtr xcomb) { return cascade(sub,xcomb,ZERO,ZERO); } /** * The main method which manages the showering of a subprocess. */ tPPair cascade(tSubProPtr sub, XCombPtr xcomb, Energy optHardPt, Energy optCutoff); /** * Build splitting generators for the given * dipole index. */ void getGenerators(const DipoleIndex&, Ptr::tptr rw = Ptr::tptr()); /** * Setup the hard scales. */ void hardScales(Energy2 scale); /** * Setup the hard scales of the dipoles after subleading emissions.//debug */ void hardScalesSubleading(list candidates,Energy hardPt); /** * Return the evolution ordering */ Ptr::tptr evolutionOrdering() const { return theEvolutionOrdering; } /** * Reshuffle to constituent mass shells */ void constituentReshuffle(); /** * Reshuffle to constituent mass shells */ void decayConstituentReshuffle( PerturbativeProcessPtr decayProc); /** * Access the generator map */ GeneratorMap& generators() { return theGenerators; } /** * Access the event record */ DipoleEventRecord& eventRecord() { return theEventRecord; } /** * Return the event record */ const DipoleEventRecord& eventRecord() const { return theEventRecord; } /** * Return the splitting kernels. */ const vector::ptr>& splittingKernels() const { return kernels; } /** * Return the set of offshell parton ids. **/ const set& offShellPartons() { return theColouredOffShellInShower; } /** * In a merging setup this function checks if the next shower * configuration is part of the matrix element region. */ bool isMERegion(const Energy winnerScale, const DipoleSplittingInfo & winner, const list::iterator winnerDip); /** * Realign the event such as to have the incoming partons along thre * beam axes. */ bool realign(); /** * The choice of z boundaries; 0 = restricted, 1 = open, 2 = mixed/other */ virtual int showerPhaseSpaceOption() const { return theZBoundaries; } protected: /** * Perform the cascade. */ void doCascade(unsigned int& emDone, Energy optHardPt = ZERO, Energy optCutoff = ZERO, const bool decay = false); /** * Set the number of emissions **/ void setNEmissions(unsigned int n){nEmissions=n;} /** * Get the winning splitting for the * given dipole and configuration. */ Energy getWinner(DipoleSplittingInfo& winner, const Dipole& dip, pair conf, Energy optHardPt = ZERO, Energy optCutoff = ZERO); /** * Get the winning splitting for the * given dipole and configuration. */ Energy getWinner(DipoleSplittingInfo& winner, Energy optHardPt = ZERO, Energy optCutoff = ZERO); /** * Get the winning splitting for the * given dipole and configuration. */ Energy getWinner(SubleadingSplittingInfo& winner, Energy optHardPt = ZERO, Energy optCutoff = ZERO); /** * Get the winning splitting for the * given dipole and configuration. */ Energy getWinner(DipoleSplittingInfo& winner, const DipoleIndex& index, double emitterX, double spectatorX, pair conf, tPPtr emitter, tPPtr spectator, Energy startScale, Energy optHardPt = ZERO, Energy optCutoff = ZERO); public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). 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(); /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); /** * Finalize this object. Called in the run phase just after a * run has ended. Used eg. to write out statistics. */ virtual void dofinish(); //@} private: /** * The splitting kernels to be used. */ vector::ptr> kernels; /** * The evolution ordering considered */ Ptr::ptr theEvolutionOrdering; /** * The ConstituentReshuffler to be used */ Ptr::ptr constituentReshuffler; /** * The intrinsic pt generator to be used. */ Ptr::ptr intrinsicPtGenerator; /** * A global alpha_s to be used for all splitting kernels. */ Ptr::ptr theGlobalAlphaS; /** * Apply chain ordering to events from matrix * element corrections. */ bool chainOrderVetoScales; /** * Limit the number of emissions. * Limit applied if > 0. */ unsigned int nEmissions; /** * Discard events which did not radiate. */ bool discardNoEmissions; /** * Perform the first MC@NLO emission only. */ bool firstMCatNLOEmission; /** * True if powheg style emissions are to be used in the decays */ bool thePowhegDecayEmission; /** * Switch to record information required for the * nearest neighbour analysis. */ //bool theAnalyseSpinCorrelations; /** * The realignment scheme */ int realignmentScheme; /** * Switch on or off subleading Nc corrections */ bool doSubleadingNc; /** * Number of emissions to do subleading Nc corrections to. */ size_t subleadingNcEmissionsLimit; /** * Current reference weight used for partial unweighting of the * subleading colour shower (updated each emission). */ int currentReferenceWeight; /** * Integer used to set which method of evolving the density operator * to use: * 0 - Vijk is Eikonal but there is a cutoff. * 1 - Vijk is Eikonal. * 2 - Vijk=1 for all i,j,k. * 3 - Semi-leading Nc, Vijk=0 for all */ int densityOperatorEvolution; /** * Cutoff scale for the invariants (e.g. pEmitter*pEmission) in the * Eikonal dipole kernel, Vijk. */ Energy2 densityOperatorCutoff; /** * Switch on or off partial unweighting in after each subleading emission. */ bool doPartialUnweightingAtEmission; /** * Switch on or off partial unweighting in the splitting generator. */ bool doPartialUnweighting; /** * Reference weight for the partial unweighting. */ double referenceWeight; /** * Factor changing the acceptance probability for the veto algorithm. */ double cmecReweightFactor; /** * Scaling factor for the negative colour matrix element corrections. */ double negCMECScaling; private: /** * The verbosity level. * 0 - print no info * 1 - print diagnostic information on setting up * splitting generators etc. * 2 - print detailed event information for up to * printEvent events. * 3 - print dipole chains after each splitting. */ int verbosity; /** * See verbosity. */ int printEvent; private: /** * The splitting generators indexed by the dipole * indices they can work on. */ GeneratorMap theGenerators; /** * The evnt record used. */ DipoleEventRecord theEventRecord; /** * The vertex record. **/ DipoleVertexRecord theVertexRecord; /** * The number of shoer tries so far. */ unsigned int nTries; /** * Whether or not we did radiate anything */ bool didRadiate; /** * Whether or not we did realign the event */ bool didRealign; /** * Vector of candidate splittings containing a vector of the * weights, scale and a bool for every step in the reweighted * veto algorithm. The bool is true for an accept step. */ vector > > theWeightsVector; /** * Winning candidate index. */ size_t winnerIndex;//debug size_t kernelIndex;//debug size_t winningKernelIndex;//debug vector scales;//debug private: /** * A freezing value for the renormalization scale */ Energy theRenormalizationScaleFreeze; /** * A freezing value for the factorization scale */ Energy theFactorizationScaleFreeze; /** * The matching subtraction, if appropriate */ Ptr::tptr theShowerApproximation; /** * True, if sampler should apply compensation */ bool theDoCompensate; /** * Return the number of accepted points after which the grid should * be frozen */ unsigned long theFreezeGrid; /** * The detuning factor applied to the sampling overestimate kernel */ double theDetuning; /** * A pointer to the dipole event reweight object */ Ptr::ptr theEventReweight; /** * A pointer to a global dipole splitting reweight */ Ptr::ptr theSplittingReweight; /** * True if no warnings have been issued yet */ static bool firstWarn; /** * The shower starting scale for the last event encountered */ Energy maxPt; /** * The shower hard scale for the last event encountered */ Energy muPt; /** * The merging helper takes care of merging multiple LO and NLO * cross sections. Here we need to check if an emission would * radiate in the matrix element region of an other multipicity. * If so, the emission is vetoed. */ Ptr::ptr theMergingHelper; /** * PDG codes of the partons which can have an off-shell mass, * this is fast storage for use during running */ set theColouredOffShellInShower; /** * PDG codes of the partons which can have an off-shell mass, * this is a vector that is interfaced so they can be changed */ vector theInputColouredOffShellInShower; /** - * Allow the dipole chains to be rearranged - */ - bool _rearrange=false; - - /** - * number of maximal ME dipoles in the rearrangement. - */ - unsigned int _dipmax=3; - - /** - * If a chain is considered long (more than dipmax dipoles) - * ME with diplong dipoles are used to test for rearrangement. - */ - unsigned int _diplong=3; - - /** - * Number of emissions to be rearranged. - */ - int _rearrangeNEmissions=-1; - - /** * The choice of z boundaries; 0 = restricted, 1 = open, 2 = mixed/other */ int theZBoundaries; private: /** * The static object used to initialize the description of this class. * Indicates that this is a concrete class with persistent data. */ static ClassDescription initDipoleShowerHandler; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ DipoleShowerHandler & operator=(const DipoleShowerHandler &) = delete; }; } #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of DipoleShowerHandler. */ template <> struct BaseClassTrait { /** Typedef of the first base class of DipoleShowerHandler. */ typedef Herwig::ShowerHandler NthBase; }; /** This template specialization informs ThePEG about the name of * the DipoleShowerHandler class and the shared object where it is defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "Herwig::DipoleShowerHandler"; } /** * The name of a file containing the dynamic library where the class * DipoleShowerHandler is implemented. It may also include several, space-separated, * libraries if the class DipoleShowerHandler depends on other classes (base classes * excepted). In this case the listed libraries will be dynamically * linked in the order they are specified. */ static string library() { return "HwDipoleShower.so"; } }; /** @endcond */ } #endif /* HERWIG_DipoleShowerHandler_H */ diff --git a/Shower/Dipole/Kernels/DipoleSplittingKernel.cc b/Shower/Dipole/Kernels/DipoleSplittingKernel.cc --- a/Shower/Dipole/Kernels/DipoleSplittingKernel.cc +++ b/Shower/Dipole/Kernels/DipoleSplittingKernel.cc @@ -1,408 +1,411 @@ // -*- C++ -*- // // DipoleSplittingKernel.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 DipoleSplittingKernel class. // #include "DipoleSplittingKernel.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/Shower/ShowerHandler.h" using namespace Herwig; DipoleSplittingKernel::DipoleSplittingKernel() : HandlerBase(), theScreeningScale(0.0*GeV), thePresamplingPoints(2000), theMaxtry(100000), theFreezeGrid(500000), theDetuning(1.0), theStrictLargeN(false), theFactorizationScaleFactor(1.0), theRenormalizationScaleFactor(1.0), theRenormalizationScaleFreeze(1.*GeV), theFactorizationScaleFreeze(1.*GeV), theVirtualitySplittingScale(false), theCMWScheme(0), presampling(false) {} DipoleSplittingKernel::~DipoleSplittingKernel() {} +// initialize static variable out of line +double DipoleSplittingKernel::theMaxPDFRatio = 1000000.; + // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void DipoleSplittingKernel::persistentOutput(PersistentOStream & os) const { os << theAlphaS << ounit(theScreeningScale,GeV) << theSplittingKinematics << thePDFRatio << thePresamplingPoints << theMaxtry << theFreezeGrid << theDetuning << theFlavour << theMCCheck << theStrictLargeN << theFactorizationScaleFactor << theRenormalizationScaleFactor << ounit(theRenormalizationScaleFreeze,GeV) << ounit(theFactorizationScaleFreeze,GeV) << theVirtualitySplittingScale<> theAlphaS >> iunit(theScreeningScale,GeV) >> theSplittingKinematics >> thePDFRatio >> thePresamplingPoints >> theMaxtry >> theFreezeGrid >> theDetuning >> theFlavour >> theMCCheck >> theStrictLargeN >> theFactorizationScaleFactor >> theRenormalizationScaleFactor >> iunit(theRenormalizationScaleFreeze,GeV) >> iunit(theFactorizationScaleFreeze,GeV) >> theVirtualitySplittingScale>>theCMWScheme>>theUseThisKernel; } double DipoleSplittingKernel::alphaPDF(const DipoleSplittingInfo& split, Energy optScale, double rScaleFactor, double fScaleFactor) const { Energy pt = optScale == ZERO ? split.lastPt() : optScale; Energy2 scale = ZERO; if ( !virtualitySplittingScale() ) { scale = sqr(pt) + sqr(theScreeningScale); } else { scale = sqr(splittingKinematics()->QFromPt(pt,split)) + sqr(theScreeningScale); } Energy2 fScale = sqr(theFactorizationScaleFactor*fScaleFactor)*scale; fScale = max( fScale , sqr(factorizationScaleFreeze()) ); Energy2 rScale = sqr(theRenormalizationScaleFactor*rScaleFactor)*scale; rScale = max( rScale , sqr(renormalizationScaleFreeze()) ); if(split.calcFixedExpansion()){ fScale = max( sqr(split.fixedScale()) , sqr(factorizationScaleFreeze()) ); rScale = max( sqr(split.fixedScale()) , sqr(renormalizationScaleFreeze()) ); } double alphas = 1.0; double pdf = 1.0; // check if we are potentially reweighting and cache evaluations bool evaluatePDF = true; bool evaluateAlphaS = true; bool variations = !ShowerHandler::currentHandler()->showerVariations().empty() && !presampling; if ( variations ) { map::const_iterator pit = thePDFCache.find(fScaleFactor); evaluatePDF = (pit == thePDFCache.end()); if ( !evaluatePDF ) { pdf = pit->second; } map::const_iterator ait = theAlphaSCache.find(rScaleFactor); evaluateAlphaS = (ait == theAlphaSCache.end()); if ( !evaluateAlphaS ) { alphas = ait->second; } } if ( evaluateAlphaS ){ if (theCMWScheme==0||split.calcFixedExpansion()) { alphas = alphaS()->value(rScale); }else if(theCMWScheme==1){ alphas = alphaS()->value(rScale); alphas *=1.+(3.*(67./18.-1./6.*sqr(Constants::pi)) -5./9.*alphaS()->Nf(rScale))* alphas/2./Constants::pi; }else if(theCMWScheme==2){ double kg=exp(-(67.-3.*sqr(Constants::pi)-10/3*alphaS()->Nf(rScale)) /(33.-2.*alphaS()->Nf(rScale))); Energy2 cmwscale2=max(kg*rScale, sqr(renormalizationScaleFreeze()) ); alphas = alphaS()->value(cmwscale2); }else{ throw Exception() << "This CMW-Scheme is not implemented." << Exception::abortnow; } } if ( evaluatePDF ) { if ( split.index().initialStateEmitter() ) { assert(pdfRatio()); pdf *= split.lastEmitterZ() * (*pdfRatio())(split.index().emitterPDF(), fScale, split.index().emitterData(),split.emitterData(), split.emitterX(),split.lastEmitterZ()); } if ( split.index().initialStateSpectator() ) { assert(pdfRatio()); pdf *= split.lastSpectatorZ() * (*pdfRatio())(split.index().spectatorPDF(), fScale, split.index().spectatorData(),split.spectatorData(), split.spectatorX(),split.lastSpectatorZ()); } } if ( evaluatePDF && variations ) { - thePDFCache[fScaleFactor] = pdf; + thePDFCache[fScaleFactor] = min(pdf,theMaxPDFRatio); } if ( evaluateAlphaS && variations ) { theAlphaSCache[rScaleFactor] = alphas; } - double ret = pdf* + double ret = min(pdf,theMaxPDFRatio)* (split.calcFixedExpansion()? 1.:(alphas / (2.*Constants::pi))); if ( ret < 0. ) ret = 0.; return ret; } void DipoleSplittingKernel::accept(const DipoleSplittingInfo& split, double, double, map& weights) const { if ( ShowerHandler::currentHandler()->showerVariations().empty() ) return; double reference = alphaPDF(split); assert(reference > 0.); for ( map::const_iterator var = ShowerHandler::currentHandler()->showerVariations().begin(); var != ShowerHandler::currentHandler()->showerVariations().end(); ++var ) { if ( ( ShowerHandler::currentHandler()->firstInteraction() && var->second.firstInteraction ) || ( !ShowerHandler::currentHandler()->firstInteraction() && var->second.secondaryInteractions ) ) { double varied = alphaPDF(split,ZERO, var->second.renormalizationScaleFactor, var->second.factorizationScaleFactor); if ( varied != reference ) { map::iterator wi = weights.find(var->first); if ( wi != weights.end() ) wi->second *= varied/reference; else weights[var->first] = varied/reference; } } } } void DipoleSplittingKernel::veto(const DipoleSplittingInfo& split, double p, double r, map& weights) const { if ( ShowerHandler::currentHandler()->showerVariations().empty() ) return; double reference = alphaPDF(split); // this is dangerous, but we have no other choice currently -- need to // carefully check for the effects; the assumption is that if the central // one ius zero, then so will be the variations. if ( reference == 0.0 ) return; for ( map::const_iterator var = ShowerHandler::currentHandler()->showerVariations().begin(); var != ShowerHandler::currentHandler()->showerVariations().end(); ++var ) { if ( ( ShowerHandler::currentHandler()->firstInteraction() && var->second.firstInteraction ) || ( !ShowerHandler::currentHandler()->firstInteraction() && var->second.secondaryInteractions ) ) { double varied = alphaPDF(split,ZERO, var->second.renormalizationScaleFactor, var->second.factorizationScaleFactor); if ( varied != reference ) { map::iterator wi = weights.find(var->first); if ( wi != weights.end() ) wi->second *= (r - varied*p/reference) / (r-p); else weights[var->first] = (r - varied*p/reference) / (r-p); } } } } AbstractClassDescription DipoleSplittingKernel::initDipoleSplittingKernel; // Definition of the static class description member. void DipoleSplittingKernel::Init() { static ClassDocumentation documentation ("DipoleSplittingKernel is the base class for all kernels " "used within the dipole shower."); static Reference interfaceAlphaS ("AlphaS", "The strong coupling to be used by this splitting kernel.", &DipoleSplittingKernel::theAlphaS, false, false, true, true, false); static Parameter interfaceScreeningScale ("ScreeningScale", "A colour screening scale", &DipoleSplittingKernel::theScreeningScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Reference interfaceSplittingKinematics ("SplittingKinematics", "The splitting kinematics to be used by this splitting kernel.", &DipoleSplittingKernel::theSplittingKinematics, false, false, true, false, false); static Reference interfacePDFRatio ("PDFRatio", "Set the optional PDF ratio object to evaluate this kernel", &DipoleSplittingKernel::thePDFRatio, false, false, true, true, false); static Parameter interfacePresamplingPoints ("PresamplingPoints", "The number of points used to presample this kernel.", &DipoleSplittingKernel::thePresamplingPoints, 2000, 1, 0, false, false, Interface::lowerlim); static Parameter interfaceMaxtry ("Maxtry", "The maximum number of attempts to generate a splitting.", &DipoleSplittingKernel::theMaxtry, 10000, 1, 0, false, false, Interface::lowerlim); static Parameter interfaceFreezeGrid ("FreezeGrid", "", &DipoleSplittingKernel::theFreezeGrid, 500000, 1, 0, false, false, Interface::lowerlim); static Reference interfaceFlavour ("Flavour", "Set the flavour to be produced if ambiguous.", &DipoleSplittingKernel::theFlavour, false, false, true, true, false); static Reference interfaceMCCheck ("MCCheck", "[debug option] MCCheck", &DipoleSplittingKernel::theMCCheck, false, false, true, true, false); interfaceMCCheck.rank(-1); static Switch interfaceStrictLargeN ("StrictLargeN", "Work in a strict large-N limit.", &DipoleSplittingKernel::theStrictLargeN, false, false, false); static SwitchOption interfaceStrictLargeNYes (interfaceStrictLargeN, "Yes", "Replace C_F -> C_A/2 where present", true); static SwitchOption interfaceStrictLargeNNo (interfaceStrictLargeN, "No", "Keep C_F=4/3", false); interfaceStrictLargeN.rank(-2); static Switch interfaceCMWScheme ("CMWScheme", "Use the CMW Scheme related Kg expression to the splitting", &DipoleSplittingKernel::theCMWScheme, 0, false, false); static SwitchOption interfaceCMWSchemeNo (interfaceCMWScheme,"No","No CMW-Scheme", 0); static SwitchOption interfaceCMWSchemeLinear (interfaceCMWScheme,"Linear", "Linear CMW multiplication: alpha_s(q) -> alpha_s(q)(1+K_g*alpha_s(q)/2pi )",1); static SwitchOption interfaceCMWSchemeFactor (interfaceCMWScheme,"Factor", "Use factor in alpha_s argument: alpha_s(q) -> alpha_s(k_g*q) with kfac=exp(-(67-3pi^2-10/3*Nf)/(33-2Nf)) ",2); static Parameter interfaceFactorizationScaleFactor ("FactorizationScaleFactor", "The factorization scale factor.", &DipoleSplittingKernel::theFactorizationScaleFactor, 1.0, 0.0, 0, false, false, Interface::lowerlim); interfaceFactorizationScaleFactor.rank(-2); static Parameter interfaceRenormalizationScaleFactor ("RenormalizationScaleFactor", "The renormalization scale factor.", &DipoleSplittingKernel::theRenormalizationScaleFactor, 1.0, 0.0, 0, false, false, Interface::lowerlim); interfaceRenormalizationScaleFactor.rank(-2); static Parameter interfaceRenormalizationScaleFreeze ("RenormalizationScaleFreeze", "The freezing scale for the renormalization scale.", &DipoleSplittingKernel::theRenormalizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter interfaceFactorizationScaleFreeze ("FactorizationScaleFreeze", "The freezing scale for the factorization scale.", &DipoleSplittingKernel::theFactorizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Switch interfaceVirtualitySplittingScale ("VirtualitySplittingScale", "Use the virtuality as the splitting scale.", &DipoleSplittingKernel::theVirtualitySplittingScale, false, false, false); static SwitchOption interfaceVirtualitySplittingScaleYes (interfaceVirtualitySplittingScale, "Yes", "Use vrituality.", true); static SwitchOption interfaceVirtualitySplittingScaleNo (interfaceVirtualitySplittingScale, "No", "Use transverse momentum.", false); static Parameter interfaceDetuning ("Detuning", "A value to detune the overestimate kernel.", &DipoleSplittingKernel::theDetuning, 1.0, 1.0, 0, false, false, Interface::lowerlim); static Switch interfaceUseThisKernel ("UseKernel", "Turn On and of the Kernel.", &DipoleSplittingKernel::theUseThisKernel, true, false, false); static SwitchOption interfaceUseThisKernelYes (interfaceUseThisKernel, "Yes", "Use this Kernel.", true); static SwitchOption interfaceUseThisKernelNo (interfaceUseThisKernel, "No", "Dont use this Kernel.", false); } diff --git a/Shower/Dipole/Kernels/DipoleSplittingKernel.h b/Shower/Dipole/Kernels/DipoleSplittingKernel.h --- a/Shower/Dipole/Kernels/DipoleSplittingKernel.h +++ b/Shower/Dipole/Kernels/DipoleSplittingKernel.h @@ -1,540 +1,546 @@ // -*- C++ -*- // // DipoleSplittingKernel.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_DipoleSplittingKernel_H #define HERWIG_DipoleSplittingKernel_H // // This is the declaration of the DipoleSplittingKernel class. // #include "ThePEG/Handlers/HandlerBase.h" #include "ThePEG/StandardModel/AlphaSBase.h" #include "ThePEG/PDF/PDF.h" #include "Herwig/Shower/Dipole/Utility/PDFRatio.h" #include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h" #include "Herwig/Shower/Dipole/Kinematics/DipoleSplittingKinematics.h" #include "ThePEG/EventRecord/RhoDMatrix.h" #include "Herwig/Decay/DecayMatrixElement.h" #include "Herwig/Decay/TwoBodyDecayMatrixElement.h" namespace Herwig { using namespace ThePEG; /** * \ingroup DipoleShower * \author Simon Platzer * * \brief DipoleSplittingKernel is the base class for all kernels * used within the dipole shower. * * @see \ref DipoleSplittingKernelInterfaces "The interfaces" * defined for DipoleSplittingKernel. */ class DipoleSplittingKernel: public HandlerBase { public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ DipoleSplittingKernel(); /** * The destructor. */ virtual ~DipoleSplittingKernel(); //@} public: /** * Return the alpha_s to be used */ Ptr::tptr alphaS() const { return theAlphaS; } /** * Set the alpha_s to be used */ void alphaS(Ptr::tptr ap) { theAlphaS = ap; } /** * Return the splitting kinematics object */ Ptr::tptr splittingKinematics() const { return theSplittingKinematics; } /** * Return the mc check object */ Ptr::ptr mcCheck() const { return theMCCheck; } /** * Set the splitting kinematics object */ void splittingKinematics(Ptr::tptr sp) { theSplittingKinematics = sp; } /** * Return the PDFRatio object */ Ptr::tptr pdfRatio() const { return thePDFRatio; } /** * Set the PDFRatio object */ void pdfRatio(Ptr::tptr sp) { thePDFRatio = sp; } /** * Return the number of additional parameter * random variables needed to evaluate this kernel * except the momentum fractions of incoming partons. * These will be accessible through the * lastSplittingParameters() container of the splitting * info object. */ virtual int nDimAdditional() const { return 0; } /** * Set the freezing value for the renormalization scale */ void renormalizationScaleFreeze(Energy s) { theRenormalizationScaleFreeze = s; } /** * Set the freezing value for the factorization scale */ void factorizationScaleFreeze(Energy s) { theFactorizationScaleFreeze = s; } /** * Get the freezing value for the renormalization scale */ Energy renormalizationScaleFreeze() const { return theRenormalizationScaleFreeze; } /** * Get the freezing value for the factorization scale */ Energy factorizationScaleFreeze() const { return theFactorizationScaleFreeze; } public: /** * Return true, if this splitting kernel * applies to the given dipole index. */ virtual bool canHandle(const DipoleIndex&) const = 0; /** * Return true, if this splitting kernel is * the same for the given index a, as the given * splitting kernel for index b. */ virtual bool canHandleEquivalent(const DipoleIndex& a, const DipoleSplittingKernel& sk, const DipoleIndex& b) const = 0; /** * Return the emitter data after splitting, given * a dipole index. */ virtual tcPDPtr emitter(const DipoleIndex&) const = 0; /** * Return the emission data after splitting, given * a dipole index. */ virtual tcPDPtr emission(const DipoleIndex&) const = 0; /** * Return the spectator data after splitting, given * a dipole index. */ virtual tcPDPtr spectator(const DipoleIndex&) const = 0; /** * Return the flavour produced, if this cannot * be determined from the dipole. */ PDPtr flavour() const { return theFlavour; } /** * Return true, if this splitting kernel is supposed to work in a * strict large-N limit, i.e. replacing C_F by C_A/2 */ bool strictLargeN() const { return theStrictLargeN; } public: /** * Inform this splitting kernel, that it is being * presampled until a call to stopPresampling */ virtual void startPresampling(const DipoleIndex&) { presampling = true; } /** * Inform this splitting kernel, that it is not being * presampled until a call to startPresampling */ virtual void stopPresampling(const DipoleIndex&) { presampling = false; } /** * Return the number of points to presample this * splitting generator. */ unsigned long presamplingPoints() const { return thePresamplingPoints; } /** * Return the maximum number of trials * to generate a splitting. */ unsigned long maxtry() const { return theMaxtry; } /** * Return the number of accepted points after which the grid should * be frozen */ unsigned long freezeGrid() const { return theFreezeGrid; } /** * Set the number of accepted points after which the grid should * be frozen */ void freezeGrid(unsigned long n) { theFreezeGrid = n; } /** * Set a detuning factor to be applied to the sampling overestimate kernel */ void detuning(double d) { theDetuning = d; } /** * Return the detuning factor applied to the sampling overestimate kernel */ double detuning() const { return theDetuning; } /** * Evaluate this splitting kernel for the given * dipole splitting. */ virtual double evaluate(const DipoleSplittingInfo&) const = 0; /** * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting, * required for generating spin-correlated azimuthal angles. **/ virtual vector< pair > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const = 0; /** * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel. **/ virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) const = 0; /** * Clear the alphaPDF cache */ void clearAlphaPDFCache() const { theAlphaSCache.clear(); thePDFCache.clear(); } /** * Update the variations vector at the given splitting using the indicated * kernel and overestimate values. */ virtual void accept(const DipoleSplittingInfo&, double, double, map&) const; /** * Update the variations vector at the given splitting using the indicated * kernel and overestimate values. */ virtual void veto(const DipoleSplittingInfo&, double, double, map&) const; /** * Return true, if this kernel is capable of * delivering an overestimate to the kernel, and * of inverting the integral over the overestimate * w.r.t. the phasepsace provided by the given * DipoleSplittingInfo object. */ virtual bool haveOverestimate(const DipoleSplittingInfo&) const { return false; } /** * Return the overestimate to this splitting kernel * for the given dipole splitting. */ virtual double overestimate(const DipoleSplittingInfo&) const { return -1.; } /** * Invert the integral over the overestimate * w.r.t. the phasepsace provided by the given * DipoleSplittingInfo object to equal * the given value. */ virtual double invertOverestimateIntegral(const DipoleSplittingInfo&, double) const { return -1.; } /** * . */ bool useThisKernel() const { return theUseThisKernel; } public: /** * Get the factorization scale factor */ double factorizationScaleFactor() const { return theFactorizationScaleFactor; } /** * Set the factorization scale factor */ void factorizationScaleFactor(double f) { theFactorizationScaleFactor = f; } /** * Get the renormalization scale factor */ double renormalizationScaleFactor() const { return theRenormalizationScaleFactor; } /** * Set the renormalization scale factor */ void renormalizationScaleFactor(double f) { theRenormalizationScaleFactor = f; } /** * Return the CMW sheme used by the kernel */ unsigned int cmwScheme() const {return theCMWScheme;} protected: /** * Return the common factor of (alphas/2pi)*(pdf ratio) */ double alphaPDF(const DipoleSplittingInfo&, Energy optScale = ZERO, double rScaleFactor = 1.0, double fScaleFactor = 1.0) const; /** * Return true, if the virtuality of the splitting should be used as the * argument of alphas rather than the pt */ bool virtualitySplittingScale() const { return theVirtualitySplittingScale; } 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(); // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). private: /** * The alpha_s to be used. */ Ptr::ptr theAlphaS; /** * An optional 'colour screening' scale * for alternative intrinsic pt generation. */ Energy theScreeningScale; /** * The splitting kinematics to be used. */ Ptr::ptr theSplittingKinematics; /** * An optional PDF ratio object to be used * when evaluating this kernel. */ Ptr::ptr thePDFRatio; /** * The number of points to presample this * splitting generator. */ unsigned long thePresamplingPoints; /** * The maximum number of trials * to generate a splitting. */ unsigned long theMaxtry; - + + /** + * The maximum value for any pdf ratio. + * TODO: JB:Should this be an interfaced value? Is there a reasobable case where it should be allowed to be bigger than 1000000.? + */ + static double theMaxPDFRatio; + /** * Return the number of accepted points after which the grid should * be frozen */ unsigned long theFreezeGrid; /** * The detuning factor applied to the sampling overestimate kernel */ double theDetuning; /** * The flavour produced, if this cannot * be determined from the dipole. */ PDPtr theFlavour; /** * Pointer to a check histogram object */ Ptr::ptr theMCCheck; /** * True, if this splitting kernel is supposed to work in a * strict large-N limit, i.e. replacing C_F by C_A/2 */ bool theStrictLargeN; /** * The factorization scale factor. */ double theFactorizationScaleFactor; /** * The renormalization scale factor. */ double theRenormalizationScaleFactor; /** * A freezing value for the renormalization scale */ Energy theRenormalizationScaleFreeze; /** * A freezing value for the factorization scale */ Energy theFactorizationScaleFreeze; /** * True, if the virtuality of the splitting should be used as the * argument of alphas rather than the pt */ bool theVirtualitySplittingScale; /** * Implementing CMW in the kernels. **/ unsigned int theCMWScheme=0; /** * Cache for alphas evaluations */ mutable map theAlphaSCache; /** * Cache for PDF evaluations */ mutable map thePDFCache; /** * True, if we are presampling */ bool presampling; /** * True, if the kernel should be used */ bool theUseThisKernel = true; private: /** * The static object used to initialize the description of this class. * Indicates that this is an abstract class with persistent data. */ static AbstractClassDescription initDipoleSplittingKernel; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ DipoleSplittingKernel & operator=(const DipoleSplittingKernel &) = delete; }; } #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of DipoleSplittingKernel. */ template <> struct BaseClassTrait { /** Typedef of the first base class of DipoleSplittingKernel. */ typedef HandlerBase NthBase; }; /** This template specialization informs ThePEG about the name of * the DipoleSplittingKernel class and the shared object where it is defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "Herwig::DipoleSplittingKernel"; } /** * The name of a file containing the dynamic library where the class * DipoleSplittingKernel is implemented. It may also include several, space-separated, * libraries if the class DipoleSplittingKernel depends on other classes (base classes * excepted). In this case the listed libraries will be dynamically * linked in the order they are specified. */ static string library() { return "HwDipoleShower.so"; } }; /** @endcond */ } #endif /* HERWIG_DipoleSplittingKernel_H */ diff --git a/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.cc b/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.cc --- a/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.cc +++ b/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.cc @@ -1,169 +1,173 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the FFgx2ggxDipoleKernel class. // #include "FFgx2ggxDipoleKernel.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; FFgx2ggxDipoleKernel::FFgx2ggxDipoleKernel() : DipoleSplittingKernel(){} FFgx2ggxDipoleKernel::~FFgx2ggxDipoleKernel() {} IBPtr FFgx2ggxDipoleKernel::clone() const { return new_ptr(*this); } IBPtr FFgx2ggxDipoleKernel::fullclone() const { return new_ptr(*this); } bool FFgx2ggxDipoleKernel::canHandle(const DipoleIndex& ind) const { return useThisKernel() && ind.emitterData()->id() == ParticleID::g && ind.spectatorData()->mass() == ZERO && !ind.initialStateEmitter() && !ind.initialStateSpectator(); } +#ifndef NDEBUG bool FFgx2ggxDipoleKernel::canHandleEquivalent(const DipoleIndex& a, +#else +bool FFgx2ggxDipoleKernel::canHandleEquivalent(const DipoleIndex& , +#endif const DipoleSplittingKernel& sk, const DipoleIndex& b) const { assert(canHandle(a)); if ( !canHandle(b) ) return false; return sk.emitter(b)->id() == ParticleID::g && sk.emission(b)->id() == ParticleID::g; } tcPDPtr FFgx2ggxDipoleKernel::emitter(const DipoleIndex&) const { return getParticleData(ParticleID::g); } tcPDPtr FFgx2ggxDipoleKernel::emission(const DipoleIndex&) const { return getParticleData(ParticleID::g); } tcPDPtr FFgx2ggxDipoleKernel::spectator(const DipoleIndex& ind) const { return ind.spectatorData(); } double FFgx2ggxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const { double ret = alphaPDF(split); double z = split.lastZ(); double y = sqr(split.lastPt() / split.scale()) / (z*(1.-z)); double S1=1./(1.-z*(1.-y)); double S2=1./(1.-(1.-z)*(1.-y)); double NS=(-2 + z*(1.-z)); if( theAsymmetryOption == 0 ){ ret *= 3.*( S1 + 0.5 * NS); }else if ( theAsymmetryOption == 1 ){ ret *= 3.*z*( S1 +S2 + NS ); }else{ ret *= 3.*0.5*( S1 + S2 + NS ); } return ret > 0. ? ret : 0.; } vector< pair > FFgx2ggxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const { double z = dInfo.lastZ(); // Altarelli-Parisi spin-indexed kernels: double v_AP_ppp = -sqrt( 1./(z*(1.-z)) ); double v_AP_ppm = z*sqrt( z / (1.-z) ); double v_AP_pmp = (1.-z)*sqrt( (1.-z)/z ); //double v_AP_mmm = -v_AP_ppp; double v_AP_mmp = -v_AP_ppm; double v_AP_mpm = -v_AP_pmp; // Initialise variables for the distributions vector< pair > distPhiDep; double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp)) - 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp); distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp))/max ) ); distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) ); distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) ); return distPhiDep; } DecayMEPtr FFgx2ggxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const { double z = dInfo.lastZ(); // Altarelli-Parisi spin-indexed kernels: double v_AP_ppp = -sqrt( 1./(z*(1.-z)) ); double v_AP_ppm = z*sqrt( z / (1.-z) ); double v_AP_pmp = (1.-z)*sqrt( (1.-z)/z ); double v_AP_mmm = -v_AP_ppp; double v_AP_mmp = -v_AP_ppm; double v_AP_mpm = -v_AP_pmp; // Construct the (phi-dependent) spin-unaveraged splitting kernel DecayMEPtr kernelPhiDep (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1,PDT::Spin1))); Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi()); // 0 = -, 2 = + (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase; (*kernelPhiDep)(2,2,2) = v_AP_ppp/phase; (*kernelPhiDep)(0,0,2) = v_AP_mmp/phase; (*kernelPhiDep)(2,2,0) = v_AP_ppm*phase; (*kernelPhiDep)(0,2,0) = v_AP_mpm/phase; (*kernelPhiDep)(2,0,2) = v_AP_pmp*phase; (*kernelPhiDep)(0,2,2) = 0; (*kernelPhiDep)(2,0,0) = 0; return kernelPhiDep; } // If needed, insert default implementations of function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void FFgx2ggxDipoleKernel::persistentOutput(PersistentOStream & os) const { os << theAsymmetryOption; } void FFgx2ggxDipoleKernel::persistentInput(PersistentIStream & is, int) { is >> theAsymmetryOption; } ClassDescription FFgx2ggxDipoleKernel::initFFgx2ggxDipoleKernel; // Definition of the static class description member. void FFgx2ggxDipoleKernel::Init() { static ClassDocumentation documentation ("FFgx2ggxDipoleKernel"); static Parameter interfacetheAsymmetryOption ("AsymmetryOption", "The asymmetry option for final state gluon spliitings.", &FFgx2ggxDipoleKernel::theAsymmetryOption, 1, 0, 0, false, false, Interface::lowerlim); } diff --git a/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.cc b/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.cc --- a/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.cc +++ b/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.cc @@ -1,154 +1,158 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the FFgx2qqxDipoleKernel class. // #include "FFgx2qqxDipoleKernel.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; FFgx2qqxDipoleKernel::FFgx2qqxDipoleKernel() : DipoleSplittingKernel() {} FFgx2qqxDipoleKernel::~FFgx2qqxDipoleKernel() {} IBPtr FFgx2qqxDipoleKernel::clone() const { return new_ptr(*this); } IBPtr FFgx2qqxDipoleKernel::fullclone() const { return new_ptr(*this); } bool FFgx2qqxDipoleKernel::canHandle(const DipoleIndex& ind) const { return useThisKernel() && ind.emitterData()->id() == ParticleID::g && ind.spectatorData()->mass() == ZERO && flavour()->mass() == ZERO && !ind.initialStateEmitter() && !ind.initialStateSpectator(); } +#ifndef NDEBUG bool FFgx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a, +#else +bool FFgx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& , +#endif const DipoleSplittingKernel& sk, const DipoleIndex& b) const { assert(canHandle(a)); if ( !canHandle(b) ) return false; return sk.emitter(b)->id() + sk.emission(b)->id() == 0 && abs(sk.emitter(b)->id()) < 6 && sk.emitter(b)->mass() == ZERO; } tcPDPtr FFgx2qqxDipoleKernel::emitter(const DipoleIndex&) const { assert(flavour()); assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO); return flavour(); } tcPDPtr FFgx2qqxDipoleKernel::emission(const DipoleIndex&) const { assert(flavour()); assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO); return flavour()->CC(); } tcPDPtr FFgx2qqxDipoleKernel::spectator(const DipoleIndex& ind) const { return ind.spectatorData(); } double FFgx2qqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const { double ret = alphaPDF(split); double z = split.lastZ(); ret *= .25 * ( 1. - 2.*z*(1.-z) ); return ret > 0. ? ret : 0.; } vector< pair > FFgx2qqxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const { double z = dInfo.lastZ(); // Altarelli-Parisi spin-indexed kernels: double v_AP_ppm = z; double v_AP_pmp = -(1.-z); double v_AP_mmp = -v_AP_ppm; double v_AP_mpm = -v_AP_pmp; // Initialise variables for the distributions vector< pair > distPhiDep; double max = (sqr(v_AP_ppm) + sqr(v_AP_pmp)) + 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp); distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*( sqr(v_AP_ppm) + sqr(v_AP_pmp) )/max ) ); distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) ); distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) ); return distPhiDep; } DecayMEPtr FFgx2qqxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const { double z = dInfo.lastZ(); // Altarelli-Parisi spin-indexed kernels: double v_AP_ppm = z; double v_AP_pmp = -(1.-z); double v_AP_mmp = -v_AP_ppm; double v_AP_mpm = -v_AP_pmp; // Construct the (phi-dependent) spin-unaveraged splitting kernel DecayMEPtr kernelPhiDep (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1Half))); Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi()); // 0 = -, 2 = + (*kernelPhiDep)(0,0,0) = 0.; (*kernelPhiDep)(2,1,1) = 0.; (*kernelPhiDep)(0,0,1) = v_AP_mmp/phase; (*kernelPhiDep)(2,1,0) = v_AP_ppm*phase; (*kernelPhiDep)(0,1,0) = v_AP_mpm/phase; (*kernelPhiDep)(2,0,1) = v_AP_pmp*phase; (*kernelPhiDep)(0,1,1) = 0.; (*kernelPhiDep)(2,0,0) = 0.; return kernelPhiDep; } // If needed, insert default implementations of function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void FFgx2qqxDipoleKernel::persistentOutput(PersistentOStream & ) const { } void FFgx2qqxDipoleKernel::persistentInput(PersistentIStream & , int) { } ClassDescription FFgx2qqxDipoleKernel::initFFgx2qqxDipoleKernel; // Definition of the static class description member. void FFgx2qqxDipoleKernel::Init() { static ClassDocumentation documentation ("FFgx2qqxDipoleKernel"); } diff --git a/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.cc b/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.cc --- a/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.cc +++ b/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.cc @@ -1,136 +1,139 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the FFqx2qgxDipoleKernel class. // #include "FFqx2qgxDipoleKernel.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; FFqx2qgxDipoleKernel::FFqx2qgxDipoleKernel() : DipoleSplittingKernel() {} FFqx2qgxDipoleKernel::~FFqx2qgxDipoleKernel() {} IBPtr FFqx2qgxDipoleKernel::clone() const { return new_ptr(*this); } IBPtr FFqx2qgxDipoleKernel::fullclone() const { return new_ptr(*this); } bool FFqx2qgxDipoleKernel::canHandle(const DipoleIndex& ind) const { return useThisKernel() && abs(ind.emitterData()->id()) < 6 && ind.emitterData()->mass() == ZERO && ind.spectatorData()->mass() == ZERO && !ind.initialStateEmitter() && !ind.initialStateSpectator(); } - +#ifndef NDEBUG bool FFqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& a, +#else +bool FFqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& , +#endif const DipoleSplittingKernel& sk, const DipoleIndex& b) const { assert(canHandle(a)); if ( !canHandle(b) ) return false; return sk.emission(b)->id() == ParticleID::g && abs(sk.emitter(b)->id()) < 6 && sk.emitter(b)->mass() == ZERO; } tcPDPtr FFqx2qgxDipoleKernel::emitter(const DipoleIndex& ind) const { return ind.emitterData(); } tcPDPtr FFqx2qgxDipoleKernel::emission(const DipoleIndex&) const { return getParticleData(ParticleID::g); } tcPDPtr FFqx2qgxDipoleKernel::spectator(const DipoleIndex& ind) const { return ind.spectatorData(); } double FFqx2qgxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const { double ret = alphaPDF(split); double z = split.lastZ(); double y = sqr(split.lastPt() / split.scale()) / (z*(1.-z)); ret *= (!strictLargeN() ? 4./3. : 3./2.)*( 2./(1.-z*(1.-y)) - (1.+z) ); return ret > 0. ? ret : 0.; } vector< pair > FFqx2qgxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const { // No dependence on the spin density matrix, // dependence on off-diagonal terms cancels. return {{ {0, 1.} }}; } DecayMEPtr FFqx2qgxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const { double z = dInfo.lastZ(); // Altarelli-Parisi spin-indexed kernels: double v_AP_ppp = sqrt( 1./(1.-z) ); double v_AP_ppm = -z/sqrt(1.-z); double v_AP_mmm = -v_AP_ppp; double v_AP_mmp = -v_AP_ppm; // Construct the (phi-dependent) spin-unaveraged splitting kernel DecayMEPtr kernelPhiDep (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1))); Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi()); // 0 = -1 or -1/2, 1=+1/2, 2 = +1 (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase; (*kernelPhiDep)(1,1,2) = v_AP_ppp/phase; (*kernelPhiDep)(0,0,2) = v_AP_mmp/phase; (*kernelPhiDep)(1,1,0) = v_AP_ppm*phase; (*kernelPhiDep)(0,1,0) = 0.; (*kernelPhiDep)(1,0,2) = 0.; (*kernelPhiDep)(0,1,2) = 0.; (*kernelPhiDep)(1,0,0) = 0.; return kernelPhiDep; } // If needed, insert default implementations of function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void FFqx2qgxDipoleKernel::persistentOutput(PersistentOStream & ) const { } void FFqx2qgxDipoleKernel::persistentInput(PersistentIStream & , int) { } ClassDescription FFqx2qgxDipoleKernel::initFFqx2qgxDipoleKernel; // Definition of the static class description member. void FFqx2qgxDipoleKernel::Init() { static ClassDocumentation documentation ("FFqx2qgxDipoleKernel"); } diff --git a/Shower/Dipole/Kinematics/FFMassiveKinematics.h b/Shower/Dipole/Kinematics/FFMassiveKinematics.h --- a/Shower/Dipole/Kinematics/FFMassiveKinematics.h +++ b/Shower/Dipole/Kinematics/FFMassiveKinematics.h @@ -1,305 +1,299 @@ // -*- C++ -*- // // FFMassiveKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2017 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FFMassiveKinematics_H #define HERWIG_FFMassiveKinematics_H // // This is the declaration of the FFMassiveKinematics class. // #include "DipoleSplittingKinematics.h" namespace Herwig { using namespace ThePEG; /** * \ingroup DipoleShower * \author Simon Platzer, Stephen Webster * * \brief FFMassiveKinematics implements massive splittings * off a final-final dipole. * */ class FFMassiveKinematics: public DipoleSplittingKinematics { public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ FFMassiveKinematics(); /** * The destructor. */ virtual ~FFMassiveKinematics(); //@} public: /** * Return the boundaries in between the evolution * variable random number is to be sampled; the lower * cuoff is assumed to correspond to the infrared cutoff. */ virtual pair kappaSupport(const DipoleSplittingInfo& dIndex) const; /** * Return the boundaries in between the momentum * fraction random number is to be sampled. */ virtual pair xiSupport(const DipoleSplittingInfo& dIndex) const; /** * Return the boundaries on the momentum fraction */ virtual pair zBoundaries(Energy, const DipoleSplittingInfo&, const DipoleSplittingKernel&) const { return {0.0,1.0}; } /** * Return the dipole scale associated to the * given pair of emitter and spectator. This * should be the invariant mass or absolute value * final/final or initial/initial and the absolute * value of the momentum transfer for intial/final or * final/initial dipoles. */ virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter, const Lorentz5Momentum& pSpectator) const; /** * Return the maximum pt for the given dipole scale. */ virtual Energy ptMax(Energy dScale, double emX, double specX, const DipoleSplittingInfo& dInfo, const DipoleSplittingKernel& split) const; /** * Return the maximum pt for the given dipole scale. */ virtual Energy ptMax(Energy dScale, double, double, const DipoleIndex& dIndex, const DipoleSplittingKernel& split, tPPtr emitter, tPPtr spectator) const; /** * Return the maximum pt for the given dipole scale. */ virtual Energy ptMax(Energy, double, double, const DipoleIndex&, const DipoleSplittingKernel&) const { // Only the DipoleSplittingInfo version should be used for massive // dipoles, for now anyway. assert(false); return ZERO; } /** * Return the maximum virtuality for the given dipole scale. */ virtual Energy QMax(Energy dScale, double emX, double specX, const DipoleSplittingInfo& dInfo, const DipoleSplittingKernel& split) const; /** * Return the maximum virtuality for the given dipole scale. */ virtual Energy QMax(Energy, double, double, const DipoleIndex&, const DipoleSplittingKernel&) const { // Only the DipoleSplittingInfo version should be used for massive // dipoles, for now anyway. assert(false); return ZERO; } /** * Return the pt given a virtuality. */ virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const; /** * Return the virtuality given a pt. */ virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const; /** * Return the random number associated to * the given pt. */ virtual double ptToRandom(Energy pt, Energy dScale, double emX, double specX, const DipoleIndex& dIndex, const DipoleSplittingKernel& split) const; /** * Generate splitting variables given three random numbers * and the momentum fractions of the emitter and spectator. * Return true on success. */ virtual bool generateSplitting(double kappa, double xi, double phi, DipoleSplittingInfo& dIndex, const DipoleSplittingKernel& split); /** * Generate the full kinematics given emitter and * spectator momentum and a previously completeted * DipoleSplittingInfo object. */ virtual void generateKinematics(const Lorentz5Momentum& pEmitter, const Lorentz5Momentum& pSpectator, const DipoleSplittingInfo& dInfo); public: /** * Triangular / Kallen function */ template inline T rootOfKallen (T a, T b, T c) const { if ( a*a + b*b + c*c - 2.*(a*b + a*c + b*c) > ZERO ) return sqrt(a*a + b*b + c*c - 2.*(a*b + a*c + b*c) ) ; else return ZERO; } /** * Perform a rotation on both momenta such that the first one will * point along the (positive) z axis. Rotate back to the original * reference frame by applying rotateUz(returnedVector) to each momentum. */ ThreeVector rotateToZ (Lorentz5Momentum& pTarget, Lorentz5Momentum& p1){ ThreeVector oldAxis = pTarget.vect().unit(); double ct = oldAxis.z(); double st = sqrt( 1.-sqr(ct) ); // cos,sin(theta) double cp = oldAxis.x()/st; double sp = oldAxis.y()/st; // cos,sin(phi) pTarget.setZ( pTarget.vect().mag() ); pTarget.setX( 0.*GeV ); pTarget.setY( 0.*GeV ); Lorentz5Momentum p1old = p1; p1.setX( sp*p1old.x() - cp*p1old.y() ); p1.setY( ct*cp*p1old.x() + ct*sp*p1old.y() - st*p1old.z() ); p1.setZ( st*cp*p1old.x() + st*sp*p1old.y() + ct*p1old.z() ); return oldAxis; } public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). private: /** * The static object used to initialize the description of this class. * Indicates that this is a concrete class with persistent data. */ static ClassDescription initFFMassiveKinematics; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ FFMassiveKinematics & operator=(const FFMassiveKinematics &) = delete; - - /** - * Option to use the full jacobian, including the z->zprime jacobian. - **/ - bool theFullJacobian; - }; } #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of FFMassiveKinematics. */ template <> struct BaseClassTrait { /** Typedef of the first base class of FFMassiveKinematics. */ typedef Herwig::DipoleSplittingKinematics NthBase; }; /** This template specialization informs ThePEG about the name of * the FFMassiveKinematics class and the shared object where it is defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "Herwig::FFMassiveKinematics"; } /** * The name of a file containing the dynamic library where the class * FFMassiveKinematics is implemented. It may also include several, space-separated, * libraries if the class FFMassiveKinematics depends on other classes (base classes * excepted). In this case the listed libraries will be dynamically * linked in the order they are specified. */ static string library() { return "HwDipoleShower.so"; } }; /** @endcond */ } #endif /* HERWIG_FFMassiveKinematics_H */ diff --git a/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.h b/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.h --- a/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.h +++ b/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.h @@ -1,331 +1,327 @@ // -*- C++ -*- // // FIMassiveDecayKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2017 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FIMassiveDecayKinematics_H #define HERWIG_FIMassiveDecayKinematics_H // // This is the declaration of the FIMassiveDecayKinematics class. // #include "DipoleSplittingKinematics.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Utilities/UtilityBase.h" namespace Herwig { using namespace ThePEG; /** * \ingroup DipoleShower * \author Stephen Webster * * \brief FIMassiveDecayKinematics implements massive splittings * off a final-initial decay dipole. * */ class FIMassiveDecayKinematics: public DipoleSplittingKinematics { public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ FIMassiveDecayKinematics(); /** * The destructor. */ virtual ~FIMassiveDecayKinematics(); //@} public: /** * Return the boundaries in between the evolution * variable random number is to be sampled; the lower * cuoff is assumed to correspond to the infrared cutoff. */ virtual pair kappaSupport(const DipoleSplittingInfo& dIndex) const; /** * Return the boundaries in between the momentum * fraction random number is to be sampled. */ virtual pair xiSupport(const DipoleSplittingInfo& dIndex) const; /** * Return the boundaries on the momentum fraction */ virtual pair zBoundaries(Energy, const DipoleSplittingInfo&, const DipoleSplittingKernel&) const { return {0.0,1.0}; } /** * Return the dipole scale associated to the * given pair of emitter and spectator. This * should be the invariant mass or absolute value * final/final or initial/initial and the absolute * value of the momentum transfer for intial/final or * final/initial dipoles. */ virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter, const Lorentz5Momentum& pSpectator) const; /** * Return the mass of the system absorbing * the recoil in the dipole splitting. * This is only used in decay dipoles. */ virtual Energy recoilMassKin(const Lorentz5Momentum& pEmitter, const Lorentz5Momentum& pSpectator) const; /** * Return the maximum pt for the given dipole scale. */ virtual Energy ptMax(Energy dScale, double emX, double specX, const DipoleSplittingInfo& dInfo, const DipoleSplittingKernel& split) const; /** * Return the maximum pt for the given dipole scale. */ virtual Energy ptMax(Energy dScale, double, double, const DipoleIndex& dIndex, const DipoleSplittingKernel& split, tPPtr emitter, tPPtr spectator) const; /** * Return the maximum virtuality for the given dipole scale. */ virtual Energy QMax(Energy dScale, double emX, double specX, const DipoleSplittingInfo& dInfo, const DipoleSplittingKernel& split) const; /** * Return the maximum pt for the given dipole scale. */ virtual Energy ptMax(Energy, double, double, const DipoleIndex&, const DipoleSplittingKernel&) const { // Only the DipoleSplittingInfo version should be used for the decays. assert(false); return ZERO; } /** * Return the maximum virtuality for the given dipole scale. */ virtual Energy QMax(Energy, double, double, const DipoleIndex&, const DipoleSplittingKernel&) const { // Only the DipoleSplittingInfo version should be used for the decays. assert(false); return ZERO; } /** * Return the pt given a virtuality. */ virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const; /** * Return the virtuality given a pt. */ virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const; /** * Return the random number associated to * the given pt. */ virtual double ptToRandom(Energy pt, Energy dScale, double emX, double specX, const DipoleIndex& dIndex, const DipoleSplittingKernel& split) const; /** * Generate splitting variables given three random numbers * and the momentum fractions of the emitter and spectator. * Return true on success. */ virtual bool generateSplitting(double kappa, double xi, double phi, DipoleSplittingInfo& info, const DipoleSplittingKernel& split); /** * Generate the full kinematics given emitter and * spectator momentum and a previously completeted * DipoleSplittingInfo object. */ virtual void generateKinematics(const Lorentz5Momentum& pEmitter, const Lorentz5Momentum& pSpectator, const DipoleSplittingInfo& dInfo); /** * Return the nVector as required for spin correlations. */ virtual Lorentz5Momentum nVector(const Lorentz5Momentum& pEmitter, const Lorentz5Momentum& pSpectator, const DipoleSplittingInfo& dInfo) const; /* * Return true if this splitting is of a dipole which contains * a decayed parton and requires the remnant to absorb the recoil. */ virtual bool isDecay() const { return true; } /** * Perform the recoil in the case of a decayed parton */ virtual void decayRecoil ( PList& recoilSystem ) { PList::iterator beginRecoil = recoilSystem.begin(); PList::iterator endRecoil = recoilSystem.end(); // This is the final momentum that we must transform the system to const Momentum3 transformMom = splitRecoilMomentum().vect(); // Calculate required Lorentz rotation Lorentz5Momentum sum = ThePEG::UtilityBase::sumMomentum(beginRecoil, endRecoil); LorentzRotation rot = ThePEG::UtilityBase::transformToCMS(sum); rot = ThePEG::UtilityBase::transformFromCMS (Lorentz5Momentum(transformMom, sqrt(transformMom.mag2() + sum.m2()))) * rot; // Transform the particle spinInfo if required for ( const auto& p : recoilSystem ) { if ( p->spinInfo() ) p->spinInfo()->transform(p->momentum(),rot); } ThePEG::UtilityBase::transform(beginRecoil, endRecoil, rot ); } public: /** * Triangular / Kallen function */ template inline T rootOfKallen (T a, T b, T c) const { if ( a*a + b*b + c*c - 2.*(a*b + a*c + b*c) > ZERO ) return sqrt(a*a + b*b + c*c - 2.*(a*b + a*c + b*c) ) ; else return ZERO; } public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). private: /** * The static object used to initialize the description of this class. * Indicates that this is a concrete class with persistent data. */ static ClassDescription initFIMassiveDecayKinematics; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ FIMassiveDecayKinematics & operator=(const FIMassiveDecayKinematics &) = delete; - - /** - * Option to use the full jacobian, including the z->zprime jacobian. - **/ - bool theFullJacobian; + }; } #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of FIMassiveDecayKinematics. */ template <> struct BaseClassTrait { /** Typedef of the first base class of FIMassiveDecayKinematics. */ typedef Herwig::DipoleSplittingKinematics NthBase; }; /** This template specialization informs ThePEG about the name of * the FIMassiveDecayKinematics class and the shared object where it is defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "Herwig::FIMassiveDecayKinematics"; } /** * The name of a file containing the dynamic library where the class * FIMassiveDecayKinematics is implemented. It may also include several, space-separated, * libraries if the class FIMassiveDecayKinematics depends on other classes (base classes * excepted). In this case the listed libraries will be dynamically * linked in the order they are specified. */ static string library() { return "HwDipoleShower.so"; } }; /** @endcond */ } #endif /* HERWIG_FIMassiveDecayKinematics_H */ diff --git a/Shower/Dipole/Makefile.am b/Shower/Dipole/Makefile.am --- a/Shower/Dipole/Makefile.am +++ b/Shower/Dipole/Makefile.am @@ -1,24 +1,23 @@ -SUBDIRS = Base Kernels Kinematics Utility AlphaS Merging SpinCorrelations Colorea +SUBDIRS = Base Kernels Kinematics Utility AlphaS Merging SpinCorrelations pkglib_LTLIBRARIES = HwDipoleShower.la HwDipoleShower_la_LDFLAGS = $(AM_LDFLAGS) -module -version-info 10:0:0 HwDipoleShower_la_LIBADD = \ Base/libHwDipoleShowerBase.la \ Kernels/libHwDipoleShowerKernels.la \ Kinematics/libHwDipoleShowerKinematics.la \ Utility/libHwDipoleShowerUtility.la \ Merging/libHwDipoleShowerMerging.la \ - SpinCorrelations/libHwDipoleShowerSpinCorrelations.la \ - Colorea/libHwDipoleShowerColorea.la + SpinCorrelations/libHwDipoleShowerSpinCorrelations.la HwDipoleShower_la_SOURCES = \ DipoleShowerHandler.h DipoleShowerHandler.fh DipoleShowerHandler.cc pkglib_LTLIBRARIES += HwKrknloEventReweight.la HwKrknloEventReweight_la_SOURCES = \ KrkNLO/KrknloEventReweight.h KrkNLO/KrknloEventReweight.cc HwKrknloEventReweight_la_LDFLAGS = $(AM_LDFLAGS) -module -version-info 2:0:0 diff --git a/Shower/Dipole/Utility/ConstituentReshuffler.cc b/Shower/Dipole/Utility/ConstituentReshuffler.cc --- a/Shower/Dipole/Utility/ConstituentReshuffler.cc +++ b/Shower/Dipole/Utility/ConstituentReshuffler.cc @@ -1,659 +1,663 @@ // -*- C++ -*- // // ConstituentReshuffler.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. // // // This is the implementation of the non-inlined, non-templated member // functions of the ConstituentReshuffler class. // #include #include "ConstituentReshuffler.h" #include "ThePEG/Interface/ClassDocumentation.h" #include #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "DipolePartonSplitter.h" #include "Herwig/Utilities/GSLBisection.h" #include "Herwig/Shower/Dipole/DipoleShowerHandler.h" #include "Herwig/Shower/ShowerHandler.h" using namespace Herwig; ConstituentReshuffler::ConstituentReshuffler() : HandlerBase() {} ConstituentReshuffler::~ConstituentReshuffler() {} IBPtr ConstituentReshuffler::clone() const { return new_ptr(*this); } IBPtr ConstituentReshuffler::fullclone() const { return new_ptr(*this); } double ConstituentReshuffler::ReshuffleEquation::aUnit() { return 1.; } double ConstituentReshuffler::ReshuffleEquation::vUnit() { return 1.; } double ConstituentReshuffler::DecayReshuffleEquation::aUnit() { return 1.; } double ConstituentReshuffler::DecayReshuffleEquation::vUnit() { return 1.; } double ConstituentReshuffler::ReshuffleEquation::operator() (double xi) const { double r = - w/GeV; for (PList::iterator p = p_begin; p != p_end; ++p) { r += sqrt(sqr((**p).dataPtr()->constituentMass()) + xi*xi*(sqr((**p).momentum().t())-sqr((**p).dataPtr()->mass()))) / GeV; } return r; } double ConstituentReshuffler::DecayReshuffleEquation::operator() (double xi) const { double r = - w/GeV; for (PList::iterator pIt = p_begin; pIt != p_end; ++pIt) { r += sqrt(sqr((**pIt).dataPtr()->constituentMass()) + xi*xi*(sqr((**pIt).momentum().t())-sqr((**pIt).dataPtr()->mass()))) / GeV; } for (PList::iterator rIt = r_begin; rIt != r_end; ++rIt) { r += sqrt(sqr((**rIt).momentum().m()) + xi*xi*(sqr((**rIt).momentum().t())-sqr((**rIt).momentum().m()))) / GeV; } return r; } void ConstituentReshuffler::reshuffle(PList& out, PPair& in, PList& intermediates, const bool decay, PList& decayPartons, PList& decayRecoilers) { assert(ShowerHandler::currentHandler()->retConstituentMasses()); if ( !decay ) { if (out.size() == 0) return; if (out.size() == 1) { PPtr recoiler; PPtr parton = out.front(); if (DipolePartonSplitter::colourConnected(parton,in.first) && DipolePartonSplitter::colourConnected(parton,in.second)) { if (UseRandom::rnd() < .5) recoiler = in.first; else recoiler = in.second; } else if (DipolePartonSplitter::colourConnected(parton,in.first)) { recoiler = in.first; } else if (DipolePartonSplitter::colourConnected(parton,in.second)) { recoiler = in.second; } else assert(false); assert(abs(recoiler->momentum().vect().perp2()/GeV2) < 1e-6); double sign = recoiler->momentum().z() < 0.*GeV ? -1. : 1.; Energy2 qperp2 = parton->momentum().perp2(); if (qperp2/GeV2 < Constants::epsilon) { // no emission off a 2 -> singlet process which // needed a single forced splitting: should never happen (?) assert(false); throw Veto(); } Energy2 m2 = sqr(parton->dataPtr()->constituentMass()); Energy abs_q = parton->momentum().vect().mag(); Energy qz = parton->momentum().z(); Energy abs_pz = recoiler->momentum().t(); assert(abs_pz > 0.*GeV); Energy xi_pz = sign*(2.*qperp2*abs_pz + m2*(abs_q + sign*qz))/(2.*qperp2); Energy x_qz = (2.*qperp2*qz + m2*(qz+sign*abs_q))/(2.*qperp2); Lorentz5Momentum recoiler_momentum (0.*GeV,0.*GeV,xi_pz,xi_pz < 0.*GeV ? - xi_pz : xi_pz); recoiler_momentum.rescaleMass(); Lorentz5Momentum parton_momentum (parton->momentum().x(),parton->momentum().y(),x_qz,sqrt(m2+qperp2+x_qz*x_qz)); parton_momentum.rescaleMass(); PPtr n_parton = new_ptr(Particle(parton->dataPtr())); n_parton->set5Momentum(parton_momentum); DipolePartonSplitter::change(parton,n_parton,false); out.pop_front(); intermediates.push_back(parton); out.push_back(n_parton); PPtr n_recoiler = new_ptr(Particle(recoiler->dataPtr())); n_recoiler->set5Momentum(recoiler_momentum); DipolePartonSplitter::change(recoiler,n_recoiler,true); intermediates.push_back(recoiler); if (recoiler == in.first) { in.first = n_recoiler; } if (recoiler == in.second) { in.second = n_recoiler; } return; } } Energy zero (0.*GeV); Lorentz5Momentum Q (zero,zero,zero,zero); for (PList::iterator p = out.begin(); p != out.end(); ++p) { Q += (**p).momentum(); } Boost beta = Q.findBoostToCM(); list mbackup; bool need_boost = (beta.mag2() > Constants::epsilon); if (need_boost) { for (PList::iterator p = out.begin(); p != out.end(); ++p) { Lorentz5Momentum mom = (**p).momentum(); mbackup.push_back(mom); (**p).set5Momentum(mom.boost(beta)); } } double xi; // Only partons if ( decayRecoilers.size()==0 ) { ReshuffleEquation solve (Q.m(),out.begin(),out.end()); GSLBisection solver(1e-10,1e-8,10000); try { xi = solver.value(solve,0.0,1.1); } catch (GSLBisection::GSLerror) { throw DipoleShowerHandler::RedoShower(); } catch (GSLBisection::IntervalError) { throw DipoleShowerHandler::RedoShower(); } } // Partons and decaying recoilers else { DecayReshuffleEquation solve (Q.m(),decayPartons.begin(),decayPartons.end(),decayRecoilers.begin(),decayRecoilers.end()); GSLBisection solver(1e-10,1e-8,10000); try { xi = solver.value(solve,0.0,1.1); } catch (GSLBisection::GSLerror) { throw DipoleShowerHandler::RedoShower(); } catch (GSLBisection::IntervalError) { throw DipoleShowerHandler::RedoShower(); } } PList reshuffled; list::const_iterator backup_it; if (need_boost) backup_it = mbackup.begin(); // Reshuffling of non-decaying partons only if ( decayRecoilers.size()==0 ) { for (PList::iterator p = out.begin(); p != out.end(); ++p) { PPtr rp = new_ptr(Particle((**p).dataPtr())); DipolePartonSplitter::change(*p,rp,false); Lorentz5Momentum rm; rm = Lorentz5Momentum (xi*(**p).momentum().x(), xi*(**p).momentum().y(), xi*(**p).momentum().z(), sqrt(sqr((**p).dataPtr()->constituentMass()) + xi*xi*(sqr((**p).momentum().t())-sqr((**p).dataPtr()->mass())))); rm.rescaleMass(); if (need_boost) { (**p).set5Momentum(*backup_it); ++backup_it; rm.boost(-beta); } rp->set5Momentum(rm); intermediates.push_back(*p); reshuffled.push_back(rp); } } // For the case of a decay process with non-partonic recoilers else { assert ( decay ); for (PList::iterator p = out.begin(); p != out.end(); ++p) { // Flag to update spinInfo bool updateSpin = false; PPtr rp = new_ptr(Particle((**p).dataPtr())); DipolePartonSplitter::change(*p,rp,false); Lorentz5Momentum rm; // If the particle is a parton and not a recoiler if ( find( decayRecoilers.begin(), decayRecoilers.end(), *p ) == decayRecoilers.end() ) { rm = Lorentz5Momentum (xi*(**p).momentum().x(), xi*(**p).momentum().y(), xi*(**p).momentum().z(), sqrt(sqr((**p).dataPtr()->constituentMass()) + xi*xi*(sqr((**p).momentum().t())-sqr((**p).dataPtr()->mass())))); } // Otherwise the parton is a recoiler // and its invariant mass must be preserved else { if ( (*p)-> spinInfo() ) updateSpin = true; rm = Lorentz5Momentum (xi*(**p).momentum().x(), xi*(**p).momentum().y(), xi*(**p).momentum().z(), sqrt(sqr((**p).momentum().m()) + xi*xi*(sqr((**p).momentum().t())-sqr((**p).momentum().m())))); } rm.rescaleMass(); if (need_boost) { (**p).set5Momentum(*backup_it); ++backup_it; rm.boost(-beta); } rp->set5Momentum(rm); // Update SpinInfo if required if ( updateSpin ) updateSpinInfo(*p, rp); intermediates.push_back(*p); reshuffled.push_back(rp); } } out.clear(); out.splice(out.end(),reshuffled); } void ConstituentReshuffler::hardProcDecayReshuffle(PList& decaying, PList& eventOutgoing, PList& eventHard, PPair& eventIncoming, PList& eventIntermediates) { // Note, when this function is called, the particle pointers // in theDecays/decaying are those prior to the showering. // Here we find the newest pointers in the outgoing. // The update of the PPtrs in theDecays is done in DipoleShowerHandler::constituentReshuffle() // as this needs to be done if ConstituentReshuffling is switched off. //Make sure the shower should return constituent masses: assert(ShowerHandler::currentHandler()->retConstituentMasses()); // Find the outgoing decaying particles PList recoilers; for ( PList::iterator decIt = decaying.begin(); decIt != decaying.end(); ++decIt) { // First find the particles in the intermediates PList::iterator pos = find(eventIntermediates.begin(),eventIntermediates.end(), *decIt); // Colourless particle or coloured particle that did not radiate. if(pos==eventIntermediates.end()) { // Check that this is not a particle from a subsequent decay. // e.g. the W from a top decay from an LHE file. if ( find( eventHard.begin(), eventHard.end(), *decIt ) == eventHard.end() && find( eventOutgoing.begin(), eventOutgoing.end(), *decIt ) == eventOutgoing.end() ) continue; else recoilers.push_back( *decIt ); } // Coloured decaying particle that radiated else { PPtr unstable = *pos; while(!unstable->children().empty()) { unstable = unstable->children()[0]; } assert( find( eventOutgoing.begin(),eventOutgoing.end(), unstable ) != eventOutgoing.end() ); recoilers.push_back( unstable ); } } // Make a list of partons PList partons; for ( PList::iterator outPos = eventOutgoing.begin(); outPos != eventOutgoing.end(); ++outPos ) { if ( find (recoilers.begin(), recoilers.end(), *outPos ) == recoilers.end() ) { partons.push_back( *outPos ); } } // If no outgoing partons, do nothing if ( partons.size() == 0 ){ return; } // Otherwise reshuffling needs to be done. // If there is only one parton, attempt to reshuffle with // the incoming to be consistent with the reshuffle for a // hard process with no decays. else if ( partons.size() == 1 && ( DipolePartonSplitter::colourConnected(partons.front(),eventIncoming.first) || DipolePartonSplitter::colourConnected(partons.front(),eventIncoming.second) ) ) { // Erase the parton from the event outgoing eventOutgoing.erase( find( eventOutgoing.begin(), eventOutgoing.end(), partons.front() ) ); // Perform the reshuffle, this update the intermediates and the incoming reshuffle(partons, eventIncoming, eventIntermediates); // Update the outgoing eventOutgoing.push_back(partons.front()); return; } // If reshuffling amongst the incoming is not possible // or if we have multiple outgoing partons. else { // Create a complete list of the outgoing from the process PList out; // Make an empty list for storing the new intermediates PList intermediates; // Empty incoming particles pair PPair in; // A single parton which cannot be reshuffled // with the incoming. if ( partons.size() == 1 ) { // Populate the out for the reshuffling out.insert(out.end(),partons.begin(),partons.end()); out.insert(out.end(),recoilers.begin(),recoilers.end()); assert( out.size() > 1 ); // Perform the reshuffle with the temporary particle lists reshuffle(out, in, intermediates, true, partons, recoilers); } // If there is more than one parton, reshuffle only // amongst the partons else { assert(partons.size() > 1); // Populate the out for the reshuffling out.insert(out.end(),partons.begin(),partons.end()); assert( out.size() > 1 ); // Perform the reshuffle with the temporary particle lists reshuffle(out, in, intermediates, true); } // Update the dipole event record updateEvent(intermediates, eventIntermediates, out, eventOutgoing, eventHard ); return; } } void ConstituentReshuffler::decayReshuffle(PerturbativeProcessPtr& decayProc, PList& eventOutgoing, PList& eventHard, PList& eventIntermediates ) { // Separate particles into those to be assigned constituent masses // i.e. non-decaying coloured partons // and those which must only absorb recoil // i.e. non-coloured and decaying particles PList partons; PList recoilers; //Make sure the shower should return constituent masses: assert(ShowerHandler::currentHandler()->retConstituentMasses()); // Populate the particle lists from the outgoing of the decay process for( unsigned int ix = 0; ixoutgoing().size(); ++ix) { // Identify recoilers if ( !decayProc->outgoing()[ix].first->coloured() || ShowerHandler::currentHandler()->decaysInShower(decayProc->outgoing()[ix].first->id() ) ) recoilers.push_back(decayProc->outgoing()[ix].first); else partons.push_back(decayProc->outgoing()[ix].first); } // If there are no outgoing partons, then no reshuffling // needs to be done if ( partons.size() == 0 ) return; // Reshuffling needs to be done: else { // Create a complete list of the outgoing from the process PList out; // Make an empty list for storing the new intermediates PList intermediates; // Empty incoming particles pair PPair in; // SW - 15/06/2018, 31/01/2019 - Always include 'recoilers' in // reshuffling, regardless of the number of partons to be put on their // constituent mass shell. This is because reshuffling between 2 partons // frequently leads to a redoShower exception. This treatment is // consistent with the AO shower // Populate the out for the reshuffling out.insert(out.end(),partons.begin(),partons.end()); out.insert(out.end(),recoilers.begin(),recoilers.end()); assert( out.size() > 1 ); // Perform the reshuffle with the temporary particle lists reshuffle(out, in, intermediates, true, partons, recoilers); // Update the dipole event record and the decay process updateEvent(intermediates, eventIntermediates, out, eventOutgoing, eventHard, decayProc ); return; } } void ConstituentReshuffler::updateEvent( PList& intermediates, PList& eventIntermediates, +#ifndef NDEBUG PList& out, +#else + PList&, +#endif PList& eventOutgoing, PList& eventHard, PerturbativeProcessPtr decayProc ) { // Loop over the new intermediates following the reshuffling for (PList::iterator p = intermediates.begin(); p != intermediates.end(); ++p) { // Update the event record intermediates eventIntermediates.push_back(*p); // Identify the reshuffled particle assert( (*p)->children().size()==1 ); PPtr reshuffled = (*p)->children()[0]; assert( find(out.begin(), out.end(), reshuffled) != out.end() ); // Update the event record outgoing PList::iterator posOut = find(eventOutgoing.begin(), eventOutgoing.end(), *p); if ( posOut != eventOutgoing.end() ) { eventOutgoing.erase(posOut); eventOutgoing.push_back(reshuffled); } else { PList::iterator posHard = find(eventHard.begin(), eventHard.end(), *p); assert( posHard != eventHard.end() ); eventHard.erase(posHard); eventHard.push_back(reshuffled); } // Replace the particle in the the decay process outgoing if ( decayProc ) { vector >::iterator decayOutIt = decayProc->outgoing().end(); for ( decayOutIt = decayProc->outgoing().begin(); decayOutIt!= decayProc->outgoing().end(); ++decayOutIt ) { if ( decayOutIt->first == *p ){ break; } } assert( decayOutIt != decayProc->outgoing().end() ); decayOutIt->first = reshuffled; } } } void ConstituentReshuffler::updateSpinInfo( PPtr& oldPart, PPtr& newPart ) { const Lorentz5Momentum& oldMom = oldPart->momentum(); const Lorentz5Momentum& newMom = newPart->momentum(); // Rotation from old momentum to +ve z-axis LorentzRotation oldToZAxis; Axis axisOld(oldMom.vect().unit()); if( axisOld.perp2() > 1e-12 ) { double sinth(sqrt(1.-sqr(axisOld.z()))); oldToZAxis.rotate( -acos(axisOld.z()),Axis(-axisOld.y()/sinth,axisOld.x()/sinth,0.)); } // Rotation from new momentum to +ve z-axis LorentzRotation newToZAxis; Axis axisNew(newMom.vect().unit()); if( axisNew.perp2() > 1e-12 ) { double sinth(sqrt(1.-sqr(axisNew.z()))); newToZAxis.rotate( -acos(axisNew.z()),Axis(-axisNew.y()/sinth,axisNew.x()/sinth,0.)); } // Boost from old momentum to new momentum along z-axis Lorentz5Momentum momOldRotated = oldToZAxis*Lorentz5Momentum(oldMom); Lorentz5Momentum momNewRotated = newToZAxis*Lorentz5Momentum(newMom); Energy2 a = sqr(momOldRotated.z()) + sqr(momNewRotated.t()); Energy2 b = 2.*momOldRotated.t()*momOldRotated.z(); Energy2 c = sqr(momOldRotated.t()) - sqr(momNewRotated.t()); double beta; // The rotated momentum should always lie along the +ve z-axis if ( momOldRotated.z() > ZERO ) beta = (-b + sqrt(sqr(b)-4.*a*c)) / 2. / a; else beta = (-b - sqrt(sqr(b)-4.*a*c)) / 2. / a; LorentzRotation boostOldToNew(0., 0., beta); // Total transform LorentzRotation transform = (newToZAxis.inverse())*boostOldToNew*oldToZAxis; // Assign the same spin info to the old and new particles newPart->spinInfo(oldPart->spinInfo()); newPart->spinInfo()->transform(oldMom, transform); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void ConstituentReshuffler::persistentOutput(PersistentOStream &) const { } void ConstituentReshuffler::persistentInput(PersistentIStream &, int) { } ClassDescription ConstituentReshuffler::initConstituentReshuffler; // Definition of the static class description member. void ConstituentReshuffler::Init() { static ClassDocumentation documentation ("The ConstituentReshuffler class implements reshuffling " "of partons on their nominal mass shell to their constituent " "mass shells."); } diff --git a/Shower/QTilde/Kinematics/KinematicsReconstructor.cc b/Shower/QTilde/Kinematics/KinematicsReconstructor.cc --- a/Shower/QTilde/Kinematics/KinematicsReconstructor.cc +++ b/Shower/QTilde/Kinematics/KinematicsReconstructor.cc @@ -1,2825 +1,2827 @@ // -*- C++ -*- // // KinematicsReconstructor.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 KinematicsReconstructor class. // #include "KinematicsReconstructor.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/EventRecord/Event.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Deleted.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/RefVector.h" #include "Herwig/Shower/QTilde/Base/PartnerFinder.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/Shower/QTilde/SplittingFunctions/SplittingFunction.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/EventRecord/ColourLine.h" #include "ThePEG/Utilities/DescribeClass.h" #include "Herwig/Shower/QTilde/QTildeShowerHandler.h" #include #include "KinematicsReconstructor.tcc" using namespace Herwig; DescribeClass describeKinematicsReconstructor("Herwig::KinematicsReconstructor", "HwShower.so"); namespace { /** * Struct to order the jets in off-shellness */ struct JetOrdering { bool operator() (const JetKinStruct & j1, const JetKinStruct & j2) { Energy diff1 = j1.q.m()-j1.p.m(); Energy diff2 = j2.q.m()-j2.p.m(); if(diff1!=diff2) { return diff1>diff2; } else if( j1.q.e() != j2.q.e() ) return j1.q.e()>j2.q.e(); else return j1.parent->uniqueId>j2.parent->uniqueId; } }; } void KinematicsReconstructor::persistentOutput(PersistentOStream & os) const { os << _reconopt << _initialBoost << ounit(_minQ,GeV) << _noRescale << _noRescaleVector << _initialStateReconOption << _finalFinalWeight; } void KinematicsReconstructor::persistentInput(PersistentIStream & is, int) { is >> _reconopt >> _initialBoost >> iunit(_minQ,GeV) >> _noRescale >> _noRescaleVector >> _initialStateReconOption >> _finalFinalWeight; } void KinematicsReconstructor::Init() { static ClassDocumentation documentation ( "This class is responsible for the kinematics reconstruction of the showering,", " including the kinematics reshuffling necessary to compensate for the recoil" "of the emissions." ); static Switch interfaceReconstructionOption ("ReconstructionOption", "Option for the kinematics reconstruction", &KinematicsReconstructor::_reconopt, 0, false, false); static SwitchOption interfaceReconstructionOptionGeneral (interfaceReconstructionOption, "General", "Use the general solution which ignores the colour structure for all processes", 0); static SwitchOption interfaceReconstructionOptionColour (interfaceReconstructionOption, "Colour", "Use the colour structure of the process to determine the reconstruction procedure.", 1); static SwitchOption interfaceReconstructionOptionColour2 (interfaceReconstructionOption, "Colour2", "Make the most use possible of the colour structure of the process to determine the reconstruction procedure. " "Start with FF, then IF then II colour connections", 2); static SwitchOption interfaceReconstructionOptionColour3 (interfaceReconstructionOption, "Colour3", "Make the most use possible of the colour structure of the process to determine the reconstruction procedure. " "Do the colour connections in order of the pT's emitted in the shower starting with the hardest." " The colour partner is fully reconstructed at the same time.", 3); static SwitchOption interfaceReconstructionOptionColour4 (interfaceReconstructionOption, "Colour4", "Make the most use possible of the colour structure of the process to determine the reconstruction procedure. " "Do the colour connections in order of the pT's emitted in the shower starting with the hardest, while leaving" " the colour partner on mass-shell", 4); static Parameter interfaceMinimumQ2 ("MinimumQ2", "The minimum Q2 for the reconstruction of initial-final systems", &KinematicsReconstructor::_minQ, GeV, 0.001*GeV, 1e-6*GeV, 10.0*GeV, false, false, Interface::limited); static RefVector interfaceNoRescale ("NoRescale", "Particles which shouldn't be rescaled to be on shell by the shower", &KinematicsReconstructor::_noRescaleVector, -1, false, false, true, false, false); static Switch interfaceInitialInitialBoostOption ("InitialInitialBoostOption", "Option for how the boost from the system before ISR to that after ISR is applied.", &KinematicsReconstructor::_initialBoost, 0, false, false); static SwitchOption interfaceInitialInitialBoostOptionOneBoost (interfaceInitialInitialBoostOption, "OneBoost", "Apply one boost from old CMS to new CMS", 0); static SwitchOption interfaceInitialInitialBoostOptionLongTransBoost (interfaceInitialInitialBoostOption, "LongTransBoost", "First apply a longitudinal and then a transverse boost", 1); static Deleted delFinalStateReconOption ("FinalStateReconOption", "The old default (0) is now the only choice"); static Switch interfaceInitialStateReconOption ("InitialStateReconOption", "Option for the reconstruction of initial state radiation", &KinematicsReconstructor::_initialStateReconOption, 0, false, false); static SwitchOption interfaceInitialStateReconOptionRapidity (interfaceInitialStateReconOption, "Rapidity", "Preserve shat and rapidity", 0); static SwitchOption interfaceInitialStateReconOptionLongitudinal (interfaceInitialStateReconOption, "Longitudinal", "Preserve longitudinal momentum", 1); static SwitchOption interfaceInitialStateReconOptionSofterFraction (interfaceInitialStateReconOption, "SofterFraction", "Preserve the momentum fraction of the parton which has emitted softer.", 2); static Switch interfaceFinalFinalWeight ("FinalFinalWeight", "Apply kinematic rejection weight for final-states", &KinematicsReconstructor::_finalFinalWeight, false, false, false); static SwitchOption interfaceFinalFinalWeightNo (interfaceFinalFinalWeight, "No", "Don't apply the weight", false); static SwitchOption interfaceFinalFinalWeightYes (interfaceFinalFinalWeight, "Yes", "Apply the weight", true); } void KinematicsReconstructor::doinit() { Interfaced::doinit(); _noRescale = set(_noRescaleVector.begin(),_noRescaleVector.end()); } bool KinematicsReconstructor:: reconstructTimeLikeJet(const tShowerParticlePtr particleJetParent) const { assert(particleJetParent); bool emitted=true; // if this is not a fixed point in the reconstruction if( !particleJetParent->children().empty() ) { // if not a reconstruction fixpoint, dig deeper for all children: for ( ParticleVector::const_iterator cit = particleJetParent->children().begin(); cit != particleJetParent->children().end(); ++cit ) reconstructTimeLikeJet(dynamic_ptr_cast(*cit)); } // it is a reconstruction fixpoint, ie kinematical data has to be available else { // check if the parent was part of the shower ShowerParticlePtr jetGrandParent; if(!particleJetParent->parents().empty()) jetGrandParent= dynamic_ptr_cast (particleJetParent->parents()[0]); // update if so if (jetGrandParent) { if (jetGrandParent->showerKinematics()) { if(particleJetParent->id()==_progenitor->id()&& !_progenitor->data().stable()&&abs(_progenitor->data().id())!=ParticleID::tauminus) { jetGrandParent->showerKinematics()->reconstructLast(particleJetParent, _progenitor->mass()); } else { jetGrandParent->showerKinematics()->reconstructLast(particleJetParent); } } } // otherwise else { Energy dm = ShowerHandler::currentHandler()->retConstituentMasses()? particleJetParent->data().constituentMass(): particleJetParent->data().mass(); if (abs(dm-particleJetParent->momentum().m())>0.001*MeV &&(particleJetParent->dataPtr()->stable() || abs(particleJetParent->id())==ParticleID::tauminus) &&particleJetParent->id()!=ParticleID::gamma &&_noRescale.find(particleJetParent->dataPtr())==_noRescale.end()) { Lorentz5Momentum dum = particleJetParent->momentum(); dum.setMass(dm); dum.rescaleEnergy(); particleJetParent->set5Momentum(dum); } else { emitted=false; } } } // recursion has reached an endpoint once, ie we can reconstruct the // kinematics from the children. if( !particleJetParent->children().empty() ) particleJetParent->showerKinematics() ->reconstructParent( particleJetParent, particleJetParent->children() ); return emitted; } bool KinematicsReconstructor:: reconstructHardJets(ShowerTreePtr hard, const map > & intrinsic, ShowerInteraction type, bool switchRecon) const { _currentTree = hard; _intrinsic=intrinsic; // extract the particles from the ShowerTree vector ShowerHardJets=hard->extractProgenitors(); for(unsigned int ix=0;ixprogenitor()] = vector(); } for(map >::const_iterator tit = _currentTree->treelinks().begin(); tit != _currentTree->treelinks().end();++tit) { _treeBoosts[tit->first] = vector(); } try { // old recon method, using new member functions if(_reconopt == 0 || switchRecon ) { reconstructGeneralSystem(ShowerHardJets); } // reconstruction based on coloured systems else if( _reconopt == 1) { reconstructColourSinglets(ShowerHardJets,type); } // reconstruction of FF, then IF, then II else if( _reconopt == 2) { reconstructFinalFirst(ShowerHardJets); } // reconstruction based on coloured systems else if( _reconopt == 3 || _reconopt == 4) { reconstructColourPartner(ShowerHardJets); } else assert(false); } catch(KinematicsReconstructionVeto) { _progenitor=tShowerParticlePtr(); _intrinsic.clear(); for(map >::const_iterator bit=_boosts.begin();bit!=_boosts.end();++bit) { for(vector::const_reverse_iterator rit=bit->second.rbegin();rit!=bit->second.rend();++rit) { LorentzRotation rot = rit->inverse(); bit->first->transform(rot); } } _boosts.clear(); for(map >::const_iterator bit=_treeBoosts.begin();bit!=_treeBoosts.end();++bit) { for(vector::const_reverse_iterator rit=bit->second.rbegin();rit!=bit->second.rend();++rit) { LorentzRotation rot = rit->inverse(); bit->first->transform(rot,false); } } _currentTree = tShowerTreePtr(); _treeBoosts.clear(); return false; } catch (Exception & ex) { _progenitor=tShowerParticlePtr(); _intrinsic.clear(); _currentTree = tShowerTreePtr(); _boosts.clear(); _treeBoosts.clear(); throw ex; } _progenitor=tShowerParticlePtr(); _intrinsic.clear(); // ensure x<1 for(map::const_iterator cit=hard->incomingLines().begin();cit!=hard->incomingLines().end();++cit) { tPPtr parent = cit->first->progenitor(); while (!parent->parents().empty()) { parent = parent->parents()[0]; } tPPtr hadron; if ( cit->first->original()->parents().empty() ) { hadron = cit->first->original(); } else { hadron = cit->first->original()->parents()[0]; } if( ! (hadron->id() == parent->id() && hadron->children().size() <= 1) && parent->momentum().rho() > hadron->momentum().rho()) { _progenitor=tShowerParticlePtr(); _intrinsic.clear(); for(map >::const_iterator bit=_boosts.begin();bit!=_boosts.end();++bit) { for(vector::const_reverse_iterator rit=bit->second.rbegin();rit!=bit->second.rend();++rit) { LorentzRotation rot = rit->inverse(); bit->first->transform(rot); } } _boosts.clear(); for(map >::const_iterator bit=_treeBoosts.begin();bit!=_treeBoosts.end();++bit) { for(vector::const_reverse_iterator rit=bit->second.rbegin();rit!=bit->second.rend();++rit) { LorentzRotation rot = rit->inverse(); bit->first->transform(rot,false); } } _currentTree = tShowerTreePtr(); _treeBoosts.clear(); return false; } } _boosts.clear(); _treeBoosts.clear(); _currentTree = tShowerTreePtr(); return true; } double KinematicsReconstructor::solveKfactor(const Energy & root_s, const JetKinVect & jets) const { Energy2 s = sqr(root_s); // must be at least two jets if ( jets.size() < 2) throw KinematicsReconstructionVeto(); // sum of jet masses must be less than roots if(momConsEq( 0.0, root_s, jets )>ZERO) throw KinematicsReconstructionVeto(); // if two jets simple solution if ( jets.size() == 2 ) { static const Energy2 eps = 1.0e-4 * MeV2; if ( sqr(jets[0].p.x()+jets[1].p.x()) < eps && sqr(jets[0].p.y()+jets[1].p.y()) < eps && sqr(jets[0].p.z()+jets[1].p.z()) < eps ) { Energy test = (jets[0].p+jets[1].p).vect().mag(); if(test > 1.0e-4 * MeV) throw KinematicsReconstructionVeto(); if ( jets[0].p.vect().mag2() < eps ) throw KinematicsReconstructionVeto(); Energy2 m1sq(jets[0].q.m2()),m2sq(jets[1].q.m2()); return sqrt( ( sqr(s - m1sq - m2sq) - 4.*m1sq*m2sq ) /(4.*s*jets[0].p.vect().mag2()) ); } else throw KinematicsReconstructionVeto(); } // i.e. jets.size() > 2, numerically // check convergence, if it's a problem maybe use Newton iteration? else { double k1 = 0.,k2 = 1.,k = 0.; if ( momConsEq( k1, root_s, jets ) < ZERO ) { while ( momConsEq( k2, root_s, jets ) < ZERO ) { k1 = k2; k2 *= 2; } while ( fabs( (k1 - k2)/(k1 + k2) ) > 1.e-10 ) { if( momConsEq( k2, root_s, jets ) == ZERO ) { return k2; } else { k = (k1+k2)/2.; if ( momConsEq( k, root_s, jets ) > ZERO ) { k2 = k; } else { k1 = k; } } } return k1; } else throw KinematicsReconstructionVeto(); } throw KinematicsReconstructionVeto(); } bool KinematicsReconstructor:: reconstructSpaceLikeJet( const tShowerParticlePtr p) const { bool emitted = true; tShowerParticlePtr child; tShowerParticlePtr parent; if(!p->parents().empty()) parent = dynamic_ptr_cast(p->parents()[0]); if(parent) { emitted=true; reconstructSpaceLikeJet(parent); } // if branching reconstruct time-like child if(p->children().size()==2) child = dynamic_ptr_cast(p->children()[1]); if(p->perturbative()==0 && child) { dynamic_ptr_cast(p->children()[0])-> showerKinematics()->reconstructParent(p,p->children()); if(!child->children().empty()) { _progenitor=child; reconstructTimeLikeJet(child); // calculate the momentum of the particle Lorentz5Momentum pnew=p->momentum()-child->momentum(); pnew.rescaleMass(); p->children()[0]->set5Momentum(pnew); } } return emitted; } Boost KinematicsReconstructor:: solveBoostBeta( const double k, const Lorentz5Momentum & newq, const Lorentz5Momentum & oldp ) { // try something different, purely numerical first: // a) boost to rest frame of newq, b) boost with kp/E Energy q = newq.vect().mag(); Energy2 qs = sqr(q); Energy2 Q2 = newq.m2(); Energy kp = k*(oldp.vect().mag()); Energy2 kps = sqr(kp); // usually we take the minus sign, since this boost will be smaller. // we only require |k \vec p| = |\vec q'| which leaves the sign of // the boost open but the 'minus' solution gives a smaller boost // parameter, i.e. the result should be closest to the previous // result. this is to be changed if we would get many momentum // conservation violations at the end of the shower from a hard // process. double betam = (q*sqrt(qs + Q2) - kp*sqrt(kps + Q2))/(kps + qs + Q2); // move directly to 'return' Boost beta = -betam*(k/kp)*oldp.vect(); // note that (k/kp)*oldp.vect() = oldp.vect()/oldp.vect().mag() but cheaper. // leave this out if it's running properly! if ( betam >= 0 ) return beta; else return Boost(0., 0., 0.); } bool KinematicsReconstructor:: reconstructDecayJets(ShowerTreePtr decay, ShowerInteraction) const { _currentTree = decay; // extract the particles from the ShowerTree vector ShowerHardJets=decay->extractProgenitors(); for(unsigned int ix=0;ixprogenitor()] = vector(); } for(map >::const_iterator tit = _currentTree->treelinks().begin(); tit != _currentTree->treelinks().end();++tit) { _treeBoosts[tit->first] = vector(); } try { bool radiated[2]={false,false}; // find the decaying particle and check if particles radiated ShowerProgenitorPtr initial; for(unsigned int ix=0;ixprogenitor()->isFinalState()) { radiated[1] |=ShowerHardJets[ix]->hasEmitted(); } else { initial=ShowerHardJets[ix]; radiated[0]|=ShowerHardJets[ix]->hasEmitted(); } } // find boost to the rest frame if needed Boost boosttorest=-initial->progenitor()->momentum().boostVector(); double gammarest = initial->progenitor()->momentum().e()/ initial->progenitor()->momentum().mass(); // check if need to boost to rest frame bool gottaBoost = (boosttorest.mag() > 1e-12); // if initial state radiation reconstruct the jet and set up the basis vectors Lorentz5Momentum pjet; Lorentz5Momentum nvect; // find the partner ShowerParticlePtr partner = initial->progenitor()->partner(); Lorentz5Momentum ppartner[2]; if(partner) ppartner[0]=partner->momentum(); // get the n reference vector if(partner) { if(initial->progenitor()->showerKinematics()) { nvect = initial->progenitor()->showerBasis()->getBasis()[1]; } else { Lorentz5Momentum ppartner=initial->progenitor()->partner()->momentum(); if(gottaBoost) ppartner.boost(boosttorest,gammarest); nvect = Lorentz5Momentum( ZERO,0.5*initial->progenitor()->mass()* ppartner.vect().unit()); nvect.boost(-boosttorest,gammarest); } } // if ISR if(radiated[0]) { // reconstruct the decay jet reconstructDecayJet(initial->progenitor()); // momentum of decaying particle after ISR pjet=initial->progenitor()->momentum() -decay->incomingLines().begin()->second->momentum(); pjet.rescaleMass(); } // boost initial state jet and basis vector if needed if(gottaBoost) { pjet.boost(boosttorest,gammarest); nvect.boost(boosttorest,gammarest); ppartner[0].boost(boosttorest,gammarest); } // loop over the final-state particles and do the reconstruction JetKinVect possiblepartners; JetKinVect jetKinematics; bool atLeastOnce = radiated[0]; LorentzRotation restboost(boosttorest,gammarest); Energy inmass(ZERO); for(unsigned int ix=0;ixprogenitor()->isFinalState()) { inmass=ShowerHardJets[ix]->progenitor()->mass(); continue; } // do the reconstruction JetKinStruct tempJetKin; tempJetKin.parent = ShowerHardJets[ix]->progenitor(); if(ShowerHardJets.size()==2) { Lorentz5Momentum dum=ShowerHardJets[ix]->progenitor()->momentum(); dum.setMass(inmass); dum.rescaleRho(); tempJetKin.parent->set5Momentum(dum); } tempJetKin.p = ShowerHardJets[ix]->progenitor()->momentum(); if(gottaBoost) tempJetKin.p.boost(boosttorest,gammarest); _progenitor=tempJetKin.parent; if(ShowerHardJets[ix]->reconstructed()==ShowerProgenitor::notReconstructed) { atLeastOnce |= reconstructTimeLikeJet(tempJetKin.parent); ShowerHardJets[ix]->reconstructed(ShowerProgenitor::done); } if(gottaBoost) deepTransform(tempJetKin.parent,restboost); tempJetKin.q = ShowerHardJets[ix]->progenitor()->momentum(); jetKinematics.push_back(tempJetKin); } if(partner) ppartner[1]=partner->momentum(); // calculate the rescaling parameters double k1,k2; Lorentz5Momentum qt; if(!solveDecayKFactor(initial->progenitor()->mass(),nvect,pjet, jetKinematics,partner,ppartner,k1,k2,qt)) { for(map >::const_iterator bit=_boosts.begin();bit!=_boosts.end();++bit) { for(vector::const_reverse_iterator rit=bit->second.rbegin();rit!=bit->second.rend();++rit) { LorentzRotation rot = rit->inverse(); bit->first->transform(rot); } } _boosts.clear(); for(map >::const_iterator bit=_treeBoosts.begin();bit!=_treeBoosts.end();++bit) { for(vector::const_reverse_iterator rit=bit->second.rbegin();rit!=bit->second.rend();++rit) { LorentzRotation rot = rit->inverse(); bit->first->transform(rot,false); } } _treeBoosts.clear(); _currentTree = tShowerTreePtr(); return false; } // apply boosts and rescalings to final-state jets for(JetKinVect::iterator it = jetKinematics.begin(); it != jetKinematics.end(); ++it) { LorentzRotation Trafo = LorentzRotation(); if(it->parent!=partner) { // boost for rescaling if(atLeastOnce) { map >::const_iterator tit; for(tit = _currentTree->treelinks().begin(); tit != _currentTree->treelinks().end();++tit) { if(tit->second.first && tit->second.second==it->parent) break; } if(it->parent->children().empty()&&!it->parent->spinInfo() && tit==_currentTree->treelinks().end()) { Lorentz5Momentum pnew(k2*it->p.vect(), sqrt(sqr(k2*it->p.vect().mag())+it->q.mass2()), it->q.mass()); it->parent->set5Momentum(pnew); } else { // rescaling boost can't ever work in this case if(k2<0. && it->q.mass()==ZERO) throw KinematicsReconstructionVeto(); Trafo = solveBoost(k2, it->q, it->p); } } if(gottaBoost) Trafo.boost(-boosttorest,gammarest); if(atLeastOnce || gottaBoost) deepTransform(it->parent,Trafo); } else { Lorentz5Momentum pnew=ppartner[0]; pnew *=k1; pnew-=qt; pnew.setMass(ppartner[1].mass()); pnew.rescaleEnergy(); LorentzRotation Trafo=solveBoost(1.,ppartner[1],pnew); if(gottaBoost) Trafo.boost(-boosttorest,gammarest); deepTransform(partner,Trafo); } } } catch(KinematicsReconstructionVeto) { for(map >::const_iterator bit=_boosts.begin();bit!=_boosts.end();++bit) { for(vector::const_reverse_iterator rit=bit->second.rbegin();rit!=bit->second.rend();++rit) { LorentzRotation rot = rit->inverse(); bit->first->transform(rot); } } _boosts.clear(); for(map >::const_iterator bit=_treeBoosts.begin();bit!=_treeBoosts.end();++bit) { for(vector::const_reverse_iterator rit=bit->second.rbegin();rit!=bit->second.rend();++rit) { LorentzRotation rot = rit->inverse(); bit->first->transform(rot,false); } } _treeBoosts.clear(); _currentTree = tShowerTreePtr(); return false; } catch (Exception & ex) { _currentTree = tShowerTreePtr(); _boosts.clear(); _treeBoosts.clear(); throw ex; } _boosts.clear(); _treeBoosts.clear(); _currentTree = tShowerTreePtr(); return true; } bool KinematicsReconstructor:: reconstructDecayJet( const tShowerParticlePtr p) const { if(p->children().empty()) return false; tShowerParticlePtr child; // if branching reconstruct time-like child child = dynamic_ptr_cast(p->children()[1]); if(child) { _progenitor=child; reconstructTimeLikeJet(child); // calculate the momentum of the particle Lorentz5Momentum pnew=p->momentum()-child->momentum(); pnew.rescaleMass(); p->children()[0]->set5Momentum(pnew); child=dynamic_ptr_cast(p->children()[0]); reconstructDecayJet(child); return true; } return false; } bool KinematicsReconstructor:: solveDecayKFactor(Energy mb, const Lorentz5Momentum & n, const Lorentz5Momentum & pjet, const JetKinVect & jetKinematics, ShowerParticlePtr partner, Lorentz5Momentum ppartner[2], double & k1, double & k2, Lorentz5Momentum & qt) const { Energy2 pjn = partner ? pjet.vect()*n.vect() : ZERO; Energy2 pcn = partner ? ppartner[0].vect()*n.vect() : 1.*MeV2; Energy2 nmag = n.vect().mag2(); Lorentz5Momentum pn = partner ? (pjn/nmag)*n : Lorentz5Momentum(); qt=pjet-pn; qt.setE(ZERO); Energy2 pt2=qt.vect().mag2(); Energy Ejet = pjet.e(); // magnitudes of the momenta for fast access vector pmag; Energy total(Ejet); for(unsigned int ix=0;ixmb) return false; Energy2 pcmag=ppartner[0].vect().mag2(); // used newton-raphson to get the rescaling static const Energy eps=1e-8*GeV; long double d1(1.),d2(1.); Energy roots, ea, ec, ds; unsigned int ix=0; do { ++ix; d2 = d1 + pjn/pcn; roots = Ejet; ds = ZERO; for(unsigned int iy=0;iyeps && ix<100); k1=d1; k2=d2; // return true if N-R succeed, otherwise false return ix<100; } bool KinematicsReconstructor:: deconstructDecayJets(HardTreePtr decay,ShowerInteraction) const { // extract the momenta of the particles vector pin; vector pout; // on-shell masses of the decay products vector mon; Energy mbar(-GeV); // the hard branchings of the particles set::iterator cit; set branchings=decay->branchings(); // properties of the incoming particle bool ISR = false; HardBranchingPtr initial; Lorentz5Momentum qisr; // find the incoming particle, both before and after // any ISR for(cit=branchings.begin();cit!=branchings.end();++cit){ if((*cit)->status()==HardBranching::Incoming|| (*cit)->status()==HardBranching::Decay) { // search back up isr if needed HardBranchingPtr branch = *cit; while(branch->parent()) branch=branch->parent(); initial=branch; // momentum or original parent pin.push_back(branch->branchingParticle()->momentum()); // ISR? ISR = !branch->branchingParticle()->children().empty(); // ISR momentum qisr = pin.back()-(**cit).branchingParticle()->momentum(); qisr.rescaleMass(); } } assert(pin.size()==1); // compute boost to rest frame Boost boostv=-pin[0].boostVector(); // partner for ISR ShowerParticlePtr partner; Lorentz5Momentum ppartner; if(initial->branchingParticle()->partner()) { partner=initial->branchingParticle()->partner(); ppartner=partner->momentum(); } // momentum of the decay products for(cit=branchings.begin();cit!=branchings.end();++cit) { if((*cit)->status()!=HardBranching::Outgoing) continue; // find the mass of the particle // including special treatment for off-shell resonances // to preserve off-shell mass Energy mass; if(!(**cit).branchingParticle()->dataPtr()->stable()) { HardBranchingPtr branch=*cit; while(!branch->children().empty()) { for(unsigned int ix=0;ixchildren().size();++ix) { if(branch->children()[ix]->branchingParticle()->id()== (**cit).branchingParticle()->id()) { branch = branch->children()[ix]; continue; } } }; mass = branch->branchingParticle()->mass(); } else { mass = (**cit).branchingParticle()->dataPtr()->mass(); } // if not evolution partner of decaying particle if((*cit)->branchingParticle()!=partner) { pout.push_back((*cit)->branchingParticle()->momentum()); mon.push_back(mass); } // evolution partner of decaying particle else { mbar = mass; } } // boost all the momenta to the rest frame of the decaying particle for(unsigned int ix=0;ixbranchingParticle()->partner()) { ppartner.boost(boostv); qisr.boost(boostv); } // compute the rescaling factors double k1,k2; if(!ISR) { if(partner) { pout.push_back(ppartner); mon.push_back(mbar); } k1=k2=inverseRescalingFactor(pout,mon,pin[0].mass()); if(partner) { pout.pop_back(); mon.pop_back(); } } else { if(!inverseDecayRescalingFactor(pout,mon,pin[0].mass(), ppartner,mbar,k1,k2)) return false; } // now calculate the p reference vectors unsigned int ifinal=0; for(cit=branchings.begin();cit!=branchings.end();++cit) { if((**cit).status()!=HardBranching::Outgoing) continue; // for partners other than colour partner of decaying particle if((*cit)->branchingParticle()!=partner) { Lorentz5Momentum pvect = (*cit)->branchingParticle()->momentum(); pvect.boost(boostv); pvect /= k1; pvect.setMass(mon[ifinal]); ++ifinal; pvect.rescaleEnergy(); pvect.boost(-boostv); (*cit)->pVector(pvect); (*cit)->showerMomentum(pvect); } // for colour partner of decaying particle else { Lorentz5Momentum pvect = (*cit)->branchingParticle()->momentum(); pvect.boost(boostv); Lorentz5Momentum qtotal; for(unsigned int ix=0;ixpVector(pvect); (*cit)->showerMomentum(pvect); } } // For initial-state if needed if(initial) { tShowerParticlePtr newPartner=initial->branchingParticle()->partner(); if(newPartner) { tHardBranchingPtr branch; for( set::iterator clt = branchings.begin(); clt != branchings.end(); ++clt ) { if((**clt).branchingParticle()==newPartner) { initial->colourPartner(*clt); branch=*clt; break; } } Lorentz5Momentum pvect = initial->branchingParticle()->momentum(); initial->pVector(pvect); Lorentz5Momentum ptemp = branch->pVector(); ptemp.boost(boostv); Lorentz5Momentum nvect = Lorentz5Momentum( ZERO, 0.5*initial->branchingParticle()->mass()* ptemp.vect().unit()); nvect.boost(-boostv); initial->nVector(nvect); } } // calculate the reference vectors, then for outgoing particles for(cit=branchings.begin();cit!=branchings.end();++cit){ if((**cit).status()!=HardBranching::Outgoing) continue; // find the partner branchings tShowerParticlePtr newPartner=(*cit)->branchingParticle()->partner(); if(!newPartner) continue; tHardBranchingPtr branch; for( set::iterator clt = branchings.begin(); clt != branchings.end(); ++clt ) { if(cit==clt) continue; if((**clt).branchingParticle()==newPartner) { (**cit).colourPartner(*clt); branch=*clt; break; } } if((**decay->incoming().begin()).branchingParticle()==newPartner) { (**cit).colourPartner(*decay->incoming().begin()); branch = *decay->incoming().begin(); } // final-state colour partner if(branch->status()==HardBranching::Outgoing) { Boost boost=((*cit)->pVector()+branch->pVector()).findBoostToCM(); Lorentz5Momentum pcm = branch->pVector(); pcm.boost(boost); Lorentz5Momentum nvect = Lorentz5Momentum(ZERO,pcm.vect()); nvect.boost( -boost); (*cit)->nVector(nvect); } // initial-state colour partner else { Boost boost=branch->pVector().findBoostToCM(); Lorentz5Momentum pcm = (*cit)->pVector(); pcm.boost(boost); Lorentz5Momentum nvect = Lorentz5Momentum( ZERO, -pcm.vect()); nvect.boost( -boost); (*cit)->nVector(nvect); } } // now compute the new momenta // and calculate the shower variables for(cit=branchings.begin();cit!=branchings.end();++cit) { if((**cit).status()!=HardBranching::Outgoing) continue; LorentzRotation B=LorentzRotation(-boostv); LorentzRotation A=LorentzRotation(boostv),R; if((*cit)->branchingParticle()==partner) { Lorentz5Momentum qnew; Energy2 dot=(*cit)->pVector()*(*cit)->nVector(); double beta = 0.5*((*cit)->branchingParticle()->momentum().m2() -sqr((*cit)->pVector().mass()))/dot; qnew=(*cit)->pVector()+beta*(*cit)->nVector(); qnew.rescaleMass(); // compute the boost R=B*solveBoost(A*qnew,A*(*cit)->branchingParticle()->momentum())*A; } else { Lorentz5Momentum qnew; if((*cit)->branchingParticle()->partner()) { Energy2 dot=(*cit)->pVector()*(*cit)->nVector(); double beta = 0.5*((*cit)->branchingParticle()->momentum().m2() -sqr((*cit)->pVector().mass()))/dot; qnew=(*cit)->pVector()+beta*(*cit)->nVector(); qnew.rescaleMass(); } else { qnew = (*cit)->pVector(); } // compute the boost R=B*solveBoost(A*qnew,A*(*cit)->branchingParticle()->momentum())*A; } // reconstruct the momenta (*cit)->setMomenta(R,1.0,Lorentz5Momentum()); } if(initial) { initial->setMomenta(LorentzRotation(),1.0,Lorentz5Momentum()); } return true; } double KinematicsReconstructor:: inverseRescalingFactor(vector pout, vector mon, Energy roots) const { double lambda=1.; if(pout.size()==2) { double mu_q1(pout[0].m()/roots), mu_q2(pout[1].m()/roots); double mu_p1(mon[0]/roots) , mu_p2(mon[1]/roots); lambda = ((1.+mu_q1+mu_q2)*(1.-mu_q1-mu_q2)*(mu_q1-1.-mu_q2)*(mu_q2-1.-mu_q1))/ ((1.+mu_p1+mu_p2)*(1.-mu_p1-mu_p2)*(mu_p1-1.-mu_p2)*(mu_p2-1.-mu_p1)); if(lambda<0.) throw Exception() << "Rescaling factor is imaginary in KinematicsReconstructor::" << "inverseRescalingFactor lambda^2= " << lambda << Exception::eventerror; lambda = sqrt(lambda); } else { unsigned int ntry=0; // compute magnitudes once for speed vector pmag; for(unsigned int ix=0;ix root(pout.size()); do { // compute new energies Energy sum(ZERO); for(unsigned int ix=0;ix::const_iterator it=tree->branchings().begin(); it!=tree->branchings().end();++it) { if((**it).status()==HardBranching::Incoming) in .jets.push_back(*it); else out.jets.push_back(*it); } LorentzRotation toRest,fromRest; bool applyBoost(false); // do the initial-state reconstruction deconstructInitialInitialSystem(applyBoost,toRest,fromRest, tree,in.jets,type); // do the final-state reconstruction deconstructFinalStateSystem(toRest,fromRest,tree, out.jets,type); // only at this point that we can be sure all the reference vectors // are correct for(set::const_iterator it=tree->branchings().begin(); it!=tree->branchings().end();++it) { if((**it).status()==HardBranching::Incoming) continue; if((**it).branchingParticle()->coloured()) (**it).setMomenta(LorentzRotation(),1.,Lorentz5Momentum(),false); } for(set::const_iterator it=tree->incoming().begin(); it!=tree->incoming().end();++it) { (**it).setMomenta(LorentzRotation(),1.,Lorentz5Momentum(),false); } return true; } bool KinematicsReconstructor::deconstructHardJets(HardTreePtr tree, ShowerInteraction type) const { // inverse of old recon method if(_reconopt == 0) { return deconstructGeneralSystem(tree,type); } else if(_reconopt == 1) { return deconstructColourSinglets(tree,type); } else if(_reconopt == 2) { throw Exception() << "Inverse reconstruction is not currently supported for ReconstructionOption Colour2 " << "in KinematicsReconstructor::deconstructHardJets(). Please use one of the other options\n" << Exception::runerror; } else if(_reconopt == 3 || _reconopt == 4 ) { return deconstructColourPartner(tree,type); } - else + else { assert(false); + return false; + } } bool KinematicsReconstructor:: deconstructColourSinglets(HardTreePtr tree, ShowerInteraction type) const { // identify the colour singlet systems unsigned int nnun(0),nnii(0),nnif(0),nnf(0),nni(0); vector systems(identifySystems(tree->branchings(),nnun,nnii,nnif,nnf,nni)); // now decide what to do LorentzRotation toRest,fromRest; bool applyBoost(false); bool general(false); // initial-initial connection and final-state colour singlet systems // Drell-Yan type if(nnun==0&&nnii==1&&nnif==0&&nnf>0&&nni==0) { // reconstruct initial-initial system for(unsigned int ix=0;ix0&&nni==1)|| (nnif==2&& nni==0))) { for(unsigned int ix=0;ix0&&nni==2) { // only FS needed // but need to boost to rest frame if QED ISR Lorentz5Momentum ptotal; for(unsigned int ix=0;ixbranchingParticle()->momentum(); } toRest = LorentzRotation(ptotal.findBoostToCM()); fromRest = toRest; fromRest.invert(); if(type!=ShowerInteraction::QCD) { combineFinalState(systems); general=false; } } // general type else { general = true; } // final-state systems except for general recon if(!general) { for(unsigned int ix=0;ix::const_iterator it=tree->branchings().begin(); it!=tree->branchings().end();++it) { if((**it).status()==HardBranching::Incoming) continue; if((**it).branchingParticle()->coloured()) (**it).setMomenta(LorentzRotation(),1.,Lorentz5Momentum(),false); } for(set::const_iterator it=tree->incoming().begin(); it!=tree->incoming().end();++it) { (**it).setMomenta(LorentzRotation(),1.,Lorentz5Momentum(),false); } return true; } else { return deconstructGeneralSystem(tree,type); } return true; } bool KinematicsReconstructor:: deconstructColourPartner(HardTreePtr tree, ShowerInteraction type) const { Lorentz5Momentum ptotal; HardBranchingPtr emitter; ColourSingletShower incomingShower,outgoingShower; for(set::const_iterator it=tree->branchings().begin(); it!=tree->branchings().end();++it) { if((**it).status()==HardBranching::Incoming) { incomingShower.jets.push_back(*it); ptotal += (*it)->branchingParticle()->momentum(); // check for emitting particle if((**it).parent() ) { if(!emitter) emitter = *it; else throw Exception() << "Only one emitting particle allowed in " << "KinematicsReconstructor::deconstructColourPartner()" << Exception::runerror; } } else if ((**it).status()==HardBranching::Outgoing) { outgoingShower.jets.push_back(*it); // check for emitting particle if(!(**it).children().empty() ) { if(!emitter) emitter = *it; else throw Exception() << "Only one emitting particle allowed in " << "KinematicsReconstructor::deconstructColourPartner()" << Exception::runerror; } } } assert(emitter); assert(emitter->colourPartner()); ColourSingletShower system; system.jets.push_back(emitter); system.jets.push_back(emitter->colourPartner()); LorentzRotation toRest,fromRest; bool applyBoost(false); // identify the colour singlet system if(emitter->status() == HardBranching::Outgoing && emitter->colourPartner()->status() == HardBranching::Outgoing ) { system.type=F; // need to boost to rest frame if QED ISR if( !incomingShower.jets[0]->branchingParticle()->coloured() && !incomingShower.jets[1]->branchingParticle()->coloured() ) { Boost boost = ptotal.findBoostToCM(); toRest = LorentzRotation( boost); fromRest = LorentzRotation(-boost); } else findInitialBoost(ptotal,ptotal,toRest,fromRest); deconstructFinalStateSystem(toRest,fromRest,tree, system.jets,type); } else if (emitter->status() == HardBranching::Incoming && emitter->colourPartner()->status() == HardBranching::Incoming) { system.type=II; deconstructInitialInitialSystem(applyBoost,toRest,fromRest,tree,system.jets,type); // make sure the recoil gets applied deconstructFinalStateSystem(toRest,fromRest,tree, outgoingShower.jets,type); } else if ((emitter->status() == HardBranching::Outgoing && emitter->colourPartner()->status() == HardBranching::Incoming ) || (emitter->status() == HardBranching::Incoming && emitter->colourPartner()->status() == HardBranching::Outgoing)) { system.type=IF; // enusre incoming first if(system.jets[0]->status() == HardBranching::Outgoing) swap(system.jets[0],system.jets[1]); deconstructInitialFinalSystem(tree,system.jets,type); } else { throw Exception() << "Unknown type of system in " << "KinematicsReconstructor::deconstructColourPartner()" << Exception::runerror; } // only at this point that we can be sure all the reference vectors // are correct for(set::const_iterator it=tree->branchings().begin(); it!=tree->branchings().end();++it) { if((**it).status()==HardBranching::Incoming) continue; if((**it).branchingParticle()->coloured()) (**it).setMomenta(LorentzRotation(),1.,Lorentz5Momentum(),false); } for(set::const_iterator it=tree->incoming().begin(); it!=tree->incoming().end();++it) { (**it).setMomenta(LorentzRotation(),1.,Lorentz5Momentum(),false); } for(set::const_iterator it=tree->branchings().begin(); it!=tree->branchings().end();++it) { if((**it).status()!=HardBranching::Incoming) continue; if(*it==system.jets[0] || *it==system.jets[1]) continue; if((**it).branchingParticle()->momentum().z()>ZERO) { (**it).z((**it).branchingParticle()->momentum().plus()/(**it).beam()->momentum().plus()); } else { (**it).z((**it).branchingParticle()->momentum().minus()/(**it).beam()->momentum().minus()); } } return true; } void KinematicsReconstructor:: reconstructInitialFinalSystem(vector jets) const { Lorentz5Momentum pin[2],pout[2],pbeam; for(unsigned int ix=0;ixprogenitor()->isFinalState()) { pout[0] +=jets[ix]->progenitor()->momentum(); _progenitor = jets[ix]->progenitor(); if(jets[ix]->reconstructed()==ShowerProgenitor::notReconstructed) { reconstructTimeLikeJet(jets[ix]->progenitor()); jets[ix]->reconstructed(ShowerProgenitor::done); } } // initial-state parton else { pin[0] +=jets[ix]->progenitor()->momentum(); if(jets[ix]->progenitor()->showerKinematics()) { pbeam = jets[ix]->progenitor()->showerBasis()->getBasis()[0]; } else { if ( jets[ix]->original()->parents().empty() ) { pbeam = jets[ix]->progenitor()->momentum(); } else { pbeam = jets[ix]->original()->parents()[0]->momentum(); } } if(jets[ix]->reconstructed()==ShowerProgenitor::notReconstructed) { reconstructSpaceLikeJet(jets[ix]->progenitor()); jets[ix]->reconstructed(ShowerProgenitor::done); } assert(!jets[ix]->original()->parents().empty()); } } // add intrinsic pt if needed addIntrinsicPt(jets); // momenta after showering for(unsigned int ix=0;ixprogenitor()->isFinalState()) pout[1] += jets[ix]->progenitor()->momentum(); else pin[1] += jets[ix]->progenitor()->momentum(); } // work out the boost to the Breit frame Lorentz5Momentum pa = pout[0]-pin[0]; Axis axis(pa.vect().unit()); LorentzRotation rot; double sinth(sqrt(sqr(axis.x())+sqr(axis.y()))); if ( sinth > 1.e-9 ) rot.setRotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.)); rot.rotateX(Constants::pi); rot.boostZ( pa.e()/pa.vect().mag()); Lorentz5Momentum ptemp=rot*pbeam; Boost trans = -1./ptemp.e()*ptemp.vect(); trans.setZ(0.); if ( trans.mag2() - 1. >= 0. ) throw KinematicsReconstructionVeto(); rot.boost(trans); pa *=rot; // project and calculate rescaling // reference vectors Lorentz5Momentum n1(ZERO,ZERO,-pa.z(),-pa.z()); Lorentz5Momentum n2(ZERO,ZERO, pa.z(),-pa.z()); Energy2 n1n2 = n1*n2; // decompose the momenta Lorentz5Momentum qbp=rot*pin[1],qcp=rot*pout[1]; qbp.rescaleMass(); qcp.rescaleMass(); double a[2],b[2]; a[0] = n2*qbp/n1n2; b[0] = n1*qbp/n1n2; Lorentz5Momentum qperp = qbp-a[0]*n1-b[0]*n2; b[1] = 0.5; a[1] = 0.5*(qcp.m2()-qperp.m2())/n1n2/b[1]; double kb; if(a[0]!=0.) { double A(0.5*a[0]),B(b[0]*a[0]-a[1]*b[1]-0.25),C(-0.5*b[0]); if(sqr(B)-4.*A*C<0.) throw KinematicsReconstructionVeto(); kb = 0.5*(-B+sqrt(sqr(B)-4.*A*C))/A; } else { kb = 0.5*b[0]/(b[0]*a[0]-a[1]*b[1]-0.25); } // changed to improve stability if(kb==0.) throw KinematicsReconstructionVeto(); if ( a[1]>b[1] && abs(a[1]) < 1e-12 ) throw KinematicsReconstructionVeto(); if ( a[1]<=b[1] && abs(0.5+b[0]/kb) < 1e-12 ) throw KinematicsReconstructionVeto(); double kc = (a[1]>b[1]) ? (a[0]*kb-0.5)/a[1] : b[1]/(0.5+b[0]/kb); if(kc==0.) throw KinematicsReconstructionVeto(); Lorentz5Momentum pnew[2] = { a[0]*kb*n1+b[0]/kb*n2+qperp, a[1]*kc*n1+b[1]/kc*n2+qperp}; LorentzRotation rotinv=rot.inverse(); for(unsigned int ix=0;ixprogenitor()->isFinalState()) { deepTransform(jets[ix]->progenitor(),rot); deepTransform(jets[ix]->progenitor(),solveBoost(pnew[1],qcp)); Energy delta = jets[ix]->progenitor()->momentum().m()-jets[ix]->progenitor()->momentum().mass(); if ( abs(delta) > MeV ) throw KinematicsReconstructionVeto(); deepTransform(jets[ix]->progenitor(),rotinv); } else { tPPtr parent; boostChain(jets[ix]->progenitor(),rot,parent); boostChain(jets[ix]->progenitor(),solveBoostZ(pnew[0],qbp),parent); // check the first boost worked, and if not apply small correction to // fix energy/momentum conservation // this is a kludge but it reduces momentum non-conservation dramatically Lorentz5Momentum pdiff = pnew[0]-jets[ix]->progenitor()->momentum(); Energy2 delta = sqr(pdiff.x())+sqr(pdiff.y())+sqr(pdiff.z())+sqr(pdiff.t()); unsigned int ntry=0; while(delta>1e-6*GeV2 && ntry<5 ) { ntry +=1; boostChain(jets[ix]->progenitor(),solveBoostZ(pnew[0],jets[ix]->progenitor()->momentum()),parent); pdiff = pnew[0]-jets[ix]->progenitor()->momentum(); delta = sqr(pdiff.x())+sqr(pdiff.y())+sqr(pdiff.z())+sqr(pdiff.t()); } // apply test in breit-frame Lorentz5Momentum ptest1 = parent->momentum(); Lorentz5Momentum ptest2 = rot*pbeam; if(ptest1.z()/ptest2.z()<0. || ptest1.z()/ptest2.z()>1.) throw KinematicsReconstructionVeto(); boostChain(jets[ix]->progenitor(),rotinv,parent); } } } bool KinematicsReconstructor::addIntrinsicPt(vector jets) const { bool added=false; // add the intrinsic pt if needed for(unsigned int ix=0;ixprogenitor()->isFinalState()|| jets[ix]->hasEmitted()|| jets[ix]->reconstructed()==ShowerProgenitor::dontReconstruct) continue; if(_intrinsic.find(jets[ix])==_intrinsic.end()) continue; pair pt=_intrinsic[jets[ix]]; Energy etemp = jets[ix]->original()->parents()[0]->momentum().z(); Lorentz5Momentum p_basis(ZERO, ZERO, etemp, abs(etemp)), n_basis(ZERO, ZERO,-etemp, abs(etemp)); double alpha = jets[ix]->progenitor()->x(); double beta = 0.5*(sqr(jets[ix]->progenitor()->data().mass())+ sqr(pt.first))/alpha/(p_basis*n_basis); Lorentz5Momentum pnew=alpha*p_basis+beta*n_basis; pnew.setX(pt.first*cos(pt.second)); pnew.setY(pt.first*sin(pt.second)); pnew.rescaleMass(); jets[ix]->progenitor()->set5Momentum(pnew); added = true; } return added; } namespace { double defaultSolveBoostGamma(const double & betam,const Energy2 & kps, const Energy2 & qs, const Energy2 & Q2, const Energy & kp, const Energy & q, const Energy & qE) { if(betam<0.5) { return 1./sqrt(1.-sqr(betam)); } else { return ( kps+ qs + Q2)/ sqrt(2.*kps*qs + kps*Q2 + qs*Q2 + sqr(Q2) + 2.*q*qE*kp*sqrt(kps + Q2)); } } } LorentzRotation KinematicsReconstructor:: solveBoost(const double k, const Lorentz5Momentum & newq, const Lorentz5Momentum & oldp ) const { Energy q = newq.vect().mag(); Energy2 qs = sqr(q); Energy2 Q2 = newq.mass2(); Energy kp = k*(oldp.vect().mag()); Energy2 kps = sqr(kp); double betam = (q*newq.e() - kp*sqrt(kps + Q2))/(kps + qs + Q2); if ( abs(betam) - 1. >= 0. ) throw KinematicsReconstructionVeto(); Boost beta = -betam*(k/kp)*oldp.vect(); double gamma = 0.; if(Q2/sqr(oldp.e())>1e-4) { gamma = defaultSolveBoostGamma(betam,kps,qs,Q2,kp,q,newq.e()); } else { if(k>0) { gamma = 4.*kps*qs/sqr(kps +qs) + 2.*sqr(kps-qs)*Q2/pow<3,1>(kps +qs) - 0.25*( sqr(kps) + 14.*kps*qs + sqr(qs))*sqr(kps-qs)/(pow<4,1>(kps +qs)*kps*qs)*sqr(Q2); } else { gamma = 0.25*sqr(Q2)/(kps*qs)*(1. - 0.5*(kps+qs)/(kps*qs)*Q2); } if(gamma<=0.) throw KinematicsReconstructionVeto(); gamma = 1./sqrt(gamma); if(gamma>2.) gamma = defaultSolveBoostGamma(betam,kps,qs,Q2,kp,q,newq.e()); } // note that (k/kp)*oldp.vect() = oldp.vect()/oldp.vect().mag() but cheaper. ThreeVector ax = newq.vect().cross( oldp.vect() ); double delta; if (newq.x()*oldp.x()+newq.y()*oldp.y()+newq.z()*oldp.z()< 1e-16*GeV2) { throw KinematicsReconstructionVeto(); }else{ delta = newq.vect().angle( oldp.vect() ); } LorentzRotation R; using Constants::pi; Energy2 scale1 = sqr(newq.x())+ sqr(newq.y())+sqr(newq.z()); Energy2 scale2 = sqr(oldp.x())+ sqr(oldp.y())+sqr(oldp.z()); if ( ax.mag2()/scale1/scale2 > 1e-28 ) { R.rotate( delta, unitVector(ax) ).boost( beta , gamma ); } else if(abs(delta-pi)/pi < 0.001) { double phi=2.*pi*UseRandom::rnd(); Axis axis(cos(phi),sin(phi),0.); axis.rotateUz(newq.vect().unit()); R.rotate(delta,axis).boost( beta , gamma ); } else { R.boost( beta , gamma ); } return R; } LorentzRotation KinematicsReconstructor::solveBoost(const Lorentz5Momentum & q, const Lorentz5Momentum & p ) const { Energy modp = p.vect().mag(); Energy modq = q.vect().mag(); double betam = (p.e()*modp-q.e()*modq)/(sqr(modq)+sqr(modp)+p.mass2()); if ( abs(betam)-1. >= 0. ) throw KinematicsReconstructionVeto(); Boost beta = -betam*q.vect().unit(); ThreeVector ax = p.vect().cross( q.vect() ); double delta = p.vect().angle( q.vect() ); LorentzRotation R; using Constants::pi; if ( beta.mag2() - 1. >= 0. ) throw KinematicsReconstructionVeto(); if ( ax.mag2()/GeV2/MeV2 > 1e-16 ) { R.rotate( delta, unitVector(ax) ).boost( beta ); } else { R.boost( beta ); } return R; } LorentzRotation KinematicsReconstructor::solveBoostZ(const Lorentz5Momentum & q, const Lorentz5Momentum & p ) const { static const double eps = 1e-6; LorentzRotation R; double beta; Energy2 mt2 = p.mass()eps) { double erat = (q.t()+q.z())/(p.t()+p.z()); Energy2 den = mt2*(erat+1./erat); Energy2 num = (q.z()-p.z())*(q.t()+p.t()) + (p.z()+q.z())*(p.t()-q.t()); beta = num/den; if ( abs(beta) - 1. >= 0. ) throw KinematicsReconstructionVeto(); R.boostZ(beta); } else { double er = sqr(p.t()/q.t()); double x = ratio+0.125*(er+10.+1./er)*sqr(ratio); beta = -(p.t()-q.t())*(p.t()+q.t())/(sqr(p.t())+sqr(q.t()))*(1.+x); double gamma = (4.*sqr(p.t()*q.t()) +sqr(p.t()-q.t())*sqr(p.t()+q.t())* (-2.*x+sqr(x)))/sqr(sqr(p.t())+sqr(q.t())); if ( abs(beta) - 1. >= 0. ) throw KinematicsReconstructionVeto(); gamma = 1./sqrt(gamma); R.boost(0.,0.,beta,gamma); } Lorentz5Momentum ptest = R*p; if(ptest.z()/q.z() < 0. || ptest.t()/q.t() < 0. ) { throw KinematicsReconstructionVeto(); } return R; } void KinematicsReconstructor:: reconstructFinalStateSystem(bool applyBoost, const LorentzRotation & toRest, const LorentzRotation & fromRest, vector jets) const { LorentzRotation trans = applyBoost? toRest : LorentzRotation(); // special for case of individual particle if(jets.size()==1) { deepTransform(jets[0]->progenitor(),trans); deepTransform(jets[0]->progenitor(),fromRest); return; } bool radiated(false); // find the hard process centre-of-mass energy Lorentz5Momentum pcm; // check if radiated and calculate total momentum for(unsigned int ix=0;ixhasEmitted(); pcm += jets[ix]->progenitor()->momentum(); } if(applyBoost) pcm *= trans; // check if in CMF frame Boost beta_cm = pcm.findBoostToCM(); bool gottaBoost(false); if(beta_cm.mag() > 1e-12) { gottaBoost = true; trans.boost(beta_cm); } // collection of pointers to initial hard particle and jet momenta // for final boosts JetKinVect jetKinematics; vector::const_iterator cit; for(cit = jets.begin(); cit != jets.end(); cit++) { JetKinStruct tempJetKin; tempJetKin.parent = (*cit)->progenitor(); if(applyBoost || gottaBoost) { deepTransform(tempJetKin.parent,trans); } tempJetKin.p = (*cit)->progenitor()->momentum(); _progenitor=tempJetKin.parent; if((**cit).reconstructed()==ShowerProgenitor::notReconstructed) { radiated |= reconstructTimeLikeJet((*cit)->progenitor()); (**cit).reconstructed(ShowerProgenitor::done); } else { radiated |= !(*cit)->progenitor()->children().empty(); } tempJetKin.q = (*cit)->progenitor()->momentum(); jetKinematics.push_back(tempJetKin); } if(_finalFinalWeight && jetKinematics.size()==2) { Energy m1 = jetKinematics[0].q.m(); Energy m2 = jetKinematics[1].q.m(); Energy m0 = pcm.m(); if(m0sqrt(lambdaNew/lambdaOld)) throw KinematicsReconstructionVeto(); } // default option rescale everything with the same factor // find the rescaling factor double k = 0.0; if(radiated) { k = solveKfactor(pcm.m(), jetKinematics); // perform the rescaling and boosts for(JetKinVect::iterator it = jetKinematics.begin(); it != jetKinematics.end(); ++it) { LorentzRotation Trafo = solveBoost(k, it->q, it->p); deepTransform(it->parent,Trafo); } } // apply the final boosts if(gottaBoost || applyBoost) { LorentzRotation finalBoosts; if(gottaBoost) finalBoosts.boost(-beta_cm); if(applyBoost) finalBoosts.transform(fromRest); for(JetKinVect::iterator it = jetKinematics.begin(); it != jetKinematics.end(); ++it) { deepTransform(it->parent,finalBoosts); } } } void KinematicsReconstructor:: reconstructInitialInitialSystem(bool & applyBoost, LorentzRotation & toRest, LorentzRotation & fromRest, vector jets) const { bool radiated = false; Lorentz5Momentum pcm; // check whether particles radiated and calculate total momentum for( unsigned int ix = 0; ix < jets.size(); ++ix ) { radiated |= jets[ix]->hasEmitted(); pcm += jets[ix]->progenitor()->momentum(); if(jets[ix]->original()->parents().empty()) return; } pcm.rescaleMass(); // check if intrinsic pt to be added radiated |= !_intrinsic.empty(); // if no radiation return if(!radiated) { for(unsigned int ix=0;ixreconstructed()==ShowerProgenitor::notReconstructed) jets[ix]->reconstructed(ShowerProgenitor::done); } return; } // initial state shuffling applyBoost=false; vector p, pq, p_in; vector pts; for(unsigned int ix=0;ixprogenitor()->momentum()); // reconstruct the jet if(jets[ix]->reconstructed()==ShowerProgenitor::notReconstructed) { radiated |= reconstructSpaceLikeJet(jets[ix]->progenitor()); jets[ix]->reconstructed(ShowerProgenitor::done); } assert(!jets[ix]->original()->parents().empty()); Energy etemp = jets[ix]->original()->parents()[0]->momentum().z(); Lorentz5Momentum ptemp = Lorentz5Momentum(ZERO, ZERO, etemp, abs(etemp)); pq.push_back(ptemp); pts.push_back(jets[ix]->highestpT()); } // add the intrinsic pt if needed radiated |=addIntrinsicPt(jets); for(unsigned int ix=0;ixprogenitor()->momentum()); } double x1 = p_in[0].z()/pq[0].z(); double x2 = p_in[1].z()/pq[1].z(); vector beta=initialStateRescaling(x1,x2,p_in[0]+p_in[1],p,pq,pts); // if not need don't apply boosts if(!(radiated && p.size() == 2 && pq.size() == 2)) return; applyBoost=true; // apply the boosts Lorentz5Momentum newcmf; for(unsigned int ix=0;ixprogenitor(); Boost betaboost(0, 0, beta[ix]); tPPtr parent; boostChain(toBoost, LorentzRotation(0.,0.,beta[ix]),parent); if(parent->momentum().e()/pq[ix].e()>1.|| parent->momentum().z()/pq[ix].z()>1.) throw KinematicsReconstructionVeto(); newcmf+=toBoost->momentum(); } if(newcmf.m() jets, ShowerInteraction) const { assert(jets.size()==2); // put beam with +z first if(jets[0]->beam()->momentum().z() pin,pq; for(unsigned int ix=0;ixbranchingParticle()->momentum()); Energy etemp = jets[ix]->beam()->momentum().z(); pq.push_back(Lorentz5Momentum(ZERO, ZERO,etemp, abs(etemp))); } // calculate the rescaling double x[2]; Lorentz5Momentum pcm=pin[0]+pin[1]; assert(pcm.mass2()>ZERO); pcm.rescaleMass(); vector boost = inverseInitialStateRescaling(x[0],x[1],pcm,pin,pq); set::const_iterator cjt=tree->incoming().begin(); HardBranchingPtr incoming[2]; incoming[0] = *cjt; ++cjt; incoming[1] = *cjt; if((*tree->incoming().begin())->beam()->momentum().z()/pq[0].z()<0.) swap(incoming[0],incoming[1]); // apply the boost the the particles unsigned int iswap[2]={1,0}; for(unsigned int ix=0;ix<2;++ix) { LorentzRotation R(0.,0.,-boost[ix]); incoming[ix]->pVector(pq[ix]); incoming[ix]->nVector(pq[iswap[ix]]); incoming[ix]->setMomenta(R,1.,Lorentz5Momentum()); jets[ix]->showerMomentum(x[ix]*jets[ix]->pVector()); } // and calculate the boosts applyBoost=true; // do one boost if(_initialBoost==0) { toRest = LorentzRotation(-pcm.boostVector()); } else if(_initialBoost==1) { // first the transverse boost Energy pT = sqrt(sqr(pcm.x())+sqr(pcm.y())); double beta = -pT/pcm.t(); toRest=LorentzRotation(Boost(beta*pcm.x()/pT,beta*pcm.y()/pT,0.)); // the longitudinal beta = pcm.z()/sqrt(pcm.m2()+sqr(pcm.z())); toRest.boost(Boost(0.,0.,-beta)); } else assert(false); fromRest = LorentzRotation((jets[0]->showerMomentum()+ jets[1]->showerMomentum()).boostVector()); } void KinematicsReconstructor:: deconstructFinalStateSystem(const LorentzRotation & toRest, const LorentzRotation & fromRest, HardTreePtr tree, vector jets, ShowerInteraction type) const { LorentzRotation trans = toRest; if(jets.size()==1) { Lorentz5Momentum pnew = toRest*(jets[0]->branchingParticle()->momentum()); pnew *= fromRest; jets[0]-> original(pnew); jets[0]->showerMomentum(pnew); // find the colour partners ShowerParticleVector particles; vector ptemp; set::const_iterator cjt; for(cjt=tree->branchings().begin();cjt!=tree->branchings().end();++cjt) { ptemp.push_back((**cjt).branchingParticle()->momentum()); (**cjt).branchingParticle()->set5Momentum((**cjt).showerMomentum()); particles.push_back((**cjt).branchingParticle()); } dynamic_ptr_cast(ShowerHandler::currentHandler())->partnerFinder() ->setInitialEvolutionScales(particles,false,type,false); // calculate the reference vectors unsigned int iloc(0); set::iterator clt; for(cjt=tree->branchings().begin();cjt!=tree->branchings().end();++cjt) { // reset the momentum (**cjt).branchingParticle()->set5Momentum(ptemp[iloc]); ++iloc; // sort out the partners tShowerParticlePtr partner = (*cjt)->branchingParticle()->partner(); if(!partner) continue; for(clt=tree->branchings().begin();clt!=tree->branchings().end();++clt) { if((**clt).branchingParticle()==partner) { (**cjt).colourPartner(*clt); break; } } tHardBranchingPtr branch; for(clt=tree->branchings().begin();clt!=tree->branchings().end();++clt) { if(clt==cjt) continue; if((*clt)->branchingParticle()==partner) { branch=*clt; break; } } } return; } vector::iterator cit; vector pout; vector mon; Lorentz5Momentum pin; for(cit=jets.begin();cit!=jets.end();++cit) { pout.push_back((*cit)->branchingParticle()->momentum()); mon.push_back(findMass(*cit)); pin+=pout.back(); } // boost all the momenta to the rest frame of the decaying particle pin.rescaleMass(); pin *=trans; Boost beta_cm = pin.findBoostToCM(); bool gottaBoost(false); if(beta_cm.mag() > 1e-12) { gottaBoost = true; trans.boost(beta_cm); pin.boost(beta_cm); } for(unsigned int ix=0;ixbranchingParticle()->momentum(); pvect.transform(trans); pvect /= lambda; pvect.setMass(mon[ix]); pvect.rescaleEnergy(); if(gottaBoost) pvect.boost(-beta_cm); pvect.transform(fromRest); jets[ix]->pVector(pvect); jets[ix]->showerMomentum(pvect); } // find the colour partners ShowerParticleVector particles; vector ptemp; set::const_iterator cjt; for(cjt=tree->branchings().begin();cjt!=tree->branchings().end();++cjt) { ptemp.push_back((**cjt).branchingParticle()->momentum()); (**cjt).branchingParticle()->set5Momentum((**cjt).showerMomentum()); particles.push_back((**cjt).branchingParticle()); } dynamic_ptr_cast(ShowerHandler::currentHandler())->partnerFinder() ->setInitialEvolutionScales(particles,false,type,false); // calculate the reference vectors unsigned int iloc(0); set::iterator clt; for(cjt=tree->branchings().begin();cjt!=tree->branchings().end();++cjt) { // reset the momentum (**cjt).branchingParticle()->set5Momentum(ptemp[iloc]); ++iloc; } for(cjt=tree->branchings().begin();cjt!=tree->branchings().end();++cjt) { // sort out the partners tShowerParticlePtr partner = (*cjt)->branchingParticle()->partner(); if(!partner) continue; for(clt=tree->branchings().begin();clt!=tree->branchings().end();++clt) { if((**clt).branchingParticle()==partner) { (**cjt).colourPartner(*clt); break; } } tHardBranchingPtr branch; for(clt=tree->branchings().begin();clt!=tree->branchings().end();++clt) { if(clt==cjt) continue; if((*clt)->branchingParticle()==partner) { branch=*clt; break; } } // compute the reference vectors // both incoming, should all ready be done if((**cjt).status()==HardBranching::Incoming && (**clt).status()==HardBranching::Incoming) { continue; } // both outgoing else if((**cjt).status()!=HardBranching::Incoming&& branch->status()==HardBranching::Outgoing) { Boost boost=((*cjt)->pVector()+branch->pVector()).findBoostToCM(); Lorentz5Momentum pcm = branch->pVector(); pcm.boost(boost); Lorentz5Momentum nvect = Lorentz5Momentum(ZERO,pcm.vect()); nvect.boost( -boost); (**cjt).nVector(nvect); } else if((**cjt).status()==HardBranching::Incoming) { Lorentz5Momentum pa = -(**cjt).showerMomentum()+branch->showerMomentum(); Lorentz5Momentum pb = (**cjt).showerMomentum(); Axis axis(pa.vect().unit()); LorentzRotation rot; double sinth(sqrt(sqr(axis.x())+sqr(axis.y()))); rot.setRotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.)); rot.rotateX(Constants::pi); rot.boostZ( pa.e()/pa.vect().mag()); pb*=rot; Boost trans = -1./pb.e()*pb.vect(); trans.setZ(0.); rot.boost(trans); Energy scale=(**cjt).beam()->momentum().e(); Lorentz5Momentum pbasis(ZERO,(**cjt).beam()->momentum().vect().unit()*scale); Lorentz5Momentum pcm = rot*pbasis; rot.invert(); (**cjt).nVector(rot*Lorentz5Momentum(ZERO,-pcm.vect())); tHardBranchingPtr branch2 = *cjt;; while (branch2->parent()) { branch2=branch2->parent(); branch2->nVector(rot*Lorentz5Momentum(ZERO,-pcm.vect())); } } else if(branch->status()==HardBranching::Incoming) { (**cjt).nVector(Lorentz5Momentum(ZERO,branch->showerMomentum().vect())); } } // now compute the new momenta for(cjt=tree->branchings().begin();cjt!=tree->branchings().end();++cjt) { if(!(*cjt)->branchingParticle()->isFinalState()) continue; Lorentz5Momentum qnew; if((*cjt)->branchingParticle()->partner()) { Energy2 dot=(*cjt)->pVector()*(*cjt)->nVector(); double beta = 0.5*((*cjt)->branchingParticle()->momentum().m2() -sqr((*cjt)->pVector().mass()))/dot; qnew=(*cjt)->pVector()+beta*(*cjt)->nVector(); qnew.rescaleMass(); } else { qnew = (*cjt)->pVector(); } // qnew is the unshuffled momentum in the rest frame of the p basis vectors, // for the simple case Z->q qbar g this was checked against analytic formulae. // compute the boost LorentzRotation R=solveBoost(qnew, toRest*(*cjt)->branchingParticle()->momentum())*toRest; (*cjt)->setMomenta(R,1.0,Lorentz5Momentum()); } } Energy KinematicsReconstructor::momConsEq(double k, const Energy & root_s, const JetKinVect & jets) const { static const Energy2 eps=1e-8*GeV2; Energy dum = ZERO; for(JetKinVect::const_iterator it = jets.begin(); it != jets.end(); ++it) { Energy2 dum2 = (it->q).m2() + sqr(k)*(it->p).vect().mag2(); if(dum2 < ZERO) { if(dum2 < -eps) throw KinematicsReconstructionVeto(); dum2 = ZERO; } dum += sqrt(dum2); } return dum - root_s; } void KinematicsReconstructor::boostChain(tPPtr p, const LorentzRotation &bv, tPPtr & parent) const { if(!p->parents().empty()) boostChain(p->parents()[0], bv,parent); else parent=p; p->transform(bv); if(p->children().size()==2) { if(dynamic_ptr_cast(p->children()[1])) deepTransform(p->children()[1],bv); } } namespace { bool sortJets(ShowerProgenitorPtr j1, ShowerProgenitorPtr j2) { return j1->highestpT()>j2->highestpT(); } } void KinematicsReconstructor:: reconstructGeneralSystem(vector & ShowerHardJets) const { // find initial- and final-state systems ColourSingletSystem in,out; for(unsigned int ix=0;ixprogenitor()->isFinalState()) out.jets.push_back(ShowerHardJets[ix]); else in.jets.push_back(ShowerHardJets[ix]); } // reconstruct initial-initial system LorentzRotation toRest,fromRest; bool applyBoost(false); // reconstruct initial-initial system reconstructInitialInitialSystem(applyBoost,toRest,fromRest,in.jets); // reconstruct the final-state systems reconstructFinalStateSystem(applyBoost,toRest,fromRest,out.jets); } void KinematicsReconstructor:: reconstructFinalFirst(vector & ShowerHardJets) const { static const Energy2 minQ2 = 1e-4*GeV2; map used; for(unsigned int ix=0;ix outgoing; // first find any particles with final state partners for(unsigned int ix=0;ixprogenitor()->isFinalState()&& ShowerHardJets[ix]->progenitor()->partner()&& ShowerHardJets[ix]->progenitor()->partner()->isFinalState()) outgoing.insert(ShowerHardJets[ix]); } // then find the colour partners if(!outgoing.empty()) { set partners; for(set::const_iterator it=outgoing.begin();it!=outgoing.end();++it) { for(unsigned int ix=0;ixpartner()==ShowerHardJets[ix]->progenitor()) { partners.insert(ShowerHardJets[ix]); break; } } } outgoing.insert(partners.begin(),partners.end()); } // do the final-state reconstruction if needed if(!outgoing.empty()) { assert(outgoing.size()!=1); LorentzRotation toRest,fromRest; vector outgoingJets(outgoing.begin(),outgoing.end()); reconstructFinalStateSystem(false,toRest,fromRest,outgoingJets); } // Now do any initial-final systems which are needed vector IFSystems; // find the systems N.B. can have duplicates // find initial-state with FS partners or FS with IS partners for(unsigned int ix=0;ixprogenitor()->isFinalState()&& ShowerHardJets[ix]->progenitor()->partner()&& ShowerHardJets[ix]->progenitor()->partner()->isFinalState()) { IFSystems.push_back(ColourSingletSystem(IF,ShowerHardJets[ix])); } else if(ShowerHardJets[ix]->progenitor()->isFinalState()&& ShowerHardJets[ix]->progenitor()->partner()&& !ShowerHardJets[ix]->progenitor()->partner()->isFinalState()) { IFSystems.push_back(ColourSingletSystem(IF,ShowerHardJets[ix])); } } // then add the partners for(unsigned int is=0;isprogenitor()->partner()==ShowerHardJets[ix]->progenitor()) { IFSystems[is].jets.push_back(ShowerHardJets[ix]); } } // ensure incoming first if(IFSystems[is].jets[0]->progenitor()->isFinalState()) swap(IFSystems[is].jets[0],IFSystems[is].jets[1]); } if(!IFSystems.empty()) { unsigned int istart = UseRandom::irnd(IFSystems.size()); unsigned int istop=IFSystems.size(); for(unsigned int is=istart;is<=istop;++is) { if(is==IFSystems.size()) { if(istart!=0) { istop = istart-1; is=0; } else break; } // skip duplicates if(used[IFSystems[is].jets[0]] && used[IFSystems[is].jets[1]] ) continue; if(IFSystems[is].jets[0]->original()&&IFSystems[is].jets[0]->original()->parents().empty()) continue; Lorentz5Momentum psum; for(unsigned int ix=0;ixprogenitor()->isFinalState()) psum += IFSystems[is].jets[ix]->progenitor()->momentum(); else psum -= IFSystems[is].jets[ix]->progenitor()->momentum(); } if(-psum.m2()>minQ2) { reconstructInitialFinalSystem(IFSystems[is].jets); for(unsigned int ix=0;ixprogenitor()->isFinalState()) out.jets.push_back(ShowerHardJets[ix]); else in.jets.push_back(ShowerHardJets[ix]); } // reconstruct initial-initial system bool doRecon = false; for(unsigned int ix=0;ix & ShowerHardJets) const { static const Energy2 minQ2 = 1e-4*GeV2; // sort the vector by hardness of emission std::sort(ShowerHardJets.begin(),ShowerHardJets.end(),sortJets); // map between particles and progenitors for easy lookup map progenitorMap; for(unsigned int ix=0;ixprogenitor()] = ShowerHardJets[ix]; } // check that the IF systems can be reconstructed bool canReconstruct = true; for(unsigned int ix=0;ixprogenitor(); tShowerParticlePtr partner = progenitor->partner(); if(!partner) continue; else if((progenitor->isFinalState() && !partner->isFinalState()) || (!progenitor->isFinalState() && partner->isFinalState()) ) { vector jets(2); jets[0] = ShowerHardJets[ix]; jets[1] = progenitorMap[partner]; Lorentz5Momentum psum; for(unsigned int iy=0;iyprogenitor()->isFinalState()) psum += jets[iy]->progenitor()->momentum(); else psum -= jets[iy]->progenitor()->momentum(); } if(-psum.m2() used; for(unsigned int ix=0;ixreconstructed()==ShowerProgenitor::done) continue; // already reconstructed if(used[ShowerHardJets[ix]]) continue; // no partner continue tShowerParticlePtr progenitor = ShowerHardJets[ix]->progenitor(); tShowerParticlePtr partner = progenitor->partner(); if(!partner) { // check if there's a daughter tree which also needs boosting Lorentz5Momentum porig = progenitor->momentum(); map >::const_iterator tit; for(tit = _currentTree->treelinks().begin(); tit != _currentTree->treelinks().end();++tit) { // if there is, boost it if(tit->second.first && tit->second.second==progenitor) { Lorentz5Momentum pnew = tit->first->incomingLines().begin() ->first->progenitor()->momentum(); pnew *= tit->first->transform(); Lorentz5Momentum pdiff = porig-pnew; Energy2 test = sqr(pdiff.x()) + sqr(pdiff.y()) + sqr(pdiff.z()) + sqr(pdiff.t()); LorentzRotation rot; if(test>1e-6*GeV2) rot = solveBoost(porig,pnew); tit->first->transform(rot,false); _treeBoosts[tit->first].push_back(rot); } } ShowerHardJets[ix]->reconstructed(ShowerProgenitor::done); continue; } // do the reconstruction // final-final if(progenitor->isFinalState() && partner->isFinalState() ) { LorentzRotation toRest,fromRest; vector jets(2); jets[0] = ShowerHardJets[ix]; jets[1] = progenitorMap[partner]; if(_reconopt==4 && jets[1]->reconstructed()==ShowerProgenitor::notReconstructed) jets[1]->reconstructed(ShowerProgenitor::dontReconstruct); reconstructFinalStateSystem(false,toRest,fromRest,jets); if(_reconopt==4 && jets[1]->reconstructed()==ShowerProgenitor::dontReconstruct) jets[1]->reconstructed(ShowerProgenitor::notReconstructed); used[jets[0]] = true; if(_reconopt==3) used[jets[1]] = true; } // initial-final else if((progenitor->isFinalState() && !partner->isFinalState()) || (!progenitor->isFinalState() && partner->isFinalState()) ) { vector jets(2); jets[0] = ShowerHardJets[ix]; jets[1] = progenitorMap[partner]; if(jets[0]->progenitor()->isFinalState()) swap(jets[0],jets[1]); if(jets[0]->original()&&jets[0]->original()->parents().empty()) continue; Lorentz5Momentum psum; for(unsigned int iy=0;iyprogenitor()->isFinalState()) psum += jets[iy]->progenitor()->momentum(); else psum -= jets[iy]->progenitor()->momentum(); } if(_reconopt==4 && progenitorMap[partner]->reconstructed()==ShowerProgenitor::notReconstructed) progenitorMap[partner]->reconstructed(ShowerProgenitor::dontReconstruct); reconstructInitialFinalSystem(jets); if(_reconopt==4 && progenitorMap[partner]->reconstructed()==ShowerProgenitor::dontReconstruct) progenitorMap[partner]->reconstructed(ShowerProgenitor::notReconstructed); used[ShowerHardJets[ix]] = true; if(_reconopt==3) used[progenitorMap[partner]] = true; } // initial-initial else if(!progenitor->isFinalState() && !partner->isFinalState() ) { ColourSingletSystem in,out; in.jets.push_back(ShowerHardJets[ix]); in.jets.push_back(progenitorMap[partner]); for(unsigned int iy=0;iyprogenitor()->isFinalState()) out.jets.push_back(ShowerHardJets[iy]); } LorentzRotation toRest,fromRest; bool applyBoost(false); if(_reconopt==4 && in.jets[1]->reconstructed()==ShowerProgenitor::notReconstructed) in.jets[1]->reconstructed(ShowerProgenitor::dontReconstruct); reconstructInitialInitialSystem(applyBoost,toRest,fromRest,in.jets); if(_reconopt==4 && in.jets[1]->reconstructed()==ShowerProgenitor::dontReconstruct) in.jets[1]->reconstructed(ShowerProgenitor::notReconstructed); used[in.jets[0]] = true; if(_reconopt==3) used[in.jets[1]] = true; for(unsigned int iy=0;iyreconstructed()==ShowerProgenitor::notReconstructed) out.jets[iy]->reconstructed(ShowerProgenitor::dontReconstruct); } // reconstruct the final-state systems LorentzRotation finalBoosts; finalBoosts.transform( toRest); finalBoosts.transform(fromRest); for(unsigned int iy=0;iyprogenitor(),finalBoosts); } for(unsigned int iy=0;iyreconstructed()==ShowerProgenitor::dontReconstruct) out.jets[iy]->reconstructed(ShowerProgenitor::notReconstructed); } } } } bool KinematicsReconstructor:: inverseDecayRescalingFactor(vector pout, vector mon,Energy roots, Lorentz5Momentum ppartner, Energy mbar, double & k1, double & k2) const { ThreeVector qtotal; vector pmag; for(unsigned int ix=0;ix1e10) return false; } while (abs(numer)>eps&&itry<100); k1 = abs(k1); k2 = a*k1; return itry<100; } void KinematicsReconstructor:: deconstructInitialFinalSystem(HardTreePtr tree,vector jets, ShowerInteraction type) const { HardBranchingPtr incoming; Lorentz5Momentum pin[2],pout[2],pbeam; HardBranchingPtr initial; Energy mc(ZERO); for(unsigned int ix=0;ixstatus()==HardBranching::Outgoing) { pout[0] += jets[ix]->branchingParticle()->momentum(); mc = jets[ix]->branchingParticle()->thePEGBase() ? jets[ix]->branchingParticle()->thePEGBase()->mass() : jets[ix]->branchingParticle()->dataPtr()->mass(); } // initial-state parton else { pin[0] += jets[ix]->branchingParticle()->momentum(); initial = jets[ix]; pbeam = jets[ix]->beam()->momentum(); Energy scale=pbeam.t(); pbeam = Lorentz5Momentum(ZERO,pbeam.vect().unit()*scale); incoming = jets[ix]; while(incoming->parent()) incoming = incoming->parent(); } } if(jets.size()>2) { pout[0].rescaleMass(); mc = pout[0].mass(); } // work out the boost to the Breit frame Lorentz5Momentum pa = pout[0]-pin[0]; Axis axis(pa.vect().unit()); LorentzRotation rot; double sinth(sqrt(sqr(axis.x())+sqr(axis.y()))); if(axis.perp2()>0.) { rot.setRotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.)); rot.rotateX(Constants::pi); rot.boostZ( pa.e()/pa.vect().mag()); } // transverse part Lorentz5Momentum paxis=rot*pbeam; Boost trans = -1./paxis.e()*paxis.vect(); trans.setZ(0.); rot.boost(trans); pa *= rot; // reference vectors Lorentz5Momentum n1(ZERO,ZERO,-pa.z(),-pa.z()); Lorentz5Momentum n2(ZERO,ZERO, pa.z(),-pa.z()); Energy2 n1n2 = n1*n2; // decompose the momenta Lorentz5Momentum qbp=rot*pin[0],qcp= rot*pout[0]; double a[2],b[2]; a[0] = n2*qbp/n1n2; b[0] = n1*qbp/n1n2; a[1] = n2*qcp/n1n2; b[1] = n1*qcp/n1n2; Lorentz5Momentum qperp = qbp-a[0]*n1-b[0]*n2; // before reshuffling Energy Q = abs(pa.z()); double c = sqr(mc/Q); Lorentz5Momentum pb(ZERO,ZERO,0.5*Q*(1.+c),0.5*Q*(1.+c)); Lorentz5Momentum pc(ZERO,ZERO,0.5*Q*(c-1.),0.5*Q*(1.+c)); double anew[2],bnew[2]; anew[0] = pb*n2/n1n2; bnew[0] = 0.5*(qbp.m2()-qperp.m2())/n1n2/anew[0]; bnew[1] = pc*n1/n1n2; anew[1] = 0.5*qcp.m2()/bnew[1]/n1n2; Lorentz5Momentum qnewb = (anew[0]*n1+bnew[0]*n2+qperp); Lorentz5Momentum qnewc = (anew[1]*n1+bnew[1]*n2); // initial-state boost LorentzRotation rotinv=rot.inverse(); LorentzRotation transb=rotinv*solveBoostZ(qnewb,qbp)*rot; // final-state boost LorentzRotation transc=rotinv*solveBoost(qnewc,qcp)*rot; // this will need changing for more than one outgoing particle // set the pvectors for(unsigned int ix=0;ixstatus()==HardBranching::Incoming) { jets[ix]->pVector(pbeam); jets[ix]->showerMomentum(rotinv*pb); incoming->pVector(jets[ix]->pVector()); } else { jets[ix]->pVector(rotinv*pc); jets[ix]->showerMomentum(jets[ix]->pVector()); } } // find the colour partners ShowerParticleVector particles; vector ptemp; set::const_iterator cjt; for(cjt=tree->branchings().begin();cjt!=tree->branchings().end();++cjt) { ptemp.push_back((**cjt).branchingParticle()->momentum()); (**cjt).branchingParticle()->set5Momentum((**cjt).showerMomentum()); particles.push_back((**cjt).branchingParticle()); } dynamic_ptr_cast(ShowerHandler::currentHandler())->partnerFinder() ->setInitialEvolutionScales(particles,false,type,false); unsigned int iloc(0); for(cjt=tree->branchings().begin();cjt!=tree->branchings().end();++cjt) { // reset the momentum (**cjt).branchingParticle()->set5Momentum(ptemp[iloc]); ++iloc; } for(vector::const_iterator cjt=jets.begin(); cjt!=jets.end();++cjt) { // sort out the partners tShowerParticlePtr partner = (*cjt)->branchingParticle()->partner(); if(!partner) continue; tHardBranchingPtr branch; for(set::const_iterator clt=tree->branchings().begin();clt!=tree->branchings().end();++clt) { if((**clt).branchingParticle()==partner) { (**cjt).colourPartner(*clt); branch=*clt; break; } } // compute the reference vectors // both incoming, should all ready be done if((**cjt).status()==HardBranching::Incoming && branch->status()==HardBranching::Incoming) { Energy etemp = (*cjt)->beam()->momentum().z(); Lorentz5Momentum nvect(ZERO, ZERO,-etemp, abs(etemp)); tHardBranchingPtr branch2 = *cjt; (**cjt).nVector(nvect); while (branch2->parent()) { branch2=branch2->parent(); branch2->nVector(nvect); } } // both outgoing else if((**cjt).status()==HardBranching::Outgoing&& branch->status()==HardBranching::Outgoing) { Boost boost=((*cjt)->pVector()+branch->pVector()).findBoostToCM(); Lorentz5Momentum pcm = branch->pVector(); pcm.boost(boost); Lorentz5Momentum nvect = Lorentz5Momentum(ZERO,pcm.vect()); nvect.boost( -boost); (**cjt).nVector(nvect); } else if((**cjt).status()==HardBranching::Incoming) { Lorentz5Momentum pa = -(**cjt).showerMomentum()+branch->showerMomentum(); Lorentz5Momentum pb = (**cjt).showerMomentum(); Axis axis(pa.vect().unit()); LorentzRotation rot; double sinth(sqrt(sqr(axis.x())+sqr(axis.y()))); if(axis.perp2()>1e-20) { rot.setRotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.)); rot.rotateX(Constants::pi); } if(abs(1.-pa.e()/pa.vect().mag())>1e-6) rot.boostZ( pa.e()/pa.vect().mag()); pb*=rot; Boost trans = -1./pb.e()*pb.vect(); trans.setZ(0.); rot.boost(trans); Energy scale=(**cjt).beam()->momentum().t(); Lorentz5Momentum pbasis(ZERO,(**cjt).beam()->momentum().vect().unit()*scale); Lorentz5Momentum pcm = rot*pbasis; rot.invert(); Lorentz5Momentum nvect = rot*Lorentz5Momentum(ZERO,-pcm.vect()); (**cjt).nVector(nvect); tHardBranchingPtr branch2 = *cjt; while (branch2->parent()) { branch2=branch2->parent(); branch2->nVector(nvect); } } else if(branch->status()==HardBranching::Incoming) { Lorentz5Momentum nvect=Lorentz5Momentum(ZERO,branch->showerMomentum().vect()); (**cjt).nVector(nvect); } } // now compute the new momenta for(vector::const_iterator cjt=jets.begin(); cjt!=jets.end();++cjt) { if((**cjt).status()==HardBranching::Outgoing) { (**cjt).setMomenta(transc,1.,Lorentz5Momentum()); } } incoming->setMomenta(transb,1.,Lorentz5Momentum()); } void KinematicsReconstructor::deepTransform(PPtr particle, const LorentzRotation & r, bool match, PPtr original) const { if(_boosts.find(particle)!=_boosts.end()) { _boosts[particle].push_back(r); } Lorentz5Momentum porig = particle->momentum(); if(!original) original = particle; for ( int i = 0, N = particle->children().size(); i < N; ++i ) { deepTransform(particle->children()[i],r, particle->children()[i]->id()==original->id()&&match,original); } particle->transform(r); // transform the p and n vectors ShowerParticlePtr sparticle = dynamic_ptr_cast(particle); if(sparticle && sparticle->showerBasis()) { sparticle->showerBasis()->transform(r); } if ( particle->next() ) deepTransform(particle->next(),r,match,original); if(!match) return; if(!particle->children().empty()) return; // force the mass shell if(particle->dataPtr()->stable()) { Lorentz5Momentum ptemp = particle->momentum(); ptemp.rescaleEnergy(); particle->set5Momentum(ptemp); } // check if there's a daughter tree which also needs boosting map >::const_iterator tit; for(tit = _currentTree->treelinks().begin(); tit != _currentTree->treelinks().end();++tit) { // if there is, boost it if(tit->second.first && tit->second.second==original) { Lorentz5Momentum pnew = tit->first->incomingLines().begin() ->first->progenitor()->momentum(); pnew *= tit->first->transform(); Lorentz5Momentum pdiff = porig-pnew; Energy2 test = sqr(pdiff.x()) + sqr(pdiff.y()) + sqr(pdiff.z()) + sqr(pdiff.t()); LorentzRotation rot; if(test>1e-6*GeV2) rot = solveBoost(porig,pnew); tit->first->transform(r*rot,false); _treeBoosts[tit->first].push_back(r*rot); } } } Energy KinematicsReconstructor::findMass(HardBranchingPtr branch) const { // KH - 230909 - If the particle has no children then it will // not have showered and so it should be "on-shell" so we can // get it's mass from it's momentum. This means that the // inverseRescalingFactor doesn't give any nans or do things // it shouldn't if it gets e.g. two Z bosons generated with // off-shell masses. This is for sure not the best solution. // PR 1/1/10 modification to previous soln // PR 28/8/14 change to procedure and factorize into a function if(branch->children().empty()) { return branch->branchingParticle()->mass(); } else if(!branch->children().empty() && !branch->branchingParticle()->dataPtr()->stable() ) { for(unsigned int ix=0;ixchildren().size();++ix) { if(branch->branchingParticle()->id()== branch->children()[ix]->branchingParticle()->id()) return findMass(branch->children()[ix]); } } return branch->branchingParticle()->dataPtr()->mass(); } vector KinematicsReconstructor::inverseInitialStateRescaling(double & x1, double & x2, const Lorentz5Momentum & pold, const vector & p, const vector & pq) const { // hadronic CMS Energy2 s = (pq[0] +pq[1] ).m2(); // partonic CMS Energy MDY = pold.m(); // find alpha, beta and pt Energy2 p12=pq[0]*pq[1]; double a[2],b[2]; Lorentz5Momentum pt[2]; for(unsigned int ix=0;ix<2;++ix) { a[ix] = p[ix]*pq[1]/p12; b [ix] = p[ix]*pq[0]/p12; pt[ix] = p[ix]-a[ix]*pq[0]-b[ix]*pq[1]; } // compute kappa // we always want to preserve the mass of the system double k1(1.),k2(1.); if(_initialStateReconOption==0) { double rap=pold.rapidity(); x2 = MDY/sqrt(s*exp(2.*rap)); x1 = sqr(MDY)/s/x2; k1=a[0]/x1; k2=b[1]/x2; } // longitudinal momentum else if(_initialStateReconOption==1) { double A = 1.; double C = -sqr(MDY)/s; double B = 2.*pold.z()/sqrt(s); if(abs(B)>1e-10) { double discrim = 1.-4.*A*C/sqr(B); if(discrim < 0.) throw KinematicsReconstructionVeto(); x1 = B>0. ? 0.5*B/A*(1.+sqrt(discrim)) : 0.5*B/A*(1.-sqrt(discrim)); } else { x1 = -C/A; if( x1 <= 0.) throw KinematicsReconstructionVeto(); x1 = sqrt(x1); } x2 = sqr(MDY)/s/x1; k1=a[0]/x1; k2=b[1]/x2; } // preserve mass and don't scale the softer system // to reproduce the dipole kinematics else if(_initialStateReconOption==2) { // in this case kp = k1 or k2 depending on who's the harder guy k1 = a[0]*b[1]*s/sqr(MDY); if ( pt[0].perp2() < pt[1].perp2() ) swap(k1,k2); x1 = a[0]/k1; x2 = b[1]/k2; } else assert(false); // decompose the momenta double anew[2] = {a[0]/k1,a[1]*k2}; double bnew[2] = {b[0]*k1,b[1]/k2}; vector boost(2); for(unsigned int ix=0;ix<2;++ix) { boost[ix] = getBeta(a [ix]+b [ix], a[ix] -b [ix], anew[ix]+bnew[ix], anew[ix]-bnew[ix]); } return boost; } vector KinematicsReconstructor::initialStateRescaling(double x1, double x2, const Lorentz5Momentum & pold, const vector & p, const vector & pq, const vector& highestpts) const { Energy2 S = (pq[0]+pq[1]).m2(); // find alphas and betas in terms of desired basis Energy2 p12 = pq[0]*pq[1]; double a[2] = {p[0]*pq[1]/p12,p[1]*pq[1]/p12}; double b[2] = {p[0]*pq[0]/p12,p[1]*pq[0]/p12}; Lorentz5Momentum p1p = p[0] - a[0]*pq[0] - b[0]*pq[1]; Lorentz5Momentum p2p = p[1] - a[1]*pq[0] - b[1]*pq[1]; // compute kappa // we always want to preserve the mass of the system Energy MDY = pold.m(); Energy2 A = a[0]*b[1]*S; Energy2 B = Energy2(sqr(MDY)) - (a[0]*b[0]+a[1]*b[1])*S - (p1p+p2p).m2(); Energy2 C = a[1]*b[0]*S; double rad = 1.-4.*A*C/sqr(B); if(rad < 0.) throw KinematicsReconstructionVeto(); double kp = B/(2.*A)*(1.+sqrt(rad)); // now compute k1 // conserve rapidity double k1(0.); double k2(0.); if(_initialStateReconOption==0) { rad = kp*(b[0]+kp*b[1])/(kp*a[0]+a[1]); rad *= pq[0].z()1e-10) { double discrim = 1.-4.*a2*c2/sqr(b2); if(discrim < 0.) throw KinematicsReconstructionVeto(); k1 = b2>0. ? 0.5*b2/a2*(1.+sqrt(discrim)) : 0.5*b2/a2*(1.-sqrt(discrim)); } else { k1 = -c2/a2; if( k1 <= 0.) throw KinematicsReconstructionVeto(); k1 = sqrt(k1); } k2 = kp/k1; } // preserve mass and don't scale the softer system // to reproduce the dipole kinematics else if(_initialStateReconOption==2) { // in this case kp = k1 or k2 depending on who's the harder guy k1 = kp; k2 = 1.; if ( highestpts[0] < highestpts[1] ) swap(k1,k2); } else assert(false); // calculate the boosts vector beta(2); beta[0] = getBeta((a[0]+b[0]), (a[0]-b[0]), (k1*a[0]+b[0]/k1), (k1*a[0]-b[0]/k1)); beta[1] = getBeta((a[1]+b[1]), (a[1]-b[1]), (a[1]/k2+k2*b[1]), (a[1]/k2-k2*b[1])); if (pq[0].z() > ZERO) { beta[0] = -beta[0]; beta[1] = -beta[1]; } return beta; } void KinematicsReconstructor:: reconstructColourSinglets(vector & ShowerHardJets, ShowerInteraction type) const { // identify and catagorize the colour singlet systems unsigned int nnun(0),nnii(0),nnif(0),nnf(0),nni(0); vector systems(identifySystems(set(ShowerHardJets.begin(),ShowerHardJets.end()), nnun,nnii,nnif,nnf,nni)); // now decide what to do // initial-initial connection and final-state colour singlet systems LorentzRotation toRest,fromRest; bool applyBoost(false),general(false); // Drell-Yan type if(nnun==0&&nnii==1&&nnif==0&&nnf>0&&nni==0) { // reconstruct initial-initial system for(unsigned int ix=0;ix0&&nni==1)|| (nnif==2&& nni==0))) { // check these systems can be reconstructed for(unsigned int ix=0;ixprogenitor()->isFinalState()) q += systems[ix].jets[iy]->progenitor()->momentum(); else q -= systems[ix].jets[iy]->progenitor()->momentum(); } q.rescaleMass(); // check above cut if(abs(q.m())>=_minQ) continue; if(nnif==1&&nni==1) { throw KinematicsReconstructionVeto(); } else { general = true; break; } } if(!general) { for(unsigned int ix=0;ix0&&nni==2) { general = type!=ShowerInteraction::QCD; } // general type else { general = true; } // final-state systems except for general recon if(!general) { for(unsigned int ix=0;ix::pointer XCPtr; public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ QTildeShowerHandler(); /** * The destructor. */ virtual ~QTildeShowerHandler(); //@} public: /** * At the end of the Showering, transform ShowerParticle objects * into ThePEG particles and fill the event record with them. * Notice that the parent/child relationships and the * transformation from ShowerColourLine objects into ThePEG * ColourLine ones must be properly handled. */ void fillEventRecord(); /** * Return the relevant hard scale to be used in the profile scales */ virtual Energy hardScale() const { return muPt; } /** * Hook to allow vetoing of event after showering hard sub-process * as in e.g. MLM merging. */ virtual bool showerHardProcessVeto() const { return false; } /** * Generate hard emissions for CKKW etc */ virtual HardTreePtr generateCKKW(ShowerTreePtr tree) const; /** * Members to perform the shower */ //@{ /** * Perform the shower of the hard process */ virtual void showerHardProcess(ShowerTreePtr,XCPtr); /** * Perform the shower of a decay */ virtual void showerDecay(ShowerTreePtr); //@} /** * Access to the flags and shower variables */ //@{ /** * Get the SplittingGenerator */ tSplittingGeneratorPtr splittingGenerator() const { return _splittingGenerator; } /** * Mode for hard emissions */ int hardEmission() const {return _hardEmission;} //@} /** * Connect the Hard and Shower trees */ virtual void connectTrees(ShowerTreePtr showerTree, HardTreePtr hardTree, bool hard ); /** * Access to switches for spin correlations */ //@{ /** * Soft correlations */ unsigned int softCorrelations() const { return _softOpt; } /** * Any correlations */ virtual bool correlations() const { return spinCorrelations()!=0||_softOpt!=0; } //@} public: /** * Access methods to access the objects */ //@{ /** * Access to the KinematicsReconstructor object */ tKinematicsReconstructorPtr kinematicsReconstructor() const { return _reconstructor; } /** * Access to the PartnerFinder object */ tPartnerFinderPtr partnerFinder() const { return _partnerfinder; } //@} protected: /** * Perform the shower */ void doShowering(bool hard,XCPtr); /** * Generate the hard matrix element correction */ virtual RealEmissionProcessPtr hardMatrixElementCorrection(bool); /** * Generate the hardest emission */ virtual void hardestEmission(bool hard); /** * Set up for applying a matrix element correction */ void setupMECorrection(RealEmissionProcessPtr real); /** * Extract the particles to be showered, set the evolution scales * and apply the hard matrix element correction * @param hard Whether this is a hard process or decay * @return The particles to be showered */ virtual vector setupShower(bool hard); /** * set the colour partners */ virtual void setEvolutionPartners(bool hard,ShowerInteraction, bool clear); /** * Methods to perform the evolution of an individual particle, including * recursive calling on the products */ //@{ /** * It does the forward evolution of the time-like input particle * (and recursively for all its radiation products). * accepting only emissions which conforms to the showerVariables * and soft matrix element correction. * If at least one emission has occurred then the method returns true. * @param particle The particle to be showered */ virtual bool timeLikeShower(tShowerParticlePtr particle, ShowerInteraction, Branching fb, bool first); /** * It does the backward evolution of the space-like input particle * (and recursively for all its time-like radiation products). * accepting only emissions which conforms to the showerVariables. * If at least one emission has occurred then the method returns true * @param particle The particle to be showered * @param beam The beam particle */ virtual bool spaceLikeShower(tShowerParticlePtr particle,PPtr beam, ShowerInteraction); /** * If does the forward evolution of the input on-shell particle * involved in a decay * (and recursively for all its time-like radiation products). * accepting only emissions which conforms to the showerVariables. * @param particle The particle to be showered * @param maxscale The maximum scale for the shower. * @param minimumMass The minimum mass of the final-state system */ virtual bool spaceLikeDecayShower(tShowerParticlePtr particle, const ShowerParticle::EvolutionScales & maxScales, Energy minimumMass,ShowerInteraction, Branching fb); /** * Truncated shower from a time-like particle */ virtual bool truncatedTimeLikeShower(tShowerParticlePtr particle, HardBranchingPtr branch, ShowerInteraction type, Branching fb, bool first); /** * Truncated shower from a space-like particle */ virtual bool truncatedSpaceLikeShower(tShowerParticlePtr particle,PPtr beam, HardBranchingPtr branch, ShowerInteraction type); /** * Truncated shower from a time-like particle */ virtual bool truncatedSpaceLikeDecayShower(tShowerParticlePtr particle, const ShowerParticle::EvolutionScales & maxScales, Energy minimumMass, HardBranchingPtr branch, ShowerInteraction type, Branching fb); //@} /** * Switches for matrix element corrections */ //@{ /** * Any ME correction? */ bool MECOn() const { return _hardEmission == 1; } /** * Any hard ME correction? */ bool hardMEC() const { return _hardEmission == 1 && (_meCorrMode == 1 || _meCorrMode == 2); } /** * Any soft ME correction? */ bool softMEC() const { return _hardEmission == 1 && (_meCorrMode == 1 || _meCorrMode > 2); } //@} /** * Is the truncated shower on? */ bool isTruncatedShowerON() const {return _trunc_Mode;} /** * Switch for intrinsic pT */ //@{ /** * Any intrinsic pT? */ bool ipTon() const { return _iptrms != ZERO || ( _beta == 1.0 && _gamma != ZERO && _iptmax !=ZERO ); } //@} /**@name Additional shower vetoes */ //@{ /** * Insert a veto. */ void addVeto (ShowerVetoPtr v) { _vetoes.push_back(v); } /** * Remove a veto. */ void removeVeto (ShowerVetoPtr v) { vector::iterator vit = find(_vetoes.begin(),_vetoes.end(),v); if (vit != _vetoes.end()) _vetoes.erase(vit); } //@} /** * Switches for vetoing hard emissions */ //@{ /** * Returns true if the hard veto read-in is to be applied to only * the primary collision and false otherwise. */ bool hardVetoReadOption() const {return _hardVetoReadOption;} //@} /** * Enhancement factors for radiation needed to generate the soft matrix * element correction. */ //@{ /** * Access the enhancement factor for initial-state radiation */ double initialStateRadiationEnhancementFactor() const { return _initialenhance; } /** * Access the enhancement factor for final-state radiation */ double finalStateRadiationEnhancementFactor() const { return _finalenhance; } /** * Set the enhancement factor for initial-state radiation */ void initialStateRadiationEnhancementFactor(double in) { _initialenhance=in; } /** * Set the enhancement factor for final-state radiation */ void finalStateRadiationEnhancementFactor(double in) { _finalenhance=in; } //@} /** * Access to set/get the HardTree currently beinging showered */ //@{ /** * The HardTree currently being showered */ tHardTreePtr hardTree() {return _hardtree;} /** * The HardTree currently being showered */ void hardTree(tHardTreePtr in) {_hardtree = in;} //@} /** * Access/set the beam particle for the current initial-state shower */ //@{ /** * Get the beam particle data */ Ptr::const_pointer beamParticle() const { return _beam; } /** * Set the beam particle data */ void setBeamParticle(Ptr::const_pointer in) { _beam=in; } //@} /** * Set/Get the current tree being evolver for inheriting classes */ //@{ /** * Get the tree */ tShowerTreePtr currentTree() { return _currenttree; } /** * Set the tree */ void currentTree(tShowerTreePtr tree) { _currenttree=tree; } //@} /** * Access the maximum number of attempts to generate the shower */ unsigned int maximumTries() const { return _maxtry; } /** * Set/Get the ShowerProgenitor for the current shower */ //@{ /** * Access the progenitor */ ShowerProgenitorPtr progenitor() { return _progenitor; } /** * Set the progenitor */ void progenitor(ShowerProgenitorPtr in) { _progenitor=in; } //@} /** * Calculate the intrinsic \f$p_T\f$. */ virtual void generateIntrinsicpT(vector); /** * Access to the intrinsic \f$p_T\f$ for inheriting classes */ map > & intrinsicpT() { return _intrinsic; } /** * find the maximally allowed pt acc to the hard process. */ void setupMaximumScales(const vector &,XCPtr); /** * find the relevant hard scales for profile scales. */ void setupHardScales(const vector &,XCPtr); /** * Convert the HardTree into an extra shower emission */ void convertHardTree(bool hard,ShowerInteraction type); protected: /** * Find the parton extracted from the incoming particle after ISR */ PPtr findFirstParton(tPPtr seed) const; /** * Fix Remnant connections after ISR */ tPPair remakeRemnant(tPPair oldp); protected: /** * Start the shower of a timelike particle */ virtual bool startTimeLikeShower(ShowerInteraction); /** * Update of the time-like stuff */ void updateHistory(tShowerParticlePtr particle); /** * Start the shower of a spacelike particle */ virtual bool startSpaceLikeShower(PPtr,ShowerInteraction); /** * Start the shower of a spacelike particle */ virtual bool startSpaceLikeDecayShower(const ShowerParticle::EvolutionScales & maxScales, Energy minimumMass,ShowerInteraction); /** * Select the branching for the next time-like emission */ Branching selectTimeLikeBranching(tShowerParticlePtr particle, ShowerInteraction type, HardBranchingPtr branch); /** * Select the branching for the next space-like emission in a decay */ Branching selectSpaceLikeDecayBranching(tShowerParticlePtr particle, const ShowerParticle::EvolutionScales & maxScales, Energy minmass,ShowerInteraction type, HardBranchingPtr branch); /** * Create the timelike child of a branching */ ShowerParticleVector createTimeLikeChildren(tShowerParticlePtr particle, IdList ids); /** * Vetos for the timelike shower */ virtual bool timeLikeVetoed(const Branching &,ShowerParticlePtr); /** * Vetos for the spacelike shower */ virtual bool spaceLikeVetoed(const Branching &,ShowerParticlePtr); /** * Vetos for the spacelike shower */ virtual bool spaceLikeDecayVetoed(const Branching &,ShowerParticlePtr); /** * Only generate the hard emission, for testing only. */ bool hardOnly() const {return _limitEmissions==3;} /** * Check the flags */ void checkFlags(); /** * */ void addFSRUsingDecayPOWHEG(HardTreePtr ISRTree); public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** * The main method which manages the showering of a subprocess. */ virtual tPPair cascade(tSubProPtr sub, XCPtr xcomb); /** * Decay a ShowerTree */ void decay(ShowerTreePtr tree, ShowerDecayMap & decay); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} protected: /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); //@} private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ QTildeShowerHandler & operator=(const QTildeShowerHandler &) = delete; private: /** * Stuff from the ShowerHandler */ //@{ /** * The ShowerTree for the hard process */ ShowerTreePtr hard_; /** * The ShowerTree for the decays */ ShowerDecayMap decay_; /** * The ShowerTrees for which the initial shower */ vector done_; //@} private : /** * Pointer to the splitting generator */ SplittingGeneratorPtr _splittingGenerator; /** * Maximum number of tries to generate the shower of a particular tree */ unsigned int _maxtry; /** * Matrix element correction switch */ unsigned int _meCorrMode; /** * Control of the reconstruction option */ unsigned int _evolutionScheme; /** * If hard veto pT scale is being read-in this determines * whether the read-in value is applied to primary and * secondary (MPI) scatters or just the primary one, with * the usual computation of the veto being performed for * the secondary (MPI) scatters. */ bool _hardVetoReadOption; /** * rms intrinsic pT of Gaussian distribution */ Energy _iptrms; /** * Proportion of inverse quadratic intrinsic pT distribution */ double _beta; /** * Parameter for inverse quadratic: 2*Beta*Gamma/(sqr(Gamma)+sqr(intrinsicpT)) */ Energy _gamma; /** * Upper bound on intrinsic pT for inverse quadratic */ Energy _iptmax; /** * Limit the number of emissions for testing */ unsigned int _limitEmissions; /** * The progenitor of the current shower */ ShowerProgenitorPtr _progenitor; /** * Matrix element */ HwMEBasePtr _hardme; /** * Decayer */ HwDecayerBasePtr _decayme; /** * The ShowerTree currently being showered */ ShowerTreePtr _currenttree; /** * The HardTree currently being showered */ HardTreePtr _hardtree; /** * Radiation enhancement factors for use with the veto algorithm * if needed by the soft matrix element correction */ //@{ /** * Enhancement factor for initial-state radiation */ double _initialenhance; /** * Enhancement factor for final-state radiation */ double _finalenhance; //@} /** * The beam particle data for the current initial-state shower */ Ptr::const_pointer _beam; /** * Storage of the intrinsic \f$p_t\f$ of the particles */ map > _intrinsic; /** * Vetoes */ vector _vetoes; /** * Full Shower Vetoes */ vector _fullShowerVetoes; /** * Number of iterations for reweighting */ unsigned int _nReWeight; /** * Whether or not we are reweighting */ bool _reWeight; /** * number of IS emissions */ unsigned int _nis; /** * Number of FS emissions */ unsigned int _nfs; /** * The option for wqhich interactions to use */ ShowerInteraction interaction_; /** * Truncated shower switch */ bool _trunc_Mode; - - /** - * Count of the number of truncated emissions - */ - unsigned int _truncEmissions; /** * Mode for the hard emissions */ int _hardEmission; /** * Option for the kernal for soft correlations */ unsigned int _softOpt; /** * Option for hard radiation in POWHEG events */ bool _hardPOWHEG; /** * True if no warnings about incorrect hard emission * mode setting have been issued yet */ static bool _hardEmissionWarn; /** * True if no warnings about missing truncated shower * have been issued yet */ static bool _missingTruncWarn; /** * The relevant hard scale to be used in the profile scales */ Energy muPt; private: /** * Pointer to the various objects */ //@{ /** * Pointer to the KinematicsReconstructor object */ KinematicsReconstructorPtr _reconstructor; /** * Pointer to the PartnerFinder object */ PartnerFinderPtr _partnerfinder; //@} }; } #endif /* HERWIG_QTildeShowerHandler_H */ diff --git a/Shower/QTilde/SplittingFunctions/SplittingFunction.h b/Shower/QTilde/SplittingFunctions/SplittingFunction.h --- a/Shower/QTilde/SplittingFunctions/SplittingFunction.h +++ b/Shower/QTilde/SplittingFunctions/SplittingFunction.h @@ -1,382 +1,386 @@ // -*- C++ -*- // // SplittingFunction.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_SplittingFunction_H #define HERWIG_SplittingFunction_H // // This is the declaration of the SplittingFunction class. // #include "ThePEG/Interface/Interfaced.h" #include "Herwig/Shower/QTilde/ShowerConfig.h" #include "ThePEG/EventRecord/RhoDMatrix.h" #include "Herwig/Decay/DecayMatrixElement.h" #include "Herwig/Shower/QTilde/Kinematics/ShowerKinematics.fh" #include "ThePEG/EventRecord/ColourLine.h" #include "ThePEG/PDT/ParticleData.h" #include "SplittingFunction.fh" namespace Herwig { using namespace ThePEG; /** \ingroup Shower * Enum to define the possible types of colour structure which can occur in * the branching. */ enum ColourStructure {Undefined=0, TripletTripletOctet = 1,OctetOctetOctet =2, OctetTripletTriplet = 3,TripletOctetTriplet=4, SextetSextetOctet = 5, ChargedChargedNeutral=-1,ChargedNeutralCharged=-2, NeutralChargedCharged=-3}; /** \ingroup Shower * * This is an abstract class which defines the common interface * for all \f$1\to2\f$ splitting functions, for both initial-state * and final-state radiation. * * The SplittingFunction class contains a number of purely virtual members * which must be implemented in the inheriting classes. The class also stores * the interaction type of the spltting function. * * The inheriting classes need to specific the splitting function * \f$P(z,2p_j\cdot p_k)\f$, in terms of the energy fraction \f$z\f$ and * the evolution scale. In order to allow the splitting functions to be used * with different choices of evolution functions the scale is given by * \f[2p_j\cdot p_k=(p_j+p_k)^2-m_{jk}^2=Q^2-(p_j+p_k)^2=z(1-z)\tilde{q}^2= * \frac{p_T^2}{z(1-z)}-m_{jk}^2+\frac{m_j^2}{z}+\frac{m_k^2}{1-z},\f] * where \f$Q^2\f$ is the virtuality of the branching particle, * $p_T$ is the relative transverse momentum of the branching products and * \f$\tilde{q}^2\f$ is the angular variable described in hep-ph/0310083. * * In addition an overestimate of the * splitting function, \f$P_{\rm over}(z)\f$ which only depends upon \f$z\f$, * the integral, inverse of the integral for this overestimate and * ratio of the true splitting function to the overestimate must be provided * as they are necessary for the veto alogrithm used to implement the evolution. * * @see \ref SplittingFunctionInterfaces "The interfaces" * defined for SplittingFunction. */ class SplittingFunction: public Interfaced { public: /** * The default constructor. * @param b All splitting functions must have an interaction order */ SplittingFunction() : Interfaced(), _interactionType(ShowerInteraction::UNDEFINED), _colourStructure(Undefined), _colourFactor(-1.), angularOrdered_(true), scaleChoice_(2), strictAO_(true) {} public: /** * Methods to return the interaction type and order for the splitting function */ //@{ /** * Return the type of the interaction */ ShowerInteraction interactionType() const {return _interactionType;} /** * Return the colour structure */ ColourStructure colourStructure() const {return _colourStructure;} /** * Return the colour factor */ double colourFactor(const IdList &ids) const { if(_colourStructure>0) return _colourFactor; else if(_colourStructure<0) { if(_colourStructure==ChargedChargedNeutral || _colourStructure==ChargedNeutralCharged) { return sqr(double(ids[0]->iCharge())/3.); } else if(_colourStructure==NeutralChargedCharged) { double fact = sqr(double(ids[1]->iCharge())/3.); if(ids[1]->coloured()) fact *= abs(double(ids[1]->iColour())); return fact; } - else + else { assert(false); + return 0.; + } } - else + else { assert(false); + return 0.; + } } //@} /** * Purely virtual method which should determine whether this splitting * function can be used for a given set of particles. * @param ids The PDG codes for the particles in the splitting. */ virtual bool accept(const IdList & ids) const = 0; /** * Method to check the colours are correct */ virtual bool checkColours(const IdList & ids) const; /** * Methods to return the splitting function. */ //@{ /** * Purely virtual method which should return the exact value of the splitting function, * \f$P\f$ evaluated in terms of the energy fraction, \f$z\f$, and the evolution scale \f$\tilde{q}^2\f$. * @param z The energy fraction. * @param t The scale \f$t=2p_j\cdot p_k\f$. * @param ids The PDG codes for the particles in the splitting. * @param mass Whether or not to include the mass dependent terms */ virtual double P(const double z, const Energy2 t, const IdList & ids, const bool mass, const RhoDMatrix & rho) const = 0; /** * Purely virtual method which should return * an overestimate of the splitting function, * \f$P_{\rm over}\f$ such that the result \f$P_{\rm over}\geq P\f$. This function * should be simple enough that it does not depend on the evolution scale. * @param z The energy fraction. * @param ids The PDG codes for the particles in the splitting. */ virtual double overestimateP(const double z, const IdList & ids) const = 0; /** * Purely virtual method which should return * the ratio of the splitting function to the overestimate, i.e. * \f$P(z,\tilde{q}^2)/P_{\rm over}(z)\f$. * @param z The energy fraction. * @param t The scale \f$t=2p_j\cdot p_k\f$. * @param ids The PDG codes for the particles in the splitting. * @param mass Whether or not to include the mass dependent terms */ virtual double ratioP(const double z, const Energy2 t, const IdList & ids, const bool mass, const RhoDMatrix & rho) const = 0; /** * Purely virtual method which should return the indefinite integral of the * overestimated splitting function, \f$P_{\rm over}\f$. * @param z The energy fraction. * @param ids The PDG codes for the particles in the splitting. * @param PDFfactor Which additional factor to include for the PDF * 0 is no additional factor, * 1 is \f$1/z\f$, 2 is \f$1/(1-z)\f$ and 3 is \f$1/z/(1-z)\f$ * */ virtual double integOverP(const double z, const IdList & ids, unsigned int PDFfactor=0) const = 0; /** * Purely virtual method which should return the inverse of the * indefinite integral of the * overestimated splitting function, \f$P_{\rm over}\f$ which is used to * generate the value of \f$z\f$. * @param r Value of the splitting function to be inverted * @param ids The PDG codes for the particles in the splitting. * @param PDFfactor Which additional factor to include for the PDF * 0 is no additional factor, * 1 is \f$1/z\f$, 2 is \f$1/(1-z)\f$ and 3 is \f$1/z/(1-z)\f$ */ virtual double invIntegOverP(const double r, const IdList & ids, unsigned int PDFfactor=0) const = 0; //@} /** * Purely virtual method which should make the proper colour connection * between the emitting parent and the branching products. * @param parent The parent for the branching * @param first The first branching product * @param second The second branching product * @param partnerType The type of evolution partner * @param back Whether this is foward or backward evolution. */ virtual void colourConnection(tShowerParticlePtr parent, tShowerParticlePtr first, tShowerParticlePtr second, ShowerPartnerType partnerType, const bool back) const; /** * Method to calculate the azimuthal angle for forward evolution * @param z The energy fraction * @param t The scale \f$t=2p_j\cdot p_k\f$. * @param ids The PDG codes for the particles in the splitting. * @param The azimuthal angle, \f$\phi\f$. * @return The weight */ virtual vector > generatePhiForward(const double z, const Energy2 t, const IdList & ids, const RhoDMatrix &) = 0; /** * Method to calculate the azimuthal angle for backward evolution * @param z The energy fraction * @param t The scale \f$t=2p_j\cdot p_k\f$. * @param ids The PDG codes for the particles in the splitting. * @return The weight */ virtual vector > generatePhiBackward(const double z, const Energy2 t, const IdList & ids, const RhoDMatrix &) = 0; /** * Calculate the matrix element for the splitting * @param z The energy fraction * @param t The scale \f$t=2p_j\cdot p_k\f$. * @param ids The PDG codes for the particles in the splitting. * @param phi The azimuthal angle, \f$\phi\f$. * @param timeLike Whether timelike or spacelike, affects inclusive of mass terms */ virtual DecayMEPtr matrixElement(const double z, const Energy2 t, const IdList & ids, const double phi, bool timeLike) = 0; /** * Whether or not the interaction is angular ordered */ bool angularOrdered() const {return angularOrdered_;} /** * Scale choice */ bool pTScale() const { return scaleChoice_ == 2 ? angularOrdered_ : scaleChoice_ == 0; } /** * Functions to state scales after branching happens */ //@{ /** * Sort out scales for final-state emission */ void evaluateFinalStateScales(ShowerPartnerType type, Energy scale, double z, tShowerParticlePtr parent, tShowerParticlePtr first, tShowerParticlePtr second); /** * Sort out scales for initial-state emission */ void evaluateInitialStateScales(ShowerPartnerType type, Energy scale, double z, tShowerParticlePtr parent, tShowerParticlePtr first, tShowerParticlePtr second); /** * Sort out scales for decay emission */ void evaluateDecayScales(ShowerPartnerType type, Energy scale, double z, tShowerParticlePtr parent, tShowerParticlePtr first, tShowerParticlePtr second); //@} 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 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: /** * Set the colour factor */ void colourFactor(double in) {_colourFactor=in;} private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ SplittingFunction & operator=(const SplittingFunction &) = delete; private: /** * The interaction type for the splitting function. */ ShowerInteraction _interactionType; /** * The colour structure */ ColourStructure _colourStructure; /** * The colour factor */ double _colourFactor; /** * Whether or not this interaction is angular-ordered */ bool angularOrdered_; /** * The choice of scale */ unsigned int scaleChoice_; /** * Enforce strict AO */ bool strictAO_; }; } #endif /* HERWIG_SplittingFunction_H */ diff --git a/Shower/ShowerHandler.cc b/Shower/ShowerHandler.cc --- a/Shower/ShowerHandler.cc +++ b/Shower/ShowerHandler.cc @@ -1,1130 +1,1132 @@ // -*- C++ -*- // // ShowerHandler.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 ShowerHandler class. // #include "ShowerHandler.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/ParVector.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Command.h" #include "ThePEG/PDF/PartonExtractor.h" #include "ThePEG/PDF/PartonBinInstance.h" #include "Herwig/PDT/StandardMatchers.h" #include "ThePEG/Cuts/Cuts.h" #include "ThePEG/Handlers/StandardXComb.h" #include "ThePEG/Utilities/Throw.h" #include "ThePEG/Utilities/StringUtils.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Repository/EventGenerator.h" #include "Herwig/Utilities/EnumParticles.h" #include "Herwig/PDF/MPIPDF.h" #include "Herwig/PDF/MinBiasPDF.h" #include "ThePEG/Handlers/EventHandler.h" #include "Herwig/PDF/HwRemDecayer.h" #include #include "ThePEG/Utilities/DescribeClass.h" #include "Herwig/Decay/DecayIntegrator.h" #include "Herwig/Decay/PhaseSpaceMode.h" using namespace Herwig; DescribeClass describeShowerHandler ("Herwig::ShowerHandler","HwShower.so"); ShowerHandler::~ShowerHandler() {} tShowerHandlerPtr ShowerHandler::currentHandler_ = tShowerHandlerPtr(); void ShowerHandler::doinit() { CascadeHandler::doinit(); // copy particles to decay before showering from input vector to the // set used in the simulation if ( particlesDecayInShower_.empty() ) { for(unsigned int ix=0;ixunrestrictedPhasespace() && restrictPhasespace() ) { generator()->log() << "ShowerApproximation warning: The scale profile chosen requires an unrestricted phase space,\n" << "however, the phase space was set to be restricted. Will switch to unrestricted phase space.\n" << flush; restrictPhasespace_ = false; } } } IBPtr ShowerHandler::clone() const { return new_ptr(*this); } IBPtr ShowerHandler::fullclone() const { return new_ptr(*this); } ShowerHandler::ShowerHandler() : maxtry_(10),maxtryMPI_(10),maxtryDP_(10),maxtryDecay_(100), factorizationScaleFactor_(1.0), renormalizationScaleFactor_(1.0), hardScaleFactor_(1.0), restrictPhasespace_(true), maxPtIsMuF_(false), spinOpt_(1), pdfFreezingScale_(2.5*GeV), doFSR_(true), doISR_(true), splitHardProcess_(true), includeSpaceTime_(false), vMin_(0.1*GeV2), reweight_(1.0) { inputparticlesDecayInShower_.push_back( 6 ); // top inputparticlesDecayInShower_.push_back( 23 ); // Z0 inputparticlesDecayInShower_.push_back( 24 ); // W+/- inputparticlesDecayInShower_.push_back( 25 ); // h0 } void ShowerHandler::doinitrun(){ CascadeHandler::doinitrun(); //can't use isMPIOn here, because the EventHandler is not set at that stage if(MPIHandler_) { MPIHandler_->initialize(); if(MPIHandler_->softInt()) remDec_->initSoftInteractions(MPIHandler_->Ptmin(), MPIHandler_->beta()); } } void ShowerHandler::dofinish() { CascadeHandler::dofinish(); if(MPIHandler_) MPIHandler_->finalize(); } void ShowerHandler::persistentOutput(PersistentOStream & os) const { os << remDec_ << ounit(pdfFreezingScale_,GeV) << maxtry_ << maxtryMPI_ << maxtryDP_ << maxtryDecay_ << inputparticlesDecayInShower_ << particlesDecayInShower_ << MPIHandler_ << PDFA_ << PDFB_ << PDFARemnant_ << PDFBRemnant_ << includeSpaceTime_ << ounit(vMin_,GeV2) << factorizationScaleFactor_ << renormalizationScaleFactor_ << hardScaleFactor_ << restrictPhasespace_ << maxPtIsMuF_ << hardScaleProfile_ << showerVariations_ << doFSR_ << doISR_ << splitHardProcess_ << spinOpt_ << useConstituentMasses_; } void ShowerHandler::persistentInput(PersistentIStream & is, int) { is >> remDec_ >> iunit(pdfFreezingScale_,GeV) >> maxtry_ >> maxtryMPI_ >> maxtryDP_ >> maxtryDecay_ >> inputparticlesDecayInShower_ >> particlesDecayInShower_ >> MPIHandler_ >> PDFA_ >> PDFB_ >> PDFARemnant_ >> PDFBRemnant_ >> includeSpaceTime_ >> iunit(vMin_,GeV2) >> factorizationScaleFactor_ >> renormalizationScaleFactor_ >> hardScaleFactor_ >> restrictPhasespace_ >> maxPtIsMuF_ >> hardScaleProfile_ >> showerVariations_ >> doFSR_ >> doISR_ >> splitHardProcess_ >> spinOpt_ >> useConstituentMasses_; } void ShowerHandler::Init() { static ClassDocumentation documentation ("Main driver class for the showering."); static Reference interfaceRemDecayer("RemDecayer", "A reference to the Remnant Decayer object", &Herwig::ShowerHandler::remDec_, false, false, true, false); static Parameter interfacePDFFreezingScale ("PDFFreezingScale", "The PDF freezing scale", &ShowerHandler::pdfFreezingScale_, GeV, 2.5*GeV, 2.0*GeV, 10.0*GeV, false, false, Interface::limited); static Parameter interfaceMaxTry ("MaxTry", "The maximum number of attempts for the main showering loop", &ShowerHandler::maxtry_, 10, 1, 100, false, false, Interface::limited); static Parameter interfaceMaxTryMPI ("MaxTryMPI", "The maximum number of regeneration attempts for an additional scattering", &ShowerHandler::maxtryMPI_, 10, 0, 100, false, false, Interface::limited); static Parameter interfaceMaxTryDP ("MaxTryDP", "The maximum number of regeneration attempts for an additional hard scattering", &ShowerHandler::maxtryDP_, 10, 0, 100, false, false, Interface::limited); static ParVector interfaceDecayInShower ("DecayInShower", "PDG codes of the particles to be decayed in the shower", &ShowerHandler::inputparticlesDecayInShower_, -1, 0l, -10000000l, 10000000l, false, false, Interface::limited); static Reference interfaceMPIHandler ("MPIHandler", "The object that administers all additional scatterings.", &ShowerHandler::MPIHandler_, false, false, true, true); static Reference interfacePDFA ("PDFA", "The PDF for beam particle A. Overrides the particle's own PDF setting." "By default used for both the shower and forced splitting in the remnant", &ShowerHandler::PDFA_, false, false, true, true, false); static Reference interfacePDFB ("PDFB", "The PDF for beam particle B. Overrides the particle's own PDF setting." "By default used for both the shower and forced splitting in the remnant", &ShowerHandler::PDFB_, false, false, true, true, false); static Reference interfacePDFARemnant ("PDFARemnant", "The PDF for beam particle A used to generate forced splittings of the remnant." " This overrides both the particle's own PDF setting and the value set by PDFA if used.", &ShowerHandler::PDFARemnant_, false, false, true, true, false); static Reference interfacePDFBRemnant ("PDFBRemnant", "The PDF for beam particle B used to generate forced splittings of the remnant." " This overrides both the particle's own PDF setting and the value set by PDFB if used.", &ShowerHandler::PDFBRemnant_, false, false, true, true, false); static Switch interfaceIncludeSpaceTime ("IncludeSpaceTime", "Whether to include the model for the calculation of space-time distances", &ShowerHandler::includeSpaceTime_, false, false, false); static SwitchOption interfaceIncludeSpaceTimeYes (interfaceIncludeSpaceTime, "Yes", "Include the model", true); static SwitchOption interfaceIncludeSpaceTimeNo (interfaceIncludeSpaceTime, "No", "Only include the displacement from the particle-s lifetime for decaying particles", false); static Parameter interfaceMinimumVirtuality ("MinimumVirtuality", "The minimum virtuality for the space-time model", &ShowerHandler::vMin_, GeV2, 0.1*GeV2, 0.0*GeV2, 1000.0*GeV2, false, false, Interface::limited); static Parameter interfaceFactorizationScaleFactor ("FactorizationScaleFactor", "The factorization scale factor.", &ShowerHandler::factorizationScaleFactor_, 1.0, 0.0, 0, false, false, Interface::lowerlim); static Parameter interfaceRenormalizationScaleFactor ("RenormalizationScaleFactor", "The renormalization scale factor.", &ShowerHandler::renormalizationScaleFactor_, 1.0, 0.0, 0, false, false, Interface::lowerlim); static Parameter interfaceHardScaleFactor ("HardScaleFactor", "The hard scale factor.", &ShowerHandler::hardScaleFactor_, 1.0, 0.0, 0, false, false, Interface::lowerlim); static Parameter interfaceMaxTryDecay ("MaxTryDecay", "The maximum number of attempts to generate a decay", &ShowerHandler::maxtryDecay_, 200, 10, 0, false, false, Interface::lowerlim); static Reference interfaceHardScaleProfile ("HardScaleProfile", "The hard scale profile to use.", &ShowerHandler::hardScaleProfile_, false, false, true, true, false); static Switch interfaceMaxPtIsMuF ("MaxPtIsMuF", "", &ShowerHandler::maxPtIsMuF_, false, false, false); static SwitchOption interfaceMaxPtIsMuFYes (interfaceMaxPtIsMuF, "Yes", "", true); static SwitchOption interfaceMaxPtIsMuFNo (interfaceMaxPtIsMuF, "No", "", false); static Switch interfaceRestrictPhasespace ("RestrictPhasespace", "Switch on or off phasespace restrictions", &ShowerHandler::restrictPhasespace_, true, false, false); static SwitchOption interfaceRestrictPhasespaceYes (interfaceRestrictPhasespace, "Yes", "Perform phasespace restrictions", true); static SwitchOption interfaceRestrictPhasespaceNo (interfaceRestrictPhasespace, "No", "Do not perform phasespace restrictions", false); static Command interfaceAddVariation ("AddVariation", "Add a shower variation.", &ShowerHandler::doAddVariation, false); static Switch interfaceDoFSR ("DoFSR", "Switch on or off final state radiation.", &ShowerHandler::doFSR_, true, false, false); static SwitchOption interfaceDoFSRYes (interfaceDoFSR, "Yes", "Switch on final state radiation.", true); static SwitchOption interfaceDoFSRNo (interfaceDoFSR, "No", "Switch off final state radiation.", false); static Switch interfaceDoISR ("DoISR", "Switch on or off initial state radiation.", &ShowerHandler::doISR_, true, false, false); static SwitchOption interfaceDoISRYes (interfaceDoISR, "Yes", "Switch on initial state radiation.", true); static SwitchOption interfaceDoISRNo (interfaceDoISR, "No", "Switch off initial state radiation.", false); static Switch interfaceSplitHardProcess ("SplitHardProcess", "Whether or not to try and split the hard process into production and decay processes", &ShowerHandler::splitHardProcess_, true, false, false); static SwitchOption interfaceSplitHardProcessYes (interfaceSplitHardProcess, "Yes", "Split the hard process", true); static SwitchOption interfaceSplitHardProcessNo (interfaceSplitHardProcess, "No", "Don't split the hard process", false); static Switch interfaceSpinCorrelations ("SpinCorrelations", "Treatment of spin correlations in the parton shower", &ShowerHandler::spinOpt_, 1, false, false); static SwitchOption interfaceSpinCorrelationsNo (interfaceSpinCorrelations, "No", "No spin correlations", 0); static SwitchOption interfaceSpinCorrelationsSpin (interfaceSpinCorrelations, "Yes", "Include the azimuthal spin correlations", 1); static Switch interfaceUseConstituentMasses ("UseConstituentMasses", "Whether or not to use constituent masses for the reconstruction of the particle after showering.", &ShowerHandler::useConstituentMasses_, true, false, false); static SwitchOption interfaceUseConstituentMassesYes (interfaceUseConstituentMasses, "Yes", "Use constituent masses.", true); static SwitchOption interfaceUseConstituentMassesNo (interfaceUseConstituentMasses, "No", "Don't use constituent masses.", false); } Energy ShowerHandler::hardScale() const { assert(false); + return ZERO; } void ShowerHandler::cascade() { useMe(); // Initialise the weights in the event object // so that any variations are output regardless of // whether showering occurs for the given event initializeWeights(); // get the PDF's from ThePEG (if locally overridden use the local versions) tcPDFPtr first = PDFA_ ? tcPDFPtr(PDFA_) : firstPDF().pdf(); tcPDFPtr second = PDFB_ ? tcPDFPtr(PDFB_) : secondPDF().pdf(); resetPDFs(make_pair(first,second)); // set the PDFs for the remnant if( ! rempdfs_.first) rempdfs_.first = PDFARemnant_ ? PDFPtr(PDFARemnant_) : const_ptr_cast(first); if( ! rempdfs_.second) rempdfs_.second = PDFBRemnant_ ? PDFPtr(PDFBRemnant_) : const_ptr_cast(second); // get the incoming partons tPPair incomingPartons = eventHandler()->currentCollision()->primarySubProcess()->incoming(); // and the parton bins PBIPair incomingBins = make_pair(lastExtractor()->partonBinInstance(incomingPartons.first), lastExtractor()->partonBinInstance(incomingPartons.second)); // and the incoming hadrons tPPair incomingHadrons = eventHandler()->currentCollision()->incoming(); remnantDecayer()->setHadronContent(incomingHadrons); // check if incoming hadron == incoming parton // and get the incoming hadron if exists or parton otherwise incoming_ = make_pair(incomingBins.first ? incomingBins.first ->particle() : incomingPartons.first, incomingBins.second ? incomingBins.second->particle() : incomingPartons.second); // check the collision is of the beam particles // and if not boost collision to the right frame // i.e. the hadron-hadron CMF of the collision bool btotal(false); LorentzRotation rtotal; if(incoming_.first != incomingHadrons.first || incoming_.second != incomingHadrons.second ) { btotal = true; boostCollision(false); } // set the current ShowerHandler setCurrentHandler(); // first shower the hard process try { SubProPtr sub = eventHandler()->currentCollision()->primarySubProcess(); incomingPartons = cascade(sub,lastXCombPtr()); } catch(ShowerTriesVeto &veto){ throw Exception() << "Failed to generate the shower after " << veto.tries << " attempts in ShowerHandler::cascade()" << Exception::eventerror; } if(showerHardProcessVeto()) throw Veto(); // if a non-hadron collision return (both incoming non-hadronic) if( ( !incomingBins.first|| !isResolvedHadron(incomingBins.first ->particle()))&& ( !incomingBins.second|| !isResolvedHadron(incomingBins.second->particle()))) { // boost back to lab if needed if(btotal) boostCollision(true); // perform the reweighting for the hard process shower combineWeights(); // unset the current ShowerHandler unSetCurrentHandler(); return; } // get the remnants for hadronic collision pair remnants(getRemnants(incomingBins)); // set the starting scale of the forced splitting to the PDF freezing scale remnantDecayer()->initialize(remnants, incoming_, *currentStep(), pdfFreezingScale()); // do the first forcedSplitting try { remnantDecayer()->doSplit(incomingPartons, make_pair(rempdfs_.first,rempdfs_.second), true); } catch (ExtraScatterVeto) { throw Exception() << "Remnant extraction failed in " << "ShowerHandler::cascade() from primary interaction" << Exception::eventerror; } // perform the reweighting for the hard process shower combineWeights(); // if no MPI return if( !isMPIOn() ) { remnantDecayer()->finalize(); // boost back to lab if needed if(btotal) boostCollision(true); // unset the current ShowerHandler unSetCurrentHandler(); return; } // generate the multiple scatters use modified pdf's now: setMPIPDFs(); // additional "hard" processes unsigned int tries(0); // This is the loop over additional hard scatters (most of the time // only one, but who knows...) for(unsigned int i=1; i <= getMPIHandler()->additionalHardProcs(); i++){ //counter for regeneration unsigned int multSecond = 0; // generate the additional scatters while( multSecond < getMPIHandler()->multiplicity(i) ) { // generate the hard scatter tStdXCombPtr lastXC = getMPIHandler()->generate(i); SubProPtr sub = lastXC->construct(); // add to the Step newStep()->addSubProcess(sub); // increment the counters tries++; multSecond++; if(tries == maxtryDP_) throw Exception() << "Failed to establish the requested number " << "of additional hard processes. If this error " << "occurs often, your selection of additional " << "scatter is probably unphysical" << Exception::eventerror; // Generate the shower. If not possible veto the event try { incomingPartons = cascade(sub,lastXC); } catch(ShowerTriesVeto &veto){ throw Exception() << "Failed to generate the shower of " << "a secondary hard process after " << veto.tries << " attempts in Evolver::showerHardProcess()" << Exception::eventerror; } try { // do the forcedSplitting remnantDecayer()->doSplit(incomingPartons, make_pair(remmpipdfs_.first,remmpipdfs_.second), false); } catch(ExtraScatterVeto){ //remove all particles associated with the subprocess newStep()->removeParticle(incomingPartons.first); newStep()->removeParticle(incomingPartons.second); //remove the subprocess from the list newStep()->removeSubProcess(sub); //regenerate the scattering multSecond--; continue; } // connect with the remnants but don't set Remnant colour, // because that causes problems due to the multiple colour lines. if ( !remnants.first ->extract(incomingPartons.first , false) || !remnants.second->extract(incomingPartons.second, false) ) throw Exception() << "Remnant extraction failed in " << "ShowerHandler::cascade() for additional scatter" << Exception::runerror; } // perform the reweighting for the additional hard scatter shower combineWeights(); } // the underlying event processes unsigned int ptveto(1), veto(0); unsigned int max(getMPIHandler()->multiplicity()); for(unsigned int i=0; i maxtryMPI_) break; //generate PSpoint tStdXCombPtr lastXC = getMPIHandler()->generate(); SubProPtr sub = lastXC->construct(); //If Algorithm=1 additional scatters of the signal type // with pt > ptmin have to be vetoed //with probability 1/(m+1), where m is the number of occurances in this event if( getMPIHandler()->Algorithm() == 1 ){ //get the pT Energy pt = sub->outgoing().front()->momentum().perp(); if(pt > getMPIHandler()->PtForVeto() && UseRandom::rnd() < 1./(ptveto+1) ){ ptveto++; i--; continue; } } // add to the SubProcess to the step newStep()->addSubProcess(sub); // Run the Shower. If not possible veto the scattering try { incomingPartons = cascade(sub,lastXC); } // discard this extra scattering, but try the next one catch(ShowerTriesVeto) { newStep()->removeSubProcess(sub); //regenerate the scattering veto++; i--; continue; } try{ //do the forcedSplitting remnantDecayer()->doSplit(incomingPartons, make_pair(remmpipdfs_.first,remmpipdfs_.second), false); } catch (ExtraScatterVeto) { //remove all particles associated with the subprocess newStep()->removeParticle(incomingPartons.first); newStep()->removeParticle(incomingPartons.second); //remove the subprocess from the list newStep()->removeSubProcess(sub); //regenerate the scattering veto++; i--; continue; } //connect with the remnants but don't set Remnant colour, //because that causes problems due to the multiple colour lines. if ( !remnants.first ->extract(incomingPartons.first , false) || !remnants.second->extract(incomingPartons.second, false) ) throw Exception() << "Remnant extraction failed in " << "ShowerHandler::cascade() for MPI hard scattering" << Exception::runerror; //reset veto counter veto = 0; // perform the reweighting for the MPI process shower combineWeights(); } // finalize the remnants remnantDecayer()->finalize(getMPIHandler()->colourDisrupt(), getMPIHandler()->softMultiplicity()); // boost back to lab if needed if(btotal) boostCollision(true); // unset the current ShowerHandler unSetCurrentHandler(); getMPIHandler()->clean(); resetPDFs(make_pair(first,second)); } void ShowerHandler::initializeWeights() { if ( !showerVariations().empty() ) { tEventPtr event = eventHandler()->currentEvent(); for ( map::const_iterator var = showerVariations().begin(); var != showerVariations().end(); ++var ) { // Check that this is behaving as intended //map::iterator wi = event->optionalWeights().find(var->first); //assert(wi == event->optionalWeights().end() ); event->optionalWeights()[var->first] = 1.0; currentWeights_[var->first] = 1.0; } } reweight_ = 1.0; } void ShowerHandler::resetWeights() { for ( map::iterator w = currentWeights_.begin(); w != currentWeights_.end(); ++w ) { w->second = 1.0; } reweight_ = 1.0; } void ShowerHandler::combineWeights() { tEventPtr event = eventHandler()->currentEvent(); for ( map::const_iterator w = currentWeights_.begin(); w != currentWeights_.end(); ++w ) { map::iterator ew = event->optionalWeights().find(w->first); if ( ew != event->optionalWeights().end() ) ew->second *= w->second; else { assert(false && "Weight name unknown."); //event->optionalWeights()[w->first] = w->second; } } if ( reweight_ != 1.0 ) { Ptr::tptr eh = dynamic_ptr_cast::tptr>(eventHandler()); if ( !eh ) { throw Exception() << "ShowerHandler::combineWeights() : Cross section reweighting " << "through the shower is currently only available with standard " << "event generators" << Exception::runerror; } eh->reweight(reweight_); } } string ShowerHandler::doAddVariation(string in) { if ( in.empty() ) return "expecting a name and a variation specification"; string name = StringUtils::car(in); ShowerVariation var; string res = var.fromInFile(StringUtils::cdr(in)); if ( res.empty() ) { if ( !var.firstInteraction && !var.secondaryInteractions ) { // TODO what about decay showers? return "variation does not apply to any shower"; } if ( var.renormalizationScaleFactor == 1.0 && var.factorizationScaleFactor == 1.0 ) { return "variation does not vary anything"; } /* Repository::clog() << "adding a variation with tag '" << name << "' using\nxir = " << var.renormalizationScaleFactor << " xif = " << var.factorizationScaleFactor << "\napplying to:\n" << "first interaction = " << var.firstInteraction << " " << "secondary interactions = " << var.secondaryInteractions << "\n" << flush; */ showerVariations()[name] = var; } return res; } tPPair ShowerHandler::cascade(tSubProPtr, XCPtr) { assert(false); + return tPPair(); } ShowerHandler::RemPair ShowerHandler::getRemnants(PBIPair incomingBins) { RemPair remnants; // first beam particle if(incomingBins.first&&!incomingBins.first->remnants().empty()) { remnants.first = dynamic_ptr_cast(incomingBins.first->remnants()[0] ); if(remnants.first) { ParticleVector children=remnants.first->children(); for(unsigned int ix=0;ixdataPtr()==remnants.first->dataPtr()) remnants.first = dynamic_ptr_cast(children[ix]); } //remove existing colour lines from the remnants if(remnants.first->colourLine()) remnants.first->colourLine()->removeColoured(remnants.first); if(remnants.first->antiColourLine()) remnants.first->antiColourLine()->removeAntiColoured(remnants.first); } } // seconnd beam particle if(incomingBins.second&&!incomingBins. second->remnants().empty()) { remnants.second = dynamic_ptr_cast(incomingBins.second->remnants()[0] ); if(remnants.second) { ParticleVector children=remnants.second->children(); for(unsigned int ix=0;ixdataPtr()==remnants.second->dataPtr()) remnants.second = dynamic_ptr_cast(children[ix]); } //remove existing colour lines from the remnants if(remnants.second->colourLine()) remnants.second->colourLine()->removeColoured(remnants.second); if(remnants.second->antiColourLine()) remnants.second->antiColourLine()->removeAntiColoured(remnants.second); } } assert(remnants.first || remnants.second); return remnants; } namespace { void addChildren(tPPtr in,set & particles) { particles.insert(in); for(unsigned int ix=0;ixchildren().size();++ix) addChildren(in->children()[ix],particles); } } void ShowerHandler::boostCollision(bool boost) { // calculate boost from lab to rest if(!boost) { Lorentz5Momentum ptotal=incoming_.first ->momentum()+incoming_.second->momentum(); boost_ = LorentzRotation(-ptotal.boostVector()); Axis axis((boost_*incoming_.first ->momentum()).vect().unit()); if(axis.perp2()>0.) { double sinth(sqrt(sqr(axis.x())+sqr(axis.y()))); boost_.rotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.)); } } // first call performs the boost and second inverse // get the particles to be boosted set particles; addChildren(incoming_.first,particles); addChildren(incoming_.second,particles); // apply the boost for(set::const_iterator cit=particles.begin(); cit!=particles.end();++cit) { (*cit)->transform(boost_); } if(!boost) boost_.invert(); } void ShowerHandler::setMPIPDFs() { if ( !mpipdfs_.first ) { // first have to check for MinBiasPDF tcMinBiasPDFPtr first = dynamic_ptr_cast(firstPDF().pdf()); if(first) mpipdfs_.first = new_ptr(MPIPDF(first->originalPDF())); else mpipdfs_.first = new_ptr(MPIPDF(firstPDF().pdf())); } if ( !mpipdfs_.second ) { tcMinBiasPDFPtr second = dynamic_ptr_cast(secondPDF().pdf()); if(second) mpipdfs_.second = new_ptr(MPIPDF(second->originalPDF())); else mpipdfs_.second = new_ptr(MPIPDF(secondPDF().pdf())); } if( !remmpipdfs_.first ) { tcMinBiasPDFPtr first = dynamic_ptr_cast(rempdfs_.first); if(first) remmpipdfs_.first = new_ptr(MPIPDF(first->originalPDF())); else remmpipdfs_.first = new_ptr(MPIPDF(rempdfs_.first)); } if( !remmpipdfs_.second ) { tcMinBiasPDFPtr second = dynamic_ptr_cast(rempdfs_.second); if(second) remmpipdfs_.second = new_ptr(MPIPDF(second->originalPDF())); else remmpipdfs_.second = new_ptr(MPIPDF(rempdfs_.second)); } // reset the PDFs stored in the base class resetPDFs(mpipdfs_); } bool ShowerHandler::isResolvedHadron(tPPtr particle) { if(!HadronMatcher::Check(particle->data())) return false; for(unsigned int ix=0;ixchildren().size();++ix) { if(particle->children()[ix]->id()==ParticleID::Remnant) return true; } return false; } namespace { bool decayProduct(tSubProPtr subProcess, tPPtr particle) { // must be time-like and not incoming if(particle->momentum().m2()<=ZERO|| particle == subProcess->incoming().first|| particle == subProcess->incoming().second) return false; // if only 1 outgoing and this is it if(subProcess->outgoing().size()==1 && subProcess->outgoing()[0]==particle) return true; // must not be the s-channel intermediate otherwise if(find(subProcess->incoming().first->children().begin(), subProcess->incoming().first->children().end(),particle)!= subProcess->incoming().first->children().end()&& find(subProcess->incoming().second->children().begin(), subProcess->incoming().second->children().end(),particle)!= subProcess->incoming().second->children().end()&& subProcess->incoming().first ->children().size()==1&& subProcess->incoming().second->children().size()==1) return false; // if non-coloured this is enough if(!particle->dataPtr()->coloured()) return true; // if coloured must be unstable if(particle->dataPtr()->stable()) return false; // must not have same particle type as a child int id = particle->id(); for(unsigned int ix=0;ixchildren().size();++ix) if(particle->children()[ix]->id()==id) return false; // otherwise its a decaying particle return true; } PPtr findParent(PPtr original, bool & isHard, set outgoingset, tSubProPtr subProcess) { PPtr parent=original; isHard |=(outgoingset.find(original) != outgoingset.end()); if(!original->parents().empty()) { PPtr orig=original->parents()[0]; if(decayProduct(subProcess,orig)) parent=findParent(orig,isHard,outgoingset,subProcess); } return parent; } } void ShowerHandler::findDecayProducts(PPtr in,PerturbativeProcessPtr hard, DecayProcessMap & decay) const { ParticleVector children=in->children(); for(ParticleVector::const_iterator it=children.begin(); it!=children.end();++it) { // if decayed or should be decayed in shower make the PerturbaitveProcess bool radiates = false; if(!(**it).children().empty()) { // remove d,u,s,c,b quarks and leptons other than on-shell taus if( StandardQCDPartonMatcher::Check((**it).id()) || ( LeptonMatcher::Check((**it).id()) && !(abs((**it).id())==ParticleID::tauminus && abs((**it).mass()-(**it).dataPtr()->mass())id()==(**it).id()) { foundParticle = true; } else if((**it).children()[iy]->id()==ParticleID::g || (**it).children()[iy]->id()==ParticleID::gamma) { foundGauge = true; } } radiates = foundParticle && foundGauge; } } if(radiates) { findDecayProducts(*it,hard,decay); } else if(!(**it).children().empty()|| (decaysInShower((**it).id())&&!(**it).dataPtr()->stable())) { createDecayProcess(*it,hard,decay); } else { hard->outgoing().push_back(make_pair(*it,PerturbativeProcessPtr())); } } } void ShowerHandler::splitHardProcess(tPVector tagged, PerturbativeProcessPtr & hard, DecayProcessMap & decay) const { // temporary storage of the particles set hardParticles; // tagged particles in a set set outgoingset(tagged.begin(),tagged.end()); bool isHard=false; // loop over the tagged particles for (tParticleVector::const_iterator taggedP = tagged.begin(); taggedP != tagged.end(); ++taggedP) { // skip remnants if (eventHandler()->currentCollision()&& eventHandler()->currentCollision()->isRemnant(*taggedP)) continue; // find the parent and whether its a decaying particle bool isDecayProd=false; // check if hard isHard |=(outgoingset.find(*taggedP) != outgoingset.end()); if(splitHardProcess_) { tPPtr parent = *taggedP; // check if from s channel decaying colourless particle while(parent&&!parent->parents().empty()&&!isDecayProd) { parent = parent->parents()[0]; if(parent == subProcess_->incoming().first || parent == subProcess_->incoming().second ) break; isDecayProd = decayProduct(subProcess_,parent); } if (isDecayProd) hardParticles.insert(findParent(parent,isHard,outgoingset,subProcess_)); } if (!isDecayProd) hardParticles.insert(*taggedP); } // there must be something to shower if(hardParticles.empty()) throw Exception() << "No particles to shower in " << "ShowerHandler::splitHardProcess()" << Exception::eventerror; // must be a hard process if(!isHard) throw Exception() << "Starting on decay not yet implemented in " << "ShowerHandler::splitHardProcess()" << Exception::runerror; // create the hard process hard = new_ptr(PerturbativeProcess()); // incoming particles hard->incoming().push_back(make_pair(subProcess_->incoming().first ,PerturbativeProcessPtr())); hard->incoming().push_back(make_pair(subProcess_->incoming().second,PerturbativeProcessPtr())); // outgoing particles for(set::const_iterator it=hardParticles.begin();it!=hardParticles.end();++it) { // if decayed or should be decayed in shower make the tree PPtr orig = *it; bool radiates = false; if(!orig->children().empty()) { // remove d,u,s,c,b quarks and leptons other than on-shell taus if( StandardQCDPartonMatcher::Check(orig->id()) || ( LeptonMatcher::Check(orig->id()) && !(abs(orig->id())==ParticleID::tauminus && abs(orig->mass()-orig->dataPtr()->mass())children().size();++iy) { if(orig->children()[iy]->id()==orig->id()) { foundParticle = true; } else if(orig->children()[iy]->id()==ParticleID::g || orig->children()[iy]->id()==ParticleID::gamma) { foundGauge = true; } } radiates = foundParticle && foundGauge; } } if(radiates) { findDecayProducts(orig,hard,decay); } else if(!(**it).children().empty()|| (decaysInShower((**it).id())&&!(**it).dataPtr()->stable())) { createDecayProcess(*it,hard,decay); } else { hard->outgoing().push_back(make_pair(*it,PerturbativeProcessPtr())); } } } void ShowerHandler::createDecayProcess(PPtr in,PerturbativeProcessPtr hard, DecayProcessMap & decay) const { // there must be an incoming particle assert(in); // create the new process and connect with the parent PerturbativeProcessPtr newDecay=new_ptr(PerturbativeProcess()); newDecay->incoming().push_back(make_pair(in,hard)); Energy width=in->dataPtr()->generateWidth(in->mass()); decay.insert(make_pair(width,newDecay)); hard->outgoing().push_back(make_pair(in,newDecay)); // we need to deal with the decay products if decayed ParticleVector children = in->children(); if(!children.empty()) { for(ParticleVector::const_iterator it = children.begin(); it!= children.end(); ++it) { // if decayed or should be decayed in shower make the tree in->abandonChild(*it); bool radiates = false; if(!(**it).children().empty()) { if(StandardQCDPartonMatcher::Check((**it).id())|| (LeptonMatcher::Check((**it).id())&& !(abs((**it).id())==ParticleID::tauminus && abs((**it).mass()-(**it).dataPtr()->mass())id()==(**it).id()) { foundParticle = true; } else if((**it).children()[iy]->id()==ParticleID::g || (**it).children()[iy]->id()==ParticleID::gamma) { foundGauge = true; } } radiates = foundParticle && foundGauge; } // finally assume all non-decaying particles are in this class // pr 27/11/15 not sure about this bit // if(!radiates) { // radiates = !decaysInShower((**it).id()); // } } if(radiates) { findDecayProducts(*it,newDecay,decay); } else if(!(**it).children().empty()|| (decaysInShower((**it).id())&&!(**it).dataPtr()->stable())) { createDecayProcess(*it,newDecay,decay); } else { newDecay->outgoing().push_back(make_pair(*it,PerturbativeProcessPtr())); } } } } tDMPtr ShowerHandler::decay(PerturbativeProcessPtr process, DecayProcessMap & decayMap, bool radPhotons ) const { PPtr parent = process->incoming()[0].first; assert(parent); if(parent->spinInfo()) parent->spinInfo()->decay(true); unsigned int ntry = 0; ParticleVector children; tDMPtr dm = DMPtr(); while (true) { // exit if fails if (++ntry>=maxtryDecay_) throw Exception() << "Failed to perform decay in ShowerHandler::decay()" << " after " << maxtryDecay_ << " attempts for " << parent->PDGName() << Exception::eventerror; // select decay mode dm = parent->data().selectMode(*parent); if(!dm) throw Exception() << "Failed to select decay mode in ShowerHandler::decay()" << "for " << parent->PDGName() << Exception::eventerror; if(!dm->decayer()) throw Exception() << "No Decayer for selected decay mode " << " in ShowerHandler::decay()" << Exception::runerror; // start of try block try { children = dm->decayer()->decay(*dm, *parent); // if no children have another go if(children.empty()) continue; if(radPhotons){ // generate radiation in the decay tDecayIntegratorPtr hwdec=dynamic_ptr_cast(dm->decayer()); if (hwdec && hwdec->canGeneratePhotons()) children = hwdec->generatePhotons(*parent,children); } // set up parent parent->decayMode(dm); // add children for (unsigned int i = 0, N = children.size(); i < N; ++i ) { children[i]->setLabVertex(parent->labDecayVertex()); //parent->addChild(children[i]); } // if succeeded break out of loop break; } catch(Veto) { } } assert(!children.empty()); for(ParticleVector::const_iterator it = children.begin(); it!= children.end(); ++it) { if(!(**it).children().empty()|| (decaysInShower((**it).id())&&!(**it).dataPtr()->stable())) { createDecayProcess(*it,process,decayMap); } else { process->outgoing().push_back(make_pair(*it,PerturbativeProcessPtr())); } } return dm; } // Note: The tag must be constructed from an ordered particle container. tDMPtr ShowerHandler::findDecayMode(const string & tag) const { static map cache; map::const_iterator pos = cache.find(tag); if ( pos != cache.end() ) return pos->second; tDMPtr dm = CurrentGenerator::current().findDecayMode(tag); cache[tag] = dm; return dm; } /** * Operator for the particle ordering * @param p1 The first ParticleData object * @param p2 The second ParticleData object */ bool ShowerHandler::ParticleOrdering::operator() (tcPDPtr p1, tcPDPtr p2) const { return abs(p1->id()) > abs(p2->id()) || ( abs(p1->id()) == abs(p2->id()) && p1->id() > p2->id() ) || ( p1->id() == p2->id() && p1->fullName() > p2->fullName() ); } diff --git a/Shower/UEBase.h b/Shower/UEBase.h --- a/Shower/UEBase.h +++ b/Shower/UEBase.h @@ -1,141 +1,146 @@ // -*- C++ -*- #ifndef HERWIG_UEBase_H #define HERWIG_UEBase_H // // This is the declaration of the UEBase class. // #include "ThePEG/Interface/Interfaced.h" #include "ThePEG/Handlers/StandardXComb.fh" #include "UEBase.fh" namespace Herwig { using namespace ThePEG; /** * Abstract base class used to minimize the dependence between * MPIHandler and all Shower classes. * * \author Manuel B\"ahr * * @see \ref UEBaseInterfaces "The interfaces" * defined for UEBase. */ class UEBase: public Interfaced { public: /** * 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(); /** @name Virtual functions used for the generation of additional interactions . */ //@{ /** * Some initialization code eventually. */ virtual void initialize() {} /** * Return true or false depending on the generator setup. */ virtual bool beamOK() const = 0; /** * Return true or false depending on whether soft interactions are enabled. */ virtual bool softInt() const {return false;} /** * Return the value of the pt cutoff. */ virtual Energy Ptmin() const = 0; /** * Return the slope of the soft pt spectrum. Only necessary when the * soft part is modelled. */ virtual InvEnergy2 beta() const {return ZERO;} /** * Some finalize code eventually. */ virtual void finalize() {} /** * Clean up method called after each event. */ virtual void clean() {} /** * Return the number of different hard processes. Use 0 as default to * not require implementation. */ virtual unsigned int additionalHardProcs() const {return 0;} /** * return the hard multiplicity of process i. Can't be constant in my * case because drawing from the probability distribution also * specifies the soft multiplicity that has to be stored.... */ virtual unsigned int multiplicity(unsigned int i=0) = 0; /** * Generate a additional interaction for ProcessHandler sel. Method * can't be const because it saves the state of the underlying XComb * object on it's way. */ virtual tStdXCombPtr generate(unsigned int sel=0) = 0; /** * Return the type of algorithm. */ virtual int Algorithm() const = 0; /** * Return the value of the hard Process pt cutoff for vetoing. */ virtual Energy PtForVeto() const = 0; /** * Return the fraction of colour disrupted subprocesses. Use default 0 * so that it is not required to implement. */ virtual double colourDisrupt() const {return 0.0;} /** * Return the soft multiplicity. Use 0 as default to not require * implementation. */ virtual unsigned int softMultiplicity() const {return 0;} //@} /** * Return the inelastic cross section ( sigmaND + sigmaDiff ) */ virtual CrossSection inelasticXSec() const =0; - + /** - * Return the diffractiv cross section assumed by the model. + * Return the diffractiv cross section (sigmaDiff) assumed by the model. */ virtual CrossSection diffractiveXSec() const =0; + + /** + * Return the non-diffractiv cross section (sigmaND) assumed by the model. + */ + virtual CrossSection nonDiffractiveXSec() const =0; private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ UEBase & operator=(const UEBase &) = delete; }; } #endif /* HERWIG_UEBase_H */ diff --git a/Tests/Makefile.am b/Tests/Makefile.am --- a/Tests/Makefile.am +++ b/Tests/Makefile.am @@ -1,386 +1,381 @@ AM_LDFLAGS += -module -avoid-version -rpath /dummy/path/not/used EXTRA_DIST = Inputs python Rivet EXTRA_LTLIBRARIES = LeptonTest.la GammaTest.la HadronTest.la DISTest.la if WANT_LIBFASTJET EXTRA_LTLIBRARIES += HadronJetTest.la LeptonJetTest.la HadronJetTest_la_SOURCES = \ Hadron/VHTest.h Hadron/VHTest.cc\ Hadron/VTest.h Hadron/VTest.cc\ Hadron/HTest.h Hadron/HTest.cc HadronJetTest_la_CPPFLAGS = $(AM_CPPFLAGS) $(FASTJETINCLUDE) \ -I$(FASTJETPATH) HadronJetTest_la_LIBADD = $(FASTJETLIBS) LeptonJetTest_la_SOURCES = \ Lepton/TopDecay.h Lepton/TopDecay.cc LeptonJetTest_la_CPPFLAGS = $(AM_CPPFLAGS) $(FASTJETINCLUDE) \ -I$(FASTJETPATH) LeptonJetTest_la_LIBADD = $(FASTJETLIBS) endif LeptonTest_la_SOURCES = \ Lepton/VVTest.h Lepton/VVTest.cc \ Lepton/VBFTest.h Lepton/VBFTest.cc \ Lepton/VHTest.h Lepton/VHTest.cc \ Lepton/FermionTest.h Lepton/FermionTest.cc GammaTest_la_SOURCES = \ Gamma/GammaMETest.h Gamma/GammaMETest.cc \ Gamma/GammaPMETest.h Gamma/GammaPMETest.cc DISTest_la_SOURCES = \ DIS/DISTest.h DIS/DISTest.cc HadronTest_la_SOURCES = \ Hadron/HadronVVTest.h Hadron/HadronVVTest.cc\ Hadron/HadronVBFTest.h Hadron/HadronVBFTest.cc\ Hadron/WHTest.h Hadron/WHTest.cc\ Hadron/ZHTest.h Hadron/ZHTest.cc\ Hadron/VGammaTest.h Hadron/VGammaTest.cc\ Hadron/ZJetTest.h Hadron/ZJetTest.cc\ Hadron/WJetTest.h Hadron/WJetTest.cc\ Hadron/QQHTest.h Hadron/QQHTest.cc REPO = $(top_builddir)/src/HerwigDefaults.rpo HERWIG = $(top_builddir)/src/Herwig HWREAD = $(HERWIG) read --repo $(REPO) -L $(builddir)/.libs -i $(top_builddir)/src HWBUILD = $(HERWIG) build --repo $(REPO) -L $(builddir)/.libs -i $(top_builddir)/src HWINTEGRATE = $(HERWIG) integrate HWRUN = $(HERWIG) run -N $${NUMEVENTS:-10000} tests : tests-LEP tests-DIS tests-LHC tests-Gamma LEPDEPS = \ test-LEP-VV \ test-LEP-VH \ test-LEP-VBF \ test-LEP-BB \ test-LEP-Quarks \ test-LEP-Leptons if WANT_LIBFASTJET LEPDEPS += test-LEP-TopDecay endif tests-LEP : $(LEPDEPS) tests-DIS : test-DIS-Charged test-DIS-Neutral LHCDEPS = \ test-LHC-WW test-LHC-WZ test-LHC-ZZ \ test-LHC-ZGamma test-LHC-WGamma \ test-LHC-ZH test-LHC-WH \ test-LHC-ZJet test-LHC-WJet \ test-LHC-Z test-LHC-W \ test-LHC-ZZVBF test-LHC-VBF \ test-LHC-WWVBF \ test-LHC-bbH test-LHC-ttH \ test-LHC-GammaGamma test-LHC-GammaJet \ test-LHC-Higgs test-LHC-HiggsJet \ test-LHC-QCDFast test-LHC-QCD \ test-LHC-Top if WANT_LIBFASTJET LHCDEPS += \ test-LHC-Bottom \ test-LHC-WHJet test-LHC-ZHJet test-LHC-HJet \ test-LHC-ZShower test-LHC-WShower \ test-LHC-WHJet-Powheg test-LHC-ZHJet-Powheg test-LHC-HJet-Powheg \ test-LHC-ZShower-Powheg test-LHC-WShower-Powheg endif tests-LHC : $(LHCDEPS) tests-Gamma : test-Gamma-FF test-Gamma-WW test-Gamma-P LEPLIBS = LeptonTest.la HADLIBS = HadronTest.la if WANT_LIBFASTJET LEPLIBS += LeptonJetTest.la HADLIBS += HadronJetTest.la endif test-LEP-% : Inputs/LEP-%.in $(LEPLIBS) $(HWREAD) $< $(HWRUN) $(notdir $(subst .in,.run,$<)) test-Gamma-% : Inputs/Gamma-%.in GammaTest.la $(HWREAD) $< $(HWRUN) $(notdir $(subst .in,.run,$<)) test-DIS-% : Inputs/DIS-%.in DISTest.la $(HWREAD) $< $(HWRUN) $(notdir $(subst .in,.run,$<)) test-LHC-% : Inputs/LHC-%.in GammaTest.la $(HADLIBS) $(HWREAD) $< $(HWRUN) $(notdir $(subst .in,.run,$<)) tests-Rivet : Rivet-EE Rivet-DIS Rivet-Star Rivet-SppS \ Rivet-TVT-WZ Rivet-TVT-Photon Rivet-TVT-Jets \ Rivet-LHC-Jets Rivet-LHC-EW Rivet-LHC-Photon Rivet-LHC-Higgs Rivet-%.run : Rivet/%.in $(HWBUILD) -c .cache/$(subst .run,,$@) $< Rivet-Matchbox-%.yoda : Rivet-Matchbox-%.run $(HWINTEGRATE) -c .cache/$(subst .run,,$<) $< $(HWRUN) -c .cache/$(subst .run,,$<) $< Rivet-%.yoda : Rivet-%.run $(HWRUN) $< Rivet/%.in : python/make_input_files.py $(notdir $(subst .in,,$@)) Rivet-inputfiles: $(shell echo Rivet/EE{,-Powheg,-Matchbox,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox-Powheg,-Merging}-{7.7,9.4,12,13,17,27.6,29,30.2,30.7,30,31.3,34,34.8,41,42.1,42.6,43.6,45,50,52,53.3,55,56,57,58,59.5,60.8,60,61.4,66,76,82,85,10,12.8,21.5,22,25,26.8,34.5,35,36.2,44,48.0,91,93.0,130,133,136,161,172,177,183,189,192,196,197,200,202,205,206,207,91-nopi}.in) \ $(shell echo Rivet/EE{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Powheg,-Matchbox-Powheg}-{14,14.8}.in) \ $(shell echo Rivet/EE{,-Dipole}-{10.5,11.96,12.8,13.96,16.86,21.84,26.8,28.48,35.44,48.0,97.0}-gg.in) \ $(shell echo Rivet/EE{,-Powheg,-Matchbox,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox-Powheg}-{2.2,2.6,3.0,3.2,4.17,4.3,4.41,5.0,5.2,4.6,4.8,5.8,6.2,6.6,7.0,7.4,3.63,4.03,4.5,9.46,10.52,10.52-sym,10.54,10.45,10.47}.in) \ - $(shell echo Rivet/EE-{Upsilon,Upsilon2,Upsilon4,JPsi,Psi2S,Tau,Phi,10.58-res,Lambdac,Omega,Xi0,Xic0,Omegac0,Xim}.in) \ + $(shell echo Rivet/EE-{Upsilon,Upsilon2,Upsilon4,JPsi,Psi2S,Tau,Phi,10.58-res,10.58,Lambdac,Omega-Meson,Omega-Baryon,Eta,Xi0,Xic0,Omegac0,Xim}.in) \ $(shell echo Rivet/DIS{,-NoME,-Powheg,-Matchbox,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox-Powheg,-Merging}-{e--LowQ2,e+-LowQ2,e+-HighQ2}.in) \ $(shell echo Rivet/TVT{,-Powheg,-Matchbox,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox-Powheg,-Merging}-{Run-I-Z,Run-I-W,Run-I-WZ,Run-II-Z-e,Run-II-Z-{,LowMass-,HighMass-}mu,Run-II-W}.in) \ $(shell echo Rivet/TVT{,-Dipole}-Run-II-{DiPhoton-GammaGamma,DiPhoton-GammaJet,PromptPhoton}.in) \ $(shell echo Rivet/TVT-Powheg-Run-II-{DiPhoton-GammaGamma,DiPhoton-GammaJet}.in) \ $(shell echo Rivet/TVT{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-{Run-II-Jets-{0..11},Run-I-Jets-{1..8}}.in ) \ $(shell echo Rivet/TVT{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-{630-Jets-{1..3},300-Jets-1,900-Jets-1}.in ) \ $(shell echo Rivet/TVT{,-Dipole}-{Run-I,Run-II,300,630,900}-UE.in) \ $(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-7-DiJets-{1..7}-{A,B,C}.in ) \ $(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-13-DiJets-{{1..11}-A,{6..11}-B}.in ) \ $(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-{7,8,13}-Jets-{0..10}.in ) \ $(shell echo Rivet/LHC{,-Dipole}-{900,2360,2760,7,8,13}-UE.in ) \ $(shell echo Rivet/LHC{,-Dipole}-{900,7,13}-UE-Long.in ) \ $(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-7-Charm-{1..5}.in) \ $(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-7-Bottom-{0..9}.in) \ $(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-7-Top-{L,SL}.in) \ $(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-{8,13}-Top-{All,L,SL}.in) \ $(shell echo Rivet/Star{,-Dipole}-{UE,Jets-{1..4}}.in ) \ - $(shell echo Rivet/SppS{,-Dipole}-{200,500,900,546}-UE.in ) \ + $(shell echo Rivet/SppS{,-Dipole}-{53,63,200,500,546,900}-UE.in ) \ $(shell echo Rivet/LHC{,-Matchbox,-Matchbox-Powheg,-Powheg,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-{W-{e,mu},13-Z-{e,mu},Z-HighMass{1,2}-e,{8,13}-W-mu,8-Z-Mass{1..4}-{e,mu},Z-{e,mu,mu-SOPHTY},Z-LowMass-{e,mu},Z-MedMass-e,WZ,WW-{emu,ll},ZZ-{ll,lv},{8,13}-WZ,8-ZZ-lv,8-WW-ll,Z-mu-Short}.in) \ $(shell echo Rivet/LHC{,-Dipole}-7-{W,Z}Gamma-{e,mu}.in) \ $(shell echo Rivet/LHC{,-Dipole}-8-ZGamma-{e,mu}.in) \ $(shell echo Rivet/LHC{,-Matchbox,-Matchbox-Powheg,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-{7-W-Jet-{1..3}-e,7-Z-Jet-{0..3}-e,7-Z-Jet-0-mu}.in) \ $(shell echo Rivet/LHC{-Matchbox,-Matchbox-Powheg,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-{Z-b,Z-bb,8-Z-b,8-Z-bb,W-b,8-Z-jj}.in) \ $(shell echo Rivet/LHC{,-Dipole}-{7,8,13}-PromptPhoton-{1..4}.in) Rivet/LHC-GammaGamma-7.in \ $(shell echo Rivet/LHC{,-Powheg}-{7,8}-{DiPhoton-GammaGamma,DiPhoton-GammaJet}.in) \ $(shell echo Rivet/LHC{,-Powheg,-Matchbox,-Matchbox-Powheg,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-{ggH,VBF,WH,ZH}.in) \ $(shell echo Rivet/LHC{,-Powheg,-Matchbox,-Matchbox-Powheg,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-8-{{ggH,VBF,WH,ZH}{,-GammaGamma},ggH-WW}.in) \ - $(shell echo Rivet/LHC{,-Matchbox,-Matchbox-Powheg,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-ggHJet.in) -# $(shell echo Rivet/ISR-{30,44,53,62}-UE.in ) $(shell echo Rivet/SppS-{53,63}-UE.in ) + $(shell echo Rivet/LHC{,-Matchbox,-Matchbox-Powheg,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-ggHJet.in) \ + $(shell echo Rivet/ISR-{30,44,53,62}-UE.in ) Rivet/EHS-UE.in + Rivet-GammaGamma: Rivet-GammaGamma/done touch $@ Rivet-GammaGamma/done: $(shell echo Rivet-GammaGamma-mumu-{3.5,4.5,5.5,6.5,7.5,9.0,12.5,17.5,30.0}.yoda ) rm -rf Rivet-GammaGamma python/merge-GammaGamma GammaGamma rivet-mkhtml -o Rivet-GammaGamma GammaGamma.yoda:Hw touch $@ Rivet-EE-Gamma: Rivet-EE-Gamma/done touch $@ Rivet-EE-Gamma/done: $(shell echo Rivet-EE-Gamma-Direct-mumu-{161,172,183,189,196,206}.yoda ) \ $(shell echo Rivet-EE-Gamma-Direct-tautau-{189,196,206}.yoda ) \ $(shell echo Rivet-EE-Gamma-{Direct,Single-Resolved,Double-Resolved}-Jets-{198,206}.yoda ) rm -rf Rivet-EE-Gamma python/merge-EE-Gamma EE-Gamma rivet-mkhtml -o Rivet-EE-Gamma EE-Gamma.yoda:Hw touch $@ Rivet-EE : Rivet-EE/done touch $@ Rivet-EE/done : $(shell echo Rivet{,-Powheg}-EE-{7.7,9.4,12,13,14,14.8,17,27.6,29,30.2,30.7,30,31.3,34,34.8,43.6,45,50,52,53.3,55,56,57,58,59.5,60.8,60,61.4,66,76,10,12.8,21.5,22,25,26.8,34.5,35,36.2,41,42.1,42.6,44,48.0,82,85,91,93.0,130,133,136,161,172,177,183,189,192,196,197,200,202,205,206,207,91-nopi}.yoda) \ $(shell echo Rivet-EE-{10.5,11.96,12.8,13.96,16.86,21.84,26.8,28.48,35.44,48.0,97.0}-gg.yoda) \ - $(shell echo Rivet-EE-{10.52,10.52-sym,2.2,2.6,3.0,3.2,4.6,4.8,5.8,6.2,6.6,7.0,7.4,3.63,4.03,4.17,4.3,4.41,5.0,5.2,4.5,9.46,10.54,10.45,10.47,Upsilon,Upsilon2,Upsilon4,Tau,Phi,10.58-res,10.58,Lambdac,Omega,Xi0,Xic0,Omegac0,Xim,JPsi,Psi2S}.yoda) + $(shell echo Rivet-EE-{10.52,10.52-sym,2.2,2.6,3.0,3.2,4.6,4.8,5.8,6.2,6.6,7.0,7.4,3.63,4.03,4.17,4.3,4.41,5.0,5.2,4.5,9.46,10.54,10.45,10.47,Upsilon,Upsilon2,Upsilon4,Tau,Phi,10.58-res,10.58,Lambdac,Omega-Meson,Omega-Baryon,Eta,Xi0,Xic0,Omegac0,Xim,JPsi,Psi2S}.yoda) rm -rf Rivet-EE python/merge-EE --with-gg EE python/merge-EE Powheg-EE rivet-mkhtml -o Rivet-EE EE.yoda:Hw Powheg-EE.yoda:Hw-Powheg python/plot-EE Rivet-EE touch $@ Rivet-LowEnergy-%.yoda: $(HWBUILD) -c .cache/$(subst .yoda,,$@) Rivet/$(subst .yoda,.in,$@) $(HWRUN) $(subst .yoda,.run,$@) Rivet-LowEnergy-%: args="--process "$(word 1,$(subst -, ,$(subst Rivet-LowEnergy-,,$@))); if [ -n "$(strip $(word 2,$(subst -, ,$(subst Rivet-LowEnergy-,,$@))))" ]; then args+=" --flavour "$(word 2,$(subst -, ,$(subst Rivet-LowEnergy-,,$@))); fi; OUTPUT=`python/LowEnergy.py $$args --non-perturbative --perturbative`; make -j12 $$OUTPUT NUMEVENTS=$${NUMEVENTS:-10000}; python/mergeLowEnergy.py $(subst Rivet-LowEnergy-,,$@) args="--process "$(word 1,$(subst -, ,$(subst Rivet-LowEnergy-,,$@))); plots=`python/LowEnergy.py $$args --plots`; if [ -e LowEnergy-EE-NonPerturbative-$(subst Rivet-LowEnergy-,,$@).yoda ] && [ -e LowEnergy-EE-Perturbative-$(subst Rivet-LowEnergy-,,$@).yoda ]; then rivet-mkhtml -o Rivet-LowEnergy-$(subst Rivet-LowEnergy-,,$@) LowEnergy-EE-NonPerturbative-$(subst Rivet-LowEnergy-,,$@).yoda:"Non-Pert" LowEnergy-EE-Perturbative-$(subst Rivet-LowEnergy-,,$@).yoda:"Pert" $$plots; elif [ -e LowEnergy-EE-NonPerturbative-$(subst Rivet-LowEnergy-,,$@).yoda ]; then rivet-mkhtml -o Rivet-LowEnergy-$(subst Rivet-LowEnergy-,,$@) LowEnergy-EE-NonPerturbative-$(subst Rivet-LowEnergy-,,$@).yoda:"Non-Pert" $$plots; elif [ -e LowEnergy-EE-Perturbative-$(subst Rivet-LowEnergy-,,$@).yoda ]; then rivet-mkhtml -o Rivet-LowEnergy-$(subst Rivet-LowEnergy-,,$@) LowEnergy-EE-Perturbative-$(subst Rivet-LowEnergy-,,$@).yoda:"Pert" $$plots; fi Rivet-R: OUTPUT=`python/R.py --perturbative`; make -j12 $$OUTPUT NUMEVENTS=$${NUMEVENTS:-10000}; python/mergeLowEnergy.py R rivet-mkhtml -o Rivet-R LowEnergy-EE-Perturbative-R.yoda:"Pert" #LowEnergy-EE-NonPerturbative-R.yoda:"Non-Pert" Rivet-DIS : Rivet-DIS/done touch $@ Rivet-DIS/done: $(shell echo Rivet{-DIS,-DIS-NoME,-Powheg-DIS}-{e--LowQ2,e+-LowQ2,e+-HighQ2}.yoda) rm -rf Rivet-DIS python/merge-DIS DIS python/merge-DIS Powheg-DIS python/merge-DIS DIS-NoME rivet-mkhtml -o Rivet-DIS DIS.yoda:Hw Powheg-DIS.yoda:Hw-Powheg DIS-NoME.yoda:Hw-NoME touch $@ Rivet-TVT-EW : Rivet-TVT-EW/done touch $@ Rivet-TVT-EW/done: $(shell echo Rivet{,-Powheg}-TVT-{Run-I-Z,Run-I-W,Run-I-WZ,Run-II-Z-{e,{,LowMass-,HighMass-}mu},Run-II-W}.yoda) rm -rf Rivet-TVT-EW python/merge-TVT-EW TVT python/merge-TVT-EW Powheg-TVT rivet-mkhtml -o Rivet-TVT-EW TVT-EW.yoda:Hw Powheg-TVT-EW.yoda:Hw-Powheg touch $@ Rivet-TVT-Photon : Rivet-TVT-Photon/done touch $@ Rivet-TVT-Photon/done: $(shell echo Rivet{,-Powheg}-TVT-Run-II-{DiPhoton-GammaGamma,DiPhoton-GammaJet}.yoda Rivet-TVT-Run-II-PromptPhoton.yoda) rm -rf Rivet-TVT-Photon python/merge-TVT-Photon TVT python/merge-TVT-Photon Powheg-TVT rivet-mkhtml -o Rivet-TVT-Photon TVT-Photon.yoda:Hw Powheg-TVT-Photon.yoda:Hw-Powheg touch $@ Rivet-TVT-Jets : Rivet-TVT-Jets/done touch $@ Rivet-TVT-Jets/done: $(shell echo Rivet-TVT-{Run-II-Jets-{0..11},Run-I-Jets-{1..8}}.yoda ) \ $(shell echo Rivet-TVT-{630-Jets-{1..3},300-Jets-1,900-Jets-1}.yoda ) \ $(shell echo Rivet-TVT-{Run-I,Run-II,300,630,900}-UE.yoda) rm -rf Rivet-TVT-Jets python/merge-TVT-Jets TVT rivet-mkhtml -o Rivet-TVT-Jets TVT-Jets.yoda:Hw touch $@ Rivet-Star : Rivet-Star/done touch $@ Rivet-Star/done : $(shell echo Rivet-Star-{UE,Jets-{1..4}}.yoda ) rm -rf Rivet-Star python/merge-Star Star rivet-mkhtml -o Rivet-Star Star.yoda:Hw touch $@ Rivet-SppS : Rivet-SppS/done touch $@ -## $(shell echo Rivet-ISR-{30,44,53,62}-UE.yoda ) \ -## {53,63,200,500,900,546} EHS-UE -Rivet-SppS/done : $(shell echo Rivet-SppS-{200,500,900,546}-UE.yoda ) +Rivet-SppS/done : $(shell echo Rivet-SppS-{53,63,200,500,546,900}-UE.yoda ) \ + $(shell echo Rivet-ISR-{30,44,53,62}-UE.yoda ) Rivet-EHS-UE.yoda rm -rf Rivet-SppS python/merge-SppS SppS rivet-mkhtml -o Rivet-SppS SppS.yoda:Hw touch $@ - - - - - Rivet-LHC-Jets : Rivet-LHC-Jets/done touch $@ Rivet-LHC-Jets/done : \ $(shell echo Rivet-LHC-7-DiJets-{1..7}-{A,B,C}.yoda ) \ $(shell echo Rivet-LHC-13-DiJets-{{1..11}-A,{6..11}-B}.yoda ) \ $(shell echo Rivet-LHC-{7,8,13}-Jets-{0..10}.yoda ) \ $(shell echo Rivet-LHC-2760-Jets-{1..3}.yoda ) \ $(shell echo Rivet-LHC-{900,2360,2760,7,8,13}-UE.yoda ) \ $(shell echo Rivet-LHC-{900,7,13}-UE-Long.yoda ) \ $(shell echo Rivet-LHC-7-Charm-{1..5}.yoda ) \ $(shell echo Rivet-LHC-7-Bottom-{0..9}.yoda ) \ $(shell echo Rivet-LHC-{7,8,13}-Top-{L,SL}.yoda ) \ $(shell echo Rivet-LHC-{8,13}-Top-All.yoda ) rm -rf Rivet-LHC-Jets python/merge-LHC-Jets LHC rivet-mkhtml -o Rivet-LHC-Jets LHC-Jets.yoda:Hw touch $@ Rivet-LHC-EW : Rivet-LHC-EW/done touch $@ Rivet-LHC-EW/done: \ $(shell echo Rivet{,-Powheg}-LHC-{13-Z-{e,mu},{8,13}-W-mu,Z-HighMass{1,2}-e,8-Z-Mass{1..4}-{e,mu},W-{e,mu},Z-{e,mu,mu-SOPHTY},Z-LowMass-{e,mu},Z-MedMass-e,WZ,WW-{emu,ll},ZZ-{ll,lv},{8,13}-WZ,8-ZZ-lv,8-WW-ll,Z-mu-Short}.yoda) \ $(shell echo Rivet-LHC-{7-W-Jet-{1..3}-e,7-Z-Jet-{0..3}-e,7-Z-Jet-0-mu}.yoda) \ $(shell echo Rivet-LHC-7-{W,Z}Gamma-{e,mu}.yoda) \ $(shell echo Rivet-LHC-8-ZGamma-{e,mu}.yoda) rm -rf Rivet-LHC-EW; python/merge-LHC-EW LHC python/merge-LHC-EW Powheg-LHC rivet-mkhtml -o Rivet-LHC-EW LHC-EW.yoda:Hw Powheg-LHC-EW.yoda:Hw-Powheg \ Rivet-LHC-Z-mu-SOPHTY.yoda:Hw Rivet-Powheg-LHC-Z-mu-SOPHTY.yoda:Hw-Powheg touch $@ Rivet-LHC-Photon : Rivet-LHC-Photon/done touch $@ Rivet-LHC-Photon/done: \ $(shell echo Rivet-LHC-{7,8,13}-PromptPhoton-{1..4}.yoda) \ Rivet-LHC-GammaGamma-7.yoda \ $(shell echo Rivet{,-Powheg}-LHC-{7,8}-{DiPhoton-GammaGamma,DiPhoton-GammaJet}.yoda) rm -rf Rivet-LHC-Photon python/merge-LHC-Photon LHC python/merge-LHC-Photon Powheg-LHC rivet-mkhtml -o Rivet-LHC-Photon LHC-Photon.yoda:Hw Powheg-LHC-Photon.yoda:Hw-Powheg touch $@ Rivet-LHC-Higgs : Rivet-LHC-Higgs/done touch $@ Rivet-LHC-Higgs/done: \ $(shell echo Rivet{,-Powheg}-LHC-{ggH,VBF,WH,ZH}.yoda) \ $(shell echo Rivet{,-Powheg}-LHC-8-{{ggH,VBF,WH,ZH}{,-GammaGamma},ggH-WW}.yoda) \ Rivet-LHC-ggHJet.yoda yodamerge --add Rivet-Powheg-LHC-8-{ggH{-GammaGamma,-WW,},{VBF,ZH,WH}{,-GammaGamma}}.yoda -o Powheg-LHC-Higgs.yoda yodamerge --add Rivet-LHC-8-{ggH{-GammaGamma,-WW,},{VBF,ZH,WH}{,-GammaGamma}}.yoda -o LHC-Higgs.yoda rm -rf Rivet-LHC-Higgs rivet-mkhtml -o Rivet-LHC-Higgs Powheg-LHC-Higgs.yoda:Hw-Powheg LHC-Higgs.yoda:Hw\ Rivet-Powheg-LHC-ggH.yoda:gg-Powheg Rivet-LHC-ggH.yoda:gg Rivet-LHC-ggHJet.yoda:HJet \ Rivet-Powheg-LHC-VBF.yoda:VBF-Powheg Rivet-LHC-VBF.yoda:VBF Rivet-LHC-WH.yoda:WH Rivet-LHC-ZH.yoda:ZH \ Rivet-Powheg-LHC-WH.yoda:WH-Powheg Rivet-Powheg-LHC-ZH.yoda:ZH-Powheg touch $@ clean-local: rm -f *.out *.log *.tex *.top *.run *.dump *.mult *.Bmult *.yoda Rivet/*.in anatohepmc.txt hepmctoana.txt rm -rf Rivet-* distclean-local: rm -rf .cache diff --git a/Tests/Rivet/EE/EE-Omega.in b/Tests/Rivet/EE/EE-Eta.in rename from Tests/Rivet/EE/EE-Omega.in rename to Tests/Rivet/EE/EE-Eta.in --- a/Tests/Rivet/EE/EE-Omega.in +++ b/Tests/Rivet/EE/EE-Eta.in @@ -1,18 +1,24 @@ # -*- ThePEG-repository -*- create ThePEG::LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxA 5.2897*GeV set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxB 5.2897*GeV set /Herwig/Generators/EventGenerator:EventHandler:Cuts:MHatMin 10.5792 set /Herwig/Particles/e-:PDF /Herwig/Partons/NoPDF set /Herwig/Particles/e+:PDF /Herwig/Partons/NoPDF set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity create Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEUpsilon HwMELepton.so set /Herwig/MatrixElements/MEUpsilon:VectorMeson /Herwig/Particles/Upsilon(4S) set /Herwig/MatrixElements/MEUpsilon:Coupling 96.72794 set /Herwig/MatrixElements/SubProcess:MatrixElements 0 /Herwig/MatrixElements/MEUpsilon -decaymode Upsilon(4S)->Omega-,Omegabar+; 1. 1 /Herwig/Decays/DecayME0 -do /Herwig/Particles/Upsilon(4S):SelectDecayModes /Herwig/Particles/Upsilon(4S)/Upsilon(4S)->Omega-,Omegabar+; -# Omega decays -insert /Herwig/Analysis/RivetAnalysis:Analyses 0 HyperCP_2005_I677384 -# Omega decays -insert /Herwig/Analysis/RivetAnalysis:Analyses 0 WA46_1984_I206647 +decaymode Upsilon(4S)->eta,eta'; 1. 1 /Herwig/Decays/DecayME0 +do /Herwig/Particles/Upsilon(4S):SelectDecayModes /Herwig/Particles/Upsilon(4S)/Upsilon(4S)->eta',eta; +# eta/omega dalitz +insert /Herwig/Analysis/RivetAnalysis:Analyses 0 A2_2017_I1486671 +# eta decay +insert /Herwig/Analysis/RivetAnalysis:Analyses 0 MC_Eta_Decay +# BES eta' dalitz +insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2015_I1364494 +insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2018_I1641075 +# eta -> pi+pi-pi0 +insert /Herwig/Analysis/RivetAnalysis:Analyses 0 KLOE2_2016_I1416990 + diff --git a/Tests/Rivet/EE/EE-Omega.in b/Tests/Rivet/EE/EE-Omega-Baryon.in copy from Tests/Rivet/EE/EE-Omega.in copy to Tests/Rivet/EE/EE-Omega-Baryon.in diff --git a/Tests/Rivet/EE/EE-Phi.in b/Tests/Rivet/EE/EE-Omega-Meson.in copy from Tests/Rivet/EE/EE-Phi.in copy to Tests/Rivet/EE/EE-Omega-Meson.in --- a/Tests/Rivet/EE/EE-Phi.in +++ b/Tests/Rivet/EE/EE-Omega-Meson.in @@ -1,22 +1,14 @@ # -*- ThePEG-repository -*- -# e+ e- -> phi -create Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEPhi HwMELepton.so -set /Herwig/MatrixElements/MEPhi:VectorMeson /Herwig/Particles/phi -set /Herwig/MatrixElements/MEPhi:Coupling 13.60507 -set /Herwig/MatrixElements/SubProcess:MatrixElements 0 /Herwig/MatrixElements/MEPhi -set EventGenerator:EventHandler:LuminosityFunction:Energy 1.019461 +# e+ e- -> omega +create Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEOmega HwMELepton.so +set /Herwig/MatrixElements/MEOmega:VectorMeson /Herwig/Particles/omega +set /Herwig/MatrixElements/MEOmega:Coupling 17.31158 +set /Herwig/MatrixElements/SubProcess:MatrixElements 0 /Herwig/MatrixElements/MEOmega +set EventGenerator:EventHandler:LuminosityFunction:Energy 0.78265 set /Herwig/Generators/EventGenerator:EventHandler:Cuts:MHatMin 0.2 set /Herwig/Particles/e-:PDF /Herwig/Partons/NoPDF set /Herwig/Particles/e+:PDF /Herwig/Partons/NoPDF -# phi -> eta pi0 gamma -insert /Herwig/Analysis/RivetAnalysis:Analyses 0 KLOE_2009_I818106 -insert /Herwig/Analysis/RivetAnalysis:Analyses 0 SND_2000_I525398 -# phi -> pi0 pi0 gamma -insert /Herwig/Analysis/RivetAnalysis:Analyses 0 KLOE_2002_I585183 -insert /Herwig/Analysis/RivetAnalysis:Analyses 0 SND_2000_I527094 -# KLOE phi -> pi0 dalitz -insert /Herwig/Analysis/RivetAnalysis:Analyses 0 KLOE2_2016_I1416825 -# KLOE phi -> eta dalitz -insert /Herwig/Analysis/RivetAnalysis:Analyses 0 KLOE2_2014_I1317236 -# phi -> pi+pi-pi0 -insert /Herwig/Analysis/RivetAnalysis:Analyses 0 SND_2001_I558279 +# eta/omega dalitz +insert /Herwig/Analysis/RivetAnalysis:Analyses 0 A2_2017_I1486671 +# omega/phi -> 3pi +insert /Herwig/Analysis/RivetAnalysis:Analyses 0 MC_OmegaPhia1_3Pion_Decay diff --git a/Tests/Rivet/EE/EE-Phi.in b/Tests/Rivet/EE/EE-Phi.in --- a/Tests/Rivet/EE/EE-Phi.in +++ b/Tests/Rivet/EE/EE-Phi.in @@ -1,22 +1,24 @@ # -*- ThePEG-repository -*- # e+ e- -> phi create Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEPhi HwMELepton.so set /Herwig/MatrixElements/MEPhi:VectorMeson /Herwig/Particles/phi set /Herwig/MatrixElements/MEPhi:Coupling 13.60507 set /Herwig/MatrixElements/SubProcess:MatrixElements 0 /Herwig/MatrixElements/MEPhi set EventGenerator:EventHandler:LuminosityFunction:Energy 1.019461 set /Herwig/Generators/EventGenerator:EventHandler:Cuts:MHatMin 0.2 set /Herwig/Particles/e-:PDF /Herwig/Partons/NoPDF set /Herwig/Particles/e+:PDF /Herwig/Partons/NoPDF # phi -> eta pi0 gamma insert /Herwig/Analysis/RivetAnalysis:Analyses 0 KLOE_2009_I818106 insert /Herwig/Analysis/RivetAnalysis:Analyses 0 SND_2000_I525398 # phi -> pi0 pi0 gamma insert /Herwig/Analysis/RivetAnalysis:Analyses 0 KLOE_2002_I585183 insert /Herwig/Analysis/RivetAnalysis:Analyses 0 SND_2000_I527094 # KLOE phi -> pi0 dalitz insert /Herwig/Analysis/RivetAnalysis:Analyses 0 KLOE2_2016_I1416825 # KLOE phi -> eta dalitz insert /Herwig/Analysis/RivetAnalysis:Analyses 0 KLOE2_2014_I1317236 # phi -> pi+pi-pi0 insert /Herwig/Analysis/RivetAnalysis:Analyses 0 SND_2001_I558279 +# omega/phi -> 3pi +insert /Herwig/Analysis/RivetAnalysis:Analyses 0 MC_OmegaPhia1_3Pion_Decay diff --git a/Tests/Rivet/EE/EE-Upsilon4.in b/Tests/Rivet/EE/EE-Upsilon4.in --- a/Tests/Rivet/EE/EE-Upsilon4.in +++ b/Tests/Rivet/EE/EE-Upsilon4.in @@ -1,56 +1,47 @@ # -*- ThePEG-repository -*- create ThePEG::LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxA 5.2897*GeV set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxB 5.2897*GeV set /Herwig/Generators/EventGenerator:EventHandler:Cuts:MHatMin 10.5792 set /Herwig/Particles/e-:PDF /Herwig/Partons/NoPDF set /Herwig/Particles/e+:PDF /Herwig/Partons/NoPDF set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity create Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEUpsilon HwMELepton.so set /Herwig/MatrixElements/MEUpsilon:VectorMeson /Herwig/Particles/Upsilon(4S) set /Herwig/MatrixElements/MEUpsilon:Coupling 96.72794 set /Herwig/MatrixElements/SubProcess:MatrixElements 0 /Herwig/MatrixElements/MEUpsilon # ARGUS pi,K, proton insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ARGUS_1993_S2653028 # ARGUS K*, rho, omega insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ARGUS_1993_S2789213 # various semileptonic decays insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2013_I1116411 insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2015_I1334693 insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2011_I878990 insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2013_I1238273 insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2015_I1397632 # BELLE b->s gamma insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2015_I1330289 # BES D -> K, pi semi-leptonic insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2015_I1391138 insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2017_I1519425 -# eta/omega dalitz -insert /Herwig/Analysis/RivetAnalysis:Analyses 0 A2_2017_I1486671 -# BES eta' dalitz -insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2015_I1364494 -insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2018_I1641075 # BES J/psi dalitz insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2018_I1697377 # multiplicities insert /Herwig/Analysis/RivetAnalysis:Analyses 0 PDG_Upsilon_4S_HADRON_MULTIPLICITIES # BES multiplicty in eta_c decays insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2019_I1724880 -# eta -> pi+pi-pi0 -insert /Herwig/Analysis/RivetAnalysis:Analyses 0 KLOE2_2016_I1416990 # kaons in b decays insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ARGUS_1994_I354224 # charm hadrons in b decays insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2006_I719111 # phi spectrum insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEO_2007_I728872 # D_s spectrum insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEO_2005_I1649168 # # MC analyses based on old internal ones insert /Herwig/Analysis/RivetAnalysis:Analyses 0 MC_Meson_Meson_Leptons_Decay -insert /Herwig/Analysis/RivetAnalysis:Analyses 0 MC_OmegaPhia1_3Pion_Decay insert /Herwig/Analysis/RivetAnalysis:Analyses 0 MC_D_Dalitz -insert /Herwig/Analysis/RivetAnalysis:Analyses 0 MC_Eta_Decay insert /Herwig/Analysis/RivetAnalysis:Analyses 0 MC_Onium_PiPi_Decay insert /Herwig/Analysis/RivetAnalysis:Analyses 0 MC_Semi_Leptonic_Decay insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ARGUS_1992_I319102 diff --git a/Tests/Rivet/LHC/LHC-900-UE.in b/Tests/Rivet/LHC/LHC-900-UE.in --- a/Tests/Rivet/LHC/LHC-900-UE.in +++ b/Tests/Rivet/LHC/LHC-900-UE.in @@ -1,53 +1,49 @@ ################################################## # select the analyses ################################################## # ATLAS UE insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ATLAS_2011_S8994773 # ATLAS UE insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ATLAS_2010_S8918562 # ATLAS UE insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ATLAS_2010_S8894728 # ATLAS charged particles insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ATLAS_2010_S8591806 # ALICE charged particles insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ALICE_2010_S8706239 # ALICE charged particles insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ALICE_2010_S8625980 # ALICE charged particles insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ALICE_2010_S8624100 # ALICE particle spectra insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ALICE_2011_S8945144 # ALICE strange particle production insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ALICE_2011_S8909580 # CMS particle spectra insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CMS_2011_S8978280 # CMS charged particle multiplicity insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CMS_2011_S8884919 # CMS charged particle pT and rapidity insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CMS_2010_S8547297 # CMS UE insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CMS_2011_S9120041 # LHCB k_s0 insert /Herwig/Analysis/RivetAnalysis:Analyses 0 LHCB_2010_S8758301 # LHCB promt hadron production insert /Herwig/Analysis/RivetAnalysis:Analyses 0 LHCB_2012_I1119400 # CMS forward energy flow insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CMS_2011_S9215166 # LHC K0s/Lambda insert /Herwig/Analysis/RivetAnalysis:Analyses 0 LHCB_2011_I917009 # ATLAS Azimuthal ordering of charged hadrons insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ATLAS_2012_I1091481 # ALICE single/double diffractive and inelastic sigma insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ALICE_2012_I1181770 -# ATLAS inelastic cross section -insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ATLAS_2011_I894867 # underlying event forward rapidities insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CMS_2013_I1218372 -# ATLAS two particle correlation -#insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ATLAS_2012_I1094061 # ATLAS correlations insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ATLAS_2012_I1093734 # ALICE pion and eta pT insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ALICE_2012_I1116147 # CMS charged particle rapidity insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CMS_2010_PAS_QCD_10_024 diff --git a/Tests/python/make_input_files.py b/Tests/python/make_input_files.py --- a/Tests/python/make_input_files.py +++ b/Tests/python/make_input_files.py @@ -1,1938 +1,1938 @@ #! /usr/bin/env python import logging,sys,os from string import strip, Template import sys if sys.version_info[:3] < (2,4,0): print "rivet scripts require Python version >= 2.4.0... exiting" sys.exit(1) if __name__ == "__main__": import logging from optparse import OptionParser, OptionGroup parser = OptionParser(usage="%prog name [...]") simulation="" numberOfAddedProcesses=0 def addProcess(thefactory,theProcess,Oas,Oew,scale,mergedlegs,NLOprocesses): global numberOfAddedProcesses global simulation numberOfAddedProcesses+=1 res ="set "+thefactory+":OrderInAlphaS "+Oas+"\n" res+="set "+thefactory+":OrderInAlphaEW "+Oew+"\n" res+="do "+thefactory+":Process "+theProcess+" " if ( mergedlegs != 0 ): if simulation!="Merging": print "simulation is not Merging, trying to add merged legs." sys.exit(1) res+="[" for j in range(mergedlegs): res+=" j " res+="]" res+="\n" if (NLOprocesses!=0): if simulation!="Merging": print "simulation is not Merging, trying to add NLOProcesses." sys.exit(1) res+="set MergingFactory:NLOProcesses %s \n" % NLOprocesses if ( scale != "" ): res+="set "+thefactory+":ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/"+scale+"\n" return res def addLeptonPairCut(minmass,maxmass): return "set /Herwig/Cuts/LeptonPairMassCut:MinMass "+minmass+"*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass "+maxmass+"*GeV\n" didaddfirstjet=False def addFirstJet(ptcut): global didaddfirstjet if(didaddfirstjet): logging.error("Can only add jetcut once.") sys.exit(1) res="set /Herwig/Cuts/Cuts:JetFinder /Herwig/Cuts/JetFinder\n" res+="insert /Herwig/Cuts/Cuts:MultiCuts 0 /Herwig/Cuts/JetCuts\n" res+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/FirstJet\n" if(ptcut!=""): - res+="set /Herwig/Cuts/FirstJet:PtMin "+ptcut+".*GeV\n" + res+="set /Herwig/Cuts/FirstJet:PtMin "+ptcut+"*GeV\n" didaddfirstjet=True return res didaddsecondjet=False def addSecondJet(ptcut): global didaddsecondjet if(didaddsecondjet): logging.error("Can only add second jetcut once.") sys.exit(1) res="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" - res+="set /Herwig/Cuts/SecondJet:PtMin "+ptcut+".*GeV\n" + res+="set /Herwig/Cuts/SecondJet:PtMin "+ptcut+"*GeV\n" didaddsecondjet=True return res didaddjetpair=False def addJetPairCut(minmass): global didaddjetpair if(didaddjetpair): logging.error("Can only add second jetcut once.") sys.exit(1) res="""\ create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass -set /Herwig/Cuts/JetPairMass:MassMin {mm}.*GeV +set /Herwig/Cuts/JetPairMass:MassMin {mm}*GeV """.format(mm=minmass) didaddjetpair=True return res addedBRReweighter=False def addBRReweighter(): global addedBRReweighter if(addedBRReweighter): logging.error("Can only add BRReweighter once.") sys.exit(1) res="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" res+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" addedBRReweighter=True return res def setHardProcessWidthToZero(list1): res="" for i in list1: res+="set /Herwig/Particles/"+i+":HardProcessWidth 0.\n" return res selecteddecaymode=False def selectDecayMode(particle,decaymodes): global selecteddecaymode res="do /Herwig/Particles/"+particle+":SelectDecayModes" for decay in decaymodes: res+=" /Herwig/Particles/"+particle+"/"+decay res+="\n" selecteddecaymode=True return res def jet_kt_cut(energy): return "set /Herwig/Cuts/JetKtCut:MinKT {E}*GeV\n".format(E=energy) def mhatmin_cut(energy): return "set /Herwig/Cuts/Cuts:MHatMin {E}*GeV\n".format(E=energy) def mhat_minm_maxm(e1,e2,e3): return """\ set /Herwig/Cuts/Cuts:MHatMin {e1}*GeV set /Herwig/Cuts/MassCut:MinM {e2}*GeV set /Herwig/Cuts/MassCut:MaxM {e3}*GeV """.format(**locals()) def collider_lumi(energy): return "set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy {E}*GeV\n".format(E=energy) def insert_ME(me,process=None,ifname='Process',subprocess="SubProcess"): result = "insert /Herwig/MatrixElements/{subprocess}:MatrixElements 0 /Herwig/MatrixElements/{me}\n".format(**locals()) if process is not None: result += "set /Herwig/MatrixElements/{me}:{ifname} {process}".format(**locals()) return result def particlegroup(name,*particles): result = ["do /Herwig/MatrixElements/Matchbox/Factory:StartParticleGroup {n}".format(n=name)] for p in particles: result.append( "insert /Herwig/MatrixElements/Matchbox/Factory:ParticleGroup 0 /Herwig/Particles/{p}".format(p=p) ) result.append("do /Herwig/MatrixElements/Matchbox/Factory:EndParticleGroup") return '\n'.join(result) # settings for four flavour scheme fourFlavour=""" read Matchbox/FourFlavourScheme.in {bjetgroup} set /Herwig/Cuts/MatchboxJetMatcher:Group bjet """.format(bjetgroup=particlegroup('bjet','b','bbar','c', 'cbar', 's','sbar','d','dbar','u','ubar','g')) ME_Upsilon = """\ create Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEUpsilon HwMELepton.so set /Herwig/MatrixElements/MEUpsilon:VectorMeson /Herwig/Particles/Upsilon(4S) set /Herwig/MatrixElements/MEUpsilon:Coupling 96.72794 """ + insert_ME("MEUpsilon") (opts, args) = parser.parse_args() ## Check args if len(args) != 1: logging.error("Must specify at least input file") sys.exit(1) name = args[0] print name # select the template to load # collider KNOWN_COLLIDERS = [ - "GammaGamma", "EE-Gamma", "BFactory", "EE", "DIS", "TVT", "LHC-GammaGamma", "LHC", "ISR", "SppS", "Star", "EHS", + "GammaGamma", ] collider = "" for cand_collider in KNOWN_COLLIDERS: if cand_collider in name: collider = cand_collider break del cand_collider assert collider have_hadronic_collider = collider in ["TVT","LHC","ISR","SppS","Star","EHS"] thefactory="Factory" parameters = { 'shower' : '', 'bscheme' : '', } # istart determines how many name parts need to be skipped istart = 1 # Dipole shower with Matchbox Powheg if "Dipole-Matchbox-Powheg" in name : istart = 4 simulation="Matchbox" parameters["shower"] = "read Matchbox/Powheg-DipoleShower.in\n" # Dipole shower with internal Powheg - Todo: Finish modifying template files. ''' elif "Dipole-Powheg" in name : istart = 3 simulation="Powheg" - parameters["shower"] = "set /Herwig/EventHandlers/EventHandler:CascadeHandler /Herwig/DipoleShower/DipoleShowerHandler\nread snippets/Dipole_AutoTune_prel.in\n" + parameters["shower"] = "set /Herwig/EventHandlers/EventHandler:CascadeHandler /Herwig/DipoleShower/DipoleShowerHandler\nread snippets/Dipole_AutoTunes_gss.in\n" ''' # Dipole shower with MCatNLO elif "Dipole-MCatNLO" in name : istart = 3 simulation="Matchbox" parameters["shower"] = "read Matchbox/MCatNLO-DipoleShower.in\n" # Dipole shower with Matchbox LO elif "Dipole-Matchbox-LO" in name : istart = 4 simulation="Matchbox" parameters["shower"] = "read Matchbox/LO-DipoleShower.in\n" # Dipole shower with internal LO elif "Dipole" in name : istart = 2 simulation="" - parameters["shower"] = "set /Herwig/EventHandlers/EventHandler:CascadeHandler /Herwig/DipoleShower/DipoleShowerHandler\nread snippets/Dipole_AutoTune_prel.in\n" + parameters["shower"] = "set /Herwig/EventHandlers/EventHandler:CascadeHandler /Herwig/DipoleShower/DipoleShowerHandler\nread snippets/Dipole_AutoTunes_gss.in\n" # AO shower with Matchbox Powheg elif "Matchbox-Powheg" in name : istart = 3 simulation="Matchbox" parameters["shower"] = "read Matchbox/Powheg-DefaultShower.in\n" # AO shower with MCatNLO elif "Matchbox" in name : istart = 2 simulation="Matchbox" parameters["shower"] = "read Matchbox/MCatNLO-DefaultShower.in\n" # AO shower with inernal Powheg elif "Powheg" in name : istart = 2 simulation="Powheg" # Dipole shower with merging elif "Merging" in name : istart = 2 simulation="Merging" thefactory="MergingFactory" # Flavour settings for Matchbox if simulation=="Matchbox" : parameters["bscheme"] = "read Matchbox/FiveFlavourScheme.in\n" if "Dipole" in parameters["shower"] : parameters["bscheme"] += "read Matchbox/FiveFlavourNoBMassScheme.in\n" if collider not in ['DIS','EE'] : parameters["nlo"] = "read Matchbox/MadGraph-OpenLoops.in\n" # Flavour settings for dipole shower with internal ME if simulation=="" and "Dipole" in parameters["shower"] : parameters["bscheme"] = "read snippets/DipoleShowerFiveFlavours.in" # find the template if simulation=="" : if collider=="LHC-GammaGamma" : istart += 1 templateName="Hadron-Gamma.in" elif have_hadronic_collider : templateName="Hadron.in" elif collider=="EE-Gamma" : istart+=1 if("Direct" in name) : templateName="EE-Gamma-Direct.in" elif("Single-Resolved" in name) : templateName="EE-Gamma-Single-Resolved.in" elif("Double-Resolved" in name) : templateName="EE-Gamma-Double-Resolved.in" else : print "Unknown type of EE-Gamma event ",name quit() elif collider=="GammaGamma" : templateName="GammaGamma.in" elif collider != "BFactory" : templateName= "%s.in" % collider else : templateName= "EE.in" else : if have_hadronic_collider : templateName= "Hadron-%s.in" % simulation elif collider != "BFactory" : templateName= "%s-%s.in" % (collider,simulation) else : templateName= "EE-%s.in" % simulation # work out the name of the parameter file parameterName="-".join(name.split("-")[istart:]) del istart class StringBuilder(object): """ Avoid expensive string additions until the end by building up a list first. This helper class avoids rewriting all the += lower down to list operations. """ def __init__(self, init = None): self.lines = [] if init is None else [init] def __iadd__(self, line): self.lines.append(line) return self def __str__(self): return '\n'.join(self.lines) # work out the process and parameters process=StringBuilder() # DIS if(collider=="DIS") : if(simulation=="") : if "NoME" in parameterName : process = StringBuilder("set /Herwig/Shower/ShowerHandler:HardEmission None") parameterName=parameterName.replace("NoME-","") else : process = StringBuilder("") elif(simulation=="Powheg") : process = StringBuilder("") elif(simulation=="Matchbox" ) : if "e-" in parameterName : process = StringBuilder(addProcess(thefactory,"e- p -> e- j","0","2","",0,0)) else : process = StringBuilder(addProcess(thefactory,"e+ p -> e+ j","0","2","",0,0)) elif(simulation=="Merging" ) : if "e-" in parameterName : process = StringBuilder(addProcess(thefactory,"e- p -> e- j","0","2","",2,2)) else : process = StringBuilder(addProcess(thefactory,"e+ p -> e+ j","0","2","",2,2)) # EE elif(collider=="EE") : if(simulation=="") : if "gg" in parameterName : process = StringBuilder("create Herwig::MEee2Higgs2SM /Herwig/MatrixElements/MEee2Higgs2SM\n") process+=insert_ME("MEee2Higgs2SM","Gluon","Allowed") else : if(parameterName=="10.58-res") : process += ME_Upsilon elif(parameterName=="10.58") : process += ME_Upsilon process += "set /Herwig/MatrixElements/MEee2gZ2qq:MaximumFlavour 4\n" else : process = StringBuilder(insert_ME("MEee2gZ2qq")) try : ecms = float(parameterName) if(ecms<=10.1) : process+= "set /Herwig/MatrixElements/MEee2gZ2qq:MaximumFlavour 4\n" except : pass elif(simulation=="Powheg") : process = StringBuilder() if(parameterName=="10") : process = StringBuilder() try : ecms = float(parameterName) if(ecms<=10.1) : process+= "set /Herwig/MatrixElements/PowhegMEee2gZ2qq:MaximumFlavour 4\n" except : pass elif(simulation=="Matchbox" ) : try : ecms = float(parameterName) if(ecms<=10.1) : process = StringBuilder(addProcess(thefactory,"e- e+ -> u ubar","0","2","",0,0)) process+=addProcess(thefactory,"e- e+ -> d dbar","0","2","",0,0) process+=addProcess(thefactory,"e- e+ -> c cbar","0","2","",0,0) process+=addProcess(thefactory,"e- e+ -> s sbar","0","2","",0,0) else : process = StringBuilder(addProcess(thefactory,"e- e+ -> j j","0","2","",0,0)) except: process = StringBuilder(addProcess(thefactory,"e- e+ -> j j","0","2","",0,0)) elif(simulation=="Merging" ) : try : ecms = float(parameterName) if(ecms<=10.1) : process = StringBuilder(addProcess(thefactory,"e- e+ -> j j","0","2","",2,2)) process+="read Matchbox/FourFlavourScheme.in" else : process = StringBuilder(addProcess(thefactory,"e- e+ -> j j","0","2","",2,2)) except: process = StringBuilder(addProcess(thefactory,"e- e+ -> j j","0","2","",2,2)) # EE-Gamma elif(collider=="EE-Gamma") : if(simulation=="") : if("mumu" in parameterName) : process = StringBuilder(insert_ME("MEgg2ff","Muon")) process +="set /Herwig/Cuts/Cuts:MHatMin 3.\n" elif( "tautau" in parameterName) : process = StringBuilder(insert_ME("MEgg2ff","Tau")) process +="set /Herwig/Cuts/Cuts:MHatMin 3.\n" elif( "Jets" in parameterName) : if("Direct" in parameterName ) : process = StringBuilder(insert_ME("MEgg2ff","Quarks")) elif("Single-Resolved" in parameterName ) : process = StringBuilder(insert_ME("MEGammaP2Jets",None,"Process","SubProcess")) process+= insert_ME("MEGammaP2Jets",None,"Process","SubProcess2") else : process = StringBuilder(insert_ME("MEQCD2to2")) process+="insert /Herwig/Cuts/Cuts:OneCuts[0] /Herwig/Cuts/JetKtCut" process+="set /Herwig/Cuts/JetKtCut:MinKT 3." else : print "process not supported for Gamma Gamma processes at EE" quit() else : print "Only internal matrix elements currently supported for Gamma Gamma processes at EE" quit() elif(collider=="GammaGamma") : if(simulation=="") : if("mumu" in parameterName) : process = StringBuilder(insert_ME("MEgg2ff")) process +="set /Herwig/MatrixElements/MEgg2ff:Process Muon\n" process +="set /Herwig/Cuts/Cuts:MHatMin 3.\n" else : print "process not supported for Gamma Gamma processes at EE" quit() else : print "Only internal matrix elements currently supported for Gamma Gamma processes at EE" quit() # TVT elif(collider=="TVT") : process = StringBuilder("set /Herwig/Generators/EventGenerator:EventHandler:BeamB /Herwig/Particles/pbar-\n") if "Run-II" in parameterName : process+=collider_lumi(1960.0) elif "Run-I" in parameterName : process+=collider_lumi(1800.0) elif "900" in parameterName : process+=collider_lumi(900.0) elif "630" in parameterName : process+=collider_lumi(630.0) elif "300" in parameterName : process+=collider_lumi(300.0) if(simulation=="") : if "PromptPhoton" in parameterName : process+=insert_ME("MEGammaJet") process+="set /Herwig/Cuts/PhotonKtCut:MinKT 15.\n" elif "DiPhoton-GammaGamma" in parameterName : process+=insert_ME("MEGammaGamma") process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n" parameterName=parameterName.replace("-GammaGamma","") elif "DiPhoton-GammaJet" in parameterName : process+=insert_ME("MEGammaJet") process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n" parameterName=parameterName.replace("-GammaJet","") elif "UE" in parameterName : if "Dipole" in parameters["shower"]: process+="read snippets/MB-DipoleShower.in\n" else: process+="read snippets/MB.in\n" process+="read snippets/Diffraction.in\n" process += "set /Herwig/Decays/DecayHandler:LifeTimeOption 0\n" process += "set /Herwig/Decays/DecayHandler:MaxLifeTime 10*mm\n" elif "Jets" in parameterName : process+=insert_ME("MEQCD2to2") process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" if "Run-II-Jets-10" in parameterName : process+=jet_kt_cut( 30.)+mhatmin_cut(500.) elif "Run-II-Jets-11" in parameterName: process+=jet_kt_cut( 30.)+mhatmin_cut(900.) elif "Run-I-Jets-1" in parameterName : process+=jet_kt_cut( 20.) elif "Run-I-Jets-2" in parameterName : process+=jet_kt_cut( 40.) elif "Run-I-Jets-3" in parameterName : process+=jet_kt_cut( 65.) elif "Run-I-Jets-4" in parameterName : process+=jet_kt_cut( 90.) elif "Run-I-Jets-5" in parameterName : process+=jet_kt_cut(160.) elif "Run-I-Jets-6" in parameterName : process+=jet_kt_cut( 30.)+mhatmin_cut(100.) elif "Run-I-Jets-7" in parameterName : process+=jet_kt_cut( 30.)+mhatmin_cut(400.) elif "Run-I-Jets-8" in parameterName : process+=jet_kt_cut( 30.)+mhatmin_cut(700.) elif "Run-II-Jets-0" in parameterName : process+=jet_kt_cut( 15.) elif "Run-II-Jets-1" in parameterName : process+=jet_kt_cut( 25.) elif "Run-II-Jets-2" in parameterName : process+=jet_kt_cut( 40.) elif "Run-II-Jets-3" in parameterName : process+=jet_kt_cut( 60.) elif "Run-II-Jets-4" in parameterName : process+=jet_kt_cut( 85.) elif "Run-II-Jets-5" in parameterName : process+=jet_kt_cut(110.) elif "Run-II-Jets-6" in parameterName : process+=jet_kt_cut(160.) elif "Run-II-Jets-7" in parameterName : process+=jet_kt_cut(250.) elif "Run-II-Jets-8" in parameterName : process+=jet_kt_cut( 30.)+mhatmin_cut(100.) elif "Run-II-Jets-9" in parameterName : process+=jet_kt_cut( 30.)+mhatmin_cut(300.) elif "900-Jets-1" in parameterName : process+=jet_kt_cut( 10.) elif "300-Jets-1" in parameterName : process+=jet_kt_cut( 6.) elif "630-Jets-1" in parameterName : process+=jet_kt_cut( 20.) elif "630-Jets-2" in parameterName : process+=jet_kt_cut( 40.) elif "630-Jets-3" in parameterName : process+=jet_kt_cut( 75.) elif "900-Jets-1" in parameterName : process+=jet_kt_cut( 10.) elif "Run-I-WZ" in parameterName : process+=insert_ME("MEqq2W2ff","Electron") process+=insert_ME("MEqq2gZ2ff","Electron") elif "Run-II-W" in parameterName or "Run-I-W" in parameterName : process+=insert_ME("MEqq2W2ff","Electron") elif "Run-II-Z-e" in parameterName or "Run-I-Z" in parameterName : process +=insert_ME("MEqq2gZ2ff","Electron") elif "Run-II-Z-LowMass-mu" in parameterName : process +=insert_ME("MEqq2gZ2ff","Muon") process+=addLeptonPairCut("25","70") elif "Run-II-Z-HighMass-mu" in parameterName : process +=insert_ME("MEqq2gZ2ff","Muon") process+=addLeptonPairCut("150","600") elif "Run-II-Z-mu" in parameterName : process +=insert_ME("MEqq2gZ2ff","Muon") elif(simulation=="Powheg") : if "Run-I-WZ" in parameterName : process+=insert_ME("PowhegMEqq2W2ff","Electron") process+=insert_ME("PowhegMEqq2gZ2ff","Electron") elif "Run-II-W" in parameterName or "Run-I-W" in parameterName : process+=insert_ME("PowhegMEqq2W2ff","Electron") elif "Run-II-Z-e" in parameterName or "Run-I-Z" in parameterName : process+=insert_ME("PowhegMEqq2gZ2ff","Electron") elif "Run-II-Z-LowMass-mu" in parameterName : process+=insert_ME("PowhegMEqq2gZ2ff","Muon") process+=addLeptonPairCut("25","70") elif "Run-II-Z-HighMass-mu" in parameterName : process+=insert_ME("PowhegMEqq2gZ2ff","Muon") process+=addLeptonPairCut("150","600") elif "Run-II-Z-mu" in parameterName : process+=insert_ME("PowhegMEqq2gZ2ff","Muon") elif "DiPhoton-GammaGamma" in parameterName : process+=insert_ME("MEGammaGammaPowheg","GammaGamma") process+=insert_ME("MEGammaGamma","gg") process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n" process+=jet_kt_cut(5.) parameterName=parameterName.replace("-GammaGamma","") elif "DiPhoton-GammaJet" in parameterName : process+=insert_ME("MEGammaGammaPowheg","VJet") process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n" process+=jet_kt_cut(5.) parameterName=parameterName.replace("-GammaJet","") elif(simulation=="Matchbox" or simulation=="Merging" ) : if "Jets" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p -> j j","2","0","MaxJetPtScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p -> j j","2","0","MaxJetPtScale",1,0) process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" if "Run-II-Jets-10" in parameterName : process+=addFirstJet("30") process+=addSecondJet("25") process+=addJetPairCut("500") elif "Run-II-Jets-11" in parameterName : process+=addFirstJet("30") process+=addSecondJet("25") process+=addJetPairCut("900") elif "Run-II-Jets-12" in parameterName : process+=addFirstJet("30") process+=addSecondJet("25") process+=addJetPairCut("300") elif "Run-I-Jets-1" in parameterName : process+=addFirstJet("20") elif "Run-I-Jets-2" in parameterName : process+=addFirstJet("40") elif "Run-I-Jets-3" in parameterName : process+=addFirstJet("65") elif "Run-I-Jets-4" in parameterName : process+=addFirstJet("90") elif "Run-I-Jets-5" in parameterName : process+=addFirstJet("160") elif "Run-I-Jets-6" in parameterName : process+=addFirstJet("30")+addSecondJet("25")+addJetPairCut("100") elif "Run-I-Jets-7" in parameterName : process+=addFirstJet("30")+addSecondJet("25")+addJetPairCut("400") elif "Run-I-Jets-8" in parameterName : process+=addFirstJet("30")+addSecondJet("25")+addJetPairCut("700") elif "Run-II-Jets-0" in parameterName : process+=addFirstJet("15") elif "Run-II-Jets-1" in parameterName : process+=addFirstJet("25") elif "Run-II-Jets-2" in parameterName : process+=addFirstJet("40") elif "Run-II-Jets-3" in parameterName : process+=addFirstJet("60") elif "Run-II-Jets-4" in parameterName : process+=addFirstJet("85") elif "Run-II-Jets-5" in parameterName : process+=addFirstJet("110") elif "Run-II-Jets-6" in parameterName : process+=addFirstJet("160") elif "Run-II-Jets-7" in parameterName : process+=addFirstJet("250") elif "Run-II-Jets-8" in parameterName : process+=addFirstJet("30")+addSecondJet("25")+addJetPairCut("100") elif "Run-II-Jets-9" in parameterName : process+=addFirstJet("30")+addSecondJet("25")+addJetPairCut("300") elif "900-Jets-1" in parameterName : process+=addFirstJet("10") elif "300-Jets-1" in parameterName : process+=addFirstJet("6") elif "630-Jets-1" in parameterName : process+=addFirstJet("20") elif "630-Jets-2" in parameterName : process+=addFirstJet("40") elif "630-Jets-3" in parameterName : process+=addFirstJet("75") elif "900-Jets-1" in parameterName : process+=addFirstJet("10") else : logging.error("Exit 00007") sys.exit(1) elif "Run-I-WZ" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p pbar e+ e-","0","2","LeptonPairMassScale",0,0) process+=addProcess(thefactory,"p pbar e+ nu","0","2","LeptonPairMassScale",0,0) process+=addProcess(thefactory,"p pbar e- nu","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=particlegroup('epm','e+','e-') process+=particlegroup('epmnu','e+','e-','nu_e','nu_ebar') process+=addProcess(thefactory,"p pbar epm epmnu","0","2","LeptonPairMassScale",2,2) process+=addLeptonPairCut("60","120") elif "Run-II-W" in parameterName or "Run-I-W" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p pbar e+ nu","0","2","LeptonPairMassScale",0,0) process+=addProcess(thefactory,"p pbar e- nu","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=particlegroup('epm','e+','e-') process+=addProcess(thefactory,"p pbar epm nu","0","2","LeptonPairMassScale",2,2) process+=addLeptonPairCut("60","120") elif "Run-II-Z-e" in parameterName or "Run-I-Z" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p pbar e+ e-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p pbar e+ e-","0","2","LeptonPairMassScale",2,2) process+=addLeptonPairCut("60","120") elif "Run-II-Z-LowMass-mu" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p pbar mu+ mu-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p pbar mu+ mu-","0","2","LeptonPairMassScale",2,2) process+=addLeptonPairCut("25","70") elif "Run-II-Z-HighMass-mu" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p pbar mu+ mu-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p pbar mu+ mu-","0","2","LeptonPairMassScale",2,2) process+=addLeptonPairCut("150","600") elif "Run-II-Z-mu" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p pbar mu+ mu-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p pbar mu+ mu-","0","2","LeptonPairMassScale",2,2) process+=addLeptonPairCut("60","120") # Star elif(collider=="Star" ) : process = StringBuilder("set /Herwig/Decays/DecayHandler:LifeTimeOption 0\n") process+= "set /Herwig/Decays/DecayHandler:MaxLifeTime 10*mm\n" process+= "set /Herwig/Generators/EventGenerator:EventHandler:BeamB /Herwig/Particles/p+\n" process+= collider_lumi(200.0) process+= "set /Herwig/Cuts/Cuts:X2Min 0.01\n" if(simulation=="") : if "UE" in parameterName : if "Dipole" in parameters["shower"]: process+="read snippets/MB-DipoleShower.in\n" else: process+="read snippets/MB.in\n" process+="read snippets/Diffraction.in\n" else : process+=insert_ME("MEQCD2to2") process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" if "Jets-1" in parameterName : process+=jet_kt_cut(2.) elif "Jets-2" in parameterName : process+=jet_kt_cut(5.) elif "Jets-3" in parameterName : process+=jet_kt_cut(20.) elif "Jets-4" in parameterName : process+=jet_kt_cut(25.) else : logging.error("Star not supported for %s " % simulation) sys.exit(1) # ISR and SppS elif(collider=="ISR" or collider =="SppS" or collider == "EHS" ) : process = StringBuilder("set /Herwig/Decays/DecayHandler:LifeTimeOption 0\n") process+="set /Herwig/Decays/DecayHandler:MaxLifeTime 10*mm\n" if(collider=="SppS") : process = StringBuilder("set /Herwig/Generators/EventGenerator:EventHandler:BeamB /Herwig/Particles/pbar-\n") if "30" in parameterName : process+=collider_lumi( 30.4) elif "44" in parameterName : process+=collider_lumi( 44.4) elif "53" in parameterName : process+=collider_lumi( 53.0) elif "62" in parameterName : process+=collider_lumi( 62.2) elif "63" in parameterName : process+=collider_lumi( 63.0) elif "200" in parameterName : process+=collider_lumi(200.0) elif "500" in parameterName : process+=collider_lumi(500.0) elif "546" in parameterName : process+=collider_lumi(546.0) elif "900" in parameterName : process+=collider_lumi(900.0) if(simulation=="") : if "Dipole" in parameters["shower"]: process+="read snippets/MB-DipoleShower.in\n" else: process+="read snippets/MB.in\n" process+="read snippets/Diffraction.in\n" else : logging.error(" SppS and ISR not supported for %s " % simulation) sys.exit(1) # LHC elif(collider=="LHC") : if parameterName.startswith("7-") : process = StringBuilder(collider_lumi(7000.0)) elif parameterName.startswith("8-") : process = StringBuilder(collider_lumi(8000.0)) elif parameterName.startswith("13-") : process = StringBuilder(collider_lumi(13000.0)) elif parameterName.startswith("900") : process = StringBuilder(collider_lumi(900.0)) elif parameterName.startswith("2360") : process = StringBuilder(collider_lumi(2360.0)) elif parameterName.startswith("2760") : process = StringBuilder(collider_lumi(2760.0)) else : process = StringBuilder(collider_lumi(7000.0)) if(simulation=="") : if "VBF" in parameterName : process+=insert_ME("MEPP2HiggsVBF") if "GammaGamma" in parameterName : process+=selectDecayMode("h0",["h0->gamma,gamma;"]) addedBRReweighter = True elif "WW" in parameterName : process+=selectDecayMode("h0",["h0->W+,W-;"]) addedBRReweighter = True elif "ZZ" in parameterName : process+=selectDecayMode("h0",["h0->Z0,Z0;"]) addedBRReweighter = True elif "8-" not in parameterName : process+=selectDecayMode("h0",["h0->tau-,tau+;"]) addedBRReweighter = True process+="set /Herwig/Particles/tau-:Stable Stable\n" elif "ggHJet" in parameterName : process+=selectDecayMode("h0",["h0->tau-,tau+;"]) addedBRReweighter = True process+="set /Herwig/Particles/tau-:Stable Stable\n" process+=insert_ME("MEHiggsJet") process+=jet_kt_cut(20.) elif "ggH" in parameterName : process+=insert_ME("MEHiggs") process+=insert_ME("MEHiggsJet","qqbar") process+=jet_kt_cut(0.0) if "GammaGamma" in parameterName : process+=selectDecayMode("h0",["h0->gamma,gamma;"]) addedBRReweighter = True elif "WW" in parameterName : process+=selectDecayMode("h0",["h0->W+,W-;"]) addedBRReweighter = True elif "ZZ" in parameterName : process+=selectDecayMode("h0",["h0->Z0,Z0;"]) addedBRReweighter = True elif "8-" not in parameterName : process+=selectDecayMode("h0",["h0->tau-,tau+;"]) addedBRReweighter = True process+="set /Herwig/Particles/tau-:Stable Stable\n" elif "PromptPhoton" in parameterName : process+=insert_ME("MEGammaJet") if "PromptPhoton-1" in parameterName : process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n" elif "PromptPhoton-2" in parameterName : process+="set /Herwig/Cuts/PhotonKtCut:MinKT 25.\n" elif "PromptPhoton-3" in parameterName : process+="set /Herwig/Cuts/PhotonKtCut:MinKT 80.\n" elif "PromptPhoton-4" in parameterName : process+="set /Herwig/Cuts/PhotonKtCut:MinKT 150.\n" elif "DiPhoton-GammaGamma" in parameterName : process+=insert_ME("MEGammaGamma") process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n" parameterName=parameterName.replace("-GammaGamma","") elif "DiPhoton-GammaJet" in parameterName : process+=insert_ME("MEGammaJet") process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n" parameterName=parameterName.replace("-GammaJet","") elif "8-WH" in parameterName : process+=insert_ME("MEPP2WH") process+=jet_kt_cut(0.0) if "GammaGamma" in parameterName : process+=selectDecayMode("h0",["h0->gamma,gamma;"]) addedBRReweighter = True elif "WW" in parameterName : process+=selectDecayMode("h0",["h0->W+,W-;"]) addedBRReweighter = True elif "ZZ" in parameterName : process+=selectDecayMode("h0",["h0->Z0,Z0;"]) addedBRReweighter = True elif "8-ZH" in parameterName : process+=insert_ME("MEPP2ZH") process+=jet_kt_cut(0.0) if "GammaGamma" in parameterName : process+=selectDecayMode("h0",["h0->gamma,gamma;"]) addedBRReweighter = True elif "WW" in parameterName : process+=selectDecayMode("h0",["h0->W+,W-;"]) addedBRReweighter = True elif "ZZ" in parameterName : process+=selectDecayMode("h0",["h0->Z0,Z0;"]) addedBRReweighter = True elif "WH" in parameterName : process+=selectDecayMode("h0",["h0->b,bbar;"]) process+=selectDecayMode("W+",["W+->nu_e,e+;", "W+->nu_mu,mu+;"]) addedBRReweighter = True process+=insert_ME("MEPP2WH") process+=jet_kt_cut(0.0) elif "ZH" in parameterName : process+=selectDecayMode("h0",["h0->b,bbar;"]) process+=selectDecayMode("Z0",["Z0->e-,e+;", "Z0->mu-,mu+;"]) addedBRReweighter = True process+=insert_ME("MEPP2ZH") process+=jet_kt_cut(0.0) elif "UE" in parameterName : if "Dipole" in parameters["shower"]: process+="read snippets/MB-DipoleShower.in\n" else: process+="set /Herwig/Shower/ShowerHandler:IntrinsicPtGaussian 2.2*GeV\n" process+="read snippets/MB.in\n" process+="read snippets/Diffraction.in\n" if "Long" in parameterName : process += "set /Herwig/Decays/DecayHandler:MaxLifeTime 100*mm\n" elif "8-DiJets" in parameterName or "7-DiJets" in parameterName or "13-DiJets" in parameterName : process+=insert_ME("MEQCD2to2") process+="set MEQCD2to2:MaximumFlavour 5\n" process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" if "13-DiJets" not in parameterName : if "-A" in parameterName : process+=jet_kt_cut(45.) process+="set /Herwig/Cuts/JetKtCut:MinEta -3.\n" process+="set /Herwig/Cuts/JetKtCut:MaxEta 3.\n" elif "-B" in parameterName : process+=jet_kt_cut(20.) process+="set /Herwig/Cuts/JetKtCut:MinEta -2.7\n" process+="set /Herwig/Cuts/JetKtCut:MaxEta 2.7\n" elif "-C" in parameterName : process+=jet_kt_cut(20.) process+="set /Herwig/Cuts/JetKtCut:MinEta -4.8\n" process+="set /Herwig/Cuts/JetKtCut:MaxEta 4.8\n" else : if "-A" in parameterName : process+=jet_kt_cut(60.) process+="set /Herwig/Cuts/JetKtCut:MinEta -3.\n" process+="set /Herwig/Cuts/JetKtCut:MaxEta 3.\n" elif "-B" in parameterName : process+=jet_kt_cut(180.) process+="set /Herwig/Cuts/JetKtCut:MinEta -3.\n" process+="set /Herwig/Cuts/JetKtCut:MaxEta 3.\n" if "DiJets-1" in parameterName : process+=mhatmin_cut(90.) elif "DiJets-2" in parameterName : process+=mhatmin_cut(200.) elif "DiJets-3" in parameterName : process+=mhatmin_cut(450.) elif "DiJets-4" in parameterName : process+=mhatmin_cut(750.) elif "DiJets-5" in parameterName : process+=mhatmin_cut(950.) elif "DiJets-6" in parameterName : process+=mhatmin_cut(1550.) elif "DiJets-7" in parameterName : process+=mhatmin_cut(2150.) elif "DiJets-8" in parameterName : process+=mhatmin_cut(2750.) elif "DiJets-9" in parameterName : process+=mhatmin_cut(3750.) elif "DiJets-10" in parameterName : process+=mhatmin_cut(4750.) elif "DiJets-11" in parameterName : process+=mhatmin_cut(5750.) elif( "7-Jets" in parameterName or "8-Jets" in parameterName or "13-Jets" in parameterName or "2760-Jets" in parameterName ) : process+=insert_ME("MEQCD2to2") process+="set MEQCD2to2:MaximumFlavour 5\n" process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" if "Jets-10" in parameterName : process+=jet_kt_cut(1800.) elif "Jets-0" in parameterName : process+=jet_kt_cut(5.) elif "Jets-1" in parameterName : process+=jet_kt_cut(10.) elif "Jets-2" in parameterName : process+=jet_kt_cut(20.) elif "Jets-3" in parameterName : process+=jet_kt_cut(40.) elif "Jets-4" in parameterName : process+=jet_kt_cut(70.) elif "Jets-5" in parameterName : process+=jet_kt_cut(150.) elif "Jets-6" in parameterName : process+=jet_kt_cut(200.) elif "Jets-7" in parameterName : process+=jet_kt_cut(300.) elif "Jets-8" in parameterName : process+=jet_kt_cut(500.) elif "Jets-9" in parameterName : process+=jet_kt_cut(800.) elif( "7-Charm" in parameterName or "7-Bottom" in parameterName or "8-Bottom" in parameterName) : if("8-Bottom" in parameterName) : addBRReweighter() process+=selectDecayMode("Jpsi",["Jpsi->mu-,mu+;"]) if "Bottom" in parameterName : process+="cp MEHeavyQuark MEBottom\n" process+="set MEBottom:QuarkType Bottom\n" process+=insert_ME("MEBottom") else : process+="cp MEHeavyQuark MECharm\n" process+="set MECharm:QuarkType Charm\n" process+=insert_ME("MECharm") process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" if "-0" in parameterName : if "Bottom" in parameterName : process+="set MEBottom:Process Pair\n" process+=jet_kt_cut(0.) elif "-1" in parameterName : process+=jet_kt_cut(5.) elif "-2" in parameterName : process+=jet_kt_cut(15.) elif "-3" in parameterName : process+=jet_kt_cut(20.) elif "-4" in parameterName : process+=jet_kt_cut(50.) elif "-5" in parameterName : process+=jet_kt_cut(80.) elif "-6" in parameterName : process+=jet_kt_cut(110.) elif "-7" in parameterName : process+=jet_kt_cut(30.)+mhatmin_cut(90.) elif "-8" in parameterName : process+=jet_kt_cut(30.)+mhatmin_cut(340.) elif "-9" in parameterName : process+=jet_kt_cut(30.)+mhatmin_cut(500.) elif "Top-L" in parameterName : process+="set MEHeavyQuark:QuarkType Top\n" process+=insert_ME("MEHeavyQuark") process+=selectDecayMode("t",["t->nu_e,e+,b;", "t->nu_mu,mu+,b;"]) process+=addBRReweighter() elif "Top-SL" in parameterName : process+="set MEHeavyQuark:QuarkType Top\n" process+=insert_ME("MEHeavyQuark") process+="set /Herwig/Particles/t:Synchronized Not_synchronized\n" process+="set /Herwig/Particles/tbar:Synchronized Not_synchronized\n" process+=selectDecayMode("t",["t->nu_e,e+,b;","t->nu_mu,mu+,b;"]) process+=selectDecayMode("tbar",["tbar->b,bbar,cbar;", "tbar->bbar,cbar,d;", "tbar->bbar,cbar,s;", "tbar->bbar,s,ubar;", "tbar->bbar,ubar,d;"]) process+=addBRReweighter() elif "Top-All" in parameterName : process+="set MEHeavyQuark:QuarkType Top\n" process+=insert_ME("MEHeavyQuark") elif "WZ" in parameterName : process+=insert_ME("MEPP2VV","WZ") process+=selectDecayMode("W+",["W+->nu_e,e+;", "W+->nu_mu,mu+;"]) process+=selectDecayMode("W-",["W-->nu_ebar,e-;", "W-->nu_mubar,mu-;"]) process+=selectDecayMode("Z0",["Z0->e-,e+;", "Z0->mu-,mu+;"]) addedBRReweighter = True elif "WW-emu" in parameterName : process+=insert_ME("MEPP2VV","WW") process+="set /Herwig/Particles/W+:Synchronized 0\n" process+="set /Herwig/Particles/W-:Synchronized 0\n" process+=selectDecayMode("W+",["W+->nu_e,e+;"]) process+=selectDecayMode("W-",["W-->nu_mubar,mu-;"]) addedBRReweighter = True elif "WW-ll" in parameterName : process+=insert_ME("MEPP2VV","WW") process+=selectDecayMode("W+",["W+->nu_e,e+;","W+->nu_mu,mu+;","W+->nu_tau,tau+;"]) addedBRReweighter = True elif "ZZ-ll" in parameterName : process+=insert_ME("MEPP2VV","ZZ") process+=selectDecayMode("Z0",["Z0->e-,e+;", "Z0->mu-,mu+;", "Z0->tau-,tau+;"]) addedBRReweighter = True elif "ZZ-lv" in parameterName : process+=insert_ME("MEPP2VV","ZZ") process+=selectDecayMode("Z0",["Z0->e-,e+;", "Z0->mu-,mu+;", "Z0->tau-,tau+;", "Z0->nu_e,nu_ebar;", "Z0->nu_mu,nu_mubar;", "Z0->nu_tau,nu_taubar;"]) addedBRReweighter = True elif "W-Z-e" in parameterName : process+=insert_ME("MEqq2gZ2ff","Electron") process+=insert_ME("MEqq2W2ff","Electron") elif "W-Z-mu" in parameterName : process+=insert_ME("MEqq2gZ2ff","Muon") process+=insert_ME("MEqq2W2ff","Muon") elif "W-e" in parameterName : process+=insert_ME("MEqq2W2ff","Electron") elif "W-mu" in parameterName : process+=insert_ME("MEqq2W2ff","Muon") elif "Z-e" in parameterName : process+=insert_ME("MEqq2gZ2ff","Electron") elif "Z-mu" in parameterName : process+=insert_ME("MEqq2gZ2ff","Muon") elif "Z-LowMass-e" in parameterName : process+=insert_ME("MEqq2gZ2ff","Electron") process+=mhat_minm_maxm(20,20,70) elif "Z-MedMass-e" in parameterName : process+=insert_ME("MEqq2gZ2ff","Electron") process+=mhat_minm_maxm(40,40,130) elif "Z-LowMass-mu" in parameterName : process+=insert_ME("MEqq2gZ2ff","Muon") process+=mhat_minm_maxm(10,10,70) elif "Z-Mass1" in parameterName : process+=mhat_minm_maxm(10,10,35) if "-e" in parameterName : process+=insert_ME("MEqq2gZ2ff","Electron") else : process+=insert_ME("MEqq2gZ2ff","Muon") elif "Z-Mass2" in parameterName : process+=mhat_minm_maxm(25,25,70) if "-e" in parameterName : process+=insert_ME("MEqq2gZ2ff","Electron") else : process+=insert_ME("MEqq2gZ2ff","Muon") elif "Z-Mass3" in parameterName : process+=mhat_minm_maxm(60,60,120) if "-e" in parameterName : process+=insert_ME("MEqq2gZ2ff","Electron") else : process+=insert_ME("MEqq2gZ2ff","Muon") elif "Z-Mass4" in parameterName : process+=mhat_minm_maxm(110,110,8000) if "-e" in parameterName : process+=insert_ME("MEqq2gZ2ff","Electron") else : process+=insert_ME("MEqq2gZ2ff","Muon") elif "Z-HighMass1" in parameterName : process+=mhat_minm_maxm(116,116,400) if "-e" in parameterName : process+=insert_ME("MEqq2gZ2ff","Electron") else : process+=insert_ME("MEqq2gZ2ff","Muon") elif "Z-HighMass2" in parameterName : process+=mhat_minm_maxm(400,400,7000) if "-e" in parameterName : process+=insert_ME("MEqq2gZ2ff","Electron") else : process+=insert_ME("MEqq2gZ2ff","Muon") elif "W-Jet" in parameterName : process+=insert_ME("MEWJet","Electron","WDecay") if "W-Jet-1-e" in parameterName : process+="set /Herwig/Cuts/WBosonKtCut:MinKT 100.0*GeV\n" parameterName=parameterName.replace("W-Jet-1-e","W-Jet-e") elif "W-Jet-2-e" in parameterName : process+="set /Herwig/Cuts/WBosonKtCut:MinKT 190.0*GeV\n" parameterName=parameterName.replace("W-Jet-2-e","W-Jet-e") elif "W-Jet-3-e" in parameterName : process+="set /Herwig/Cuts/WBosonKtCut:MinKT 270.0*GeV\n" parameterName=parameterName.replace("W-Jet-3-e","W-Jet-e") elif "Z-Jet" in parameterName : if "-e" in parameterName : process+=insert_ME("MEZJet","Electron","ZDecay") if "Z-Jet-0-e" in parameterName : process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 35.0*GeV\n" parameterName=parameterName.replace("Z-Jet-0-e","Z-Jet-e") elif "Z-Jet-1-e" in parameterName : process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 100.0*GeV\n" parameterName=parameterName.replace("Z-Jet-1-e","Z-Jet-e") elif "Z-Jet-2-e" in parameterName : process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 190.0*GeV\n" parameterName=parameterName.replace("Z-Jet-2-e","Z-Jet-e") elif "Z-Jet-3-e" in parameterName : process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 270.0*GeV\n" parameterName=parameterName.replace("Z-Jet-3-e","Z-Jet-e") else : process+=insert_ME("MEZJet","Muon","ZDecay") process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 35.0*GeV\n" parameterName=parameterName.replace("Z-Jet-0-mu","Z-Jet-mu") elif "WGamma" in parameterName : process+=insert_ME("MEPP2VGamma","1") process+="set MEPP2VGamma:MassOption 1" process+="set /Herwig/Cuts/PhotonKtCut:MinKT 10.\n" if "-e" in parameterName : process+=selectDecayMode("W+",["W+->nu_e,e+;"]) addedBRReweighter=True else : process+=selectDecayMode("W+",["W+->nu_mu,mu+;"]) addedBRReweighter=True elif "ZGamma" in parameterName : process+=insert_ME("MEPP2VGamma","2") process+="set /Herwig/Cuts/PhotonKtCut:MinKT 10.\n" if "-e" in parameterName : process+=selectDecayMode("Z0",["Z0->e-,e+;"]) addedBRReweighter=True else : process+=selectDecayMode("Z0",["Z0->mu-,mu+;"]) addedBRReweighter=True else : logging.error(" Process %s not supported for internal matrix elements" % name) sys.exit(1) elif(simulation=="Powheg") : if "VBF" in parameterName : process+=insert_ME("PowhegMEPP2HiggsVBF") if "GammaGamma" in parameterName : process+=selectDecayMode("h0",["h0->gamma,gamma;"]) addedBRReweighter = True elif "WW" in parameterName : process+=selectDecayMode("h0",["h0->W+,W-;"]) addedBRReweighter = True elif "ZZ" in parameterName : process+=selectDecayMode("h0",["h0->Z0,Z0;"]) addedBRReweighter = True elif "8-" not in parameterName : process+=selectDecayMode("h0",["h0->tau-,tau+;"]) addedBRReweighter = True process+="set /Herwig/Particles/tau-:Stable Stable\n" elif "ggHJet" in parameterName : logging.error(" Process %s not supported for POWHEG matrix elements" % name) sys.exit(1) elif "ggH" in parameterName : process+=insert_ME("PowhegMEHiggs") if "GammaGamma" in parameterName : process+=selectDecayMode("h0",["h0->gamma,gamma;"]) addedBRReweighter = True elif "WW" in parameterName : process+=selectDecayMode("h0",["h0->W+,W-;"]) addedBRReweighter = True elif "ZZ" in parameterName : process+=selectDecayMode("h0",["h0->Z0,Z0;"]) addedBRReweighter = True elif "8-" not in parameterName : process+=selectDecayMode("h0",["h0->tau-,tau+;"]) addedBRReweighter = True process+="set /Herwig/Particles/tau-:Stable Stable\n" elif "8-WH" in parameterName : process+=insert_ME("PowhegMEPP2WH") process+=jet_kt_cut(0.0) if "GammaGamma" in parameterName : process+=selectDecayMode("h0",["h0->gamma,gamma;"]) addedBRReweighter = True elif "WW" in parameterName : process+=selectDecayMode("h0",["h0->W+,W-;"]) addedBRReweighter = True elif "ZZ" in parameterName : process+=selectDecayMode("h0",["h0->Z0,Z0;"]) addedBRReweighter = True elif "8-ZH" in parameterName : process+=insert_ME("PowhegMEPP2ZH") process+=jet_kt_cut(0.0) if "GammaGamma" in parameterName : process+=selectDecayMode("h0",["h0->gamma,gamma;"]) addedBRReweighter = True elif "WW" in parameterName : process+=selectDecayMode("h0",["h0->W+,W-;"]) addedBRReweighter = True elif "ZZ" in parameterName : process+=selectDecayMode("h0",["h0->Z0,Z0;"]) addedBRReweighter = True elif "WH" in parameterName : process+=selectDecayMode("h0",["h0->b,bbar;"]) process+=selectDecayMode("W+",["W+->nu_e,e+;", "W+->nu_mu,mu+;"]) addedBRReweighter = True process+=insert_ME("PowhegMEPP2WH") process+=jet_kt_cut(0.0) elif "ZH" in parameterName : process+=selectDecayMode("h0",["h0->b,bbar;"]) process+=selectDecayMode("Z0",["Z0->e-,e+;", "Z0->mu-,mu+;"]) addedBRReweighter = True process+=insert_ME("PowhegMEPP2ZH") process+=jet_kt_cut(0.0) elif "UE" in parameterName : logging.error(" Process %s not supported for powheg matrix elements" % name) sys.exit(1) elif "WZ" in parameterName : process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n" process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n" process+="set /Herwig/Shower/ShowerHandler:SplitHardProcess No\n"; process+="set /Herwig/Decays/ZDecayer:PhotonGenerator NULL\n"; process+="set /Herwig/Decays/WDecayer:PhotonGenerator NULL\n"; process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n" process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n" process+=insert_ME("PowhegMEPP2VV","WZ") process+=selectDecayMode("W+",["W+->nu_e,e+;", "W+->nu_mu,mu+;"]) process+=selectDecayMode("W-",["W-->nu_ebar,e-;", "W-->nu_mubar,mu-;"]) process+=selectDecayMode("Z0",["Z0->e-,e+;", "Z0->mu-,mu+;"]) addedBRReweighter = True elif "WW-emu" in parameterName : process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n" process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n" process+="set /Herwig/Shower/ShowerHandler:SplitHardProcess No\n"; process+="set /Herwig/Decays/ZDecayer:PhotonGenerator NULL\n"; process+="set /Herwig/Decays/WDecayer:PhotonGenerator NULL\n"; process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n" process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n" process+=insert_ME("PowhegMEPP2VV","WW") process+="set /Herwig/Particles/W+:Synchronized 0\n" process+="set /Herwig/Particles/W-:Synchronized 0\n" process+=selectDecayMode("W+",["W+->nu_e,e+;"]) process+=selectDecayMode("W-",["W-->nu_mubar,mu-;"]) addedBRReweighter = True elif "WW-ll" in parameterName : process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n" process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n" process+="set /Herwig/Shower/ShowerHandler:SplitHardProcess No\n"; process+="set /Herwig/Decays/ZDecayer:PhotonGenerator NULL\n"; process+="set /Herwig/Decays/WDecayer:PhotonGenerator NULL\n"; process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n" process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n" process+=insert_ME("PowhegMEPP2VV","WW") process+=selectDecayMode("W+",["W+->nu_e,e+;", "W+->nu_mu,mu+;", "W+->nu_tau,tau+;"]) addedBRReweighter = True elif "ZZ-ll" in parameterName : process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n" process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n" process+="set /Herwig/Shower/ShowerHandler:SplitHardProcess No\n"; process+="set /Herwig/Decays/ZDecayer:PhotonGenerator NULL\n"; process+="set /Herwig/Decays/WDecayer:PhotonGenerator NULL\n"; process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n" process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n" process+=insert_ME("PowhegMEPP2VV","ZZ") process+=selectDecayMode("Z0",["Z0->e-,e+;", "Z0->mu-,mu+;", "Z0->tau-,tau+;"]) addedBRReweighter = True elif "ZZ-lv" in parameterName : process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n" process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n" process+="set /Herwig/Shower/ShowerHandler:SplitHardProcess No\n"; process+="set /Herwig/Decays/ZDecayer:PhotonGenerator NULL\n"; process+="set /Herwig/Decays/WDecayer:PhotonGenerator NULL\n"; process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n" process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n" process+=insert_ME("PowhegMEPP2VV","ZZ") process+=selectDecayMode("Z0",["Z0->e-,e+;", "Z0->mu-,mu+;", "Z0->tau-,tau+;", "Z0->nu_e,nu_ebar;", "Z0->nu_mu,nu_mubar;", "Z0->nu_tau,nu_taubar;"]) addedBRReweighter = True elif "W-Z-e" in parameterName : process+=insert_ME("PowhegMEqq2gZ2ff","Electron") process+=insert_ME("PowhegMEqq2W2ff","Electron") elif "W-Z-mu" in parameterName : process+=insert_ME("MEqq2gZ2ff","Muon") process+=insert_ME("MEqq2W2ff","Muon") elif "W-e" in parameterName : process+=insert_ME("PowhegMEqq2W2ff","Electron") elif "W-mu" in parameterName : process+=insert_ME("PowhegMEqq2W2ff","Muon") elif "Z-e" in parameterName : process+=insert_ME("PowhegMEqq2gZ2ff","Electron") elif "Z-mu" in parameterName : process+=insert_ME("PowhegMEqq2gZ2ff","Muon") elif "Z-LowMass-e" in parameterName : process+=insert_ME("PowhegMEqq2gZ2ff","Electron") process+=mhat_minm_maxm(20,20,70) elif "Z-MedMass-e" in parameterName : process+=insert_ME("PowhegMEqq2gZ2ff","Electron") process+=mhat_minm_maxm(40,40,130) elif "Z-LowMass-mu" in parameterName : process+=insert_ME("PowhegMEqq2gZ2ff","Muon") process+=mhat_minm_maxm(10,10,70) elif "Z-Mass1" in parameterName : process+=mhat_minm_maxm(10,10,35) if "-e" in parameterName : process+=insert_ME("PowhegMEqq2gZ2ff","Electron") else : process+=insert_ME("PowhegMEqq2gZ2ff","Muon") elif "Z-Mass2" in parameterName : process+=mhat_minm_maxm(25,25,70) if "-e" in parameterName : process+=insert_ME("PowhegMEqq2gZ2ff","Electron") else : process+=insert_ME("PowhegMEqq2gZ2ff","Muon") elif "Z-Mass3" in parameterName : process+=mhat_minm_maxm(60,60,120) if "-e" in parameterName : process+=insert_ME("PowhegMEqq2gZ2ff","Electron") else : process+=insert_ME("PowhegMEqq2gZ2ff","Muon") elif "Z-Mass4" in parameterName : process+=mhat_minm_maxm(110,110,8000) if "-e" in parameterName : process+=insert_ME("PowhegMEqq2gZ2ff","Electron") else : process+=insert_ME("PowhegMEqq2gZ2ff","Muon") elif "Z-HighMass1" in parameterName : process+=mhat_minm_maxm(116,116,400) if "-e" in parameterName : process+=insert_ME("PowhegMEqq2gZ2ff","Electron") else : process+=insert_ME("PowhegMEqq2gZ2ff","Muon") elif "Z-HighMass2" in parameterName : process+=mhat_minm_maxm(400,400,7000) if "-e" in parameterName : process+=insert_ME("PowhegMEqq2gZ2ff","Electron") else : process+=insert_ME("PowhegMEqq2gZ2ff","Muon") elif "DiPhoton-GammaGamma" in parameterName : process+=insert_ME("MEGammaGammaPowheg","GammaGamma") process+=insert_ME("MEGammaGamma","gg") process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n" process+=jet_kt_cut(5.) parameterName=parameterName.replace("-GammaGamma","") elif "DiPhoton-GammaJet" in parameterName : process+=insert_ME("MEGammaGammaPowheg","VJet") process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n" process+=jet_kt_cut(5.) parameterName=parameterName.replace("-GammaJet","") else : logging.error(" Process %s not supported for internal POWHEG matrix elements" % name) sys.exit(1) elif( simulation=="Matchbox" or simulation=="Merging" ) : if "VBF" in parameterName : parameters["nlo"] = "read Matchbox/VBFNLO.in\n" if(simulation=="Merging"): process+="cd /Herwig/Merging/\n" process+="insert "+thefactory+":DiagramGenerator:RestrictLines 0 /Herwig/Particles/Z0\n" process+="insert "+thefactory+":DiagramGenerator:RestrictLines 0 /Herwig/Particles/W+\n" process+="insert "+thefactory+":DiagramGenerator:RestrictLines 0 /Herwig/Particles/W-\n" process+="insert "+thefactory+":DiagramGenerator:RestrictLines 0 /Herwig/Particles/gamma\n" process+="do "+thefactory+":DiagramGenerator:TimeLikeRange 0 0\n" if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p h0 j j","0","3","FixedScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p h0 j j","0","3","FixedScale",1,1) process+=setHardProcessWidthToZero(["h0"]) process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n" if "GammaGamma" in parameterName : process+=selectDecayMode("h0",["h0->gamma,gamma;"]) process+=addBRReweighter() elif "WW" in parameterName : process+=selectDecayMode("h0",["h0->W+,W-;"]) process+=addBRReweighter() elif "ZZ" in parameterName : process+=selectDecayMode("h0",["h0->Z0,Z0;"]) process+=addBRReweighter() elif "8-" not in parameterName : process+=selectDecayMode("h0",["h0->tau-,tau+;"]) process+=addBRReweighter() process+="set /Herwig/Particles/tau-:Stable Stable\n" elif "ggHJet" in parameterName : if(simulation=="Merging"): logging.warning("ggHJet not explicitly tested for %s " % simulation) sys.exit(0) parameters["nlo"] = "read Matchbox/MadGraph-GoSam.in\nread Matchbox/HiggsEffective.in\n" process+=selectDecayMode("h0",["h0->tau-,tau+;"]) process+=addBRReweighter() process+="set /Herwig/Particles/tau-:Stable Stable\n" process+=setHardProcessWidthToZero(["h0"]) process+=addProcess(thefactory,"p p h0 j","3","1","FixedScale",0,0) process+=addFirstJet("20") process+="set "+thefactory+":ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n" process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n" elif "ggH" in parameterName : parameters["nlo"] = "read Matchbox/MadGraph-GoSam.in\nread Matchbox/HiggsEffective.in\n" if(simulation=="Merging"): process+= "cd /Herwig/MatrixElements/Matchbox/Amplitudes\nset OpenLoops:HiggsEff On\nset MadGraph:Model heft\n" process+="cd /Herwig/Merging/\n" process+=setHardProcessWidthToZero(["h0"]) if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p h0","2","1","FixedScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p h0","2","1","FixedScale",2,2) process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n" if "GammaGamma" in parameterName : process+=selectDecayMode("h0",["h0->gamma,gamma;"]) process+=addBRReweighter() elif "WW" in parameterName : process+=selectDecayMode("h0",["h0->W+,W-;"]) process+=addBRReweighter() elif "ZZ" in parameterName : process+=selectDecayMode("h0",["h0->Z0,Z0;"]) process+=addBRReweighter() elif "8-" not in parameterName : process+=selectDecayMode("h0",["h0->tau-,tau+;"]) process+=addBRReweighter() process+="set /Herwig/Particles/tau-:Stable Stable\n" elif "8-WH" in parameterName : if(simulation=="Merging"): logging.warning("8-WH not explicitly tested for %s " % simulation) sys.exit(0) process+=setHardProcessWidthToZero(["h0","W+","W-"]) process+=addProcess(thefactory,"p p W+ h0","0","2","FixedScale",0,0) process+=addProcess(thefactory,"p p W- h0","0","2","FixedScale",0,0) process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n" if "GammaGamma" in parameterName : process+=selectDecayMode("h0",["h0->gamma,gamma;"]) process+=addBRReweighter() elif "WW" in parameterName : process+=selectDecayMode("h0",["h0->W+,W-;"]) process+=addBRReweighter() elif "ZZ" in parameterName : process+=selectDecayMode("h0",["h0->Z0,Z0;"]) process+=addBRReweighter() elif "8-ZH" in parameterName : if(simulation=="Merging"): logging.warning("8-ZH not explicitly tested for %s " % simulation) sys.exit(0) process+=setHardProcessWidthToZero(["h0","Z0"]) process+=addProcess(thefactory,"p p Z0 h0","0","2","FixedScale",0,0) process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n" if "GammaGamma" in parameterName : process+=selectDecayMode("h0",["h0->gamma,gamma;"]) process+=addBRReweighter() elif "WW" in parameterName : process+=selectDecayMode("h0",["h0->W+,W-;"]) process+=addBRReweighter() elif "ZZ" in parameterName : process+=selectDecayMode("h0",["h0->Z0,Z0;"]) process+=addBRReweighter() elif "WH" in parameterName : if(simulation=="Merging"): logging.warning("WH not explicitly tested for %s " % simulation) sys.exit(0) process+=selectDecayMode("h0",["h0->b,bbar;"]) process+=addBRReweighter() process+=setHardProcessWidthToZero(["h0"]) process+=addProcess(thefactory,"p p e+ nu h0","0","3","LeptonPairMassScale",0,0) process+=addProcess(thefactory,"p p e- nu h0","0","3","LeptonPairMassScale",0,0) process+=addProcess(thefactory,"p p mu+ nu h0","0","3","LeptonPairMassScale",0,0) process+=addProcess(thefactory,"p p mu- nu h0","0","3","LeptonPairMassScale",0,0) process+=addLeptonPairCut("60","120") elif "ZH" in parameterName : if(simulation=="Merging"): logging.warning("ZH not explicitly tested for %s " % simulation) sys.exit(0) process+=selectDecayMode("h0",["h0->b,bbar;"]) process+=addBRReweighter() process+=setHardProcessWidthToZero(["h0"]) process+=addProcess(thefactory,"p p e+ e- h0","0","3","LeptonPairMassScale",0,0) process+=addProcess(thefactory,"p p mu+ mu- h0","0","3","LeptonPairMassScale",0,0) process+=addLeptonPairCut("60","120") elif "UE" in parameterName : logging.error(" Process %s not supported for Matchbox matrix elements" % name) sys.exit(1) elif "8-DiJets" in parameterName or "7-DiJets" in parameterName or "13-DiJets" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p j j","2","0","MaxJetPtScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p j j","2","0","MaxJetPtScale",1,1) process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" if "13-DiJets" not in parameterName : if "-A" in parameterName : process+=addFirstJet("45") process+=addSecondJet("25") process+="set /Herwig/Cuts/FirstJet:YRange -3. 3.\n" process+="set /Herwig/Cuts/SecondJet:YRange -3. 3.\n" elif "-B" in parameterName : process+=addFirstJet("20") process+=addSecondJet("15") process+="set /Herwig/Cuts/FirstJet:YRange -2.7 2.7\n" process+="set /Herwig/Cuts/SecondJet:YRange -2.7 2.7\n" elif "-C" in parameterName : process+=addFirstJet("20") process+=addSecondJet("15") process+="set /Herwig/Cuts/FirstJet:YRange -4.8 4.8\n" process+="set /Herwig/Cuts/SecondJet:YRange -4.8 4.8\n" else : logging.error("Exit 00001") sys.exit(1) else : if "-A" in parameterName : process+= addFirstJet("75.") process+=addSecondJet("60.") process+="set /Herwig/Cuts/JetKtCut:MinEta -3.\n" process+="set /Herwig/Cuts/JetKtCut:MaxEta 3.\n" elif "-B" in parameterName : process+= addFirstJet("220.") process+=addSecondJet("180.") process+="set /Herwig/Cuts/JetKtCut:MinEta -3.\n" process+="set /Herwig/Cuts/JetKtCut:MaxEta 3.\n" else : logging.error("Exit 00001") sys.exit(1) if "DiJets-1" in parameterName : process+=addJetPairCut("90") elif "DiJets-2" in parameterName : process+=addJetPairCut("200") elif "DiJets-3" in parameterName : process+=addJetPairCut("450") elif "DiJets-4" in parameterName : process+=addJetPairCut("750") elif "DiJets-5" in parameterName : process+=addJetPairCut("950") elif "DiJets-6" in parameterName : process+=addJetPairCut("1550") elif "DiJets-7" in parameterName : process+=addJetPairCut("2150") elif "DiJets-8" in parameterName : process+=addJetPairCut("2750") elif "DiJets-9" in parameterName : process+=mhatmin_cut(3750.) elif "DiJets-10" in parameterName : process+=mhatmin_cut(4750.) elif "DiJets-11" in parameterName : process+=mhatmin_cut(5750.) else : logging.error("Exit 00002") sys.exit(1) elif( "7-Jets" in parameterName or "8-Jets" in parameterName or "13-Jets" in parameterName or "2760-Jets" in parameterName ) : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p j j","2","0","MaxJetPtScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p j j","2","0","MaxJetPtScale",1,1) process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" if "Jets-10" in parameterName : process+=addFirstJet("1800") elif "Jets-0" in parameterName : process+=addFirstJet("5") elif "Jets-1" in parameterName : process+=addFirstJet("10") elif "Jets-2" in parameterName : process+=addFirstJet("20") elif "Jets-3" in parameterName : process+=addFirstJet("40") elif "Jets-4" in parameterName : process+=addFirstJet("70") elif "Jets-5" in parameterName : process+=addFirstJet("150") elif "Jets-6" in parameterName : process+=addFirstJet("200") elif "Jets-7" in parameterName : process+=addFirstJet("300") elif "Jets-8" in parameterName : process+=addFirstJet("500") elif "Jets-9" in parameterName : process+=addFirstJet("800") else : logging.error("Exit 00003") sys.exit(1) elif( "7-Charm" in parameterName or "7-Bottom" in parameterName or "8-Bottom" in parameterName) : parameters["bscheme"]=fourFlavour process+="set /Herwig/Particles/b:HardProcessMass 4.2*GeV\n" process+="set /Herwig/Particles/bbar:HardProcessMass 4.2*GeV\n" if("8-Bottom" in parameterName) : addBRReweighter() process+=selectDecayMode("Jpsi",["Jpsi->mu-,mu+;"]) if "Bottom" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p b bbar","2","0","MaxJetPtScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p b bbar","2","0","MaxJetPtScale",1,0) else: if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p c cbar","2","0","MaxJetPtScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p c cbar","2","0","MaxJetPtScale",1,0) process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" if "-0" in parameterName : process+=addFirstJet("0") elif "-1" in parameterName : process+=addFirstJet("5") elif "-2" in parameterName : process+=addFirstJet("15") elif "-3" in parameterName : process+=addFirstJet("20") elif "-4" in parameterName : process+=addFirstJet("50") elif "-5" in parameterName : process+=addFirstJet("80") elif "-6" in parameterName : process+=addFirstJet("110") elif "-7" in parameterName : process+=addFirstJet("30") process+=addSecondJet("25") process+=addJetPairCut("90") elif "-8" in parameterName : process+=addFirstJet("30") process+=addSecondJet("25") process+=addJetPairCut("340") elif "-9" in parameterName : process+=addFirstJet("30") process+=addSecondJet("25") process+=addJetPairCut("500") else : logging.error("Exit 00004") sys.exit(1) elif "Top-L" in parameterName : process+=setHardProcessWidthToZero(["t","tbar"]) if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p t tbar","2","0","TopPairMTScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p t tbar","2","0","TopPairMTScale",2,2) process+=selectDecayMode("t",["t->nu_e,e+,b;", "t->nu_mu,mu+,b;"]) process+=addBRReweighter() elif "Top-SL" in parameterName : process+=setHardProcessWidthToZero(["t","tbar"]) if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p t tbar","2","0","TopPairMTScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p t tbar","2","0","TopPairMTScale",2,2) process+="set /Herwig/Particles/t:Synchronized Not_synchronized\n" process+="set /Herwig/Particles/tbar:Synchronized Not_synchronized\n" process+=selectDecayMode("t",["t->nu_e,e+,b;", "t->nu_mu,mu+,b;"]) process+=selectDecayMode("tbar",["tbar->b,bbar,cbar;", "tbar->bbar,cbar,d;", "tbar->bbar,cbar,s;", "tbar->bbar,s,ubar;", "tbar->bbar,ubar,d;"]) process+=addBRReweighter() elif "Top-All" in parameterName : process+=setHardProcessWidthToZero(["t","tbar"]) if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p t tbar","2","0","TopPairMTScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p t tbar","2","0","TopPairMTScale",2,2) elif "WZ" in parameterName : if(simulation=="Merging"): logging.warning("WZ not explicitly tested for %s " % simulation) sys.exit(0) process+=setHardProcessWidthToZero(["W+","W-","Z0"]) process+=addProcess(thefactory,"p p W+ Z0","0","2","FixedScale",0,0) process+=addProcess(thefactory,"p p W- Z0","0","2","FixedScale",0,0) process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 171.6*GeV\n\n" process+=selectDecayMode("W+",["W+->nu_e,e+;", "W+->nu_mu,mu+;"]) process+=selectDecayMode("W-",["W-->nu_ebar,e-;", "W-->nu_mubar,mu-;"]) process+=selectDecayMode("Z0",["Z0->e-,e+;", "Z0->mu-,mu+;"]) process+=addBRReweighter() process+=addLeptonPairCut("60","120") elif "WW-emu" in parameterName : if(simulation=="Merging"): logging.warning("WW-emu not explicitly tested for %s " % simulation) sys.exit(0) process+=setHardProcessWidthToZero(["W+","W-","Z0"]) process+=addProcess(thefactory,"p p W+ W-","0","2","FixedScale",0,0) process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 160.8*GeV\n" process+="set /Herwig/Particles/W+:Synchronized 0\n" process+="set /Herwig/Particles/W-:Synchronized 0\n" process+=selectDecayMode("W+",["W+->nu_e,e+;"]) process+=selectDecayMode("W-",["W-->nu_mubar,mu-;"]) process+=addBRReweighter() parameters["bscheme"] = "read Matchbox/FourFlavourScheme.in\n" process+=addLeptonPairCut("60","120") elif "WW-ll" in parameterName : if(simulation=="Merging"): logging.warning("WW-ll not explicitly tested for %s " % simulation) sys.exit(0) process+=setHardProcessWidthToZero(["W+","W-","Z0"]) process+=addProcess(thefactory,"p p W+ W-","0","2","FixedScale",0,0) process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 160.8*GeV\n" process+=selectDecayMode("W+",["W+->nu_e,e+;", "W+->nu_mu,mu+;", "W+->nu_tau,tau+;"]) process+=addBRReweighter() process+=addLeptonPairCut("60","120") parameters["bscheme"] = "read Matchbox/FourFlavourScheme.in\n" elif "ZZ-ll" in parameterName : if(simulation=="Merging"): logging.warning("ZZ-ll not explicitly tested for %s " % simulation) sys.exit(0) process+=setHardProcessWidthToZero(["W+","W-","Z0"]) process+=addProcess(thefactory,"p p Z0 Z0","0","2","FixedScale",0,0) process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 182.2*GeV\n" process+=selectDecayMode("Z0",["Z0->e-,e+;", "Z0->mu-,mu+;", "Z0->tau-,tau+;"]) process+=addBRReweighter() process+=addLeptonPairCut("60","120") elif "ZZ-lv" in parameterName : if(simulation=="Merging"): logging.warning("ZZ-lv not explicitly tested for %s " % simulation) sys.exit(0) process+=setHardProcessWidthToZero(["W+","W-","Z0"]) process+=addProcess(thefactory,"p p Z0 Z0","0","2","FixedScale",0,0) process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 182.2*GeV\n" process+=selectDecayMode("Z0",["Z0->e-,e+;", "Z0->mu-,mu+;", "Z0->tau-,tau+;", "Z0->nu_e,nu_ebar;", "Z0->nu_mu,nu_mubar;", "Z0->nu_tau,nu_taubar;"]) process+=addBRReweighter() process+=addLeptonPairCut("60","120") elif "W-Z-e" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",0,0) process+=addProcess(thefactory,"p p e+ nu","0","2","LeptonPairMassScale",0,0) process+=addProcess(thefactory,"p p e- nu","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=particlegroup('epm','e+','e-') process+=particlegroup('epmnu','e+','e-','nu_e','nu_ebar') process+=addProcess(thefactory,"p p epm epmnu","0","2","LeptonPairMassScale",2,2) process+=addLeptonPairCut("60","120") elif "W-Z-mu" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",0,0) process+=addProcess(thefactory,"p p mu+ nu","0","2","LeptonPairMassScale",0,0) process+=addProcess(thefactory,"p p mu- nu","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=particlegroup('mupm','mu+','mu-') process+=particlegroup('mupmnu','mu+','mu-','nu_mu','nu_mubar') process+=addProcess(thefactory,"p p mupm mupmnu","0","2","LeptonPairMassScale",2,2) process+=addLeptonPairCut("60","120") elif "W-e" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p e+ nu","0","2","LeptonPairMassScale",0,0) process+=addProcess(thefactory,"p p e- nu","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=particlegroup('epm','e+','e-') process+=addProcess(thefactory,"p p epm nu","0","2","LeptonPairMassScale",2,2) process+=addLeptonPairCut("60","120") elif "W-mu" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p mu+ nu","0","2","LeptonPairMassScale",0,0) process+=addProcess(thefactory,"p p mu- nu","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=particlegroup('mupm','mu+','mu-') process+=addProcess(thefactory,"p p mupm nu","0","2","LeptonPairMassScale",2,2) process+=addLeptonPairCut("60","120") elif "Z-e" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",2,2) process+=addLeptonPairCut("60","120") elif "Z-mu" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",2,2) process+=addLeptonPairCut("60","120") elif "Z-jj" in parameterName : if(simulation=="Merging"): logging.warning("Z-jj not explicitly tested for %s " % simulation) sys.exit(0) process+=addProcess(thefactory,"p p e+ e- j j","2","2","LeptonPairMassScale",0,0) process+=addFirstJet("40") process+=addSecondJet("30") process+=addLeptonPairCut("60","120") elif "Z-LowMass-e" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",2,2) process+=addLeptonPairCut("20","70") elif "Z-MedMass-e" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",2,2) process+=addLeptonPairCut("40","130") elif "Z-LowMass-mu" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",2,2) process+=addLeptonPairCut("10","70") elif "Z-Mass1" in parameterName : process+=addLeptonPairCut("10","35") if "-e" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",2,2) else : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",2,2) elif "Z-Mass2" in parameterName : process+=addLeptonPairCut("25","70") if "-e" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",2,2) else : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",2,2) elif "Z-Mass3" in parameterName : process+=addLeptonPairCut("60","120") if "-e" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",2,2) else : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",2,2) elif "Z-Mass4" in parameterName : process+=addLeptonPairCut("115","8000") if "-e" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",2,2) else : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",2,2) elif "Z-HighMass1" in parameterName : process+=addLeptonPairCut("116","400") if "-e" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",2,2) else : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",2,2) elif "Z-HighMass2" in parameterName : process+=addLeptonPairCut("400","7000") if "-e" in parameterName : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",2,2) else : if(simulation=="Matchbox"): process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",0,0) elif(simulation=="Merging"): process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",2,2) elif "W-Jet" in parameterName : if(simulation=="Merging"): logging.warning("W-Jet not explicitly tested for %s " % simulation) sys.exit(0) process+=addProcess(thefactory,"p p e+ nu j","1","2","HTScale",0,0) process+=addProcess(thefactory,"p p e- nu j","1","2","HTScale",0,0) process+=addLeptonPairCut("60","120") if "W-Jet-1-e" in parameterName : process+=addFirstJet("100") parameterName=parameterName.replace("W-Jet-1-e","W-Jet-e") elif "W-Jet-2-e" in parameterName : process+=addFirstJet("190") parameterName=parameterName.replace("W-Jet-2-e","W-Jet-e") elif "W-Jet-3-e" in parameterName : process+=addFirstJet("270") parameterName=parameterName.replace("W-Jet-3-e","W-Jet-e") else : logging.error("Exit 00005") sys.exit(1) elif "Z-Jet" in parameterName : if(simulation=="Merging"): logging.warning("Z-Jet not explicitly tested for %s " % simulation) sys.exit(0) if "-e" in parameterName : process+=addProcess(thefactory,"p p e+ e- j","1","2","HTScale",0,0) if "Z-Jet-0-e" in parameterName : process+=addFirstJet("35") parameterName=parameterName.replace("Z-Jet-0-e","Z-Jet-e") elif "Z-Jet-1-e" in parameterName : process+=addFirstJet("100") parameterName=parameterName.replace("Z-Jet-1-e","Z-Jet-e") elif "Z-Jet-2-e" in parameterName : process+=addFirstJet("190") parameterName=parameterName.replace("Z-Jet-2-e","Z-Jet-e") elif "Z-Jet-3-e" in parameterName : process+=addFirstJet("270") parameterName=parameterName.replace("Z-Jet-3-e","Z-Jet-e") else : logging.error("Exit 00006") sys.exit(1) else : process+=addProcess(thefactory,"p p mu+ mu- j","1","2","HTScale",0,0) process+=addFirstJet("35") parameterName=parameterName.replace("Z-Jet-0-mu","Z-Jet-mu") process+=addLeptonPairCut("60","120") elif "Z-bb" in parameterName : if(simulation=="Merging"): logging.warning("Z-bb not explicitly tested for %s " % simulation) sys.exit(0) parameters["bscheme"]=fourFlavour process+="set /Herwig/Particles/b:HardProcessMass 4.2*GeV\nset /Herwig/Particles/bbar:HardProcessMass 4.2*GeV\n" process+=addProcess(thefactory,"p p e+ e- b bbar","2","2","FixedScale",0,0) process+=addLeptonPairCut("66","116") process+=addFirstJet("18") process+=addSecondJet("15") process+=addLeptonPairCut("60","120") elif "Z-b" in parameterName : if(simulation=="Merging"): logging.warning("Z-b not explicitly tested for %s " % simulation) sys.exit(0) process+=particlegroup('bjet','b','bbar') process+=addProcess(thefactory,"p p e+ e- bjet","1","2","FixedScale",0,0) process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 91.2*GeV\n" process+=addLeptonPairCut("60","120") process+=addFirstJet("15") elif "W-b" in parameterName : if(simulation=="Merging"): logging.warning("W-b not explicitly tested for %s " % simulation) sys.exit(0) parameters["bscheme"]=fourFlavour process += "set /Herwig/Particles/b:HardProcessMass 4.2*GeV\nset /Herwig/Particles/bbar:HardProcessMass 4.2*GeV\n" process+=addProcess(thefactory,"p p e- nu b bbar","2","2","FixedScale",0,0) process+=addProcess(thefactory,"p p mu+ nu b bbar","2","2","FixedScale",0,0) process += "set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 80.4*GeV\n" process+=addFirstJet("30") process+=addLeptonPairCut("60","120") else : logging.error(" Process %s not supported for Matchbox matrix elements" % name) sys.exit(1) # LHC-GammaGamma elif(collider=="LHC-GammaGamma" ) : if "-7-" in parameterName : process = StringBuilder(collider_lumi(7000.0)) elif "-8-" in parameterName : process = StringBuilder(collider_lumi(8000.0)) else : process = StringBuilder(collider_lumi(7000.0)) if(simulation=="") : if "7" in parameterName : process += insert_ME("MEgg2ff","Muon") else : logging.error(" Process %s not supported for default matrix elements" % name) sys.exit(1) else : logging.error("LHC-GammaGamma not supported for %s " % simulation) sys.exit(1) parameters['parameterFile'] = os.path.join(collider,"{c}-{pn}.in".format(c=collider, pn=parameterName)) parameters['runname'] = 'Rivet-%s' % name parameters['process'] = str(process) if have_hadronic_collider : if collider == "EHS" : parameters['collider'] = "PPCollider.in\nread snippets/FixedTarget-PP.in" else : parameters['collider'] = "PPCollider.in" #check if selecteddecaymode and addedBRReweighter is consistent if selecteddecaymode and not addedBRReweighter: logging.error("Decaymode was selected but no BRReweighter was added.") sys.exit(1) if addedBRReweighter and not selecteddecaymode: logging.error("BRReweighter was added but no Decaymode was selected.") sys.exit(1) # check that we only add one process if in merging mode: if numberOfAddedProcesses > 1 and simulation =="Merging": logging.error("In Merging only one process is allowed at the moment. See ticket #403.") sys.exit(1) # Check if a process was added for Merging or Matchbox: if numberOfAddedProcesses == 0 and (simulation =="Merging" or simulation =="Matchbox"): logging.error("No process was selected.") sys.exit(1) # get template and write the file with open(os.path.join("Rivet/Templates",templateName), 'r') as f: templateText = f.read() template = Template( templateText ) with open(os.path.join("Rivet",name+".in"), 'w') as f: f.write( template.substitute(parameters) ) diff --git a/Tests/python/merge-DIS b/Tests/python/merge-DIS --- a/Tests/python/merge-DIS +++ b/Tests/python/merge-DIS @@ -1,155 +1,162 @@ #! /usr/bin/env python import logging import sys if sys.version_info[:3] < (2,4,0): print "rivet scripts require Python version >= 2.4.0... exiting" sys.exit(1) import os, yoda # ############################################# def fillAbove(desthisto, sourcehistosbyq2): q2high=1e100 q2low=-1e100 for q2,h in sorted(sourcehistosbyq2.iteritems(),reverse=True) : q2low=q2 - for i in range(0,h.numBins) : - if(h.bins[i].xMin >= q2low and - h.bins[i].xMin < q2high ) : - desthisto.bins[i] += h.bins[i] + for i in range(0,h.numBins()) : + if(h.bins()[i].xMin() >= q2low and + h.bins()[i].xMin() < q2high ) : + desthisto.bins()[i] += h.bins()[i] q2high=q2 def merge(hpath): global inhistos global outhistos try: fillAbove(outhistos[hpath], inhistos[hpath]) except: pass def useOne(hpath, q2): global inhistos global outhistos try: outhistos[hpath] = inhistos[hpath][float(q2)] except: pass if __name__ == "__main__": import logging from optparse import OptionParser, OptionGroup parser = OptionParser(usage="%prog name") verbgroup = OptionGroup(parser, "Verbosity control") verbgroup.add_option("-v", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL", default=logging.INFO, help="print debug (very verbose) messages") verbgroup.add_option("-q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL", default=logging.INFO, help="be very quiet") parser.add_option_group(verbgroup) (opts, args) = parser.parse_args() logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s") ## Check args if len(args) < 1: logging.error("Must specify at least the name of the files") sys.exit(1) # ####################################### yodafiles=["-e--LowQ2","-e+-LowQ2","-e+-HighQ2"] ## Get histos inhistos = {} outhistos={} weights = {} for f in yodafiles: file = "Rivet-%s%s.yoda" % (args[0], f) if(file.find("Low")> 0) : q2=0 elif(file.find("High")>0) : q2=50 if not os.access(file, os.R_OK): logging.error("%s can not be read" % file) continue try: aos = yoda.read(file) except: logging.error("%s can not be parsed as YODA" % file) continue ## Get histos from this YODA file for aopath, ao in aos.iteritems() : if("RAW" in aopath) :continue if(aopath.find("4129130")>0 ) : if not inhistos.has_key(aopath): inhistos[aopath] = {} tmpE = inhistos[aopath] if not tmpE.has_key(q2): tmpE[q2] = ao else: raise Exception("A set with q2 = %s already exists" % ( q2 )) elif(aopath.find("2919893")>0 ) : outhistos[aopath] = ao elif(aopath.find("_XSEC")>=0 or aopath.find("_EVTCOUNT")>=0) : continue else : logging.error("Analysis %s is unknown" % aopath) sys.exit(1) ## Make empty output histos if needed for hpath,hsets in inhistos.iteritems(): if( hpath.find("4129130")>0 and (hpath.find("d33")>0 or hpath.find("d34")>0)) : - if(type(hsets.values()[0])==yoda.core.Scatter2D) : - outhistos[hpath] = yoda.core.Scatter2D(hsets.values()[0].path,hsets.values()[0].title) - elif(type(hsets.values()[0])==yoda.core.Profile1D) : - outhistos[hpath] = yoda.core.Profile1D(hsets.values()[0].path,hsets.values()[0].title) - for i in range(0,hsets.values()[0].numBins) : - outhistos[hpath].addBin(hsets.values()[0].bins[i].xMin,hsets.values()[0].bins[i].xMax) + title="" + path="" + histo = hsets.values()[0] + if hasattr(histo, 'title'): + title=histo.title() + if hasattr(histo, 'path'): + path=histo.path() + if(type(histo)==yoda.core.Scatter2D) : + outhistos[hpath] = yoda.core.Scatter2D(path,title) + elif(type(histo)==yoda.core.Profile1D) : + outhistos[hpath] = yoda.core.Profile1D(path,title) + for i in range(0,histo.numBins()) : + outhistos[hpath].addBin(histo.bins()[i].xMin(),histo.bins()[i].xMax()) else : logging.error("Histogram %s is of unknown type" % hpath) sys.exit(1) # H1 transverse energy useOne("/H1_2000_S4129130/d01-x01-y01","0") useOne("/H1_2000_S4129130/d02-x01-y01","0") useOne("/H1_2000_S4129130/d03-x01-y01","0") useOne("/H1_2000_S4129130/d04-x01-y01","0") useOne("/H1_2000_S4129130/d05-x01-y01","0") useOne("/H1_2000_S4129130/d06-x01-y01","0") useOne("/H1_2000_S4129130/d07-x01-y01","0") useOne("/H1_2000_S4129130/d08-x01-y01","0") useOne("/H1_2000_S4129130/d09-x01-y01","0") useOne("/H1_2000_S4129130/d10-x01-y01","0") useOne("/H1_2000_S4129130/d11-x01-y01","0") useOne("/H1_2000_S4129130/d12-x01-y01","0") useOne("/H1_2000_S4129130/d13-x01-y01","0") useOne("/H1_2000_S4129130/d14-x01-y01","0") useOne("/H1_2000_S4129130/d15-x01-y01","0") useOne("/H1_2000_S4129130/d16-x01-y01","50") useOne("/H1_2000_S4129130/d17-x01-y01","50") useOne("/H1_2000_S4129130/d18-x01-y01","50") useOne("/H1_2000_S4129130/d19-x01-y01","50") useOne("/H1_2000_S4129130/d20-x01-y01","50") useOne("/H1_2000_S4129130/d21-x01-y01","50") useOne("/H1_2000_S4129130/d22-x01-y01","50") useOne("/H1_2000_S4129130/d23-x01-y01","50") useOne("/H1_2000_S4129130/d24-x01-y01","50") useOne("/H1_2000_S4129130/d25-x01-y01","0") useOne("/H1_2000_S4129130/d26-x01-y01","0") useOne("/H1_2000_S4129130/d27-x01-y01","0") useOne("/H1_2000_S4129130/d28-x01-y01","0") useOne("/H1_2000_S4129130/d29-x01-y01","50") useOne("/H1_2000_S4129130/d30-x01-y01","50") useOne("/H1_2000_S4129130/d31-x01-y01","50") useOne("/H1_2000_S4129130/d32-x01-y01","50") merge("/H1_2000_S4129130/d33-x01-y01") merge("/H1_2000_S4129130/d34-x01-y01") # Choose output file name = args[0]+".yoda" # output the yoda file yoda.writeYODA(outhistos,name) sys.exit(0) diff --git a/Tests/python/merge-EE b/Tests/python/merge-EE --- a/Tests/python/merge-EE +++ b/Tests/python/merge-EE @@ -1,1204 +1,1225 @@ #! /usr/bin/env python # import lighthisto import logging import sys if sys.version_info[:3] < (2,4,0): print "rivet scripts require Python version >= 2.4.0... exiting" sys.exit(1) import os, yoda, copy # # ############################################# def fillAbove(desthisto, sourcehistosbysqrts): if type(desthisto) is yoda.core.Scatter2D : for sqrts,h in sorted(sourcehistosbysqrts.iteritems()) : if(sqrts=="U1") : sqrts2=9.46 elif sqrts=="U2" : sqrts2=10.02 elif sqrts=="U4" : sqrts2=10.58 else : sqrts2=float(sqrts) if("ARGUS_1989_I276860" in desthisto.path() and sqrts2==10.) : sqrts2=9.98 step = 0.001 if("TASSO_1980_I143691" in desthisto.path()) : step=0.3 for i in range(0,h.numPoints()) : xmin = min(h.points()[i].xMin(),h.points()[i].x()-step) xmax = max(h.points()[i].xMax(),h.points()[i].x()+step) if(sqrts2>=xmin and sqrts2<=xmax) : desthisto.addPoint(h.points()[i]) elif(type(desthisto)==yoda.core.Profile1D) : for sqrts, h in sorted(sourcehistosbysqrts.iteritems()) : step = 0.001 for i in range(0,h.numBins()) : xmin = min(h.bins()[i].xMin(),h.bins()[i].xMid()-step) xmax = max(h.bins()[i].xMax(),h.bins()[i].xMid()+step) if(sqrts>=xmin and sqrts<=xmax) : desthisto.bins()[i] += h.bins()[i] break else : logging.error("Unknown analysis object" + desthisto.path) sys.exit(1) def merge(hpath): global inhistos global outhistos try: fillAbove(outhistos[hpath], inhistos[hpath]) except: pass def useOne(hpath, sqrts): global inhistos global outhistos try: outhistos[hpath] = inhistos[hpath][float(sqrts)] except: try: outhistos[hpath] = inhistos[hpath][sqrts] except: pass def average(hpath, sqrts1,sqrts2): global inhistos global outhistos outhistos[hpath] = inhistos[hpath][float(sqrts1)]+inhistos[hpath][float(sqrts2)] outhistos[hpath].setPath(hpath) outhistos[hpath].scaleW(0.5) if __name__ == "__main__": import logging from optparse import OptionParser, OptionGroup parser = OptionParser(usage="%prog name") verbgroup = OptionGroup(parser, "Verbosity control") verbgroup.add_option("-v", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL", default=logging.INFO, help="print debug (very verbose) messages") verbgroup.add_option("-q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL", default=logging.INFO, help="be very quiet") parser.add_option_group(verbgroup) parser.add_option("--with-gg", action='store_true' , dest="gg", default=False, help="Include gg analyese") parser.add_option("--without-gg", action='store_false', dest="gg", default=False, help="Don\'t include gg analyses") (opts, args) = parser.parse_args() logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s") ## Check args if len(args) < 1: logging.error("Must specify at least the name of the files") sys.exit(1) ####################################### yodafiles=["130","133","136","177","192", "196","202","205","206","207","91" ,"91-nopi" ,\ "161","183","197","35" ,"36.2","172",\ "189","200","44","14","14.8","21.5","22","25","10",\ "12.8","26.8","48.0","93.0",\ "12","13","17","27.6","29","30.2","34.5",\ "30.7","30","31.3","34","34.8","43.6","50","52","53.3",\ "55","56","57","58","59.5","60.8","60","61.4","7.7", "9.4","45","66","76","41","42.6","82","85"] # add gg if needed if(opts.gg) : yodafiles += ["10.5-gg","12.8-gg","16.86-gg","26.8-gg",\ "35.44-gg","97.0-gg","11.96-gg","13.96-gg",\ "21.84-gg","28.48-gg","48.0-gg"] yodafiles += ["2.2","2.6","3.0","3.2","4.6","4.8", "5.8","6.2","6.6","7.0","7.4","3.63","4.03","4.17","4.3", "4.41","5.0","5.2","4.5","9.46","10.52","10.52-sym","10.54", "10.58-res","10.58","Upsilon","10.6-sym", "Upsilon2","Upsilon4","10.45","10.47","Tau","Phi", - "Lambdac","Omega","Xi0","Xic0","Omegac0","Xim","JPsi","Psi2S"] + "Lambdac","Omega-Meson","Omega-Baryon","Eta","Xi0","Xic0","Omegac0","Xim","JPsi","Psi2S"] ## Get histos inhistos = {} outhistos={} for f in yodafiles: file = "Rivet-%s-%s.yoda" % (args[0], f) if(file.find("Tau")>0) : sqrts=10.58 elif(file.find("Upsilon4")>0) : sqrts="U4" elif(file.find("Upsilon2")>0) : sqrts="U2" elif(file.find("Upsilon")>0) : sqrts="U1" elif(file.find("Phi")>0) : sqrts="phi" + elif(file.find("Omega-Meson")>0) : + sqrts="omega" elif(file.find("JPsi")>0) : sqrts="psi" elif(file.find("Psi2S")>0) : sqrts="psi2s" elif(file.find("Lambdac")>0 or file.find("Xic0")>0 or file.find("Omega")>0 or file.find("Xi0")>0 or - file.find("Xim")>0) : + file.find("Xim")>0 or + file.find("Eta")>0) : sqrts="baryon" else : sqrts=float(f.split("-")[0]) if not os.access(file, os.R_OK): logging.error("%s cannot be read" % file) continue try: aos = yoda.read(file) except: logging.error("%s cannot be parsed as yoda" % file) continue ## Get histos from this YODA file for aopath, ao in aos.iteritems() : if("RAW" in aopath) :continue # plots which neede merging/selecting if(aopath.find("4300807")>0 or aopath.find("6132243")>0 or aopath.find("5765862")>0 or aopath.find("3612880")>0 or aopath.find("4328825")>0 or aopath.find("5361494")>0 or aopath.find("2148048")>0 or aopath.find("295160" )>0 or aopath.find("190818" )>0 or aopath.find("154270" )>0 or aopath.find("277658" )>0 or aopath.find("143691" )>0 or aopath.find("6265367")>0 or aopath.find("6895344")>0 or aopath.find("6181155")>0 or aopath.find("2789213")>0 or aopath.find("2669951")>0 or aopath.find("278933" )>0 or aopath.find("276860" )>0 or aopath.find("251097" )>0 or aopath.find("262551" )>0 or aopath.find("262415" )>0 or aopath.find("165122" )>0 or aopath.find("118873" )>0 or aopath.find("177174" )>0 or aopath.find("284251" )>0 or aopath.find("191161" )>0 or aopath.find("1422780")>0 or aopath.find("132410" )>0 or ("OPAL_2000_I513476" in aopath and ("d14" in aopath or "d20" in aopath )) or (aopath.find("MULTIPLICITIES")>0 and aopath.find("Upsilon_4S")<0)) : if not inhistos.has_key(aopath): inhistos[aopath] = {} tmpE = inhistos[aopath] sqrttemp=sqrts if(aopath.find("2669951")>0 and aopath.find("d01")>0 and sqrts==10.45) : sqrts=9.9 if not tmpE.has_key(sqrts): tmpE[sqrts] = ao else: raise Exception("A set with sqrts = %s already exists" % ( sqrts)) sqrts=sqrttemp elif(aopath.find("OPAL_2004_I648738")>=0) : if(file.find("gg")>=0) : if(aopath.find("y03")>=0) : outhistos[aopath] = ao else : if(aopath.find("y03")<0) : outhistos[aopath] = ao elif(aopath.find("ARGUS_1991_I315059")>=0) : if(file.find("sym")>=0) : if("d01" in aopath or "d02" in aopath or "d03" in aopath or "d04" in aopath) : outhistos[aopath] = ao else : if("d05" in aopath or "d07" in aopath or "d07" in aopath) : outhistos[aopath] = ao else : if("ARGUS_1992_I319102" in aopath) : if("d02" in aopath and sqrts==10.47) : outhistos[aopath] = ao elif("d03"in aopath and sqrts=="U4") : outhistos[aopath] = ao else: + elif(aopath.find("A2_2017_I1486671")>=0) : + if("Eta" in file) : + if "d01" in aopath : outhistos[aopath] = ao + elif("Omega" in file) : + if "d02" in aopath : outhistos[aopath] = ao + else : outhistos[aopath] = ao + elif("ARGUS_1992_I319102" in aopath) : + if("d02" in aopath and sqrts==10.47) : + outhistos[aopath] = ao + elif("d03"in aopath and sqrts=="U4") : + outhistos[aopath] = ao + elif("MC_OmegaPhia1_3Pion_Decay" in aopath) : + if("_1" in aopath and "Omega" in file) : + outhistos[aopath] = ao + elif("_2" in aopath and "Phi" in file) : + outhistos[aopath] = ao + else: + outhistos[aopath] = ao # ## Make empty output histos if needed for hpath,hsets in inhistos.iteritems(): if( hpath.find("4300807")>0 or hpath.find("6132243")>0 or hpath.find("5765862")>0 or hpath.find("295160" )>0 or hpath.find("4328825")>0 or hpath.find("5361494")>0 or hpath.find("190818" )>0 or hpath.find("154270" )>0 or hpath.find("277658" )>0 or hpath.find("2669951")>0 or hpath.find("276860" )>0 or hpath.find("165122" )>0 or hpath.find("118873" )>0 or hpath.find("143691" )>0 or hpath.find("284251" )>0 or hpath.find("191161" )>0 or hpath.find("1422780")>0 or hpath.find("132410" )>0 or "OPAL_2000_I513476" in hpath ): if(hpath=="/PLUTO_1981_I165122/d01-x01-y01" or hpath=="/PLUTO_1981_I165122/d03-x01-y01" ) : continue title="" path="" histo = hsets.values()[0] if hasattr(histo, 'title'): title=histo.title() if hasattr(histo, 'path'): path=histo.path() if(type(histo)==yoda.core.Scatter2D) : outhistos[hpath] = yoda.core.Scatter2D(path,title) elif(type(histo)==yoda.core.Profile1D) : outhistos[hpath] = yoda.core.Profile1D(path,title) for i in range(0,histo.numBins()) : outhistos[hpath].addBin(histo.bins()[i].xMin(), histo.bins()[i].xMax()) elif(type(histo)==yoda.core.Histo1D) : outhistos[hpath] = yoda.core.Histo1D(path,title) for i in range(0,histo.numBins()) : outhistos[hpath].addBin(histo.bins()[i].xMin(), histo.bins()[i].xMax()) else : logging.error("Histogram %s is of unknown type" % hpath) sys.exit(1) # tasso useOne("/TASSO_1990_S2148048/d06-x01-y01","14") useOne("/TASSO_1990_S2148048/d07-x01-y01","14") useOne("/TASSO_1990_S2148048/d08-x01-y01","14") useOne("/TASSO_1990_S2148048/d06-x01-y02","22") useOne("/TASSO_1990_S2148048/d07-x01-y02","22") useOne("/TASSO_1990_S2148048/d08-x01-y02","22") useOne("/TASSO_1990_S2148048/d06-x01-y03","35") useOne("/TASSO_1990_S2148048/d07-x01-y03","35") useOne("/TASSO_1990_S2148048/d08-x01-y03","35") useOne("/TASSO_1990_S2148048/d06-x01-y04","44") useOne("/TASSO_1990_S2148048/d07-x01-y04","44") useOne("/TASSO_1990_S2148048/d08-x01-y04","44") # jade useOne("/JADE_1998_S3612880/d02-x01-y01","44") useOne("/JADE_1998_S3612880/d03-x01-y01","44") useOne("/JADE_1998_S3612880/d04-x01-y01","44") useOne("/JADE_1998_S3612880/d05-x01-y01","44") useOne("/JADE_1998_S3612880/d06-x01-y01","35") useOne("/JADE_1998_S3612880/d07-x01-y01","35") useOne("/JADE_1998_S3612880/d08-x01-y01","35") useOne("/JADE_1998_S3612880/d09-x01-y01","35") useOne("/JADE_1998_S3612880/d10-x01-y01","44") useOne("/JADE_1998_S3612880/d11-x01-y01","35") useOne("/JADE_1998_S3612880/d12-x01-y01","22") # opal/jade useOne("/JADE_OPAL_2000_S4300807/d07-x01-y01","35") useOne("/JADE_OPAL_2000_S4300807/d07-x01-y02","35") useOne("/JADE_OPAL_2000_S4300807/d07-x01-y03","35") useOne("/JADE_OPAL_2000_S4300807/d07-x01-y04","35") useOne("/JADE_OPAL_2000_S4300807/d07-x01-y05","35") useOne("/JADE_OPAL_2000_S4300807/d08-x01-y01","44") useOne("/JADE_OPAL_2000_S4300807/d08-x01-y02","44") useOne("/JADE_OPAL_2000_S4300807/d08-x01-y03","44") useOne("/JADE_OPAL_2000_S4300807/d08-x01-y04","44") useOne("/JADE_OPAL_2000_S4300807/d08-x01-y05","44") useOne("/JADE_OPAL_2000_S4300807/d09-x01-y01","91") useOne("/JADE_OPAL_2000_S4300807/d09-x01-y02","91") useOne("/JADE_OPAL_2000_S4300807/d09-x01-y03","91") useOne("/JADE_OPAL_2000_S4300807/d09-x01-y04","91") useOne("/JADE_OPAL_2000_S4300807/d09-x01-y05","91") useOne("/JADE_OPAL_2000_S4300807/d10-x01-y01","133") useOne("/JADE_OPAL_2000_S4300807/d10-x01-y02","133") useOne("/JADE_OPAL_2000_S4300807/d10-x01-y03","133") useOne("/JADE_OPAL_2000_S4300807/d10-x01-y04","133") useOne("/JADE_OPAL_2000_S4300807/d10-x01-y05","133") useOne("/JADE_OPAL_2000_S4300807/d11-x01-y01","161") useOne("/JADE_OPAL_2000_S4300807/d11-x01-y02","161") useOne("/JADE_OPAL_2000_S4300807/d11-x01-y03","161") useOne("/JADE_OPAL_2000_S4300807/d11-x01-y04","161") useOne("/JADE_OPAL_2000_S4300807/d11-x01-y05","161") useOne("/JADE_OPAL_2000_S4300807/d12-x01-y01","172") useOne("/JADE_OPAL_2000_S4300807/d12-x01-y02","172") useOne("/JADE_OPAL_2000_S4300807/d12-x01-y03","172") useOne("/JADE_OPAL_2000_S4300807/d12-x01-y04","172") useOne("/JADE_OPAL_2000_S4300807/d12-x01-y05","172") useOne("/JADE_OPAL_2000_S4300807/d13-x01-y01","183") useOne("/JADE_OPAL_2000_S4300807/d13-x01-y02","183") useOne("/JADE_OPAL_2000_S4300807/d13-x01-y03","183") useOne("/JADE_OPAL_2000_S4300807/d13-x01-y04","183") useOne("/JADE_OPAL_2000_S4300807/d13-x01-y05","183") useOne("/JADE_OPAL_2000_S4300807/d14-x01-y01","189") useOne("/JADE_OPAL_2000_S4300807/d14-x01-y02","189") useOne("/JADE_OPAL_2000_S4300807/d14-x01-y03","189") useOne("/JADE_OPAL_2000_S4300807/d14-x01-y04","189") useOne("/JADE_OPAL_2000_S4300807/d14-x01-y05","189") useOne("/JADE_OPAL_2000_S4300807/d16-x01-y01","35") useOne("/JADE_OPAL_2000_S4300807/d16-x01-y02","35") useOne("/JADE_OPAL_2000_S4300807/d16-x01-y03","35") useOne("/JADE_OPAL_2000_S4300807/d16-x01-y04","35") useOne("/JADE_OPAL_2000_S4300807/d16-x01-y05","35") useOne("/JADE_OPAL_2000_S4300807/d17-x01-y01","44") useOne("/JADE_OPAL_2000_S4300807/d17-x01-y02","44") useOne("/JADE_OPAL_2000_S4300807/d17-x01-y03","44") useOne("/JADE_OPAL_2000_S4300807/d17-x01-y04","44") useOne("/JADE_OPAL_2000_S4300807/d17-x01-y05","44") useOne("/JADE_OPAL_2000_S4300807/d18-x01-y01","91") useOne("/JADE_OPAL_2000_S4300807/d18-x01-y02","91") useOne("/JADE_OPAL_2000_S4300807/d18-x01-y03","91") useOne("/JADE_OPAL_2000_S4300807/d18-x01-y04","91") useOne("/JADE_OPAL_2000_S4300807/d18-x01-y05","91") useOne("/JADE_OPAL_2000_S4300807/d19-x01-y01","133") useOne("/JADE_OPAL_2000_S4300807/d19-x01-y02","133") useOne("/JADE_OPAL_2000_S4300807/d19-x01-y03","133") useOne("/JADE_OPAL_2000_S4300807/d19-x01-y04","133") useOne("/JADE_OPAL_2000_S4300807/d19-x01-y05","133") useOne("/JADE_OPAL_2000_S4300807/d20-x01-y01","161") useOne("/JADE_OPAL_2000_S4300807/d20-x01-y02","161") useOne("/JADE_OPAL_2000_S4300807/d20-x01-y03","161") useOne("/JADE_OPAL_2000_S4300807/d20-x01-y04","161") useOne("/JADE_OPAL_2000_S4300807/d20-x01-y05","161") useOne("/JADE_OPAL_2000_S4300807/d21-x01-y01","172") useOne("/JADE_OPAL_2000_S4300807/d21-x01-y02","172") useOne("/JADE_OPAL_2000_S4300807/d21-x01-y03","172") useOne("/JADE_OPAL_2000_S4300807/d21-x01-y04","172") useOne("/JADE_OPAL_2000_S4300807/d21-x01-y05","172") useOne("/JADE_OPAL_2000_S4300807/d22-x01-y01","183") useOne("/JADE_OPAL_2000_S4300807/d22-x01-y02","183") useOne("/JADE_OPAL_2000_S4300807/d22-x01-y03","183") useOne("/JADE_OPAL_2000_S4300807/d22-x01-y04","183") useOne("/JADE_OPAL_2000_S4300807/d22-x01-y05","183") useOne("/JADE_OPAL_2000_S4300807/d23-x01-y01","189") useOne("/JADE_OPAL_2000_S4300807/d23-x01-y02","189") useOne("/JADE_OPAL_2000_S4300807/d23-x01-y03","189") useOne("/JADE_OPAL_2000_S4300807/d23-x01-y04","189") useOne("/JADE_OPAL_2000_S4300807/d23-x01-y05","189") useOne("/JADE_OPAL_2000_S4300807/d24-x01-y01","35") useOne("/JADE_OPAL_2000_S4300807/d24-x01-y02","35") useOne("/JADE_OPAL_2000_S4300807/d24-x01-y03","35") useOne("/JADE_OPAL_2000_S4300807/d24-x01-y04","35") useOne("/JADE_OPAL_2000_S4300807/d25-x01-y01","44") useOne("/JADE_OPAL_2000_S4300807/d25-x01-y02","44") useOne("/JADE_OPAL_2000_S4300807/d25-x01-y03","44") useOne("/JADE_OPAL_2000_S4300807/d25-x01-y04","44") useOne("/JADE_OPAL_2000_S4300807/d26-x01-y01","91") useOne("/JADE_OPAL_2000_S4300807/d26-x01-y02","91") useOne("/JADE_OPAL_2000_S4300807/d26-x01-y03","91") useOne("/JADE_OPAL_2000_S4300807/d26-x01-y04","91") useOne("/JADE_OPAL_2000_S4300807/d27-x01-y01","133") useOne("/JADE_OPAL_2000_S4300807/d27-x01-y02","133") useOne("/JADE_OPAL_2000_S4300807/d27-x01-y03","133") useOne("/JADE_OPAL_2000_S4300807/d27-x01-y04","133") useOne("/JADE_OPAL_2000_S4300807/d28-x01-y01","161") useOne("/JADE_OPAL_2000_S4300807/d28-x01-y02","161") useOne("/JADE_OPAL_2000_S4300807/d28-x01-y03","161") useOne("/JADE_OPAL_2000_S4300807/d28-x01-y04","161") useOne("/JADE_OPAL_2000_S4300807/d29-x01-y01","172") useOne("/JADE_OPAL_2000_S4300807/d29-x01-y02","172") useOne("/JADE_OPAL_2000_S4300807/d29-x01-y03","172") useOne("/JADE_OPAL_2000_S4300807/d29-x01-y04","172") useOne("/JADE_OPAL_2000_S4300807/d30-x01-y01","183") useOne("/JADE_OPAL_2000_S4300807/d30-x01-y02","183") useOne("/JADE_OPAL_2000_S4300807/d30-x01-y03","183") useOne("/JADE_OPAL_2000_S4300807/d30-x01-y04","183") useOne("/JADE_OPAL_2000_S4300807/d31-x01-y01","189") useOne("/JADE_OPAL_2000_S4300807/d31-x01-y02","189") useOne("/JADE_OPAL_2000_S4300807/d31-x01-y03","189") useOne("/JADE_OPAL_2000_S4300807/d31-x01-y04","189") useOne("/OPAL_2004_S6132243/d01-x01-y01","91") useOne("/OPAL_2004_S6132243/d01-x01-y02","133") useOne("/OPAL_2004_S6132243/d01-x01-y03","177") useOne("/OPAL_2004_S6132243/d01-x01-y04","197") useOne("/OPAL_2004_S6132243/d02-x01-y01","91") useOne("/OPAL_2004_S6132243/d02-x01-y02","133") useOne("/OPAL_2004_S6132243/d02-x01-y03","177") useOne("/OPAL_2004_S6132243/d02-x01-y04","197") useOne("/OPAL_2004_S6132243/d03-x01-y01","91") useOne("/OPAL_2004_S6132243/d03-x01-y02","133") useOne("/OPAL_2004_S6132243/d03-x01-y03","177") useOne("/OPAL_2004_S6132243/d03-x01-y04","197") useOne("/OPAL_2004_S6132243/d04-x01-y01","91") useOne("/OPAL_2004_S6132243/d04-x01-y02","133") useOne("/OPAL_2004_S6132243/d04-x01-y03","177") useOne("/OPAL_2004_S6132243/d04-x01-y04","197") useOne("/OPAL_2004_S6132243/d05-x01-y01","91") useOne("/OPAL_2004_S6132243/d05-x01-y02","133") useOne("/OPAL_2004_S6132243/d05-x01-y03","177") useOne("/OPAL_2004_S6132243/d05-x01-y04","197") useOne("/OPAL_2004_S6132243/d06-x01-y01","91") useOne("/OPAL_2004_S6132243/d06-x01-y02","133") useOne("/OPAL_2004_S6132243/d06-x01-y03","177") useOne("/OPAL_2004_S6132243/d06-x01-y04","197") useOne("/OPAL_2004_S6132243/d07-x01-y01","91") useOne("/OPAL_2004_S6132243/d07-x01-y02","133") useOne("/OPAL_2004_S6132243/d07-x01-y03","177") useOne("/OPAL_2004_S6132243/d07-x01-y04","197") useOne("/OPAL_2004_S6132243/d08-x01-y01","91") useOne("/OPAL_2004_S6132243/d08-x01-y02","133") useOne("/OPAL_2004_S6132243/d08-x01-y03","177") useOne("/OPAL_2004_S6132243/d08-x01-y04","197") useOne("/OPAL_2004_S6132243/d09-x01-y01","91") useOne("/OPAL_2004_S6132243/d09-x01-y02","133") useOne("/OPAL_2004_S6132243/d09-x01-y03","177") useOne("/OPAL_2004_S6132243/d09-x01-y04","197") useOne("/OPAL_2004_S6132243/d10-x01-y01","91") useOne("/OPAL_2004_S6132243/d10-x01-y02","133") useOne("/OPAL_2004_S6132243/d10-x01-y03","177") useOne("/OPAL_2004_S6132243/d10-x01-y04","197") useOne("/OPAL_2004_S6132243/d11-x01-y01","91") useOne("/OPAL_2004_S6132243/d11-x01-y02","133") useOne("/OPAL_2004_S6132243/d11-x01-y03","177") useOne("/OPAL_2004_S6132243/d11-x01-y04","197") useOne("/OPAL_2004_S6132243/d12-x01-y01","91") useOne("/OPAL_2004_S6132243/d12-x01-y02","133") useOne("/OPAL_2004_S6132243/d12-x01-y03","177") useOne("/OPAL_2004_S6132243/d12-x01-y04","197") useOne("/OPAL_2004_S6132243/d13-x01-y01","91") useOne("/OPAL_2004_S6132243/d13-x01-y02","133") useOne("/OPAL_2004_S6132243/d13-x01-y03","177") useOne("/OPAL_2004_S6132243/d13-x01-y04","197") useOne("/OPAL_2004_S6132243/d14-x01-y01","91") useOne("/OPAL_2004_S6132243/d14-x01-y02","133") useOne("/OPAL_2004_S6132243/d14-x01-y03","177") useOne("/OPAL_2004_S6132243/d14-x01-y04","197") useOne("/OPAL_2004_S6132243/d15-x01-y01","91") useOne("/OPAL_2004_S6132243/d15-x01-y02","133") useOne("/OPAL_2004_S6132243/d15-x01-y03","177") useOne("/OPAL_2004_S6132243/d15-x01-y04","197") useOne("/OPAL_2004_S6132243/d16-x01-y01","91") useOne("/OPAL_2004_S6132243/d16-x01-y02","133") useOne("/OPAL_2004_S6132243/d16-x01-y03","177") useOne("/OPAL_2004_S6132243/d16-x01-y04","197") useOne("/OPAL_2004_S6132243/d17-x01-y01","91") useOne("/OPAL_2004_S6132243/d17-x01-y02","133") useOne("/OPAL_2004_S6132243/d17-x01-y03","177") useOne("/OPAL_2004_S6132243/d17-x01-y04","197") useOne("/OPAL_2004_S6132243/d18-x01-y01","91") useOne("/OPAL_2004_S6132243/d18-x01-y02","133") useOne("/OPAL_2004_S6132243/d18-x01-y03","177") useOne("/OPAL_2004_S6132243/d18-x01-y04","197") useOne("/OPAL_2004_S6132243/d19-x01-y01","91") useOne("/OPAL_2004_S6132243/d19-x01-y02","133") useOne("/OPAL_2004_S6132243/d19-x01-y03","177") useOne("/OPAL_2004_S6132243/d19-x01-y04","197") useOne("/OPAL_2004_S6132243/d20-x01-y01","91") useOne("/OPAL_2004_S6132243/d20-x01-y02","133") useOne("/OPAL_2004_S6132243/d20-x01-y03","177") useOne("/OPAL_2004_S6132243/d20-x01-y04","197") useOne("/OPAL_2004_S6132243/d21-x01-y01","91") useOne("/OPAL_2004_S6132243/d21-x01-y02","133") useOne("/OPAL_2004_S6132243/d21-x01-y03","177") useOne("/OPAL_2004_S6132243/d21-x01-y04","197") useOne("/OPAL_2004_S6132243/d22-x01-y01","91") useOne("/OPAL_2004_S6132243/d22-x01-y02","133") useOne("/OPAL_2004_S6132243/d22-x01-y03","177") useOne("/OPAL_2004_S6132243/d22-x01-y04","197") useOne("/OPAL_2004_S6132243/d23-x01-y01","91") useOne("/OPAL_2004_S6132243/d23-x01-y02","133") useOne("/OPAL_2004_S6132243/d23-x01-y03","177") useOne("/OPAL_2004_S6132243/d23-x01-y04","197") useOne("/OPAL_2004_S6132243/d24-x01-y01","91") useOne("/OPAL_2004_S6132243/d24-x01-y02","133") useOne("/OPAL_2004_S6132243/d24-x01-y03","177") useOne("/OPAL_2004_S6132243/d24-x01-y04","197") useOne("/OPAL_2004_S6132243/d25-x01-y01","91") useOne("/OPAL_2004_S6132243/d25-x01-y02","133") useOne("/OPAL_2004_S6132243/d25-x01-y03","177") useOne("/OPAL_2004_S6132243/d25-x01-y04","197") useOne("/OPAL_2004_S6132243/d26-x01-y01","91") useOne("/OPAL_2004_S6132243/d26-x01-y02","133") useOne("/OPAL_2004_S6132243/d26-x01-y03","177") useOne("/OPAL_2004_S6132243/d26-x01-y04","197") merge( "/OPAL_2002_S5361494/d01-x01-y01") merge( "/OPAL_2002_S5361494/d01-x01-y02") merge( "/OPAL_2002_S5361494/d01-x01-y03") merge( "/OPAL_2002_S5361494/d01-x01-y04") merge("/DELPHI_2000_S4328825/d01-x01-y01") merge("/DELPHI_2000_S4328825/d01-x01-y02") merge("/DELPHI_2000_S4328825/d01-x01-y03") merge("/DELPHI_2000_S4328825/d01-x01-y04") merge("/ALEPH_2004_S5765862/d01-x01-y01") useOne("/ALEPH_2004_S5765862/d02-x01-y01","133") useOne("/ALEPH_2004_S5765862/d03-x01-y01","161") useOne("/ALEPH_2004_S5765862/d04-x01-y01","172") useOne("/ALEPH_2004_S5765862/d05-x01-y01","183") useOne("/ALEPH_2004_S5765862/d06-x01-y01","189") useOne("/ALEPH_2004_S5765862/d07-x01-y01","196") useOne("/ALEPH_2004_S5765862/d08-x01-y01","200") useOne("/ALEPH_2004_S5765862/d09-x01-y01","206") useOne("/ALEPH_2004_S5765862/d11-x01-y01","133") useOne("/ALEPH_2004_S5765862/d12-x01-y01","161") useOne("/ALEPH_2004_S5765862/d13-x01-y01","172") useOne("/ALEPH_2004_S5765862/d14-x01-y01","183") useOne("/ALEPH_2004_S5765862/d15-x01-y01","189") useOne("/ALEPH_2004_S5765862/d16-x01-y01","196") useOne("/ALEPH_2004_S5765862/d17-x01-y01","200") useOne("/ALEPH_2004_S5765862/d18-x01-y01","206") useOne("/ALEPH_2004_S5765862/d19-x01-y01","133") useOne("/ALEPH_2004_S5765862/d20-x01-y01","161") useOne("/ALEPH_2004_S5765862/d21-x01-y01","172") useOne("/ALEPH_2004_S5765862/d22-x01-y01","183") useOne("/ALEPH_2004_S5765862/d23-x01-y01","189") useOne("/ALEPH_2004_S5765862/d24-x01-y01","196") useOne("/ALEPH_2004_S5765862/d25-x01-y01","200") useOne("/ALEPH_2004_S5765862/d26-x01-y01","206") useOne("/ALEPH_2004_S5765862/d27-x01-y01","133") useOne("/ALEPH_2004_S5765862/d28-x01-y01","161") useOne("/ALEPH_2004_S5765862/d29-x01-y01","172") useOne("/ALEPH_2004_S5765862/d30-x01-y01","183") useOne("/ALEPH_2004_S5765862/d31-x01-y01","189") useOne("/ALEPH_2004_S5765862/d32-x01-y01","196") useOne("/ALEPH_2004_S5765862/d33-x01-y01","200") useOne("/ALEPH_2004_S5765862/d34-x01-y01","206") useOne("/ALEPH_2004_S5765862/d35-x01-y01","206") useOne("/ALEPH_2004_S5765862/d36-x01-y01","133") useOne("/ALEPH_2004_S5765862/d37-x01-y01","161") useOne("/ALEPH_2004_S5765862/d38-x01-y01","172") useOne("/ALEPH_2004_S5765862/d39-x01-y01","183") useOne("/ALEPH_2004_S5765862/d40-x01-y01","189") useOne("/ALEPH_2004_S5765862/d41-x01-y01","196") useOne("/ALEPH_2004_S5765862/d42-x01-y01","200") useOne("/ALEPH_2004_S5765862/d43-x01-y01","206") useOne("/ALEPH_2004_S5765862/d44-x01-y01","133") useOne("/ALEPH_2004_S5765862/d45-x01-y01","161") useOne("/ALEPH_2004_S5765862/d46-x01-y01","172") useOne("/ALEPH_2004_S5765862/d47-x01-y01","183") useOne("/ALEPH_2004_S5765862/d48-x01-y01","189") useOne("/ALEPH_2004_S5765862/d49-x01-y01","196") useOne("/ALEPH_2004_S5765862/d50-x01-y01","200") useOne("/ALEPH_2004_S5765862/d51-x01-y01","206") useOne("/ALEPH_2004_S5765862/d54-x01-y01","91") useOne("/ALEPH_2004_S5765862/d55-x01-y01","133") useOne("/ALEPH_2004_S5765862/d56-x01-y01","161") useOne("/ALEPH_2004_S5765862/d57-x01-y01","172") useOne("/ALEPH_2004_S5765862/d58-x01-y01","183") useOne("/ALEPH_2004_S5765862/d59-x01-y01","189") useOne("/ALEPH_2004_S5765862/d60-x01-y01","200") useOne("/ALEPH_2004_S5765862/d61-x01-y01","206") useOne("/ALEPH_2004_S5765862/d62-x01-y01","91") useOne("/ALEPH_2004_S5765862/d63-x01-y01","133") useOne("/ALEPH_2004_S5765862/d64-x01-y01","161") useOne("/ALEPH_2004_S5765862/d65-x01-y01","172") useOne("/ALEPH_2004_S5765862/d66-x01-y01","183") useOne("/ALEPH_2004_S5765862/d67-x01-y01","189") useOne("/ALEPH_2004_S5765862/d68-x01-y01","200") useOne("/ALEPH_2004_S5765862/d69-x01-y01","206") useOne("/ALEPH_2004_S5765862/d70-x01-y01","91") useOne("/ALEPH_2004_S5765862/d71-x01-y01","133") useOne("/ALEPH_2004_S5765862/d72-x01-y01","161") useOne("/ALEPH_2004_S5765862/d73-x01-y01","172") useOne("/ALEPH_2004_S5765862/d74-x01-y01","183") useOne("/ALEPH_2004_S5765862/d75-x01-y01","189") useOne("/ALEPH_2004_S5765862/d76-x01-y01","200") useOne("/ALEPH_2004_S5765862/d77-x01-y01","206") useOne("/ALEPH_2004_S5765862/d78-x01-y01","91") useOne("/ALEPH_2004_S5765862/d79-x01-y01","133") useOne("/ALEPH_2004_S5765862/d80-x01-y01","161") useOne("/ALEPH_2004_S5765862/d81-x01-y01","172") useOne("/ALEPH_2004_S5765862/d82-x01-y01","183") useOne("/ALEPH_2004_S5765862/d83-x01-y01","189") useOne("/ALEPH_2004_S5765862/d84-x01-y01","200") useOne("/ALEPH_2004_S5765862/d85-x01-y01","206") useOne("/ALEPH_2004_S5765862/d86-x01-y01","91") useOne("/ALEPH_2004_S5765862/d87-x01-y01","133") useOne("/ALEPH_2004_S5765862/d88-x01-y01","161") useOne("/ALEPH_2004_S5765862/d89-x01-y01","172") useOne("/ALEPH_2004_S5765862/d90-x01-y01","183") useOne("/ALEPH_2004_S5765862/d91-x01-y01","189") useOne("/ALEPH_2004_S5765862/d92-x01-y01","200") useOne("/ALEPH_2004_S5765862/d93-x01-y01","206") useOne("/ALEPH_2004_S5765862/d94-x01-y01","91") useOne("/ALEPH_2004_S5765862/d95-x01-y01","133") useOne("/ALEPH_2004_S5765862/d96-x01-y01","161") useOne("/ALEPH_2004_S5765862/d97-x01-y01","172") useOne("/ALEPH_2004_S5765862/d98-x01-y01","183") useOne("/ALEPH_2004_S5765862/d99-x01-y01","189") useOne("/ALEPH_2004_S5765862/d100-x01-y01","200") useOne("/ALEPH_2004_S5765862/d101-x01-y01","206") useOne("/ALEPH_2004_S5765862/d102-x01-y01","91") useOne("/ALEPH_2004_S5765862/d103-x01-y01","133") useOne("/ALEPH_2004_S5765862/d104-x01-y01","161") useOne("/ALEPH_2004_S5765862/d105-x01-y01","172") useOne("/ALEPH_2004_S5765862/d106-x01-y01","183") useOne("/ALEPH_2004_S5765862/d107-x01-y01","189") useOne("/ALEPH_2004_S5765862/d108-x01-y01","200") useOne("/ALEPH_2004_S5765862/d109-x01-y01","206") useOne("/ALEPH_2004_S5765862/d110-x01-y01","91") useOne("/ALEPH_2004_S5765862/d111-x01-y01","133") useOne("/ALEPH_2004_S5765862/d112-x01-y01","161") useOne("/ALEPH_2004_S5765862/d113-x01-y01","172") useOne("/ALEPH_2004_S5765862/d114-x01-y01","183") useOne("/ALEPH_2004_S5765862/d115-x01-y01","189") useOne("/ALEPH_2004_S5765862/d116-x01-y01","200") useOne("/ALEPH_2004_S5765862/d117-x01-y01","206") useOne("/ALEPH_2004_S5765862/d118-x01-y01","91") useOne("/ALEPH_2004_S5765862/d119-x01-y01","133") useOne("/ALEPH_2004_S5765862/d120-x01-y01","161") useOne("/ALEPH_2004_S5765862/d121-x01-y01","172") useOne("/ALEPH_2004_S5765862/d122-x01-y01","183") useOne("/ALEPH_2004_S5765862/d123-x01-y01","189") useOne("/ALEPH_2004_S5765862/d124-x01-y01","200") useOne("/ALEPH_2004_S5765862/d125-x01-y01","206") useOne("/ALEPH_2004_S5765862/d126-x01-y01","133") useOne("/ALEPH_2004_S5765862/d127-x01-y01","161") useOne("/ALEPH_2004_S5765862/d128-x01-y01","172") useOne("/ALEPH_2004_S5765862/d129-x01-y01","183") useOne("/ALEPH_2004_S5765862/d130-x01-y01","189") useOne("/ALEPH_2004_S5765862/d131-x01-y01","200") useOne("/ALEPH_2004_S5765862/d132-x01-y01","206") useOne("/ALEPH_2004_S5765862/d133-x01-y01","91") useOne("/ALEPH_2004_S5765862/d134-x01-y01","133") useOne("/ALEPH_2004_S5765862/d135-x01-y01","161") useOne("/ALEPH_2004_S5765862/d136-x01-y01","172") useOne("/ALEPH_2004_S5765862/d137-x01-y01","183") useOne("/ALEPH_2004_S5765862/d138-x01-y01","189") useOne("/ALEPH_2004_S5765862/d139-x01-y01","200") useOne("/ALEPH_2004_S5765862/d140-x01-y01","206") useOne("/ALEPH_2004_S5765862/d141-x01-y01","91") useOne("/ALEPH_2004_S5765862/d142-x01-y01","133") useOne("/ALEPH_2004_S5765862/d143-x01-y01","161") useOne("/ALEPH_2004_S5765862/d144-x01-y01","172") useOne("/ALEPH_2004_S5765862/d145-x01-y01","183") useOne("/ALEPH_2004_S5765862/d146-x01-y01","189") useOne("/ALEPH_2004_S5765862/d147-x01-y01","200") useOne("/ALEPH_2004_S5765862/d148-x01-y01","206") useOne("/ALEPH_2004_S5765862/d149-x01-y01","91") useOne("/ALEPH_2004_S5765862/d150-x01-y01","133") useOne("/ALEPH_2004_S5765862/d151-x01-y01","161") useOne("/ALEPH_2004_S5765862/d152-x01-y01","172") useOne("/ALEPH_2004_S5765862/d153-x01-y01","183") useOne("/ALEPH_2004_S5765862/d154-x01-y01","189") useOne("/ALEPH_2004_S5765862/d155-x01-y01","200") useOne("/ALEPH_2004_S5765862/d156-x01-y01","206") useOne("/ALEPH_2004_S5765862/d157-x01-y01","91") useOne("/ALEPH_2004_S5765862/d158-x01-y01","133") useOne("/ALEPH_2004_S5765862/d159-x01-y01","161") useOne("/ALEPH_2004_S5765862/d160-x01-y01","172") useOne("/ALEPH_2004_S5765862/d161-x01-y01","183") useOne("/ALEPH_2004_S5765862/d162-x01-y01","189") useOne("/ALEPH_2004_S5765862/d163-x01-y01","200") useOne("/ALEPH_2004_S5765862/d164-x01-y01","206") useOne("/ALEPH_2004_S5765862/d165-x01-y01","91") useOne("/ALEPH_2004_S5765862/d166-x01-y01","133") useOne("/ALEPH_2004_S5765862/d167-x01-y01","161") useOne("/ALEPH_2004_S5765862/d168-x01-y01","172") useOne("/ALEPH_2004_S5765862/d169-x01-y01","183") useOne("/ALEPH_2004_S5765862/d170-x01-y01","189") useOne("/ALEPH_2004_S5765862/d172-x01-y01","206") useOne("/ALEPH_2004_S5765862/d173-x01-y01","91") useOne("/ALEPH_2004_S5765862/d174-x01-y01","133") useOne("/ALEPH_2004_S5765862/d175-x01-y01","161") useOne("/ALEPH_2004_S5765862/d176-x01-y01","172") useOne("/ALEPH_2004_S5765862/d177-x01-y01","183") useOne("/ALEPH_2004_S5765862/d178-x01-y01","189") useOne("/ALEPH_2004_S5765862/d179-x01-y01","200") useOne("/ALEPH_2004_S5765862/d180-x01-y01","91") useOne("/ALEPH_2004_S5765862/d181-x01-y01","133") useOne("/ALEPH_2004_S5765862/d182-x01-y01","161") useOne("/ALEPH_2004_S5765862/d183-x01-y01","172") useOne("/ALEPH_2004_S5765862/d184-x01-y01","183") useOne("/ALEPH_2004_S5765862/d185-x01-y01","189") useOne("/ALEPH_2004_S5765862/d186-x01-y01","200") useOne("/ALEPH_2004_S5765862/d187-x01-y01","91") useOne("/ALEPH_2004_S5765862/d188-x01-y01","133") useOne("/ALEPH_2004_S5765862/d189-x01-y01","161") useOne("/ALEPH_2004_S5765862/d190-x01-y01","172") useOne("/ALEPH_2004_S5765862/d191-x01-y01","183") useOne("/ALEPH_2004_S5765862/d192-x01-y01","189") useOne("/ALEPH_2004_S5765862/d193-x01-y01","200") useOne("/ALEPH_2004_S5765862/d194-x01-y01","206") useOne("/ALEPH_2004_S5765862/d195-x01-y01","91") useOne("/ALEPH_2004_S5765862/d196-x01-y01","133") useOne("/ALEPH_2004_S5765862/d197-x01-y01","161") useOne("/ALEPH_2004_S5765862/d198-x01-y01","172") useOne("/ALEPH_2004_S5765862/d199-x01-y01","183") useOne("/ALEPH_2004_S5765862/d200-x01-y01","189") useOne("/ALEPH_2004_S5765862/d201-x01-y01","200") useOne("/ALEPH_2004_S5765862/d202-x01-y01","206") useOne("/ALEPH_2004_S5765862/d203-x01-y01","91") useOne("/ALEPH_2004_S5765862/d204-x01-y01","133") useOne("/ALEPH_2004_S5765862/d205-x01-y01","161") useOne("/ALEPH_2004_S5765862/d206-x01-y01","172") useOne("/ALEPH_2004_S5765862/d207-x01-y01","183") useOne("/ALEPH_2004_S5765862/d208-x01-y01","189") useOne("/ALEPH_2004_S5765862/d209-x01-y01","200") useOne("/ALEPH_2004_S5765862/d210-x01-y01","206") useOne("/ALEPH_2004_S5765862/d211-x01-y01","91") useOne("/ALEPH_2004_S5765862/d212-x01-y01","133") useOne("/ALEPH_2004_S5765862/d213-x01-y01","161") useOne("/ALEPH_2004_S5765862/d214-x01-y01","172") useOne("/ALEPH_2004_S5765862/d215-x01-y01","183") useOne("/ALEPH_2004_S5765862/d216-x01-y01","189") useOne("/ALEPH_2004_S5765862/d217-x01-y01","200") useOne("/ALEPH_2004_S5765862/d218-x01-y01","206") useOne("/ALEPH_2004_S5765862/d219-x01-y01","91") useOne("/ALEPH_2004_S5765862/d220-x01-y01","133") useOne("/ALEPH_2004_S5765862/d221-x01-y01","161") useOne("/ALEPH_2004_S5765862/d222-x01-y01","172") useOne("/ALEPH_2004_S5765862/d223-x01-y01","183") useOne("/ALEPH_2004_S5765862/d224-x01-y01","189") useOne("/ALEPH_2004_S5765862/d225-x01-y01","200") useOne("/ALEPH_2004_S5765862/d226-x01-y01","206") useOne("/ALEPH_2004_S5765862/d227-x01-y01","91") useOne("/ALEPH_2004_S5765862/d228-x01-y01","133") useOne("/ALEPH_2004_S5765862/d229-x01-y01","161") useOne("/ALEPH_2004_S5765862/d230-x01-y01","172") useOne("/ALEPH_2004_S5765862/d231-x01-y01","183") useOne("/ALEPH_2004_S5765862/d232-x01-y01","189") useOne("/ALEPH_2004_S5765862/d233-x01-y01","200") useOne("/ALEPH_2004_S5765862/d234-x01-y01","206") # hadron multiplicities useOne("/PDG_HADRON_MULTIPLICITIES/d01-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d02-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d03-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d04-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d05-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d06-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d07-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d08-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d09-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d13-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d15-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d17-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d18-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d19-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d20-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d21-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d22-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d23-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d25-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d31-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d38-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d39-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d40-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d44-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d45-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d46-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d47-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d48-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d49-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d50-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d51-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d53-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d54-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES/d01-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d02-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d03-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d04-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d05-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d06-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d07-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d08-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d09-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d13-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d15-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d18-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d19-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d20-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d21-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d22-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d31-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d33-x01-y01","35") useOne("/PDG_HADRON_MULTIPLICITIES/d34-x01-y01","35") useOne("/PDG_HADRON_MULTIPLICITIES/d38-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d39-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d44-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d46-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d47-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d48-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d50-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d51-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES/d01-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d02-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d03-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d04-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d05-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d06-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d07-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d08-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d09-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d10-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d11-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d12-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d13-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d14-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d15-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d16-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d17-x01-y02","91") useOne("/PDG_HADRON_MULTIPLICITIES/d18-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d19-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d20-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d21-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d23-x01-y02","91") useOne("/PDG_HADRON_MULTIPLICITIES/d24-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d25-x01-y02","91") useOne("/PDG_HADRON_MULTIPLICITIES/d26-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d27-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d28-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d29-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d30-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d31-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d32-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d34-x01-y02","91") useOne("/PDG_HADRON_MULTIPLICITIES/d35-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d36-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d37-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d38-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d39-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d40-x01-y02","91") useOne("/PDG_HADRON_MULTIPLICITIES/d41-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d42-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d43-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d44-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d45-x01-y02","91") useOne("/PDG_HADRON_MULTIPLICITIES/d46-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d47-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d48-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d49-x01-y02","91") useOne("/PDG_HADRON_MULTIPLICITIES/d50-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d51-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES/d52-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES/d54-x01-y02","91") useOne("/PDG_HADRON_MULTIPLICITIES/d01-x01-y04","177") useOne("/PDG_HADRON_MULTIPLICITIES/d03-x01-y04","177") useOne("/PDG_HADRON_MULTIPLICITIES/d04-x01-y04","177") useOne("/PDG_HADRON_MULTIPLICITIES/d38-x01-y04","177") useOne("/PDG_HADRON_MULTIPLICITIES/d39-x01-y04","177") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d02-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d03-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d04-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d05-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d06-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d07-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d08-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d09-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d13-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d15-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d17-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d18-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d19-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d20-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d21-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d22-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d23-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d25-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d31-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d38-x01-y01","10" ) useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d39-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d40-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d44-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d45-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d46-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d47-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d48-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d49-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d50-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d51-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d53-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d54-x01-y01","10") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d02-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d03-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d04-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d05-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d06-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d07-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d08-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d09-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d13-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d15-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d18-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d19-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d20-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d21-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d22-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d31-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d33-x01-y01","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d34-x01-y01","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d38-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d39-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d44-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d46-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d47-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d48-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d50-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d51-x01-y02","35") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d02-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d03-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d04-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d05-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d06-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d07-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d08-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d09-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d10-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d11-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d12-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d13-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d14-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d15-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d16-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d17-x01-y02","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d18-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d19-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d20-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d21-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d23-x01-y02","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d24-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d25-x01-y02","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d26-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d27-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d28-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d29-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d30-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d31-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d32-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d34-x01-y02","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d35-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d36-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d37-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d38-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d39-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d40-x01-y02","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d41-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d42-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d43-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d44-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d45-x01-y02","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d46-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d47-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d48-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d49-x01-y02","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d50-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d51-x01-y03","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d52-x01-y01","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d54-x01-y02","91") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d03-x01-y04","177") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d04-x01-y04","177") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d38-x01-y04","177") useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d39-x01-y04","177") # AMY analysis useOne("/AMY_1990_I295160/d01-x01-y01","50") useOne("/AMY_1990_I295160/d01-x01-y02","52") useOne("/AMY_1990_I295160/d01-x01-y03","55") useOne("/AMY_1990_I295160/d01-x01-y04","56") useOne("/AMY_1990_I295160/d01-x01-y05","57") useOne("/AMY_1990_I295160/d01-x01-y06","60") useOne("/AMY_1990_I295160/d01-x01-y07","60.8") useOne("/AMY_1990_I295160/d01-x01-y08","61.4") useOne("/AMY_1990_I295160/d01-x01-y09","57") useOne("/AMY_1990_I295160/d02-x02-y01","57") merge("/AMY_1990_I295160/d02-x01-y01") merge("/JADE_1983_I190818/d01-x01-y01") merge("/PLUTO_1980_I154270/d01-x01-y01") merge("/TASSO_1989_I277658/d02-x01-y01") useOne("/TASSO_1989_I277658/d05-x01-y01","14") useOne("/TASSO_1989_I277658/d05-x01-y02","22") useOne("/TASSO_1989_I277658/d05-x01-y03","34.8") useOne("/TASSO_1989_I277658/d05-x01-y04","43.6") # BELLE useOne("/BELLE_2006_S6265367/d01-x01-y01","10.52") useOne("/BELLE_2006_S6265367/d01-x01-y02","10.52") useOne("/BELLE_2006_S6265367/d01-x01-y03","10.52") useOne("/BELLE_2006_S6265367/d01-x01-y04","10.52") useOne("/BELLE_2006_S6265367/d01-x01-y05","10.52") useOne("/BELLE_2006_S6265367/d01-x01-y06","10.52") useOne("/BELLE_2006_S6265367/d01-x01-y07","10.52") useOne("/BELLE_2006_S6265367/d01-x01-y08","10.52") useOne("/BELLE_2006_S6265367/d02-x01-y01","10.52") useOne("/BELLE_2006_S6265367/d02-x01-y02","10.52") useOne("/BELLE_2006_S6265367/d03-x01-y01","10.52") useOne("/BELLE_2006_S6265367/d03-x01-y02","10.52") useOne("/BELLE_2006_S6265367/d04-x01-y01","10.52") useOne("/BELLE_2006_S6265367/d04-x01-y02","10.52") useOne("/BELLE_2006_S6265367/d05-x01-y01","10.52") useOne("/BELLE_2006_S6265367/d05-x01-y02","10.52") useOne("/BELLE_2006_S6265367/d06-x01-y01","10.52") useOne("/BELLE_2006_S6265367/d06-x01-y02","10.52") useOne("/BELLE_2006_S6265367/d07-x01-y01","10.52") useOne("/BELLE_2006_S6265367/d07-x01-y02","10.52") useOne("/BELLE_2006_S6265367/d08-x01-y01","10.52") useOne("/BELLE_2006_S6265367/d08-x01-y02","10.52") useOne("/BELLE_2006_S6265367/d09-x01-y01","U4") useOne("/BELLE_2006_S6265367/d09-x01-y02","U4") useOne("/BELLE_2006_S6265367/d10-x01-y01","U4") useOne("/BELLE_2006_S6265367/d10-x01-y02","U4") useOne("/BELLE_2006_S6265367/d11-x01-y01","U4") useOne("/BELLE_2006_S6265367/d11-x01-y02","U4") useOne("/BELLE_2006_S6265367/d12-x01-y01","U4") useOne("/BELLE_2006_S6265367/d12-x01-y02","U4") useOne("/BELLE_2006_S6265367/d13-x01-y01","U4") useOne("/BELLE_2006_S6265367/d13-x01-y02","U4") useOne("/BELLE_2006_S6265367/d14-x01-y01","U4") useOne("/BELLE_2006_S6265367/d14-x01-y02","U4") useOne("/BELLE_2006_S6265367/d15-x01-y01","U4") useOne("/BELLE_2006_S6265367/d15-x01-y02","U4") # BABAR useOne("/BABAR_2007_S6895344/d01-x01-y01","10.54") useOne("/BABAR_2007_S6895344/d02-x01-y01","10.54") useOne("/BABAR_2007_S6895344/d03-x01-y01","10.58") useOne("/BABAR_2007_S6895344/d04-x01-y01","10.58") # BABAR useOne("/BABAR_2005_S6181155/d01-x01-y01","10.58") useOne("/BABAR_2005_S6181155/d02-x01-y01","10.58") useOne("/BABAR_2005_S6181155/d02-x01-y02","10.54") useOne("/BABAR_2005_S6181155/d03-x01-y01","10.54") useOne("/BABAR_2005_S6181155/d04-x01-y01","10.58") useOne("/BABAR_2005_S6181155/d05-x01-y01","10.58") useOne("/BABAR_2005_S6181155/d05-x01-y02","10.54") # ARGUS useOne("/ARGUS_1993_S2789213/d01-x01-y01","10.45") useOne("/ARGUS_1993_S2789213/d01-x01-y02","10.45") useOne("/ARGUS_1993_S2789213/d01-x01-y03","10.45") useOne("/ARGUS_1993_S2789213/d01-x01-y04","10.45") useOne("/ARGUS_1993_S2789213/d01-x01-y05","10.45") useOne("/ARGUS_1993_S2789213/d02-x01-y01", "U1") useOne("/ARGUS_1993_S2789213/d02-x01-y02", "U1") useOne("/ARGUS_1993_S2789213/d02-x01-y03", "U1") useOne("/ARGUS_1993_S2789213/d02-x01-y04", "U1") useOne("/ARGUS_1993_S2789213/d02-x01-y05", "U1") useOne("/ARGUS_1993_S2789213/d03-x01-y01","U4") useOne("/ARGUS_1993_S2789213/d03-x01-y02","U4") useOne("/ARGUS_1993_S2789213/d03-x01-y03","U4") useOne("/ARGUS_1993_S2789213/d03-x01-y04","U4") useOne("/ARGUS_1993_S2789213/d03-x01-y05","U4") useOne("/ARGUS_1993_S2789213/d04-x01-y01","10.45") useOne("/ARGUS_1993_S2789213/d05-x01-y01", "U1") useOne("/ARGUS_1993_S2789213/d06-x01-y01","U4") useOne("/ARGUS_1993_S2789213/d07-x01-y01","10.45") useOne("/ARGUS_1993_S2789213/d08-x01-y01", "U1") useOne("/ARGUS_1993_S2789213/d09-x01-y01","U4") useOne("/ARGUS_1993_S2789213/d10-x01-y01","10.45") useOne("/ARGUS_1993_S2789213/d11-x01-y01", "U1") useOne("/ARGUS_1993_S2789213/d12-x01-y01","U4") useOne("/ARGUS_1993_S2789213/d13-x01-y01","10.45") useOne("/ARGUS_1993_S2789213/d14-x01-y01", "U1") useOne("/ARGUS_1993_S2789213/d15-x01-y01","U4") if("/ARGUS_1993_S2669951/d04-x01-y01" in outhistos) : useOne("/ARGUS_1993_S2669951/d02-x01-y01","10.45") useOne("/ARGUS_1993_S2669951/d03-x01-y01","U1") useOne("/ARGUS_1993_S2669951/d04-x01-y01","U2") merge("/ARGUS_1993_S2669951/d01-x01-y01") merge("/ARGUS_1993_S2669951/d01-x01-y02") merge("/ARGUS_1993_S2669951/d05-x01-y01") useOne("/ARGUS_1990_I278933/d01-x01-y01","9.46") useOne("/ARGUS_1990_I278933/d01-x01-y02","U1") useOne("/ARGUS_1990_I278933/d01-x01-y03","U2") useOne("/ARGUS_1990_I278933/d02-x01-y01","9.46") useOne("/ARGUS_1990_I278933/d02-x01-y02","U1") useOne("/ARGUS_1990_I278933/d02-x01-y03","U2") useOne("/ARGUS_1990_I278933/d03-x01-y01","9.46") useOne("/ARGUS_1990_I278933/d03-x01-y02","9.46") useOne("/ARGUS_1990_I278933/d04-x01-y01","U1") useOne("/ARGUS_1990_I278933/d04-x01-y02","U2") useOne("/ARGUS_1990_I278933/d05-x01-y01","9.46") useOne("/ARGUS_1990_I278933/d05-x01-y02","9.46") useOne("/ARGUS_1990_I278933/d06-x01-y01","U1") useOne("/ARGUS_1990_I278933/d06-x01-y02","U2") useOne("/ARGUS_1989_I262551/d01-x01-y01","10.00") useOne("/ARGUS_1989_I262551/d02-x01-y01","U1") useOne("/ARGUS_1989_I262551/d02-x01-y02","U2") useOne("/ARGUS_1989_I262551/d03-x01-y01","U1") useOne("/ARGUS_1989_I262551/d04-x01-y01","U2") merge("/ARGUS_1989_I276860/d01-x01-y01") merge("/ARGUS_1989_I276860/d01-x01-y02") merge("/ARGUS_1989_I276860/d02-x01-y01") merge("/ARGUS_1989_I276860/d03-x01-y01") merge("/ARGUS_1989_I276860/d04-x01-y01") merge("/ARGUS_1989_I276860/d04-x01-y02") for i in range(5,13) : useOne("/ARGUS_1989_I276860/d%02d-x01-y01" %i,"U1") useOne("/ARGUS_1989_I276860/d%02d-x01-y02" %i,"10.00") for i in range(1,8) : useOne("/ARGUS_1988_I251097/d01-x01-y%02d" %i,"U1") useOne("/ARGUS_1988_I251097/d02-x01-y%02d" %i,"10.00") useOne("/ARGUS_1988_I251097/d03-x01-y01","U1") useOne("/ARGUS_1988_I251097/d04-x01-y01","U2") useOne("/ARGUS_1988_I251097/d05-x01-y01","10.00") useOne("/ARGUS_1988_I251097/d06-x01-y01","10.00") useOne("/ARGUS_1988_I251097/d07-x01-y01","U1") useOne("/ARGUS_1988_I251097/d08-x01-y01","U2") useOne("/ARGUS_1988_I251097/d09-x01-y01","10.00") useOne("/ARGUS_1989_I262415/d03-x01-y01","U1") useOne("/ARGUS_1989_I262415/d04-x01-y01","10.00") merge("/PLUTO_1981_I165122/d01-x01-y01") merge("/PLUTO_1981_I165122/d02-x01-y01") useOne("/PLUTO_1981_I165122/d06-x01-y01","U1") useOne("/PLUTO_1981_I165122/d04-x01-y01","30.2") useOne("/PLUTO_1981_I165122/d05-x01-y01","9.4") useOne("/PLUTO_1977_I118873/d02-x01-y01","3.63") useOne("/PLUTO_1977_I118873/d03-x01-y01","4.03") useOne("/PLUTO_1977_I118873/d04-x01-y01","4.5") useOne("/TASSO_1982_I177174/d01-x01-y01","14.") useOne("/TASSO_1982_I177174/d01-x01-y02","22.") useOne("/TASSO_1982_I177174/d01-x01-y03","34.") for i in range(2,4) : useOne("/TASSO_1982_I177174/d0%s-x01-y01" %i ,"12.") useOne("/TASSO_1982_I177174/d0%s-x01-y02" %i ,"14.") useOne("/TASSO_1982_I177174/d0%s-x01-y03" %i ,"22.") useOne("/TASSO_1982_I177174/d0%s-x01-y04" %i ,"25.") useOne("/TASSO_1982_I177174/d0%s-x01-y05" %i ,"30.") useOne("/TASSO_1982_I177174/d0%s-x01-y06" %i ,"34.") useOne("/TASSO_1982_I177174/d0%s-x01-y07" %i ,"35.") merge("/TASSO_1980_I143691/d01-x01-y01") useOne("/TASSO_1980_I143691/d02-x01-y01","13.") useOne("/TASSO_1980_I143691/d05-x01-y01","13.") if("/TASSO_1980_I143691/d03-x01-y01" in inhistos) : average("/TASSO_1980_I143691/d03-x01-y01","17.","22.") average("/TASSO_1980_I143691/d06-x01-y01","17.","22.") useOne("/TASSO_1980_I143691/d04-x01-y01","30.2") useOne("/TASSO_1980_I143691/d07-x01-y01","30.2") useOne("/TASSO_1990_I284251/d01-x01-y01","42.6") useOne("/TASSO_1990_I284251/d01-x01-y02","35.") useOne("/TASSO_1990_I284251/d01-x01-y03","34.5") useOne("/TASSO_1990_I284251/d02-x01-y01","14.8") useOne("/TASSO_1990_I284251/d03-x01-y01","21.5") merge("/TASSO_1990_I284251/d04-x01-y01") useOne("/TASSO_1990_I284251/d05-x01-y01","42.6") useOne("/TASSO_1990_I284251/d05-x01-y02","42.6") useOne("/TASSO_1990_I284251/d05-x01-y03","35") useOne("/TASSO_1990_I284251/d05-x01-y04","35") useOne("/TASSO_1990_I284251/d06-x01-y01","14.8") useOne("/TASSO_1990_I284251/d06-x01-y02","14.8") useOne("/TASSO_1990_I284251/d07-x01-y01","21.5") useOne("/TASSO_1990_I284251/d07-x01-y02","21.5") useOne("/TASSO_1990_I284251/d08-x01-y01","42.6") useOne("/TASSO_1990_I284251/d08-x01-y02","35.") useOne("/TASSO_1990_I284251/d08-x01-y03","34.5") merge("/TASSO_1990_I284251/d09-x01-y01") useOne("/TASSO_1990_I284251/d10-x01-y01","35") useOne("/TASSO_1990_I284251/d10-x01-y02","35") merge("/DASP_1979_I132410/d01-x01-y01") # BES xi analysis useOne("/BESIII_2016_I1422780/d02-x01-y01","psi") useOne("/BESIII_2016_I1422780/d02-x01-y02","psi") useOne("/BESIII_2016_I1422780/d02-x01-y03","psi") useOne("/BESIII_2016_I1422780/d02-x01-y04","psi2s") useOne("/BESIII_2016_I1422780/d02-x01-y05","psi2s") useOne("/BESIII_2016_I1422780/d02-x01-y06","psi2s") if ( "/BESIII_2016_I1422780/d01-x01-y03" in inhistos and "psi" in inhistos["/BESIII_2016_I1422780/d01-x01-y03"]) : for point in inhistos["/BESIII_2016_I1422780/d01-x01-y03"]["psi"].points(): outhistos["/BESIII_2016_I1422780/d01-x01-y03"].addPoint(point) if ( "/BESIII_2016_I1422780/d01-x01-y03" in inhistos and "psi2s" in inhistos["/BESIII_2016_I1422780/d01-x01-y03"]) : for point in inhistos["/BESIII_2016_I1422780/d01-x01-y03"]["psi2s"].points(): outhistos["/BESIII_2016_I1422780/d01-x01-y03"].addPoint(point) # pluto analysis for id in range(1,3) : for iy in range(1,5) : merge("/PLUTO_1983_I191161/d0%s-x01-y0%s" % (id,iy)) merge("/OPAL_2000_I513476/d14-x01-y01") merge("/OPAL_2000_I513476/d20-x01-y01") merge("/OPAL_2000_I513476/d20-x01-y02") merge("/OPAL_2000_I513476/d20-x01-y03") merge("/OPAL_2000_I513476/d20-x01-y04") # Choose output file name = args[0]+".yoda" # output the yoda file yoda.writeYODA(outhistos,name) sys.exit(0) diff --git a/Tests/python/merge-LHC-EW b/Tests/python/merge-LHC-EW --- a/Tests/python/merge-LHC-EW +++ b/Tests/python/merge-LHC-EW @@ -1,431 +1,435 @@ #! /usr/bin/env python import logging import sys import os, yoda """%prog Script for merging aida files """ def fillAbove(scale,desthisto, sourcehistosbyptmin) : pthigh= 1e100 ptlow =-1e100 for pt, h in sorted(sourcehistosbyptmin.iteritems(),reverse=True): ptlow=pt if(type(desthisto)==yoda.core.Scatter2D) : for i in range(0,h.numPoints) : xMin = h.points[i].x-h.points[i].xErrs.minus if( xMin*scale >= ptlow and xMin*scale < pthigh ) : desthisto.addPoint(h.points[i]) elif(type(desthisto)==yoda.core.Profile1D) : - for i in range(0,h.numBins) : - if(h.bins[i].xMin*scale >= ptlow and - h.bins[i].xMin*scale < pthigh ) : - desthisto.bins[i] += h.bins[i] + for i in range(0,h.numBins()) : + if(h.bins()[i].xMin()*scale >= ptlow and + h.bins()[i].xMin()*scale < pthigh ) : + desthisto.bins()[i] += h.bins()[i] elif(type(desthisto)==yoda.core.Histo1D) : - for i in range(0,h.numBins) : - if(h.bins[i].xMin*scale >= ptlow and - h.bins[i].xMin*scale < pthigh ) : - desthisto.bins[i] += h.bins[i] + for i in range(0,h.numBins()) : + if(h.bins()[i].xMin()*scale >= ptlow and + h.bins()[i].xMin()*scale < pthigh ) : + desthisto.bins()[i] += h.bins()[i] else : logging.error("Can't merge %s, unknown type" % desthisto.path) sys.exit(1) pthigh=pt def mergeByMass(hpath, sqrts, scale=1.): global inhistos_mass global outhistos try: fillAbove(scale,outhistos[hpath], inhistos_mass[hpath][float(sqrts)]) except: pass def useOneMass(hpath, sqrts, ptmin): global inhistos_mass global outhistos try: ## Find best pT_min match ptmins = inhistos_mass[hpath][float(sqrts)].keys() closest_ptmin = None for ptm in ptmins: if closest_ptmin is None or \ abs(ptm-float(ptmin)) < abs(closest_ptmin-float(ptmin)): closest_ptmin = ptm if closest_ptmin != float(ptmin): logging.warning("Inexact match for requested pTmin=%s: " % ptmin + \ "using pTmin=%e instead" % closest_ptmin) outhistos[hpath] = inhistos_mass[hpath][float(sqrts)][closest_ptmin] except: pass import sys if sys.version_info[:3] < (2,4,0): print "rivet scripts require Python version >= 2.4.0... exiting" sys.exit(1) if __name__ == "__main__": import logging from optparse import OptionParser, OptionGroup parser = OptionParser(usage="%prog base") verbgroup = OptionGroup(parser, "Verbosity control") verbgroup.add_option("-v", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL", default=logging.INFO, help="print debug (very verbose) messages") verbgroup.add_option("-q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL", default=logging.INFO, help="be very quiet") parser.add_option_group(verbgroup) (opts, args) = parser.parse_args() logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s") ## Check args if len(args) < 1: logging.error("Must specify at least the name of the files") sys.exit(1) yodafiles=["-13-Z-e","-13-Z-mu","-Z-HighMass1-e","-Z-HighMass2-e", "-8-Z-Mass1-e","-8-Z-Mass1-mu","-8-Z-Mass2-e","-8-Z-Mass2-mu","-8-Z-Mass3-e","-8-Z-Mass3-mu","-8-Z-Mass4-e","-8-Z-Mass4-mu", "-W-e","-W-mu","-Z-e","-Z-mu","-Z-mu-Short","-Z-LowMass-e","-Z-LowMass-mu", "-Z-MedMass-e", "-WW-emu","-WW-ll","-WZ","-ZZ-ll","-ZZ-lv","-8-WZ","-13-WZ","-8-ZZ-lv","-8-WW-ll", "-7-W-Jet-1-e","-7-W-Jet-2-e","-7-W-Jet-3-e","-7-Z-Jet-1-e","-7-Z-Jet-2-e","-7-Z-Jet-3-e", "-7-WGamma-e","-7-WGamma-mu","-7-ZGamma-e","-7-ZGamma-mu"] ## Get histos outhistos={} inhistos_mass = {} for f in yodafiles: file='Rivet-'+args[0]+f+".yoda" if not os.access(file, os.R_OK): logging.error("%s can not be read" % file) continue try: aos = yoda.read(file) except: logging.error("%s can not be parsed as yoda" % file) continue mass=66 if(file.find("HighMass1")>=0) : mass = 116 elif(file.find("HighMass2")>=0) : mass = 400 elif(file.find("Mass1")>=0) : mass = 12 elif(file.find("Mass2")>=0) : mass = 30 elif(file.find("Mass3")>=0) : mass = 66 elif(file.find("Mass4")>=0) : mass = 116 ## Get histos from this YODA file for aopath, ao in aos.iteritems() : if("RAW" in aopath) :continue if(aopath.find("ATLAS_2010_S8919674")>0) : if((aopath.find("d01")>0 or aopath.find("d05")>0 or aopath.find("d07")>0) and file.find("-e")>0) : outhistos[aopath] = ao elif((aopath.find("d02")>0 or aopath.find("d06")>0 or aopath.find("d08")>0) and file.find("-mu")>0) : outhistos[aopath] = ao elif (aopath.find("ATLAS_2011_S9131140")>0) : if(aopath.find("d01")>0 and file.find("-e")>0) : outhistos[aopath] = ao elif(aopath.find("d02")>0 and file.find("-mu")>0) : outhistos[aopath] = ao elif (aopath.find("ATLAS_2011_I925932")>0) : if(aopath.find("d01")>0 and file.find("-e")>0) : outhistos[aopath] = ao elif(aopath.find("d02")>0 and file.find("-mu")>0) : outhistos[aopath] = ao elif (aopath.find("ATLAS_2011_I945498")>0) : if(aopath.find("y01")>0 and file.find("-e")>0) : outhistos[aopath] = ao elif(aopath.find("y02")>0 and file.find("-mu")>0) : outhistos[aopath] = ao elif(aopath.find("y03")>0 and file.find("-mu")>0) : outhistos[aopath] = ao elif (aopath.find("ATLAS_2013_I1217867")>0) : if(aopath.find("y01")>0 and file.find("-e")>0) : outhistos[aopath] = ao elif(aopath.find("y02")>0 and file.find("-mu")>0) : outhistos[aopath] = ao elif (aopath.find("CMS_2012_I941555")>0) : if((aopath.find("y01")>0 or aopath.find("y03")>0 ) and file.find("-mu")>0) : outhistos[aopath] = ao elif(aopath.find("y02")>0 and file.find("-e")>0) : outhistos[aopath] = ao elif (aopath.find("ATLAS_2014_I1300647" )>0) : if(aopath.find("y01")>0 and file.find("-e")>0) : outhistos[aopath] = ao elif((not aopath.find("y01")>0) and file.find("-mu")>0) : outhistos[aopath] = ao elif (aopath.find("ATLAS_2014_I1288706" )>0) : if(aopath.find("y02")>0 and file.find("-e")>0) : outhistos[aopath] = ao elif(aopath.find("y01")>0 and file.find("-mu")>0) : outhistos[aopath] = ao elif (aopath.find("ATLAS_2012_I1204784" )>0) : if( file.find("-e")>0 and ( aopath.find("d03")>0 or ((aopath.find("d01")>0 or aopath.find("d02")>0) and aopath.find("y01")>0))) : outhistos[aopath] = ao elif(file.find("-mu")>0 and ( aopath.find("d04")>0 or ((aopath.find("d01")>0 or aopath.find("d02")>0) and aopath.find("y02")>0))) : outhistos[aopath] = ao elif (aopath.find("ATLAS_2014_I1312627_EL") >0) : if(file.find("-e")>0) : if(file.find("W")>0 and aopath.find("x02")>0) : outhistos[aopath] = ao elif(file.find("Z")>0 and aopath.find("x03")>0) : outhistos[aopath] = ao elif (aopath.find("ATLAS_2014_I1312627_MU") >0) : if(file.find("-mu")>0) : if(file.find("W")>0 and aopath.find("x02")>0) : outhistos[aopath] = ao elif(file.find("Z")>0 and aopath.find("x03")>0) : outhistos[aopath] = ao elif (aopath.find("ATLAS_2014_I1312627") >0) : if(file.find("-e")>0) : if(file.find("W")>0 and aopath.find("x02")>0) : outhistos[aopath] = ao elif(file.find("Z")>0 and aopath.find("x03")>0) : outhistos[aopath] = ao elif (aopath.find("CMS_2013_I1224539_WJET" )>0) : if(file.find("-1-e")>0 and (aopath.find("d52")>0 or aopath.find("d53")>0 or aopath.find("d56")>0 or aopath.find("d57")>0 or aopath.find("d60")>0 or aopath.find("d61")>0 or aopath.find("d64")>0 or aopath.find("d65")>0 or aopath.find("d68")>0 or aopath.find("d69")>0 or aopath.find("d72")>0)) : outhistos[aopath] = ao elif(file.find("-2-e")>0 and (aopath.find("d54")>0 or aopath.find("d58")>0 or aopath.find("d62")>0 or aopath.find("d66")>0 or aopath.find("d70")>0 or aopath.find("d73")>0)) : outhistos[aopath] = ao elif(file.find("-3-e")>0 and (aopath.find("d55")>0 or aopath.find("d59")>0 or aopath.find("d63")>0 or aopath.find("d67")>0 or aopath.find("d71")>0 or aopath.find("d74")>0)) : outhistos[aopath] = ao elif (aopath.find("CMS_2013_I1224539_ZJET" )>0) : if(file.find("-1-e")>0 and (aopath.find("d29")>0 or aopath.find("d30")>0 or aopath.find("d33")>0 or aopath.find("d34")>0 or aopath.find("d37")>0 or aopath.find("d38")>0 or aopath.find("d41")>0 or aopath.find("d42")>0 or aopath.find("d45")>0 or aopath.find("d46")>0 or aopath.find("d49")>0)) : outhistos[aopath] = ao elif(file.find("-2-e")>0 and (aopath.find("d31")>0 or aopath.find("d35")>0 or aopath.find("d39")>0 or aopath.find("d43")>0 or aopath.find("d47")>0 or aopath.find("d50")>0)) : outhistos[aopath] = ao elif(file.find("-3-e")>0 and (aopath.find("d32")>0 or aopath.find("d36")>0 or aopath.find("d40")>0 or aopath.find("d44")>0 or aopath.find("d48")>0 or aopath.find("d51")>0)) : outhistos[aopath] = ao elif (aopath.find("CMS_2013_I1258128")>0) : if(aopath.find("d01")>0 or aopath.find("d02")>0 or aopath.find("d03")>0 or aopath.find("d04")>0) : outhistos[aopath] = ao elif (aopath.find("CMS_2013_I1209721" )>0 and file.find("-0")>0 ) : outhistos[aopath] = ao elif (aopath.find("ATLAS_2011_I928289")>0) : if(file.find("-e")>=0 and (aopath.find("y01")>=0 or aopath.find("y02")>=0)) : outhistos[aopath] = ao elif(file.find("-mu")>=0 and (aopath.find("y03")>=0 or aopath.find("y04")>=0)) : outhistos[aopath] = ao elif (aopath.find("CMS_2013_I1122847")>0) : if(file.find("-mu")>=0 and aopath.find("d01")>=0 ) : outhistos[aopath] = ao elif(file.find("-e")>=0 and (aopath.find("d02")>=0 or aopath.find("d03")>=0)) : outhistos[aopath] = ao elif (aopath.find("ATLAS_2016_I1424838")>0) : ihist = int(aopath.split("/")[2].split("-")[0].replace("d","")) if(file.find("-mu")>=0 and ihist>30 ) : outhistos[aopath] = ao elif(file.find("-e")>=0 and ihist<=30) : outhistos[aopath] = ao elif ("CMS_2015_I1310737" in aopath or "ATLAS_2013_I1219109" in aopath or ("ATLAS_2014_I1319490" in aopath and "y01" in aopath )) : if aopath in outhistos : outhistos[aopath] += ao else : outhistos[aopath] = ao elif (aopath.find("ATLAS_2015_I1351916")>=0) : if(aopath.find("-y01")>=0) : pathBase = aopath.replace("-y01","") hp = aos[pathBase+"-y02"] hm = aos[pathBase+"-y03"] ratio = (hp-hm)/(hp+hm) hnew = yoda.Scatter2D(aopath,ao.title) hnew.combineWith(ratio) outhistos[aopath] = hnew else : continue elif (aopath.find("ATLAS_2014_I1282447")>=0) : if((aopath.find("/ATLAS_2014_I1282447/d02-x01-y01")>=0 or aopath.find("/ATLAS_2014_I1282447/d08-x01-y01")>=0 or aopath.find("/ATLAS_2014_I1282447/d02-x01-y02")>=0 or aopath.find("/ATLAS_2014_I1282447/d02-x01-y01")>=0 or aopath.find("/ATLAS_2014_I1282447/d05-x01-y02")>=0 or aopath.find("/ATLAS_2014_I1282447/d05-x01-y03")>=0 or aopath.find("/ATLAS_2014_I1282447/d06-x01-y01")>=0 or aopath.find("/ATLAS_2014_I1282447/d06-x01-y02")>=0 or aopath.find("/ATLAS_2014_I1282447/d06-x01-y03")>=0 or aopath.find("/ATLAS_2014_I1282447/d06-x01-y04")>=0) and not (aopath.find("plus")>=0 or aopath.find("minus")>=0 or aopath.find("inc")>=0)) : continue if aopath in outhistos : outhistos[aopath] += ao else : outhistos[aopath] = ao elif (aopath.find("ATLAS_2015_I1408516")>=0) : if not inhistos_mass.has_key(aopath): inhistos_mass[aopath] = {} tmpE = inhistos_mass[aopath] sqrts=8000 if not tmpE.has_key(sqrts): tmpE[sqrts] = {} tmpP = tmpE[sqrts] if not tmpP.has_key(mass): tmpP[mass] = ao else: raise Exception("A set with mass = %s already exists" % ( mass)) elif (aopath.find("ATLAS_2013_I1234228")>=0) : if not inhistos_mass.has_key(aopath): inhistos_mass[aopath] = {} tmpE = inhistos_mass[aopath] sqrts=7000 if not tmpE.has_key(sqrts): tmpE[sqrts] = {} tmpP = tmpE[sqrts] if not tmpP.has_key(mass): tmpP[mass] = ao else: raise Exception("A set with mass = %s already exists" % ( mass)) elif ( "2015_041_" in aopath) : aopath=aopath.replace("_EL","").replace("_MU","") - ao.path = aopath + ao.setPath(aopath) outhistos[aopath] = ao else : outhistos[aopath] = ao for hpath,hsets in inhistos_mass.iteritems(): - if(hpath!="/ATLAS_2015_I1408516_EL/d41-x01-y01" and - hpath!="/ATLAS_2015_I1408516_MU/d41-x01-y02" and + if(hpath!="/ATLAS_2015_I1408516:LMODE=EL/d41-x01-y01" and + hpath!="/ATLAS_2015_I1408516:LMODE=MU/d41-x01-y02" and hpath!="/ATLAS_2013_I1234228/d01-x01-y02" ) : continue - if(type(hsets.values()[0].values()[0])==yoda.core.Scatter2D) : - outhistos[hpath] = yoda.core.Scatter2D(hsets.values()[0].values()[0].path, - hsets.values()[0].values()[0].title) - elif(type(hsets.values()[0].values()[0])==yoda.core.Profile1D) : - outhistos[hpath] = yoda.core.Profile1D(hsets.values()[0].values()[0].path, - hsets.values()[0].values()[0].title) - for i in range(0,hsets.values()[0].values()[0].numBins) : - outhistos[hpath].addBin(hsets.values()[0].values()[0].bins[i].xMin, - hsets.values()[0].values()[0].bins[i].xMax) - elif(type(hsets.values()[0].values()[0])==yoda.core.Histo1D) : - outhistos[hpath] = yoda.core.Histo1D(hsets.values()[0].values()[0].path, - hsets.values()[0].values()[0].title) - for i in range(0,hsets.values()[0].values()[0].numBins) : - outhistos[hpath].addBin(hsets.values()[0].values()[0].bins[i].xMin, - hsets.values()[0].values()[0].bins[i].xMax) + title="" + path="" + histo = hsets.values()[0].values()[0] + if hasattr(histo, 'title'): + title=histo.title() + if hasattr(histo, 'path'): + path=histo.path() + if(type(histo)==yoda.core.Scatter2D) : + outhistos[hpath] = yoda.core.Scatter2D(path,title) + elif(type(histo)==yoda.core.Profile1D) : + outhistos[hpath] = yoda.core.Profile1D(path,title) + for i in range(0,histo.numBins()) : + outhistos[hpath].addBin(histo.bins()[i].xMin(), + histo.bins()[i].xMax()) + elif(type(histo)==yoda.core.Histo1D) : + outhistos[hpath] = yoda.core.Histo1D(path,title) + for i in range(0,histo.numBins()) : + outhistos[hpath].addBin(histo.bins()[i].xMin(), + histo.bins()[i].xMax()) else : logging.error("Histogram %s is of unknown type" % hpath) sys.exit(1) # sort out mass bins for ATLAS Z-> e,mu at 8 TeV for ltype in ["EL","MU"] : if(ltype=="EL") : y = "y01" - mergeByMass("/ATLAS_2015_I1408516_EL/d41-x01-y01", "8000") + mergeByMass("/ATLAS_2015_I1408516:LMODE=EL/d41-x01-y01", "8000") else : y = "y04" - mergeByMass("/ATLAS_2015_I1408516_MU/d41-x01-y02", "8000") + mergeByMass("/ATLAS_2015_I1408516:LMODE=MU/d41-x01-y02", "8000") for d in [2,3,04,14,26,38]: - useOneMass("/ATLAS_2015_I1408516_%s/d%02d-x01-%s" % (ltype,d,y), "8000", "30" ) + useOneMass("/ATLAS_2015_I1408516:LMODE=%s/d%02d-x01-%s" % (ltype,d,y), "8000", "30" ) for d in [5,6,7,8,9,10,15,17,18,19,20,21,22,27,29,30,31,32,33,34,39]: - useOneMass("/ATLAS_2015_I1408516_%s/d%02d-x01-%s" % (ltype,d,y), "8000", "66" ) + useOneMass("/ATLAS_2015_I1408516:LMODE=%s/d%02d-x01-%s" % (ltype,d,y), "8000", "66" ) for d in [11,12,13,16,28,40]: - useOneMass("/ATLAS_2015_I1408516_%s/d%02d-x01-%s" % (ltype,d,y), "8000", "116" ) + useOneMass("/ATLAS_2015_I1408516:LMODE=%s/d%02d-x01-%s" % (ltype,d,y), "8000", "116" ) for d in [23,35]: - useOneMass("/ATLAS_2015_I1408516_%s/d%02d-x01-%s" % (ltype,d,y), "8000", "12" ) + useOneMass("/ATLAS_2015_I1408516:LMODE=%s/d%02d-x01-%s" % (ltype,d,y), "8000", "12" ) for d in [24,36]: - useOneMass("/ATLAS_2015_I1408516_%s/d%02d-x01-%s" % (ltype,d,y), "8000", "12" ) + useOneMass("/ATLAS_2015_I1408516:LMODE=%s/d%02d-x01-%s" % (ltype,d,y), "8000", "12" ) for d in [25,37]: - useOneMass("/ATLAS_2015_I1408516_%s/d%02d-x01-%s" % (ltype,d,y), "8000", "30" ) + useOneMass("/ATLAS_2015_I1408516:LMODE=%s/d%02d-x01-%s" % (ltype,d,y), "8000", "30" ) # sort out ratios for ATLAS W+c if("/ATLAS_2014_I1282447/d02-x01-y01_plus" in outhistos and "/ATLAS_2014_I1282447/d02-x01-y01_minus" in outhistos) : d02y01_plus = outhistos["/ATLAS_2014_I1282447/d02-x01-y01_plus"] d02y01_minus = outhistos["/ATLAS_2014_I1282447/d02-x01-y01_minus"] ratio_d02y01 = d02y01_plus/d02y01_minus - ratio_d02y01.path = "/ATLAS_2014_I1282447/d02-x01-y01" + ratio_d02y01.setPath("/ATLAS_2014_I1282447/d02-x01-y01") del outhistos["/ATLAS_2014_I1282447/d02-x01-y01_plus"] del outhistos["/ATLAS_2014_I1282447/d02-x01-y01_minus"] outhistos["/ATLAS_2014_I1282447/d02-x01-y01"] = ratio_d02y01 if("/ATLAS_2014_I1282447/d02-x01-y02_plus" in outhistos and "/ATLAS_2014_I1282447/d02-x01-y02_minus" in outhistos) : d02y02_plus = outhistos["/ATLAS_2014_I1282447/d02-x01-y02_plus"] d02y02_minus = outhistos["/ATLAS_2014_I1282447/d02-x01-y02_minus"] ratio_d02y02 = d02y02_plus/d02y02_minus - ratio_d02y02.path = "/ATLAS_2014_I1282447/d02-x01-y02" + ratio_d02y02.setPath("/ATLAS_2014_I1282447/d02-x01-y02") del outhistos["/ATLAS_2014_I1282447/d02-x01-y02_plus"] del outhistos["/ATLAS_2014_I1282447/d02-x01-y02_minus"] outhistos["/ATLAS_2014_I1282447/d02-x01-y02"] = ratio_d02y02 if("/ATLAS_2014_I1282447/d08-x01-y01_plus" in outhistos and "/ATLAS_2014_I1282447/d08-x01-y01_minus" in outhistos) : d08y01_plus = outhistos["/ATLAS_2014_I1282447/d08-x01-y01_plus"] d08y01_minus = outhistos["/ATLAS_2014_I1282447/d08-x01-y01_minus"] ratio_d08y01 = d08y01_plus/d08y01_minus - ratio_d08y01.path = "/ATLAS_2014_I1282447/d08-x01-y01" + ratio_d08y01.setPath("/ATLAS_2014_I1282447/d08-x01-y01") del outhistos["/ATLAS_2014_I1282447/d08-x01-y01_plus"] del outhistos["/ATLAS_2014_I1282447/d08-x01-y01_minus"] outhistos["/ATLAS_2014_I1282447/d08-x01-y01"] = ratio_d08y01 if ("/ATLAS_2014_I1282447/d05-x01-y01" in outhistos and "/ATLAS_2014_I1282447/d01-x01-y02" in outhistos) : h_winc = outhistos["/ATLAS_2014_I1282447/d05-x01-y01"] h_d = outhistos["/ATLAS_2014_I1282447/d01-x01-y02"] ratio_wd = h_d/h_winc - ratio_wd.path = "/ATLAS_2014_I1282447/d05-x01-y02" + ratio_wd.setPath("/ATLAS_2014_I1282447/d05-x01-y02") outhistos["/ATLAS_2014_I1282447/d05-x01-y02"] = ratio_wd if ("/ATLAS_2014_I1282447/d05-x01-y01" in outhistos and "/ATLAS_2014_I1282447/d01-x01-y03" in outhistos) : h_winc = outhistos["/ATLAS_2014_I1282447/d05-x01-y01"] h_dstar= outhistos["/ATLAS_2014_I1282447/d01-x01-y03"] ratio_wdstar = h_dstar/h_winc - ratio_wdstar.path = "/ATLAS_2014_I1282447/d05-x01-y03" + ratio_wdstar.setPath("/ATLAS_2014_I1282447/d05-x01-y03") outhistos["/ATLAS_2014_I1282447/d05-x01-y03"] = ratio_wdstar if("/ATLAS_2014_I1282447/d06-x01-y01_winc" in outhistos and "/ATLAS_2014_I1282447/d06-x01-y02_winc" in outhistos) : h_winc_plus = outhistos["/ATLAS_2014_I1282447/d06-x01-y01_winc"] h_winc_minus = outhistos["/ATLAS_2014_I1282447/d06-x01-y02_winc"] if( "/ATLAS_2014_I1282447/d06-x01-y01_wplus" in outhistos ) : h_wd_plus = outhistos["/ATLAS_2014_I1282447/d06-x01-y01_wplus"] ratio_wd_plus = h_wd_plus/h_winc_plus - ratio_wd_plus.path = "/ATLAS_2014_I1282447/d06-x01-y01" + ratio_wd_plus.setPath("/ATLAS_2014_I1282447/d06-x01-y01") outhistos["/ATLAS_2014_I1282447/d06-x01-y01"] = ratio_wd_plus del outhistos["/ATLAS_2014_I1282447/d06-x01-y01_wplus"] if( "/ATLAS_2014_I1282447/d06-x01-y02_wminus" in outhistos ) : h_wd_minus = outhistos["/ATLAS_2014_I1282447/d06-x01-y02_wminus"] ratio_wd_minus = h_wd_minus/h_winc_minus - ratio_wd_minus.path = "/ATLAS_2014_I1282447/d06-x01-y02" + ratio_wd_minus.setPath("/ATLAS_2014_I1282447/d06-x01-y02") outhistos["/ATLAS_2014_I1282447/d06-x01-y02"] = ratio_wd_minus del outhistos["/ATLAS_2014_I1282447/d06-x01-y02_wminus"] if ( "/ATLAS_2014_I1282447/d06-x01-y03_wplus" in outhistos) : h_wdstar_plus = outhistos["/ATLAS_2014_I1282447/d06-x01-y03_wplus"] ratio_wdstar_plus = h_wdstar_plus/h_winc_plus - ratio_wdstar_plus.path = "/ATLAS_2014_I1282447/d06-x01-y03" + ratio_wdstar_plus.setPath("/ATLAS_2014_I1282447/d06-x01-y03") outhistos["/ATLAS_2014_I1282447/d06-x01-y03"] = ratio_wdstar_plus del outhistos["/ATLAS_2014_I1282447/d06-x01-y03_wplus"] if ( "/ATLAS_2014_I1282447/d06-x01-y04_wminus" in outhistos) : h_wdstar_minus = outhistos["/ATLAS_2014_I1282447/d06-x01-y04_wminus"] ratio_wdstar_minus = h_wdstar_minus/h_winc_minus - ratio_wdstar_minus.path = "/ATLAS_2014_I1282447/d06-x01-y04" + ratio_wdstar_minus.setPath("/ATLAS_2014_I1282447/d06-x01-y04") outhistos["/ATLAS_2014_I1282447/d06-x01-y04"] = ratio_wdstar_minus del outhistos["/ATLAS_2014_I1282447/d06-x01-y04_wminus"] del outhistos["/ATLAS_2014_I1282447/d06-x01-y01_winc"] del outhistos["/ATLAS_2014_I1282447/d06-x01-y02_winc"] mergeByMass("/ATLAS_2013_I1234228/d01-x01-y02", "7000") # ATLAS W/Z ratios iy=0 for suffix in ["","_EL","_MU"] : iy+=1 basePath = "/ATLAS_2014_I1312627%s/" % suffix for ihist in range(1,21) : num = "%sd%02d-x02-y%02d" % (basePath,ihist,iy) den = "%sd%02d-x03-y%02d" % (basePath,ihist,iy) if(den in outhistos and num in outhistos) : ratio = outhistos[num]/outhistos[den] - ratio.path = "%sd%02d-x01-y%02d" % (basePath,ihist,iy) + ratio.setPath("%sd%02d-x01-y%02d" % (basePath,ihist,iy)) del outhistos[num] del outhistos[den] outhistos[ "%sd%02d-x01-y%02d" % (basePath,ihist,iy)]=ratio # Choose output file name = args[0]+"-EW.yoda" yoda.writeYODA(outhistos,name) sys.exit(0) diff --git a/Tests/python/merge-LHC-Jets b/Tests/python/merge-LHC-Jets --- a/Tests/python/merge-LHC-Jets +++ b/Tests/python/merge-LHC-Jets @@ -1,1628 +1,1639 @@ #! /usr/bin/env python import logging import sys import math if sys.version_info[:3] < (2,4,0): print "rivet scripts require Python version >= 2.4.0... exiting" sys.exit(1) import os, yoda # ############################################# def rescale(path,scale) : if(path not in outhistos) : return outhistos[path].scaleW(scale) def fillAbove(scale,desthisto, sourcehistosbyptmin) : pthigh= 1e100 ptlow =-1e100 for pt, h in sorted(sourcehistosbyptmin.iteritems(),reverse=True): ptlow=pt if(type(desthisto)==yoda.core.Scatter2D) : for i in range(0,h.numPoints) : xMin = h.points[i].x-h.points[i].xErrs.minus if( xMin*scale >= ptlow and xMin*scale < pthigh ) : desthisto.addPoint(h.points[i]) elif(type(desthisto)==yoda.core.Profile1D) : - for i in range(0,h.numBins) : - if(h.bins[i].xMin*scale >= ptlow and - h.bins[i].xMin*scale < pthigh ) : - desthisto.bins[i] += h.bins[i] + for i in range(0,h.numBins()) : + if(h.bins()[i].xMin()*scale >= ptlow and + h.bins()[i].xMin()*scale < pthigh ) : + desthisto.bins()[i] += h.bins()[i] elif(type(desthisto)==yoda.core.Histo1D) : - for i in range(0,h.numBins) : - if(h.bins[i].xMin*scale >= ptlow and - h.bins[i].xMin*scale < pthigh ) : - desthisto.bins[i] += h.bins[i] + for i in range(0,h.numBins()) : + if(h.bins()[i].xMin()*scale >= ptlow and + h.bins()[i].xMin()*scale < pthigh ) : + desthisto.bins()[i] += h.bins()[i] elif(type(desthisto)==yoda.core.Counter) : desthisto += h else : logging.error("Can't merge %s, unknown type" % desthisto.path) sys.exit(1) pthigh=pt def mergeByPt(hpath, sqrts, scale=1.) : global inhistos_pt global outhistos try: fillAbove(scale,outhistos[hpath], inhistos_pt[hpath][float(sqrts)]) except: pass def mergeByMass(hpath, sqrts, scale=1.): global inhistos_mass global outhistos try: fillAbove(scale,outhistos[hpath], inhistos_mass[hpath][float(sqrts)]) except: pass def useOnePt(hpath, sqrts, ptmin): global inhistos_pt global outhistos try: ## Find best pT_min match ptmins = inhistos_pt[hpath][float(sqrts)].keys() closest_ptmin = None for ptm in ptmins: if closest_ptmin is None or \ abs(ptm-float(ptmin)) < abs(closest_ptmin-float(ptmin)): closest_ptmin = ptm if closest_ptmin != float(ptmin): logging.warning("Inexact match for requested pTmin=%s: " % ptmin + \ "using pTmin=%e instead" % closest_ptmin) outhistos[hpath] = inhistos_pt[hpath][float(sqrts)][closest_ptmin] except: pass def useOneMass(hpath, sqrts, ptmin): global inhistos_pt global outhistos try: ## Find best pT_min match ptmins = inhistos_mass[hpath][float(sqrts)].keys() closest_ptmin = None for ptm in ptmins: if closest_ptmin is None or \ abs(ptm-float(ptmin)) < abs(closest_ptmin-float(ptmin)): closest_ptmin = ptm if closest_ptmin != float(ptmin): logging.warning("Inexact match for requested mass=%s: " % ptmin + \ "using mass=%e instead" % closest_ptmin) outhistos[hpath] = inhistos_mass[hpath][float(sqrts)][closest_ptmin] except: pass # ####################################### if __name__ == "__main__": import logging from optparse import OptionParser, OptionGroup parser = OptionParser(usage="%prog name") verbgroup = OptionGroup(parser, "Verbosity control") parser.add_option("--with-ue", action='store_true' , dest="ue", default=True, help="Include UE analyses") parser.add_option("--without-ue", action='store_false', dest="ue", default=True, help="Don\'t include UE analyses") verbgroup.add_option("-v", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL", default=logging.INFO, help="print debug (very verbose) messages") verbgroup.add_option("-q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL", default=logging.INFO, help="be very quiet") parser.add_option_group(verbgroup) (opts, args) = parser.parse_args() logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s") (opts, args) = parser.parse_args() ## Check args if len(args) < 1: logging.error("Must specify at least the name of the files") sys.exit(1) yodafiles=["-7-Bottom-0.yoda","-7-Bottom-1.yoda","-7-Bottom-2.yoda", "-7-Bottom-3.yoda","-7-Bottom-4.yoda","-7-Bottom-5.yoda","-7-Bottom-6.yoda", "-7-Charm-1.yoda","-7-Charm-2.yoda", "-7-Charm-3.yoda","-7-Charm-4.yoda","-7-Charm-5.yoda", "-7-Top-SL.yoda","-7-Top-L.yoda", "-8-Top-SL.yoda","-8-Top-L.yoda","-8-Top-All.yoda", "-13-Top-L.yoda","-13-Top-SL.yoda","-13-Top-All.yoda"] for i in range(1,11) : for j in [7,8,13] : yodafiles.append("-%1.1i-Jets-%1.1i.yoda" % (j,i)) for i in range(1,3) : yodafiles.append("-2760-Jets-%1.1i.yoda" % i) if(opts.ue) : yodafiles += ["-7-Jets-0.yoda" ,"-8-Jets-0.yoda" , "-900-UE.yoda" ,"-2360-UE.yoda" , "-2760-UE.yoda" ,"-7-UE.yoda" , "-900-UE-Long.yoda" ,"-8-UE.yoda" , "-7-UE-Long.yoda","-13-UE.yoda","-13-UE-Long.yoda"] ## Get histos inhistos_pt = {} inhistos_mass = {} outhistos={} weights = {} for f in yodafiles: file='Rivet-'+args[0]+f ptmin=0. sqrts=7000 # CMS energy if(file.find("-900-")>0) : sqrts=900 elif(file.find("-2360-")>0) : sqrts=2360 elif(file.find("-2760-")>0) : sqrts=2760 elif(file.find("-7-")>=0) : sqrts=7000 elif(file.find("-8-")>=0) : sqrts=8000 elif(file.find("-13-")>0) : sqrts=13000 # pT min if(file.find("UE")>0) : ptmin=0. elif(file.find("Jets-0")>0) : ptmin=4. elif(file.find("Jets-10")>0) : ptmin=1900. elif(file.find("Jets-1")>0) : if( not opts.ue) : ptmin = 10. else : ptmin = 20. elif(file.find("Jets-2")>0) : ptmin=40. elif(file.find("Jets-3")>0) : ptmin=80. elif(file.find("Jets-4")>0) : ptmin=110. elif(file.find("Jets-5")>0) : ptmin=210. elif(file.find("Jets-6")>0) : ptmin=260. elif(file.find("Jets-7")>0) : ptmin=400. elif(file.find("Jets-8")>0) : ptmin=600. elif(file.find("Jets-9")>0) : ptmin=900. elif(file.find("Bottom-0")>0) : ptmin=0. elif(file.find("Bottom-1")>0 or file.find("Charm-1")>0) : ptmin=10. elif(file.find("Bottom-2")>0 or file.find("Charm-2")>0) : ptmin=20. elif(file.find("Bottom-3")>0 or file.find("Charm-3")>0) : ptmin=30. elif(file.find("Bottom-4")>0 or file.find("Charm-4")>0) : ptmin=70. elif(file.find("Bottom-5")>0 or file.find("Charm-5")>0) : ptmin=100. elif(file.find("Bottom-6")>0 or file.find("Charm-6")>0) : ptmin=130. elif(file.find("Top-SL.yoda")>0 or file.find("Top-L.yoda")>0 or \ file.find("Top-All.yoda")>0): ptmin=0. if not os.access(file, os.R_OK): logging.error("%s can not be read" % file) continue try: aos = yoda.read(file) except: logging.error("%s can not be parsed as YODA" % file) continue ## Get histos from this YODA file for aopath, ao in aos.iteritems() : if("RAW" in aopath) :continue if(aopath.find("S8924791")>0 or aopath.find("S8971293")>0 or aopath.find("S8817804")>0 or aopath.find("I1082936")>0 or aopath.find("S8994773")>0 or aopath.find("S8918562")>0 or aopath.find("S8624100")>0 or aopath.find("S8625980")>0 or aopath.find("S8894728")>0 or aopath.find("S8957746")>0 or aopath.find("S9126244")>0 or aopath.find("S9120041")>0 or aopath.find("S8950903")>0 or aopath.find("S9086218")>0 or aopath.find("S9088458")>0 or aopath.find("I919017" )>0 or aopath.find("I926145" )>0 or aopath.find("S8941262")>0 or aopath.find("S8973270")>0 or aopath.find("I1118269")>0 or aopath.find("I1188891")>0 or aopath.find("I1082009")>0 or aopath.find("I1087342")>0 or aopath.find("S9035664")>0 or aopath.find("I1125575")>0 or aopath.find("I1094564")>0 or aopath.find("I930220" )>0 or aopath.find("I1224539")>0 or aopath.find("I1273574")>0 or aopath.find("I1261026")>0 or aopath.find("I1307243")>0 or aopath.find("I1325553")>0 or aopath.find("I1298810")>0 or aopath.find("I1298811")>0 or aopath.find("I1208923")>0 or aopath.find("I1305624")>0 or aopath.find("I1419070")>0 or aopath.find("I1394679")>0 or aopath.find("I929691" )>0 or aopath.find("I1393758")>0 or aopath.find("I1459051")>0 or aopath.find("I1487277")>0 or aopath.find("I1421646")>0 or aopath.find("I1111014")>0 or aopath.find("I1605749")>0 or aopath.find("I1682495")>0 or aopath.find("I1609253")>0 or aopath.find("1385107" )>0 or aopath.find("I1486238")>0 or aopath.find("1634970" )>0 or aopath.find("ATLAS_2016_CONF_2016_092")>0 or aopath.find("CMS_2012_PAS_QCD_11_010")>0) : if not inhistos_pt.has_key(aopath): inhistos_pt[aopath] = {} tmpE = inhistos_pt[aopath] if not tmpE.has_key(sqrts): tmpE[sqrts] = {} if not tmpE[sqrts].has_key(ptmin): tmpE[sqrts][ptmin] = ao else: tmpE[sqrts][ptmin] += ao #raise Exception("A set with ptmin = %s already exists" % ( ptmin)) else : if(aopath.find("I1243871")>0) : if(aopath.find("x01")>0 and file.find("-7-Top-L.yoda")>0 ) : outhistos[aopath] = ao elif(aopath.find("x02")>0 and file.find("-7-Top-SL.yoda")>0 ) : outhistos[aopath] = ao elif(aopath.find("1467230")>0 or aopath.find("1419652")>0) : if(aopath.find("y01")>0 and file.find("Long")>0 ) : outhistos[aopath] = ao elif(aopath.find("y02")>0 and file.find("Long")<0 ) : outhistos[aopath] = ao elif("CMS_2017_I1471287" in aopath) : if("CMS_2017_I1471287/d" in aopath) : outhistos[aopath] = ao elif("ATLAS_2018_I1705857" in aopath ) : ihist = int(aopath.split("/d")[1].split("-")[0]) if "-SL" in file : if ihist in [9,10,11,12,19,20,21,22,23,24,25,26,33,34,35,36,37,38,45,46,47,48,49,50] : outhistos[aopath] = ao elif "-L" in file : if ihist in [3,4,5,6,7,8,13,14,15,16,17,18,27,28,29,30,31,32,39,40,41,42,43,44] : outhistos[aopath] = ao if ihist in [1,2] : if aopath not in outhistos : outhistos[aopath] = ao else : - temp = yoda.core.Histo1D(ao.path, - ao.title) - for i in range(0,ao.numBins) : - temp.addBin(ao.bins[i].xMin,ao.bins[i].xMax) + title="" + path="" + if hasattr(ao, 'title'): + title=ao.title() + if hasattr(ao, 'path'): + path=ao.path() + temp = yoda.core.Histo1D(path,title) + for i in range(0,ao.numBins()) : + temp.addBin(ao.bins()[i].xMin(),ao.bins()[i].xMax()) if("-SL" in file) : - temp.bins[0] += outhistos[aopath].bins[0] - temp.bins[1] += outhistos[aopath].bins[1] - temp.bins[2] += ao.bins[2] - temp.bins[3] += ao.bins[3] - temp.bins[2] += ao.bins[2] - temp.bins[3] += ao.bins[3] + temp.bins()[0] += outhistos[aopath].bins()[0] + temp.bins()[1] += outhistos[aopath].bins()[1] + temp.bins()[2] += ao.bins()[2] + temp.bins()[3] += ao.bins()[3] + temp.bins()[2] += ao.bins()[2] + temp.bins()[3] += ao.bins()[3] else : - temp.bins[0] += ao.bins[0] - temp.bins[1] += ao.bins[1] - temp.bins[2] += outhistos[aopath].bins[2] - temp.bins[3] += outhistos[aopath].bins[3] - temp.bins[2] += outhistos[aopath].bins[2] - temp.bins[3] += outhistos[aopath].bins[3] + temp.bins()[0] += ao.bins()[0] + temp.bins()[1] += ao.bins()[1] + temp.bins()[2] += outhistos[aopath].bins()[2] + temp.bins()[3] += outhistos[aopath].bins()[3] + temp.bins()[2] += outhistos[aopath].bins()[2] + temp.bins()[3] += outhistos[aopath].bins()[3] outhistos[aopath] = temp else : outhistos[aopath] = ao yodafiles=["-7-Bottom-7.yoda","-7-Bottom-8.yoda","-7-Bottom-9.yoda"] for i in range(1,8) : yodafiles.append("-7-DiJets-%1.1i-A.yoda" % i) yodafiles.append("-7-DiJets-%1.1i-B.yoda" % i) yodafiles.append("-7-DiJets-%1.1i-C.yoda" % i) for i in range(1,12) : yodafiles.append("-13-DiJets-%1.1i-A.yoda" % i) -for i in range(6,12) : - yodafiles.append("-13-DiJets-%1.1i-B.yoda" % i) +# for i in range(6,12) : +# yodafiles.append("-13-DiJets-%1.1i-B.yoda" % i) for f in yodafiles: file='Rivet-'+args[0]+f if "-7-Jets" in file or "-7-DiJets" in file : sqrts = 7000 elif "-13-Jets" in file or "-13-DiJets" in file : sqrts = 13000 if(file.find("-DiJets-2")>0) : mass=250 elif(file.find("-DiJets-3")>0) : mass=500 elif(file.find("-DiJets-4")>0) : mass=800 elif(file.find("-DiJets-5")>0) : mass=1000 elif(file.find("-DiJets-6")>0) : mass=1600 elif(file.find("-DiJets-7")>0) : mass=2200 elif(file.find("-DiJets-8")>0) : mass=2800 elif(file.find("-DiJets-9")>0) : mass=3900 elif(file.find("-DiJets-10")>0) : mass=4900 elif(file.find("-DiJets-11")>0) : mass=5900 elif(file.find("-DiJets-1")>0) : mass=100 elif(file.find("-Bottom-7")>0) : mass=110 elif(file.find("-Bottom-8")>0) : mass=370 elif(file.find("-Bottom-9")>0) : mass=550 elif(file.find("-Jets-1")>0) : mass=0 if not os.access(file, os.R_OK): logging.error("%s can not be read" % file) continue try: aos = yoda.read(file) except: logging.error("%s can not be parsed as YODA" % file) continue ## Get histos from this YODA file for aopath, ao in aos.iteritems() : if("RAW" in aopath) :continue if(aopath.find("8817804")>0 or aopath.find("8968497")>0 or aopath.find("1082936")>0 or aopath.find("I930220")>0 or aopath.find("1261026")>0 or aopath.find("1090423")>0 or aopath.find("1268975")>0 or aopath.find("1519995") >0 or aopath.find("1663452") >0 or aopath.find("1634970" )>0 or aopath.find("CMS_2013_I1208923")>0) : if not inhistos_mass.has_key(aopath): inhistos_mass[aopath] = {} tmpE = inhistos_mass[aopath] if not tmpE.has_key(sqrts): tmpE[sqrts] = {} tmpP = tmpE[sqrts] if not tmpP.has_key(mass): tmpP[mass] = ao else: print aopath print sqrts,mass,file raise Exception("A set with mass = %s already exists" % ( mass)) ## Make empty output histos if needed for hpath,hsets in inhistos_pt.iteritems(): if( hpath.find("8924791")>0 or hpath.find("8971293")>0 or hpath.find("8817804")>0 or hpath.find("8968497")>0 or (hpath.find("9120041")>0 and (hpath.find("d01")>0 or hpath.find("d02")>0)) or hpath.find("9126244")>0 or hpath.find("926145") >0 or hpath.find("9086218")>0 or hpath.find("1082936")>0 or hpath.find("8941262")>0 or hpath.find("1118269")>0 or hpath.find("1087342")>0 or hpath.find("1188891")>0 or hpath.find("919017")>0 or hpath.find("9035664")>0 or hpath.find("1125575")>0 or hpath.find("1094564")>0 or hpath.find("I930220")>0 or hpath.find("S9088458")>0 or hpath.find("I1273574")>0 or hpath.find("I1261026")>0 or hpath.find("I1090423")>0 or hpath.find("QCD_11_010")>0 or hpath.find("1298811" )>0 or hpath.find("I1325553" )>0 or hpath.find("I1298810" )>0 or hpath.find("1307243" )>0 or hpath.find("I1419070")>0 or hpath.find("I1394679")>0 or hpath.find("I1487277")>0 or hpath.find("CMS_2013_I1208923")>0 or hpath.find("1393758")>0 or hpath.find("ATLAS_2016_CONF_2016_092")>0 or hpath.find("1111014")>0 or hpath.find("1385107")>0 or hpath.find("I1486238") or hpath.find("1459051")>0 or hpath.find("1634970")>0) : - if(type(hsets.values()[0].values()[0])==yoda.core.Counter) : - outhistos[hpath] = yoda.core.Counter(hsets.values()[0].values()[0].path, - hsets.values()[0].values()[0].title) - elif(type(hsets.values()[0].values()[0])==yoda.core.Scatter2D) : - outhistos[hpath] = yoda.core.Scatter2D(hsets.values()[0].values()[0].path, - hsets.values()[0].values()[0].title) - elif(type(hsets.values()[0].values()[0])==yoda.core.Profile1D) : - outhistos[hpath] = yoda.core.Profile1D(hsets.values()[0].values()[0].path, - hsets.values()[0].values()[0].title) - for i in range(0,hsets.values()[0].values()[0].numBins) : - outhistos[hpath].addBin(hsets.values()[0].values()[0].bins[i].xMin, - hsets.values()[0].values()[0].bins[i].xMax) - elif(type(hsets.values()[0].values()[0])==yoda.core.Histo1D) : - outhistos[hpath] = yoda.core.Histo1D(hsets.values()[0].values()[0].path, - hsets.values()[0].values()[0].title) - for i in range(0,hsets.values()[0].values()[0].numBins) : - outhistos[hpath].addBin(hsets.values()[0].values()[0].bins[i].xMin, - hsets.values()[0].values()[0].bins[i].xMax) + title="" + path="" + histo = hsets.values()[0].values()[0] + if hasattr(histo, 'title'): + title=histo.title() + if hasattr(histo, 'path'): + path=histo.path() + if(type(histo)==yoda.core.Counter) : + outhistos[hpath] = yoda.core.Counter(path,title) + elif(type(histo)==yoda.core.Scatter2D) : + outhistos[hpath] = yoda.core.Scatter2D(path,title) + elif(type(histo)==yoda.core.Profile1D) : + outhistos[hpath] = yoda.core.Profile1D(path,title) + for i in range(0,histo.numBins()) : + outhistos[hpath].addBin(histo.bins()[i].xMin(), + histo.bins()[i].xMax()) + elif(type(histo)==yoda.core.Histo1D) : + outhistos[hpath] = yoda.core.Histo1D(path,title) + for i in range(0,histo.numBins()) : + outhistos[hpath].addBin(histo.bins()[i].xMin(), + histo.bins()[i].xMax()) else : logging.error("Histogram %s is of unknown type" % hpath) sys.exit(1) ## Make empty output histos if needed for hpath,hsets in inhistos_mass.iteritems(): if(hpath.find("1268975")>0 or hpath.find("1634970")>0) : - if(type(hsets.values()[0].values()[0])==yoda.core.Counter) : - outhistos[hpath] = yoda.core.Counter(hsets.values()[0].values()[0].path, - hsets.values()[0].values()[0].title) - elif(type(hsets.values()[0].values()[0])==yoda.core.Scatter2D) : - outhistos[hpath] = yoda.core.Scatter2D(hsets.values()[0].values()[0].path, - hsets.values()[0].values()[0].title) - elif(type(hsets.values()[0].values()[0])==yoda.core.Profile1D) : - outhistos[hpath] = yoda.core.Profile1D(hsets.values()[0].values()[0].path, - hsets.values()[0].values()[0].title) - for i in range(0,hsets.values()[0].values()[0].numBins) : - outhistos[hpath].addBin(hsets.values()[0].values()[0].bins[i].xMin, - hsets.values()[0].values()[0].bins[i].xMax) - elif(type(hsets.values()[0].values()[0])==yoda.core.Histo1D) : - outhistos[hpath] = yoda.core.Histo1D(hsets.values()[0].values()[0].path, - hsets.values()[0].values()[0].title) - for i in range(0,hsets.values()[0].values()[0].numBins) : - outhistos[hpath].addBin(hsets.values()[0].values()[0].bins[i].xMin, - hsets.values()[0].values()[0].bins[i].xMax) + title="" + path="" + histo = hsets.values()[0].values()[0] + if hasattr(histo, 'title'): + title=histo.title() + if hasattr(histo, 'path'): + path=histo.path() + if(type(histo)==yoda.core.Counter) : + outhistos[hpath] = yoda.core.Counter(path,title) + elif(type(histo)==yoda.core.Scatter2D) : + outhistos[hpath] = yoda.core.Scatter2D(path,title) + elif(type(histo)==yoda.core.Profile1D) : + outhistos[hpath] = yoda.core.Profile1D(path,title) + for i in range(0,histo.numBins()) : + outhistos[hpath].addBin(histo.bins()[i].xMin(), + histo.bins()[i].xMax()) + elif(type(histo)==yoda.core.Histo1D) : + outhistos[hpath] = yoda.core.Histo1D(path,title) + for i in range(0,histo.numBins()) : + outhistos[hpath].addBin(histo.bins()[i].xMin(), + histo.bins()[i].xMax()) else : logging.error("Histogram %s is of unknown type" % hpath) sys.exit(1) logging.info("Processing CMS_2011_S8957746") useOnePt("/CMS_2011_S8957746/d01-x01-y01", "7000", "80" ) useOnePt("/CMS_2011_S8957746/d02-x01-y01", "7000", "80" ) useOnePt("/CMS_2011_S8957746/d03-x01-y01", "7000", "110" ) useOnePt("/CMS_2011_S8957746/d04-x01-y01", "7000", "110" ) useOnePt("/CMS_2011_S8957746/d05-x01-y01", "7000", "210" ) useOnePt("/CMS_2011_S8957746/d06-x01-y01", "7000", "210" ) logging.info("Processing ATLAS_2010_S8894728") useOnePt("/ATLAS_2010_S8894728/d01-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d01-x01-y02", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d01-x01-y03", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d02-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d02-x01-y02", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d02-x01-y03", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d03-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d03-x01-y02", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d03-x01-y03", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d04-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d04-x01-y02", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d04-x01-y03", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d05-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d06-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d07-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d08-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d09-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d09-x01-y02", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d09-x01-y03", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d10-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d10-x01-y02", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d10-x01-y03", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d11-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d11-x01-y02", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d11-x01-y03", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d12-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d12-x01-y02", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d12-x01-y03", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d13-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d13-x01-y02", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d13-x01-y03", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d13-x01-y04", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d14-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d14-x01-y02", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d14-x01-y03", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d14-x01-y04", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d15-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d15-x01-y02", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d15-x01-y03", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d15-x01-y04", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d16-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d16-x01-y02", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d16-x01-y03", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d16-x01-y04", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d17-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d17-x01-y02", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d17-x01-y03", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d18-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d18-x01-y02", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d18-x01-y03", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d19-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d19-x01-y02", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d19-x01-y03", "900", "0" ) useOnePt("/ATLAS_2010_S8894728/d20-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d20-x01-y02", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d20-x01-y03", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d21-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8894728/d22-x01-y01", "7000", "0" ) logging.info("Processing ATLAS_2011_S8994773") useOnePt("/ATLAS_2011_S8994773/d01-x01-y01", "900", "0" ) useOnePt("/ATLAS_2011_S8994773/d02-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2011_S8994773/d03-x01-y01", "900", "0" ) useOnePt("/ATLAS_2011_S8994773/d04-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2011_S8994773/d13-x01-y01", "900", "0" ) useOnePt("/ATLAS_2011_S8994773/d13-x01-y02", "900", "0" ) useOnePt("/ATLAS_2011_S8994773/d13-x01-y03", "900", "0" ) useOnePt("/ATLAS_2011_S8994773/d14-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2011_S8994773/d14-x01-y02", "7000", "0" ) useOnePt("/ATLAS_2011_S8994773/d14-x01-y03", "7000", "0" ) logging.info("Processing ALICE_2010_S8624100") useOnePt("/ALICE_2010_S8624100/d11-x01-y01", "900", "0" ) useOnePt("/ALICE_2010_S8624100/d12-x01-y01", "900", "0" ) useOnePt("/ALICE_2010_S8624100/d13-x01-y01", "900", "0" ) useOnePt("/ALICE_2010_S8624100/d17-x01-y01","2360", "0" ) useOnePt("/ALICE_2010_S8624100/d18-x01-y01","2360", "0" ) useOnePt("/ALICE_2010_S8624100/d19-x01-y01","2360", "0" ) logging.info("Processing ALICE_2010_S8625980") useOnePt("/ALICE_2010_S8625980/d03-x01-y01", "7000", "0" ) useOnePt("/ALICE_2010_S8625980/d04-x01-y01", "900", "0" ) useOnePt("/ALICE_2010_S8625980/d05-x01-y01", "2360", "0" ) useOnePt("/ALICE_2010_S8625980/d06-x01-y01", "7000", "0" ) logging.info("Processing ATLAS_2010_S8918562") useOnePt("/ATLAS_2010_S8918562/d01-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8918562/d02-x01-y01", "2360", "0" ) useOnePt("/ATLAS_2010_S8918562/d03-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8918562/d04-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8918562/d05-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8918562/d06-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8918562/d07-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8918562/d08-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8918562/d09-x01-y01", "2360", "0" ) useOnePt("/ATLAS_2010_S8918562/d10-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8918562/d11-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8918562/d12-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8918562/d13-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8918562/d14-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8918562/d15-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8918562/d16-x01-y01", "2360", "0" ) useOnePt("/ATLAS_2010_S8918562/d17-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8918562/d18-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8918562/d19-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8918562/d20-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8918562/d21-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8918562/d22-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8918562/d23-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8918562/d24-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8918562/d25-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8918562/d26-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8918562/d27-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8918562/d28-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8918562/d29-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8918562/d30-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8918562/d31-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8918562/d32-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8918562/d33-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8918562/d34-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8918562/d35-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8918562/d36-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8918562/d37-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2010_S8918562/d38-x01-y01", "900", "0" ) useOnePt("/ATLAS_2010_S8918562/d39-x01-y01", "7000", "0" ) logging.info("Processing ATLAS_2011_S8971293") useOnePt("/ATLAS_2011_S8971293/d01-x01-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S8971293/d01-x01-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S8971293/d01-x01-y03", "7000", "210" ) useOnePt("/ATLAS_2011_S8971293/d01-x01-y04", "7000", "260" ) useOnePt("/ATLAS_2011_S8971293/d01-x01-y05", "7000", "260" ) useOnePt("/ATLAS_2011_S8971293/d01-x01-y06", "7000", "400" ) useOnePt("/ATLAS_2011_S8971293/d01-x01-y07", "7000", "400" ) useOnePt("/ATLAS_2011_S8971293/d01-x01-y08", "7000", "600" ) useOnePt("/ATLAS_2011_S8971293/d01-x01-y09", "7000", "600" ) logging.info("Processing ATLAS_2011_S8924791") if( not opts.ue) : useOnePt("/ATLAS_2011_S8924791/d01-x01-y01", "7000", "10" ) useOnePt("/ATLAS_2011_S8924791/d01-x01-y02", "7000", "10" ) useOnePt("/ATLAS_2011_S8924791/d01-x02-y01", "7000", "10" ) useOnePt("/ATLAS_2011_S8924791/d01-x02-y02", "7000", "10" ) useOnePt("/ATLAS_2011_S8924791/d01-x03-y01", "7000", "10" ) useOnePt("/ATLAS_2011_S8924791/d01-x03-y02", "7000", "10" ) useOnePt("/ATLAS_2011_S8924791/d01-x04-y01", "7000", "10" ) useOnePt("/ATLAS_2011_S8924791/d01-x04-y02", "7000", "10" ) useOnePt("/ATLAS_2011_S8924791/d01-x05-y01", "7000", "10" ) useOnePt("/ATLAS_2011_S8924791/d01-x05-y02", "7000", "10" ) useOnePt("/ATLAS_2011_S8924791/d01-x06-y01", "7000", "10" ) useOnePt("/ATLAS_2011_S8924791/d01-x06-y02", "7000", "10" ) else : useOnePt("/ATLAS_2011_S8924791/d01-x01-y01", "7000", "20" ) useOnePt("/ATLAS_2011_S8924791/d01-x01-y02", "7000", "20" ) useOnePt("/ATLAS_2011_S8924791/d01-x02-y01", "7000", "20" ) useOnePt("/ATLAS_2011_S8924791/d01-x02-y02", "7000", "20" ) useOnePt("/ATLAS_2011_S8924791/d01-x03-y01", "7000", "20" ) useOnePt("/ATLAS_2011_S8924791/d01-x03-y02", "7000", "20" ) useOnePt("/ATLAS_2011_S8924791/d01-x04-y01", "7000", "20" ) useOnePt("/ATLAS_2011_S8924791/d01-x04-y02", "7000", "20" ) useOnePt("/ATLAS_2011_S8924791/d01-x05-y01", "7000", "20" ) useOnePt("/ATLAS_2011_S8924791/d01-x05-y02", "7000", "20" ) useOnePt("/ATLAS_2011_S8924791/d01-x06-y01", "7000", "20" ) useOnePt("/ATLAS_2011_S8924791/d01-x06-y02", "7000", "20" ) useOnePt("/ATLAS_2011_S8924791/d02-x01-y01", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d02-x01-y02", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d02-x02-y01", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d02-x02-y02", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d02-x03-y01", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d02-x03-y02", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d02-x04-y01", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d02-x04-y02", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d02-x05-y01", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d02-x05-y02", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d02-x06-y01", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d02-x06-y02", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d03-x01-y01", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d03-x01-y02", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d03-x02-y01", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d03-x02-y02", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d03-x03-y01", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d03-x03-y02", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d03-x04-y01", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d03-x04-y02", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d03-x05-y01", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d03-x05-y02", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d03-x06-y01", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d03-x06-y02", "7000", "40" ) useOnePt("/ATLAS_2011_S8924791/d04-x01-y01", "7000", "80" ) useOnePt("/ATLAS_2011_S8924791/d04-x01-y02", "7000", "80" ) useOnePt("/ATLAS_2011_S8924791/d04-x02-y01", "7000", "80" ) useOnePt("/ATLAS_2011_S8924791/d04-x02-y02", "7000", "80" ) useOnePt("/ATLAS_2011_S8924791/d04-x03-y01", "7000", "80" ) useOnePt("/ATLAS_2011_S8924791/d04-x03-y02", "7000", "80" ) useOnePt("/ATLAS_2011_S8924791/d04-x04-y01", "7000", "80" ) useOnePt("/ATLAS_2011_S8924791/d04-x04-y02", "7000", "80" ) useOnePt("/ATLAS_2011_S8924791/d04-x05-y01", "7000", "80" ) useOnePt("/ATLAS_2011_S8924791/d04-x05-y02", "7000", "80" ) useOnePt("/ATLAS_2011_S8924791/d04-x06-y01", "7000", "80" ) useOnePt("/ATLAS_2011_S8924791/d04-x06-y02", "7000", "80" ) useOnePt("/ATLAS_2011_S8924791/d05-x01-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d05-x01-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d05-x02-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d05-x02-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d05-x03-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d05-x03-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d05-x04-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d05-x04-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d05-x05-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d05-x05-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d05-x06-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d05-x06-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d06-x01-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d06-x01-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d06-x02-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d06-x02-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d06-x03-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d06-x03-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d06-x04-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d06-x04-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d06-x05-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d06-x05-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d06-x06-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d06-x06-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S8924791/d07-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2011_S8924791/d07-x01-y02", "7000", "210" ) useOnePt("/ATLAS_2011_S8924791/d07-x02-y01", "7000", "210" ) useOnePt("/ATLAS_2011_S8924791/d07-x02-y02", "7000", "210" ) useOnePt("/ATLAS_2011_S8924791/d07-x03-y01", "7000", "210" ) useOnePt("/ATLAS_2011_S8924791/d07-x03-y02", "7000", "210" ) useOnePt("/ATLAS_2011_S8924791/d07-x04-y01", "7000", "210" ) useOnePt("/ATLAS_2011_S8924791/d07-x04-y02", "7000", "210" ) useOnePt("/ATLAS_2011_S8924791/d07-x05-y01", "7000", "210" ) useOnePt("/ATLAS_2011_S8924791/d07-x05-y02", "7000", "210" ) useOnePt("/ATLAS_2011_S8924791/d07-x06-y01", "7000", "210" ) useOnePt("/ATLAS_2011_S8924791/d07-x06-y02", "7000", "210" ) useOnePt("/ATLAS_2011_S8924791/d08-x01-y01", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d08-x01-y02", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d08-x02-y01", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d08-x02-y02", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d08-x03-y01", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d08-x03-y02", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d08-x04-y01", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d08-x04-y02", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d08-x05-y01", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d08-x05-y02", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d08-x06-y01", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d08-x06-y02", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d09-x01-y01", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d09-x01-y02", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d09-x02-y01", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d09-x02-y02", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d09-x03-y01", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d09-x03-y02", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d09-x04-y01", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d09-x04-y02", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d09-x05-y01", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d09-x05-y02", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d09-x06-y01", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d09-x06-y02", "7000", "260" ) useOnePt("/ATLAS_2011_S8924791/d10-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d10-x01-y02", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d10-x02-y01", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d10-x02-y02", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d10-x03-y01", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d10-x03-y02", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d10-x04-y01", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d10-x04-y02", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d10-x05-y01", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d10-x05-y02", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d10-x06-y01", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d10-x06-y02", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d11-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d11-x01-y02", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d11-x02-y01", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d11-x02-y02", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d11-x03-y01", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d11-x03-y02", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d11-x04-y01", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d11-x04-y02", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d11-x05-y01", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d11-x05-y02", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d11-x06-y01", "7000", "400" ) useOnePt("/ATLAS_2011_S8924791/d11-x06-y02", "7000", "400" ) logging.info("Processing ATLAS_2010_S8817804") mergeByPt("/ATLAS_2010_S8817804/d01-x01-y01", "7000") mergeByPt("/ATLAS_2010_S8817804/d02-x01-y01", "7000") mergeByPt("/ATLAS_2010_S8817804/d03-x01-y01", "7000") mergeByPt("/ATLAS_2010_S8817804/d04-x01-y01", "7000") mergeByPt("/ATLAS_2010_S8817804/d05-x01-y01", "7000") mergeByPt("/ATLAS_2010_S8817804/d06-x01-y01", "7000") mergeByPt("/ATLAS_2010_S8817804/d07-x01-y01", "7000") mergeByPt("/ATLAS_2010_S8817804/d08-x01-y01", "7000") mergeByPt("/ATLAS_2010_S8817804/d09-x01-y01", "7000") mergeByPt("/ATLAS_2010_S8817804/d10-x01-y01", "7000") mergeByMass("/ATLAS_2010_S8817804/d11-x01-y01", "7000") mergeByMass("/ATLAS_2010_S8817804/d12-x01-y01", "7000") mergeByMass("/ATLAS_2010_S8817804/d13-x01-y01", "7000") mergeByMass("/ATLAS_2010_S8817804/d14-x01-y01", "7000") mergeByMass("/ATLAS_2010_S8817804/d15-x01-y01", "7000") mergeByMass("/ATLAS_2010_S8817804/d16-x01-y01", "7000") mergeByMass("/ATLAS_2010_S8817804/d17-x01-y01", "7000") mergeByMass("/ATLAS_2010_S8817804/d18-x01-y01", "7000") mergeByMass("/ATLAS_2010_S8817804/d19-x01-y01", "7000") mergeByMass("/ATLAS_2010_S8817804/d20-x01-y01", "7000") useOneMass("/ATLAS_2010_S8817804/d21-x01-y01", "7000", "250" ) useOneMass("/ATLAS_2010_S8817804/d22-x01-y01", "7000", "250" ) useOneMass("/ATLAS_2010_S8817804/d23-x01-y01", "7000", "650" ) useOneMass("/ATLAS_2010_S8817804/d24-x01-y01", "7000", "250" ) useOneMass("/ATLAS_2010_S8817804/d25-x01-y01", "7000", "250" ) useOneMass("/ATLAS_2010_S8817804/d26-x01-y01", "7000", "650" ) logging.info("Processing ATLAS_2011_I930220") mergeByPt("/ATLAS_2011_I930220/d01-x01-y01", "7000" ) mergeByPt("/ATLAS_2011_I930220/d02-x01-y01", "7000" ) mergeByPt("/ATLAS_2011_I930220/d03-x01-y01", "7000" ) mergeByPt("/ATLAS_2011_I930220/d04-x01-y01", "7000" ) mergeByPt("/ATLAS_2011_I930220/d05-x01-y01", "7000" ) mergeByPt("/ATLAS_2011_I930220/d06-x01-y01", "7000" ) mergeByMass("/ATLAS_2011_I930220/d07-x01-y01", "7000") useOneMass("/ATLAS_2011_I930220/d08-x01-y01", "7000", "110" ) useOneMass("/ATLAS_2011_I930220/d09-x01-y01", "7000", "110" ) useOneMass("/ATLAS_2011_I930220/d10-x01-y01", "7000", "370" ) logging.info("Processing ATLAS_2012_I1082936") mergeByPt("/ATLAS_2012_I1082936/d01-x01-y01", "7000") mergeByPt("/ATLAS_2012_I1082936/d01-x01-y02", "7000") mergeByPt("/ATLAS_2012_I1082936/d01-x01-y03", "7000") mergeByPt("/ATLAS_2012_I1082936/d01-x01-y04", "7000") mergeByPt("/ATLAS_2012_I1082936/d01-x01-y05", "7000") mergeByPt("/ATLAS_2012_I1082936/d01-x01-y06", "7000") mergeByPt("/ATLAS_2012_I1082936/d01-x01-y07", "7000") mergeByPt("/ATLAS_2012_I1082936/d02-x01-y01", "7000") mergeByPt("/ATLAS_2012_I1082936/d02-x01-y02", "7000") mergeByPt("/ATLAS_2012_I1082936/d02-x01-y03", "7000") mergeByPt("/ATLAS_2012_I1082936/d02-x01-y04", "7000") mergeByPt("/ATLAS_2012_I1082936/d02-x01-y05", "7000") mergeByPt("/ATLAS_2012_I1082936/d02-x01-y06", "7000") mergeByPt("/ATLAS_2012_I1082936/d02-x01-y07", "7000") mergeByMass("/ATLAS_2012_I1082936/d03-x01-y01", "7000", 1000.) mergeByMass("/ATLAS_2012_I1082936/d03-x01-y02", "7000", 1000.) mergeByMass("/ATLAS_2012_I1082936/d03-x01-y03", "7000", 1000.) mergeByMass("/ATLAS_2012_I1082936/d03-x01-y04", "7000", 1000.) mergeByMass("/ATLAS_2012_I1082936/d03-x01-y05", "7000", 1000.) mergeByMass("/ATLAS_2012_I1082936/d03-x01-y06", "7000", 1000.) mergeByMass("/ATLAS_2012_I1082936/d03-x01-y07", "7000", 1000.) mergeByMass("/ATLAS_2012_I1082936/d03-x01-y08", "7000", 1000.) mergeByMass("/ATLAS_2012_I1082936/d03-x01-y09", "7000", 1000.) mergeByMass("/ATLAS_2012_I1082936/d04-x01-y01", "7000", 1000.) mergeByMass("/ATLAS_2012_I1082936/d04-x01-y02", "7000", 1000.) mergeByMass("/ATLAS_2012_I1082936/d04-x01-y03", "7000", 1000.) mergeByMass("/ATLAS_2012_I1082936/d04-x01-y04", "7000", 1000.) mergeByMass("/ATLAS_2012_I1082936/d04-x01-y05", "7000", 1000.) mergeByMass("/ATLAS_2012_I1082936/d04-x01-y06", "7000", 1000.) mergeByMass("/ATLAS_2012_I1082936/d04-x01-y07", "7000", 1000.) mergeByMass("/ATLAS_2012_I1082936/d04-x01-y08", "7000", 1000.) mergeByMass("/ATLAS_2012_I1082936/d04-x01-y09", "7000", 1000.) logging.info("Processing CMS_2011_S8968497") useOneMass("/CMS_2011_S8968497/d01-x01-y01", "7000", "1700" ) useOneMass("/CMS_2011_S8968497/d02-x01-y01", "7000", "1700" ) useOneMass("/CMS_2011_S8968497/d03-x01-y01", "7000", "1100" ) useOneMass("/CMS_2011_S8968497/d04-x01-y01", "7000", "1100" ) useOneMass("/CMS_2011_S8968497/d05-x01-y01", "7000", "650" ) useOneMass("/CMS_2011_S8968497/d06-x01-y01", "7000", "650" ) useOneMass("/CMS_2011_S8968497/d07-x01-y01", "7000", "250" ) useOneMass("/CMS_2011_S8968497/d08-x01-y01", "7000", "250" ) useOneMass("/CMS_2011_S8968497/d09-x01-y01", "7000", "250" ) logging.info("Processing ATLAS_2011_S9126244") mergeByPt("/ATLAS_2011_S9126244/d01-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9126244/d01-x01-y02", "7000") mergeByPt("/ATLAS_2011_S9126244/d02-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9126244/d02-x01-y02", "7000") mergeByPt("/ATLAS_2011_S9126244/d03-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9126244/d03-x01-y02", "7000") mergeByPt("/ATLAS_2011_S9126244/d04-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9126244/d04-x01-y02", "7000") mergeByPt("/ATLAS_2011_S9126244/d05-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9126244/d05-x01-y02", "7000") useOnePt("/ATLAS_2011_S9126244/d06-x01-y01", "7000", "40" ) useOnePt("/ATLAS_2011_S9126244/d06-x01-y02", "7000", "40" ) useOnePt("/ATLAS_2011_S9126244/d07-x01-y01", "7000", "80" ) useOnePt("/ATLAS_2011_S9126244/d07-x01-y02", "7000", "80" ) useOnePt("/ATLAS_2011_S9126244/d08-x01-y01", "7000", "80" ) useOnePt("/ATLAS_2011_S9126244/d08-x01-y02", "7000", "80" ) useOnePt("/ATLAS_2011_S9126244/d09-x01-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d09-x01-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d10-x01-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d10-x01-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d11-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2011_S9126244/d11-x01-y02", "7000", "210" ) useOnePt("/ATLAS_2011_S9126244/d12-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2011_S9126244/d12-x01-y02", "7000", "210" ) useOnePt("/ATLAS_2011_S9126244/d13-x01-y01", "7000", "40" ) useOnePt("/ATLAS_2011_S9126244/d13-x01-y02", "7000", "40" ) useOnePt("/ATLAS_2011_S9126244/d14-x01-y01", "7000", "40" ) useOnePt("/ATLAS_2011_S9126244/d14-x01-y02", "7000", "40" ) useOnePt("/ATLAS_2011_S9126244/d15-x01-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d15-x01-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d16-x01-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d16-x01-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d17-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2011_S9126244/d17-x01-y02", "7000", "210" ) useOnePt("/ATLAS_2011_S9126244/d18-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2011_S9126244/d18-x01-y02", "7000", "210" ) useOnePt("/ATLAS_2011_S9126244/d19-x01-y01", "7000", "40" ) useOnePt("/ATLAS_2011_S9126244/d20-x01-y01", "7000", "80" ) useOnePt("/ATLAS_2011_S9126244/d21-x01-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d22-x01-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d23-x01-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d24-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2011_S9126244/d25-x01-y01", "7000", "210" ) mergeByPt("/ATLAS_2011_S9126244/d26-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9126244/d26-x01-y02", "7000") mergeByPt("/ATLAS_2011_S9126244/d27-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9126244/d27-x01-y02", "7000") mergeByPt("/ATLAS_2011_S9126244/d28-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9126244/d28-x01-y02", "7000") mergeByPt("/ATLAS_2011_S9126244/d29-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9126244/d29-x01-y02", "7000") useOnePt("/ATLAS_2011_S9126244/d30-x01-y01", "7000", "40" ) useOnePt("/ATLAS_2011_S9126244/d31-x01-y01", "7000", "80" ) useOnePt("/ATLAS_2011_S9126244/d32-x01-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d33-x01-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d34-x01-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d35-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2011_S9126244/d36-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2011_S9126244/d37-x01-y01", "7000", "40" ) useOnePt("/ATLAS_2011_S9126244/d37-x01-y02", "7000", "40" ) useOnePt("/ATLAS_2011_S9126244/d38-x01-y01", "7000", "80" ) useOnePt("/ATLAS_2011_S9126244/d38-x01-y02", "7000", "80" ) useOnePt("/ATLAS_2011_S9126244/d39-x01-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d39-x01-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d40-x01-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d40-x01-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d41-x01-y01", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d41-x01-y02", "7000", "110" ) useOnePt("/ATLAS_2011_S9126244/d42-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2011_S9126244/d42-x01-y02", "7000", "210" ) useOnePt("/ATLAS_2011_S9126244/d43-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2011_S9126244/d43-x01-y02", "7000", "210" ) # CMS_2011_S9120041 UE analysis logging.info("Processing CMS_2011_S9120041") mergeByPt("/CMS_2011_S9120041/d01-x01-y01", "7000") mergeByPt("/CMS_2011_S9120041/d02-x01-y01", "7000") if(opts.ue) : useOnePt("/CMS_2011_S9120041/d03-x01-y01", "900", "0" ) useOnePt("/CMS_2011_S9120041/d04-x01-y01", "900", "0" ) useOnePt("/CMS_2011_S9120041/d05-x01-y01", "7000", "0" ) useOnePt("/CMS_2011_S9120041/d06-x01-y01", "7000", "0" ) useOnePt("/CMS_2011_S9120041/d07-x01-y01", "7000", "0" ) useOnePt("/CMS_2011_S9120041/d11-x01-y01", "900", "0" ) useOnePt("/CMS_2011_S9120041/d12-x01-y01", "900", "0" ) useOnePt("/CMS_2011_S9120041/d13-x01-y01", "900", "0" ) useOnePt("/CMS_2011_S9120041/d08-x01-y01", "7000", "20" ) useOnePt("/CMS_2011_S9120041/d09-x01-y01", "7000", "20" ) useOnePt("/CMS_2011_S9120041/d10-x01-y01", "7000", "20" ) else : useOnePt("/CMS_2011_S9120041/d08-x01-y01", "7000", "10" ) useOnePt("/CMS_2011_S9120041/d09-x01-y01", "7000", "10" ) useOnePt("/CMS_2011_S9120041/d10-x01-y01", "7000", "10" ) # CMS dijet decorrelation logging.info("Processing CMS_2011_S8950903") useOnePt("/CMS_2011_S8950903/d01-x01-y01", "7000", "80" ) useOnePt("/CMS_2011_S8950903/d02-x01-y01", "7000", "110" ) useOnePt("/CMS_2011_S8950903/d03-x01-y01", "7000", "110" ) useOnePt("/CMS_2011_S8950903/d04-x01-y01", "7000", "210" ) useOnePt("/CMS_2011_S8950903/d05-x01-y01", "7000", "260" ) # CMS jet cross section logging.info("Processing CMS_2011_S9086218") mergeByPt("/CMS_2011_S9086218/d01-x01-y01", "7000") mergeByPt("/CMS_2011_S9086218/d02-x01-y01", "7000") mergeByPt("/CMS_2011_S9086218/d03-x01-y01", "7000") mergeByPt("/CMS_2011_S9086218/d04-x01-y01", "7000") mergeByPt("/CMS_2011_S9086218/d05-x01-y01", "7000") mergeByPt("/CMS_2011_S9086218/d06-x01-y01", "7000") # CMS 2/3 jet cross section ratio logging.info("Processing CMS_2011_S9086218") mergeByPt("/CMS_2011_S9088458/d01-x01-y01", "7000",500.) # ATLAS track jet logging.info("Processing ATLAS_2011_I919017") for d in range(1,3) : for y in range(1,5) : mergeByPt("/ATLAS_2011_I919017/d0%s-x01-y0%s" % (d,y), "7000") if( opts.ue) : for x in range(2,6) : for y in ["01","02","06","07","11","12","16","17","21","22"] : useOnePt("/ATLAS_2011_I919017/d0%s-x0%s-y%s" % (d,x,y), "7000", "0" ) for y in ["03","04","08","09","13","14","18","19","23","24"] : useOnePt("/ATLAS_2011_I919017/d0%s-x0%s-y%s" % (d,x,y), "7000", "4" ) for y in range(5,30,5) : useOnePt("/ATLAS_2011_I919017/d0%s-x%02d-y%02d" % (d,x,y) , "7000", "20" ) else : for x in range(2,6) : for y in range(5,30,5) : useOnePt("/ATLAS_2011_I919017/d0%s-x%02d-y%02d" % (d,x,y) , "7000", "10" ) logging.info("Processing ATLAS_2011_I926145") mergeByPt("/ATLAS_2011_I926145/d01-x01-y01", "7000",1.5) mergeByPt("/ATLAS_2011_I926145/d02-x01-y01", "7000",1.5) mergeByPt("/ATLAS_2011_I926145/d03-x01-y01", "7000",1.5) logging.info("Processing CMS_2011_S8941262") useOnePt("/CMS_2011_S8941262/d01-x01-y01", "7000", "10" ) useOnePt("/CMS_2011_S8941262/d03-x01-y01", "7000", "10" ) mergeByPt("/CMS_2011_S8941262/d02-x01-y01", "7000",1.5) logging.info("Processing CMS_2011_S8973270") useOnePt("/CMS_2011_S8973270/d01-x01-y01", "7000", "70" ) useOnePt("/CMS_2011_S8973270/d02-x01-y01", "7000", "100" ) useOnePt("/CMS_2011_S8973270/d03-x01-y01", "7000", "130" ) useOnePt("/CMS_2011_S8973270/d04-x01-y01", "7000", "70" ) useOnePt("/CMS_2011_S8973270/d05-x01-y01", "7000", "100" ) useOnePt("/CMS_2011_S8973270/d06-x01-y01", "7000", "130" ) logging.info("Processing ATLAS_2012_I1082009") useOnePt("/ATLAS_2012_I1082009/d08-x01-y01", "7000", "40" ) useOnePt("/ATLAS_2012_I1082009/d09-x01-y01", "7000", "40" ) useOnePt("/ATLAS_2012_I1082009/d10-x01-y01", "7000", "40" ) useOnePt("/ATLAS_2012_I1082009/d11-x01-y01", "7000", "80" ) useOnePt("/ATLAS_2012_I1082009/d12-x01-y01", "7000", "80" ) useOnePt("/ATLAS_2012_I1082009/d13-x01-y01", "7000", "40" ) logging.info("Processing ATLAS_2012_I1118269") mergeByPt("/ATLAS_2012_I1118269/d01-x01-y01", "7000") useOnePt("/ATLAS_2012_I1118269/d02-x01-y01", "7000", "10" ) logging.info("Processing ATLAS_2012_I1188891") mergeByPt("/ATLAS_2012_I1188891/d01-x01-y01", "7000") mergeByPt("/ATLAS_2012_I1188891/d02-x01-y01", "7000") mergeByPt("/ATLAS_2012_I1188891/d03-x01-y01", "7000") mergeByPt("/ATLAS_2012_I1188891/d04-x01-y01", "7000") mergeByPt("/ATLAS_2012_I1188891/d05-x01-y01", "7000") mergeByPt("/ATLAS_2012_I1188891/d06-x01-y01", "7000") logging.info("Processing CMS_2012_I1087342") mergeByPt("/CMS_2012_I1087342/d01-x01-y01", "7000") mergeByPt("/CMS_2012_I1087342/d02-x01-y01", "7000") mergeByPt("/CMS_2012_I1087342/d03-x01-y01", "7000") logging.info("Processing CMS_2012_PAS_QCD_11_010") mergeByPt("/CMS_2012_PAS_QCD_11_010/d01-x01-y01", "7000") mergeByPt("/CMS_2012_PAS_QCD_11_010/d02-x01-y01", "7000") mergeByPt("/CMS_2012_PAS_QCD_11_010/d03-x01-y01", "7000") mergeByPt("/CMS_2012_PAS_QCD_11_010/d04-x01-y01", "7000") logging.info("Processing ATLAS_2011_S9035664") mergeByPt("/ATLAS_2011_S9035664/d11-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9035664/d12-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9035664/d13-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9035664/d14-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9035664/d15-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9035664/d16-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9035664/d17-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9035664/d18-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9035664/d20-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9035664/d21-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9035664/d22-x01-y01", "7000") mergeByPt("/ATLAS_2011_S9035664/d23-x01-y01", "7000") logging.info("Processing ATLAS_2012_I1125575") mergeByPt("/ATLAS_2012_I1125575/d01-x01-y01", "7000") mergeByPt("/ATLAS_2012_I1125575/d01-x01-y02", "7000") mergeByPt("/ATLAS_2012_I1125575/d01-x02-y01", "7000") mergeByPt("/ATLAS_2012_I1125575/d01-x02-y02", "7000") mergeByPt("/ATLAS_2012_I1125575/d01-x03-y01", "7000") mergeByPt("/ATLAS_2012_I1125575/d01-x03-y02", "7000") mergeByPt("/ATLAS_2012_I1125575/d01-x04-y01", "7000") mergeByPt("/ATLAS_2012_I1125575/d01-x04-y02", "7000") mergeByPt("/ATLAS_2012_I1125575/d01-x05-y01", "7000") mergeByPt("/ATLAS_2012_I1125575/d01-x05-y02", "7000") mergeByPt("/ATLAS_2012_I1125575/d02-x01-y01", "7000") mergeByPt("/ATLAS_2012_I1125575/d02-x01-y02", "7000") mergeByPt("/ATLAS_2012_I1125575/d02-x02-y01", "7000") mergeByPt("/ATLAS_2012_I1125575/d02-x02-y02", "7000") mergeByPt("/ATLAS_2012_I1125575/d02-x03-y01", "7000") mergeByPt("/ATLAS_2012_I1125575/d02-x03-y02", "7000") mergeByPt("/ATLAS_2012_I1125575/d02-x04-y01", "7000") mergeByPt("/ATLAS_2012_I1125575/d02-x04-y02", "7000") mergeByPt("/ATLAS_2012_I1125575/d02-x05-y01", "7000") mergeByPt("/ATLAS_2012_I1125575/d02-x05-y02", "7000") mergeByPt("/ATLAS_2012_I1125575/d03-x01-y01", "7000") mergeByPt("/ATLAS_2012_I1125575/d03-x01-y02", "7000") mergeByPt("/ATLAS_2012_I1125575/d03-x02-y01", "7000") mergeByPt("/ATLAS_2012_I1125575/d03-x02-y02", "7000") mergeByPt("/ATLAS_2012_I1125575/d03-x03-y01", "7000") mergeByPt("/ATLAS_2012_I1125575/d03-x03-y02", "7000") mergeByPt("/ATLAS_2012_I1125575/d03-x04-y01", "7000") mergeByPt("/ATLAS_2012_I1125575/d03-x04-y02", "7000") mergeByPt("/ATLAS_2012_I1125575/d03-x05-y01", "7000") mergeByPt("/ATLAS_2012_I1125575/d03-x05-y02", "7000") for d in range(4,7) : for x in range(1,6) : if(opts.ue) : for y in range(1,9) : useOnePt("/ATLAS_2012_I1125575/d0%s-x0%s-y0%s" % (d,x,y), "7000", "0" ) for y in ["09","10","11","12","13","14","15","16"] : useOnePt("/ATLAS_2012_I1125575/d0%s-x0%s-y%s" % (d,x,y), "7000", "0" ) for y in range(17,19) : useOnePt("/ATLAS_2012_I1125575/d0%s-x0%s-y%s" % (d,x,y), "7000", "20" ) else : for y in range(17,19) : useOnePt("/ATLAS_2012_I1125575/d0%s-x0%s-y%s" % (d,x,y), "7000", "10" ) for y in range(19,21) : useOnePt("/ATLAS_2012_I1125575/d0%s-x0%s-y%s" % (d,x,y), "7000", "40" ) # ATLAS_2012_I1094564 useOnePt("/ATLAS_2012_I1094564/d01-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2012_I1094564/d02-x01-y01", "7000", "260" ) useOnePt("/ATLAS_2012_I1094564/d03-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2012_I1094564/d04-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2012_I1094564/d05-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2012_I1094564/d06-x01-y01", "7000", "260" ) useOnePt("/ATLAS_2012_I1094564/d07-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2012_I1094564/d08-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2012_I1094564/d09-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2012_I1094564/d10-x01-y01", "7000", "260" ) useOnePt("/ATLAS_2012_I1094564/d11-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2012_I1094564/d12-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2012_I1094564/d13-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2012_I1094564/d14-x01-y01", "7000", "260" ) useOnePt("/ATLAS_2012_I1094564/d15-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2012_I1094564/d16-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2012_I1094564/d17-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2012_I1094564/d18-x01-y01", "7000", "260" ) useOnePt("/ATLAS_2012_I1094564/d19-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2012_I1094564/d20-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2012_I1094564/d21-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2012_I1094564/d22-x01-y01", "7000", "260" ) useOnePt("/ATLAS_2012_I1094564/d23-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2012_I1094564/d24-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2012_I1094564/d25-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2012_I1094564/d26-x01-y01", "7000", "260" ) useOnePt("/ATLAS_2012_I1094564/d27-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2012_I1094564/d28-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2012_I1094564/d29-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2012_I1094564/d30-x01-y01", "7000", "260" ) useOnePt("/ATLAS_2012_I1094564/d31-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2012_I1094564/d32-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2012_I1094564/d33-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2012_I1094564/d34-x01-y01", "7000", "260" ) useOnePt("/ATLAS_2012_I1094564/d35-x01-y01", "7000", "400" ) useOnePt("/ATLAS_2012_I1094564/d36-x01-y01", "7000", "400" ) logging.info("Processing CMS_2013_I1224539_DIJET") useOnePt("/CMS_2013_I1224539_DIJET/d01-x01-y01", "7000", "210" ) useOnePt("/CMS_2013_I1224539_DIJET/d02-x01-y01", "7000", "260" ) useOnePt("/CMS_2013_I1224539_DIJET/d03-x01-y01", "7000", "400" ) useOnePt("/CMS_2013_I1224539_DIJET/d04-x01-y01", "7000", "400" ) useOnePt("/CMS_2013_I1224539_DIJET/d05-x01-y01", "7000", "600" ) useOnePt("/CMS_2013_I1224539_DIJET/d06-x01-y01", "7000", "600" ) useOnePt("/CMS_2013_I1224539_DIJET/d07-x01-y01", "7000", "600" ) useOnePt("/CMS_2013_I1224539_DIJET/d08-x01-y01", "7000", "210" ) useOnePt("/CMS_2013_I1224539_DIJET/d09-x01-y01", "7000", "260" ) useOnePt("/CMS_2013_I1224539_DIJET/d10-x01-y01", "7000", "400" ) useOnePt("/CMS_2013_I1224539_DIJET/d11-x01-y01", "7000", "400" ) useOnePt("/CMS_2013_I1224539_DIJET/d12-x01-y01", "7000", "600" ) useOnePt("/CMS_2013_I1224539_DIJET/d13-x01-y01", "7000", "600" ) useOnePt("/CMS_2013_I1224539_DIJET/d14-x01-y01", "7000", "600" ) useOnePt("/CMS_2013_I1224539_DIJET/d15-x01-y01", "7000", "210" ) useOnePt("/CMS_2013_I1224539_DIJET/d16-x01-y01", "7000", "260" ) useOnePt("/CMS_2013_I1224539_DIJET/d17-x01-y01", "7000", "400" ) useOnePt("/CMS_2013_I1224539_DIJET/d18-x01-y01", "7000", "400" ) useOnePt("/CMS_2013_I1224539_DIJET/d19-x01-y01", "7000", "600" ) useOnePt("/CMS_2013_I1224539_DIJET/d20-x01-y01", "7000", "600" ) useOnePt("/CMS_2013_I1224539_DIJET/d21-x01-y01", "7000", "600" ) useOnePt("/CMS_2013_I1224539_DIJET/d22-x01-y01", "7000", "210" ) useOnePt("/CMS_2013_I1224539_DIJET/d23-x01-y01", "7000", "260" ) useOnePt("/CMS_2013_I1224539_DIJET/d24-x01-y01", "7000", "400" ) useOnePt("/CMS_2013_I1224539_DIJET/d25-x01-y01", "7000", "600" ) useOnePt("/CMS_2013_I1224539_DIJET/d26-x01-y01", "7000", "600" ) useOnePt("/CMS_2013_I1224539_DIJET/d27-x01-y01", "7000", "600" ) useOnePt("/CMS_2013_I1224539_DIJET/d28-x01-y01", "7000", "600" ) useOnePt("/CMS_2013_I1273574/d01-x01-y01", "7000", "80" ) mergeByPt("/CMS_2013_I1273574/d02-x01-y01", "7000",1.) useOnePt("/CMS_2013_I1273574/d03-x01-y01", "7000", "80" ) useOnePt("/CMS_2013_I1273574/d04-x01-y01", "7000", "80" ) useOnePt("/CMS_2013_I1273574/d05-x01-y01", "7000", "80" ) useOnePt("/CMS_2013_I1273574/d06-x01-y01", "7000", "80" ) mergeByPt("/CMS_2013_I1273574/d07-x01-y01", "7000",1.) useOnePt("/CMS_2013_I1273574/d08-x01-y01", "7000", "80" ) mergeByPt("/CMS_2013_I1273574/d09-x01-y01", "7000",1.) useOnePt("/CMS_2013_I1273574/d10-x01-y01", "7000", "80" ) mergeByPt("/CMS_2013_I1273574/d11-x01-y01", "7000",1.) useOnePt("/CMS_2013_I1261026/d01-x01-y01", "7000", "0" ) useOnePt("/CMS_2013_I1261026/d02-x01-y01", "7000", "0" ) useOnePt("/CMS_2013_I1261026/d03-x01-y01", "7000", "0" ) useOnePt("/CMS_2013_I1261026/d04-x01-y01", "7000", "0" ) useOnePt("/CMS_2013_I1261026/d05-x01-y01", "7000", "0" ) useOnePt("/CMS_2013_I1261026/d06-x01-y01", "7000", "0" ) useOnePt("/CMS_2013_I1261026/d07-x01-y01", "7000", "0" ) useOnePt("/CMS_2013_I1261026/d08-x01-y01", "7000", "0" ) useOnePt("/CMS_2013_I1261026/d09-x01-y01", "7000", "0" ) useOnePt("/CMS_2013_I1261026/d10-x01-y01", "7000", "0" ) useOnePt("/CMS_2013_I1261026/d11-x01-y01", "7000", "0" ) useOnePt("/CMS_2013_I1261026/d12-x01-y01", "7000", "0" ) useOnePt("/CMS_2013_I1261026/d13-x01-y01", "7000", "0" ) useOnePt("/CMS_2013_I1261026/d14-x01-y01", "7000", "0" ) useOnePt("/CMS_2013_I1261026/d15-x01-y01", "7000", "0" ) useOnePt("/CMS_2013_I1261026/d16-x01-y01", "7000", "0" ) useOnePt("/CMS_2013_I1261026/d17-x01-y01", "7000", "0" ) logging.info("Processing CMS_2012_I1090423") useOneMass("/CMS_2012_I1090423/d01-x01-y01", "7000", "2900" ) useOneMass("/CMS_2012_I1090423/d02-x01-y01", "7000", "2300" ) useOneMass("/CMS_2012_I1090423/d03-x01-y01", "7000", "1700" ) useOneMass("/CMS_2012_I1090423/d04-x01-y01", "7000", "1100" ) useOneMass("/CMS_2012_I1090423/d05-x01-y01", "7000", "1100" ) useOneMass("/CMS_2012_I1090423/d06-x01-y01", "7000", "650" ) useOneMass("/CMS_2012_I1090423/d07-x01-y01", "7000", "650" ) useOneMass("/CMS_2012_I1090423/d08-x01-y01", "7000", "250" ) useOneMass("/CMS_2012_I1090423/d09-x01-y01", "7000", "250" ) logging.info("Processing ATLAS_2014_I1298811") mergeByPt("/ATLAS_2014_I1298811/d01-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1298811/d01-x01-y02", "7000") mergeByPt("/ATLAS_2014_I1298811/d02-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1298811/d02-x01-y02", "7000") mergeByPt("/ATLAS_2014_I1298811/d03-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1298811/d03-x01-y02", "7000") mergeByPt("/ATLAS_2014_I1298811/d04-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1298811/d04-x01-y02", "7000") mergeByPt("/ATLAS_2014_I1298811/d05-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1298811/d05-x01-y02", "7000") mergeByPt("/ATLAS_2014_I1298811/d06-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1298811/d06-x01-y02", "7000") mergeByPt("/ATLAS_2014_I1298811/d07-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1298811/d07-x01-y02", "7000") mergeByPt("/ATLAS_2014_I1298811/d08-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1298811/d08-x01-y02", "7000") mergeByPt("/ATLAS_2014_I1298811/d09-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1298811/d09-x01-y02", "7000") mergeByPt("/ATLAS_2014_I1298811/d10-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1298811/d10-x01-y02", "7000") useOnePt("/ATLAS_2014_I1298811/d11-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2014_I1298811/d12-x01-y01", "7000", "0" ) useOnePt("/ATLAS_2014_I1298811/d13-x01-y01", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d13-x01-y02", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d14-x01-y01", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d14-x01-y02", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d15-x01-y01", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d15-x01-y02", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d25-x01-y01", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d25-x01-y02", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d26-x01-y01", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d26-x01-y02", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d27-x01-y01", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d27-x01-y02", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d16-x01-y01", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d16-x01-y02", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d17-x01-y01", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d17-x01-y02", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d18-x01-y01", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d18-x01-y02", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d28-x01-y01", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d28-x01-y02", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d29-x01-y01", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d29-x01-y02", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d30-x01-y01", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d30-x01-y02", "7000", "4" ) useOnePt("/ATLAS_2014_I1298811/d19-x01-y01", "7000", "40" ) useOnePt("/ATLAS_2014_I1298811/d19-x01-y02", "7000", "40" ) useOnePt("/ATLAS_2014_I1298811/d20-x01-y01", "7000", "40" ) useOnePt("/ATLAS_2014_I1298811/d20-x01-y02", "7000", "40" ) useOnePt("/ATLAS_2014_I1298811/d21-x01-y01", "7000", "40" ) useOnePt("/ATLAS_2014_I1298811/d21-x01-y02", "7000", "40" ) useOnePt("/ATLAS_2014_I1298811/d31-x01-y01", "7000", "40" ) useOnePt("/ATLAS_2014_I1298811/d31-x01-y02", "7000", "40" ) useOnePt("/ATLAS_2014_I1298811/d32-x01-y01", "7000", "40" ) useOnePt("/ATLAS_2014_I1298811/d32-x01-y02", "7000", "40" ) useOnePt("/ATLAS_2014_I1298811/d33-x01-y01", "7000", "40" ) useOnePt("/ATLAS_2014_I1298811/d33-x01-y02", "7000", "40" ) useOnePt("/ATLAS_2014_I1298811/d22-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2014_I1298811/d22-x01-y02", "7000", "210" ) useOnePt("/ATLAS_2014_I1298811/d23-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2014_I1298811/d23-x01-y02", "7000", "210" ) useOnePt("/ATLAS_2014_I1298811/d24-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2014_I1298811/d24-x01-y02", "7000", "210" ) useOnePt("/ATLAS_2014_I1298811/d34-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2014_I1298811/d34-x01-y02", "7000", "210" ) useOnePt("/ATLAS_2014_I1298811/d35-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2014_I1298811/d35-x01-y02", "7000", "210" ) useOnePt("/ATLAS_2014_I1298811/d36-x01-y01", "7000", "210" ) useOnePt("/ATLAS_2014_I1298811/d36-x01-y02", "7000", "210" ) logging.info("Processing ATLAS_2014_I1268975") mergeByMass("/ATLAS_2014_I1268975/d01-x01-y01", "7000", 1000.) mergeByMass("/ATLAS_2014_I1268975/d01-x01-y02", "7000", 1000.) mergeByMass("/ATLAS_2014_I1268975/d01-x01-y03", "7000", 1000.) mergeByMass("/ATLAS_2014_I1268975/d01-x01-y04", "7000", 1000.) mergeByMass("/ATLAS_2014_I1268975/d01-x01-y05", "7000", 1000.) mergeByMass("/ATLAS_2014_I1268975/d01-x01-y06", "7000", 1000.) mergeByMass("/ATLAS_2014_I1268975/d02-x01-y01", "7000", 1000.) mergeByMass("/ATLAS_2014_I1268975/d02-x01-y02", "7000", 1000.) mergeByMass("/ATLAS_2014_I1268975/d02-x01-y03", "7000", 1000.) mergeByMass("/ATLAS_2014_I1268975/d02-x01-y04", "7000", 1000.) mergeByMass("/ATLAS_2014_I1268975/d02-x01-y05", "7000", 1000.) mergeByMass("/ATLAS_2014_I1268975/d02-x01-y06", "7000", 1000.) logging.info("Processing ATLAS_2014_I1307243") useOnePt( "/ATLAS_2014_I1307243/d01-x01-y01", "7000", "80" ) mergeByPt("/ATLAS_2014_I1307243/d02-x01-y01", "7000") useOnePt( "/ATLAS_2014_I1307243/d03-x01-y01", "7000", "80" ) mergeByPt("/ATLAS_2014_I1307243/d04-x01-y01", "7000") useOnePt( "/ATLAS_2014_I1307243/d05-x01-y01", "7000", "80" ) mergeByPt("/ATLAS_2014_I1307243/d06-x01-y01", "7000") useOnePt( "/ATLAS_2014_I1307243/d07-x01-y01", "7000", "80" ) mergeByPt("/ATLAS_2014_I1307243/d08-x01-y01", "7000") useOnePt( "/ATLAS_2014_I1307243/d09-x01-y01", "7000", "80" ) mergeByPt("/ATLAS_2014_I1307243/d10-x01-y01", "7000") useOnePt( "/ATLAS_2014_I1307243/d11-x01-y01", "7000", "80" ) mergeByPt("/ATLAS_2014_I1307243/d12-x01-y01", "7000") useOnePt( "/ATLAS_2014_I1307243/d13-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d14-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d15-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d16-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d17-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d18-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d19-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d20-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d21-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d22-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d23-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d24-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d25-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d26-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d27-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d28-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d29-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d30-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d31-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d32-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d33-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d34-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d35-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d36-x01-y01", "7000", "80" ) useOnePt( "/ATLAS_2014_I1307243/d37-x01-y01", "7000", "80" ) mergeByPt("/ATLAS_2014_I1307243/d38-x01-y01", "7000") useOnePt( "/ATLAS_2014_I1307243/d39-x01-y01", "7000", "80" ) mergeByPt("/ATLAS_2014_I1307243/d40-x01-y01", "7000") logging.info("Processing ATLAS_2014_I1325553") mergeByPt("/ATLAS_2014_I1325553/d01-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1325553/d02-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1325553/d03-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1325553/d04-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1325553/d05-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1325553/d06-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1325553/d07-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1325553/d08-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1325553/d09-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1325553/d10-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1325553/d11-x01-y01", "7000") mergeByPt("/ATLAS_2014_I1325553/d12-x01-y01", "7000") logging.info("Processing ATLAS_2016_I1419070") for i in range(1,13) : if(i<10) : mergeByPt("/ATLAS_2016_I1419070/d0%s-x01-y01" % i, "8000") else : mergeByPt("/ATLAS_2016_I1419070/d%s-x01-y01" % i, "8000") # remake differences and sums for ihist in range(1,4) : if not ("/ATLAS_2016_I1419070/d0%s-x01-y01" % ihist) in outhistos : continue h1 = outhistos["/ATLAS_2016_I1419070/d0%s-x01-y01" % ihist ] h2 = outhistos["/ATLAS_2016_I1419070/d0%s-x01-y01" % (ihist+3)] sstring = "/ATLAS_2016_I1419070/d%s-x01-y01" % (9+ihist) dstring = "/ATLAS_2016_I1419070/d0%s-x01-y01" % (6+ihist) hdiff = yoda.Scatter2D(dstring,dstring) hsum = yoda.Scatter2D(sstring,sstring) outhistos[dstring]= hdiff outhistos[sstring]= hsum - for nbin in range(0,h2.numBins) : - bsum = h1.bins[nbin]+h2.bins[nbin] + for nbin in range(0,h2.numBins()) : + bsum = h1.bins()[nbin]+h2.bins()[nbin] try: - ydiff = h2.bins[nbin].mean-h1.bins[nbin].mean + ydiff = h2.bins()[nbin].mean()-h1.bins()[nbin].mean() except: ydiff = 0 try: - ysum = bsum.mean - bstderr = bsum.stdErr + ysum = bsum.mean() + bstderr = bsum.stdErr() except: ysum = 0 bstderr = 0 try: - yerr = math.sqrt(h1.bins[nbin].stdErr**2+h2.bins[nbin].stdErr**2) + yerr = math.sqrt(h1.bins()[nbin].stdErr()**2+h2.bins()[nbin].stdErr()**2) except: yerr = 0 - x = h1.bins[nbin].xMid - xerr = 0.5*h1.bins[nbin].xWidth + x = h1.bins()[nbin].xMid() + xerr = 0.5*h1.bins()[nbin].xWidth() hdiff.addPoint(x,ydiff,xerr,yerr) hsum.addPoint(x,ysum ,xerr,bstderr) logging.info("Processing ATLAS_2015_I1394679") for i in range(1,5) : mergeByPt("/ATLAS_2015_I1394679/d0%s-x01-y01" % i, "8000") for i in range(5,11) : if(i<10) : useOnePt( "/ATLAS_2015_I1394679/d0%s-x01-y01" % i, "8000", "110" ) else : useOnePt( "/ATLAS_2015_I1394679/d%s-x01-y01" % i, "8000", "110" ) for i in range(0,4) : useOnePt( "/ATLAS_2015_I1394679/d%s-x01-y01" % (11+4*i), "8000", "110" ) useOnePt( "/ATLAS_2015_I1394679/d%s-x01-y01" % (12+4*i), "8000", "260" ) useOnePt( "/ATLAS_2015_I1394679/d%s-x01-y01" % (13+4*i), "8000", "600" ) useOnePt( "/ATLAS_2015_I1394679/d%s-x01-y01" % (14+4*i), "8000", "900" ) for i in range(0,5) : useOnePt( "/ATLAS_2015_I1394679/d%s-x01-y01" % (27+4*i), "8000", "110" ) useOnePt( "/ATLAS_2015_I1394679/d%s-x01-y01" % (28+4*i), "8000", "260" ) useOnePt( "/ATLAS_2015_I1394679/d%s-x01-y01" % (29+4*i), "8000", "400" ) useOnePt( "/ATLAS_2015_I1394679/d%s-x01-y01" % (30+4*i), "8000", "400" ) logging.info("Processing CMS_2013_I1208923") for i in range(1,6) : mergeByPt ("/CMS_2013_I1208923/d01-x01-y0%s" % i, "7000") mergeByMass("/CMS_2013_I1208923/d02-x01-y0%s" % i, "7000", 1.) logging.info("Processing CMS_2014_I1298810") for i in range(1,19) : if(i<10) : mergeByPt("/CMS_2014_I1298810/d0"+str(i)+"-x01-y01", "7000") else : mergeByPt("/CMS_2014_I1298810/d"+str(i)+"-x01-y01", "7000") logging.info("Processing CMS_2014_I1305624") for x in range(1,6) : useOnePt( "/CMS_2014_I1305624/d01-x%02d-y01" % x, "7000", "110" ) useOnePt( "/CMS_2014_I1305624/d01-x%02d-y02" % x, "7000", "110" ) useOnePt( "/CMS_2014_I1305624/d01-x%02d-y03" % x, "7000", "260" ) useOnePt( "/CMS_2014_I1305624/d01-x%02d-y04" % x, "7000", "260" ) useOnePt( "/CMS_2014_I1305624/d01-x%02d-y05" % x, "7000", "400" ) logging.info("Processing ATLAS_2011_I929691") for x in range(0,3) : useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+ 1), "7000", "20" ) useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+ 2), "7000", "40" ) useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+ 3), "7000", "40" ) useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+ 4), "7000", "80" ) useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+ 5), "7000", "110" ) useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+ 6), "7000", "110" ) useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+ 7), "7000", "210" ) useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+ 8), "7000", "260" ) useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+ 9), "7000", "260" ) useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+10), "7000", "400" ) logging.info("Processing ATLAS_2015_I1393758") for i in range(1,13) : mergeByPt("/ATLAS_2015_I1393758/d%02d-x01-y01" % i, "8000") logging.info("Processing CMS_2016_I1459051") for i in range(1,15) : mergeByPt("/CMS_2016_I1459051/d%02d-x01-y01" % i, "13000") logging.info("Processing ATLAS_2016_CONF_2016_092") for i in range(1,7) : mergeByPt("/ATLAS_2016_CONF_2016_092/d%02d-x01-y01" % i, "13000") logging.info("Processing ATLAS_2017_I1609253") useOnePt( "/ATLAS_2017_I1609253/d01-x01-y01", "8000", "260" ) useOnePt( "/ATLAS_2017_I1609253/d02-x01-y01", "8000", "260" ) useOnePt( "/ATLAS_2017_I1609253/d03-x01-y01", "8000", "260" ) useOnePt( "/ATLAS_2017_I1609253/d04-x01-y01", "8000", "260" ) useOnePt( "/ATLAS_2017_I1609253/d05-x01-y01", "8000", "400" ) useOnePt( "/ATLAS_2017_I1609253/d06-x01-y01", "8000", "400" ) useOnePt( "/ATLAS_2017_I1609253/d07-x01-y01", "8000", "400" ) useOnePt( "/ATLAS_2017_I1609253/d08-x01-y01", "8000", "400" ) useOnePt( "/ATLAS_2017_I1609253/d09-x01-y01", "8000", "400" ) useOnePt( "/ATLAS_2017_I1609253/d10-x01-y01", "8000", "400" ) useOnePt( "/ATLAS_2017_I1609253/d11-x01-y01", "8000", "600" ) useOnePt( "/ATLAS_2017_I1609253/d12-x01-y01", "8000", "600" ) logging.info("Processing CMS_2016_I1487277") mergeByPt("/CMS_2016_I1487277/d01-x01-y01", "8000") mergeByPt("/CMS_2016_I1487277/d02-x01-y01", "8000") mergeByPt("/CMS_2016_I1487277/d03-x01-y01", "8000") mergeByPt("/CMS_2016_I1487277/d04-x01-y01", "8000") mergeByPt("/CMS_2016_I1487277/d05-x01-y01", "8000") mergeByPt("/CMS_2016_I1487277/d06-x01-y01", "8000") mergeByPt("/CMS_2016_I1487277/d07-x01-y01", "8000") logging.info("Processing CMS_2016_I1421646") useOnePt( "/CMS_2016_I1421646/d01-x01-y01", "8000", "210" ) useOnePt( "/CMS_2016_I1421646/d02-x01-y01", "8000", "260" ) useOnePt( "/CMS_2016_I1421646/d03-x01-y01", "8000", "400" ) useOnePt( "/CMS_2016_I1421646/d04-x01-y01", "8000", "400" ) useOnePt( "/CMS_2016_I1421646/d05-x01-y01", "8000", "600" ) useOnePt( "/CMS_2016_I1421646/d06-x01-y01", "8000", "900" ) useOnePt( "/CMS_2016_I1421646/d07-x01-y01", "8000", "900" ) logging.info("Processing CMS_2017_I1605749") for i in [1,2,3,4,5,6,7,8,9,10,13,16] : useOnePt("/CMS_2017_I1605749/d%02d-x01-y01" % i, "8000", "400" ) for i in [11,14,17]: useOnePt("/CMS_2017_I1605749/d%02d-x01-y01" % i, "8000", "600" ) for i in [12,15,18]: useOnePt("/CMS_2017_I1605749/d%02d-x01-y01" % i, "8000", "900" ) def CMS_2012_I1111014_name(i,j) : if(i+j<100) : return "/CMS_2012_I1111014/d%02d-x01-y01" % (i+j) else : return "/CMS_2012_I1111014/d%03d-x01-y01" % (i+j) logging.info("Processing CMS_2012_I1111014") for j in [0,22,44,66,87,106]: for i in [1,2,3] : useOnePt(CMS_2012_I1111014_name(i,j), "7000", "20" ) for i in [4,5,6,7]: useOnePt(CMS_2012_I1111014_name(i,j), "7000", "40" ) for i in [8,9,10]: useOnePt(CMS_2012_I1111014_name(i,j), "7000", "80" ) for i in [11,12,13,14,15,16]: useOnePt(CMS_2012_I1111014_name(i,j), "7000", "110" ) for i in [17,18]: useOnePt(CMS_2012_I1111014_name(i,j), "7000", "210" ) useOnePt(CMS_2012_I1111014_name(19,j), "7000", "260" ) if(j<87) : for i in [20,21]: useOnePt(CMS_2012_I1111014_name(i,j), "7000", "400" ) if(j<66) : useOnePt(CMS_2012_I1111014_name(22,j), "7000", "600" ) for i in [126,127,128] : for j in [1,2] : mergeByPt("/CMS_2012_I1111014/d%03d-x01-y%02d" % (i,j), "7000") logging.info("Processing CMS_2018_I1682495") for i in [0,1,2,3] : useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+ 1), "13000", "110" ) useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+ 2), "13000", "260" ) useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+ 3), "13000", "260" ) useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+ 4), "13000", "400" ) useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+ 5), "13000", "400" ) useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+ 6), "13000", "600" ) useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+ 7), "13000", "600" ) useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+ 8), "13000", "900" ) useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+ 9), "13000", "900" ) useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+10), "13000", "900" ) useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+11), "13000", "900" ) useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+12), "13000", "900" ) logging.info("Processing CMS_2015_I1385107") for i in range(1,9) : mergeByPt("/CMS_2015_I1385107/d%02d-x01-y01" % i, "2760") logging.info("Processing CMS_2018_I1663452") useOneMass("/CMS_2018_I1663452/d01-x01-y01", "13000", "5900" ) useOneMass("/CMS_2018_I1663452/d02-x01-y01", "13000", "4900" ) useOneMass("/CMS_2018_I1663452/d03-x01-y01", "13000", "3900" ) useOneMass("/CMS_2018_I1663452/d04-x01-y01", "13000", "3900" ) useOneMass("/CMS_2018_I1663452/d05-x01-y01", "13000", "2800" ) useOneMass("/CMS_2018_I1663452/d06-x01-y01", "13000", "2800" ) useOneMass("/CMS_2018_I1663452/d07-x01-y01", "13000", "2200" ) logging.info("Processing CMS_2017_I1519995") useOneMass("/CMS_2017_I1519995/d01-x01-y01", "13000", "3900" ) useOneMass("/CMS_2017_I1519995/d02-x01-y01", "13000", "3900" ) useOneMass("/CMS_2017_I1519995/d03-x01-y01", "13000", "2800" ) useOneMass("/CMS_2017_I1519995/d04-x01-y01", "13000", "2800" ) useOneMass("/CMS_2017_I1519995/d05-x01-y01", "13000", "2200" ) useOneMass("/CMS_2017_I1519995/d06-x01-y01", "13000", "1600" ) logging.info("Processing CMS_2016_I1486238") for i in [1,5,9,10,12,13,14,16,17] : useOnePt("/CMS_2016_I1486238/d%02d-x01-y01" % i, "7000", "20" ) mergeByPt("/CMS_2016_I1486238/d11-x01-y01", "7000") mergeByPt("/CMS_2016_I1486238/d15-x01-y01", "7000") logging.info("Processing ATLAS_2018_I1634970") for i in range(1,7) : mergeByPt("/ATLAS_2018_I1634970/d%02d-x01-y01"%i, "13000") for i in range(7,13) : mergeByMass("/ATLAS_2018_I1634970/d%02d-x01-y01"%i, "13000", 1.) # rescaling for semi-leptonic top decays (we only simulate 1 charge combination) for i in range(96,116,2) : rescale("/ATLAS_2018_I1656578/d%s-x01-y01" % i,2.) for i in range(15,29,2) : rescale("/ATLAS_2017_I1614149/d%s-x01-y01" % i,2.) for i in range(1,23,2) : rescale("/ATLAS_2015_I1404878/d%02d-x01-y01" % i,2.) rescale("/ATLAS_2015_I1397637/d01-x01-y01",2.) for i in range(1,22,1) : rescale("/ATLAS_2015_I1345452/d%02d-x01-y01" % i,2.) for i in range(1,10,1) : rescale("/ATLAS_2014_I1304688/d%02d-x01-y01" % i,2.) for i in range(1,82) : rescale("/CMS_2018_I1663958/d%02d-x01-y01" % i,2.) for i in range(169,173,1) : rescale("/CMS_2018_I1663958/d%02d-x01-y01" % i,2.) for i in range(8,15) : rescale("/CMS_2018_I1662081/d%02d-x01-y01" % i,2.) for i in range(1,41) : rescale("/CMS_2016_I1491950/d%02d-x02-y01" % i,2.) for i in range(1,13) : rescale("/CMS_2016_I1454211/d%02d-x01-y01" % i,2.) rescale("/CMS_2017_I1518399/d01-x01-y01",2.) # Choose output file name = args[0]+"-Jets.yoda" yoda.writeYODA(outhistos,name) sys.exit(0) diff --git a/Tests/python/merge-LHC-Photon b/Tests/python/merge-LHC-Photon --- a/Tests/python/merge-LHC-Photon +++ b/Tests/python/merge-LHC-Photon @@ -1,298 +1,302 @@ #! /usr/bin/env python import logging import sys import os, yoda """%prog Script for merging aida files """ def fillAbove(scale,desthisto, sourcehistosbyptmin): pthigh= 1e100 ptlow =-1e100 for pt, h in sorted(sourcehistosbyptmin.iteritems(),reverse=True): ptlow=pt if(type(desthisto)==yoda.core.Scatter2D) : for i in range(0,h.numPoints) : xMin = h.points[i].x-h.points[i].xErrs.minus if( xMin*scale >= ptlow and xMin*scale < pthigh ) : desthisto.addPoint(h.points[i]) elif(type(desthisto)==yoda.core.Profile1D) : - for i in range(0,h.numBins) : - if(h.bins[i].xMin*scale >= ptlow and - h.bins[i].xMin*scale < pthigh ) : - desthisto.bins[i] += h.bins[i] + for i in range(0,h.numBins()) : + if(h.bins()[i].xMin()*scale >= ptlow and + h.bins()[i].xMin()*scale < pthigh ) : + desthisto.bins()[i] += h.bins()[i] elif(type(desthisto)==yoda.core.Histo1D) : - for i in range(0,h.numBins) : - if(h.bins[i].xMin*scale >= ptlow and - h.bins[i].xMin*scale < pthigh ) : - desthisto.bins[i] += h.bins[i] + for i in range(0,h.numBins()) : + if(h.bins()[i].xMin()*scale >= ptlow and + h.bins()[i].xMin()*scale < pthigh ) : + desthisto.bins()[i] += h.bins()[i] else : - logging.error("Can't merge %s, unknown type" % desthisto.path) + logging.error("Can't merge %s, unknown type" % desthisto.path()) sys.exit(1) pthigh=pt def mergeByPt(hpath, scale=1.): global inhistos global outhistos try: fillAbove(scale,outhistos[hpath], inhistos[hpath]) except: pass def useOnePt(hpath, ptmin): global inhistos global outhistos try: ## Find best pT_min match ptmins = inhistos[hpath].keys() closest_ptmin = None for ptm in ptmins: if closest_ptmin is None or \ abs(ptm-float(ptmin)) < abs(closest_ptmin-float(ptmin)): closest_ptmin = ptm if closest_ptmin != float(ptmin): logging.warning("Inexact match for requested pTmin=%s: " % ptmin + \ "using pTmin=%e instead" % closest_ptmin) outhistos[hpath] = inhistos[hpath][closest_ptmin] except: pass if sys.version_info[:3] < (2,4,0): print "rivet scripts require Python version >= 2.4.0... exiting" sys.exit(1) if __name__ == "__main__": import logging from optparse import OptionParser, OptionGroup parser = OptionParser(usage="%prog base") verbgroup = OptionGroup(parser, "Verbosity control") verbgroup.add_option("-v", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL", default=logging.INFO, help="print debug (very verbose) messages") verbgroup.add_option("-q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL", default=logging.INFO, help="be very quiet") parser.add_option_group(verbgroup) (opts, args) = parser.parse_args() logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s") ## Check args if len(args) < 1: logging.error("Must specify at least the name of the files") sys.exit(1) files=["-7-DiPhoton-GammaGamma.yoda","-7-DiPhoton-GammaJet.yoda","-GammaGamma-7.yoda", "-8-DiPhoton-GammaGamma.yoda","-8-DiPhoton-GammaJet.yoda","-GammaGamma-8.yoda"] for i in [7,8,13] : for j in range(1,5) : files.append("-%s-PromptPhoton-%s.yoda" % (i,j)) ## Get histos inhistos = {} outhistos={} for f in files: file='Rivet-'+args[0]+f if not os.access(file, os.R_OK): logging.error("%s can not be read" % file) continue try: aos = yoda.read(file) except: logging.error("%s can not be parsed as XML" % file) continue if(file.find("PromptPhoton")>=0) : if(file.find("PromptPhoton-1")>0) : ptmin=0. elif(file.find("PromptPhoton-2")>0) : ptmin=35. elif(file.find("PromptPhoton-3")>0) : ptmin=90. elif(file.find("PromptPhoton-4")>0) : ptmin=170. ## Get histos from this YODA file for aopath, ao in aos.iteritems() : if("RAW" in aopath) :continue if not inhistos.has_key(aopath): inhistos[aopath] = {} if (aopath.find("CMS_2013_I1258128")>0) : if(aopath.find("d05")>0 or aopath.find("d06")>0 or aopath.find("d07")>0 or aopath.find("d08")>0) : inhistos[aopath][ptmin] = ao else : inhistos[aopath][ptmin] = ao else : ## Get histos from this YODA file for aopath, ao in aos.iteritems() : if("RAW" in aopath) :continue if(aopath.find("XSEC")>=0 or aopath.find("EVTCOUNT")>=0) : continue if ( aopath in outhistos ) : aotype = type(ao) if aotype in (yoda.Counter, yoda.Histo1D, yoda.Histo2D, yoda.Profile1D, yoda.Profile2D): outhistos[aopath] += ao else : quit() else: outhistos[aopath] = ao for hpath,hsets in inhistos.iteritems(): if( hpath.find("1263495")>0 or hpath.find("1093738")>0 or hpath.find("921594" )>0 or hpath.find("8914702")>0 or hpath.find("1244522")>0 or hpath.find("1457605")>0 or hpath.find("1632756")>0 or hpath.find("1266056")>0 or hpath.find("1645627")>0) : - if(type(hsets.values()[0])==yoda.core.Scatter2D) : - outhistos[hpath] = yoda.core.Scatter2D(hsets.values()[0].path, - hsets.values()[0].title) - elif(type(hsets.values()[0])==yoda.core.Profile1D) : - outhistos[hpath] = yoda.core.Profile1D(hsets.values()[0].path, - hsets.values()[0].title) - for i in range(0,hsets.values()[0].numBins) : - outhistos[hpath].addBin(hsets.values()[0].bins[i].xMin, - hsets.values()[0].bins[i].xMax) - elif(type(hsets.values()[0])==yoda.core.Histo1D) : - outhistos[hpath] = yoda.core.Histo1D(hsets.values()[0].path, - hsets.values()[0].title) - for i in range(0,hsets.values()[0].numBins) : - outhistos[hpath].addBin(hsets.values()[0].bins[i].xMin, - hsets.values()[0].bins[i].xMax) + title="" + path="" + histo = hsets.values()[0] + if hasattr(histo, 'title'): + title=histo.title() + if hasattr(histo, 'path'): + path=histo.path() + if(type(histo)==yoda.core.Scatter2D) : + outhistos[hpath] = yoda.core.Scatter2D(path,title) + elif(type(histo)==yoda.core.Profile1D) : + outhistos[hpath] = yoda.core.Profile1D(path,title) + for i in range(0,histo.numBins()) : + outhistos[hpath].addBin(histo.bins()[i].xMin(), + histo.bins()[i].xMax()) + elif(type(histo)==yoda.core.Histo1D) : + outhistos[hpath] = yoda.core.Histo1D(path,title) + for i in range(0,histo.numBins()) : + outhistos[hpath].addBin(histo.bins()[i].xMin(), + histo.bins()[i].xMax()) else : logging.error("Histogram %s is of unknown type" % hpath) - print hpath,type(hsets.values()[0]) + print hpath,type(histo) sys.exit(1) logging.info("Processing ATLAS_2013_I1263495") mergeByPt("/ATLAS_2013_I1263495/d01-x01-y01") mergeByPt("/ATLAS_2013_I1263495/d02-x01-y01") useOnePt("/ATLAS_2013_I1263495/d03-x01-y01", "90" ) logging.info("Processing ATLAS_2012_I1093738") mergeByPt("/ATLAS_2012_I1093738/d01-x01-y01") mergeByPt("/ATLAS_2012_I1093738/d02-x01-y01") mergeByPt("/ATLAS_2012_I1093738/d03-x01-y01") mergeByPt("/ATLAS_2012_I1093738/d04-x01-y01") mergeByPt("/ATLAS_2012_I1093738/d05-x01-y01") mergeByPt("/ATLAS_2012_I1093738/d06-x01-y01") logging.info("Processing ATLAS_2011_I921594") mergeByPt("/ATLAS_2011_I921594/d01-x01-y01") mergeByPt("/ATLAS_2011_I921594/d01-x01-y02") mergeByPt("/ATLAS_2011_I921594/d01-x01-y04") mergeByPt("/ATLAS_2011_I921594/d01-x01-y05") logging.info("Processing ATLAS_2010_S8914702") mergeByPt("/ATLAS_2010_S8914702/d01-x01-y01") mergeByPt("/ATLAS_2010_S8914702/d01-x01-y02") mergeByPt("/ATLAS_2010_S8914702/d01-x01-y03") logging.info("Processing CMS_2013_I1258128") useOnePt("/CMS_2013_I1258128/d05-x01-y01", "35" ) useOnePt("/CMS_2013_I1258128/d06-x01-y01", "35" ) useOnePt("/CMS_2013_I1258128/d07-x01-y01", "35" ) useOnePt("/CMS_2013_I1258128/d08-x01-y01", "35" ) logging.info("Processing ATLAS_2013_I1244522") mergeByPt("/ATLAS_2013_I1244522/d01-x01-y01") mergeByPt("/ATLAS_2013_I1244522/d02-x01-y01") useOnePt("/ATLAS_2013_I1244522/d03-x01-y01", "35" ) useOnePt("/ATLAS_2013_I1244522/d04-x01-y01", "35" ) useOnePt("/ATLAS_2013_I1244522/d05-x01-y01", "35" ) useOnePt("/ATLAS_2013_I1244522/d06-x01-y01", "35" ) useOnePt("/ATLAS_2013_I1244522/d07-x01-y01", "35" ) logging.info("Processing ATLAS_2016_I1457605") mergeByPt("/ATLAS_2016_I1457605/d01-x01-y01") mergeByPt("/ATLAS_2016_I1457605/d02-x01-y01") mergeByPt("/ATLAS_2016_I1457605/d03-x01-y01") mergeByPt("/ATLAS_2016_I1457605/d04-x01-y01") logging.info("Processing ATLAS_2017_I1632756") mergeByPt("/ATLAS_2017_I1632756/d02-x01-y01") mergeByPt("/ATLAS_2017_I1632756/d03-x01-y01") mergeByPt("/ATLAS_2017_I1632756/d04-x01-y01") mergeByPt("/ATLAS_2017_I1632756/d05-x01-y01") logging.info("Processing CMS_2014_I1266056") mergeByPt("/CMS_2014_I1266056/d01-x01-y01") mergeByPt("/CMS_2014_I1266056/d01-x01-y02") mergeByPt("/CMS_2014_I1266056/d02-x01-y01") mergeByPt("/CMS_2014_I1266056/d02-x01-y02") mergeByPt("/CMS_2014_I1266056/d03-x01-y01") mergeByPt("/CMS_2014_I1266056/d03-x01-y02") mergeByPt("/CMS_2014_I1266056/d04-x01-y01") mergeByPt("/CMS_2014_I1266056/d04-x01-y02") logging.info("Processing ATLAS_2017_I1645627") mergeByPt("/ATLAS_2017_I1645627/d01-x01-y01") mergeByPt("/ATLAS_2017_I1645627/d02-x01-y01") useOnePt("/ATLAS_2017_I1645627/d03-x01-y01","90") useOnePt("/ATLAS_2017_I1645627/d04-x01-y01","90") useOnePt("/ATLAS_2017_I1645627/d05-x01-y01","90") logging.info("Processing /MC_PHOTONJETS") useOnePt("/MC_PHOTONJETS/jet_HT","0") useOnePt("/MC_PHOTONJETS/jet_eta_1","0") useOnePt("/MC_PHOTONJETS/jet_eta_2","0") useOnePt("/MC_PHOTONJETS/jet_eta_3","0") useOnePt("/MC_PHOTONJETS/jet_eta_4","0") useOnePt("/MC_PHOTONJETS/jet_eta_pmratio_1","0") useOnePt("/MC_PHOTONJETS/jet_eta_pmratio_2","0") useOnePt("/MC_PHOTONJETS/jet_eta_pmratio_3","0") useOnePt("/MC_PHOTONJETS/jet_eta_pmratio_4","0") useOnePt("/MC_PHOTONJETS/jet_mass_1","0") useOnePt("/MC_PHOTONJETS/jet_mass_2","0") useOnePt("/MC_PHOTONJETS/jet_mass_3","0") useOnePt("/MC_PHOTONJETS/jet_mass_4","0") useOnePt("/MC_PHOTONJETS/jet_multi_exclusive","0") useOnePt("/MC_PHOTONJETS/jet_multi_inclusive","0") useOnePt("/MC_PHOTONJETS/jet_multi_ratio","0") useOnePt("/MC_PHOTONJETS/jet_pT_1","0") useOnePt("/MC_PHOTONJETS/jet_pT_2","0") useOnePt("/MC_PHOTONJETS/jet_pT_3","0") useOnePt("/MC_PHOTONJETS/jet_pT_4","0") useOnePt("/MC_PHOTONJETS/jet_y_1","0") useOnePt("/MC_PHOTONJETS/jet_y_2","0") useOnePt("/MC_PHOTONJETS/jet_y_3","0") useOnePt("/MC_PHOTONJETS/jet_y_4","0") useOnePt("/MC_PHOTONJETS/jet_y_pmratio_1","0") useOnePt("/MC_PHOTONJETS/jet_y_pmratio_2","0") useOnePt("/MC_PHOTONJETS/jet_y_pmratio_3","0") useOnePt("/MC_PHOTONJETS/jet_y_pmratio_4","0") useOnePt("/MC_PHOTONJETS/jets_dR_12","0") useOnePt("/MC_PHOTONJETS/jets_dR_13","0") useOnePt("/MC_PHOTONJETS/jets_dR_23","0") useOnePt("/MC_PHOTONJETS/jets_deta_12","0") useOnePt("/MC_PHOTONJETS/jets_deta_13","0") useOnePt("/MC_PHOTONJETS/jets_deta_23","0") useOnePt("/MC_PHOTONJETS/jets_dphi_12","0") useOnePt("/MC_PHOTONJETS/jets_dphi_13","0") useOnePt("/MC_PHOTONJETS/jets_dphi_23","0") useOnePt("/MC_PHOTONJETS/photon_jet1_dR","0") useOnePt("/MC_PHOTONJETS/photon_jet1_deta","0") useOnePt("/MC_PHOTONJETS/photon_jet1_dphi","0") useOnePt("/MC_PHOTONJETUE/gammajet-dR","0") useOnePt("/MC_PHOTONJETUE/gammajet-dphi","0") useOnePt("/MC_PHOTONJETUE/trans-maxnchg-gamma","0") useOnePt("/MC_PHOTONJETUE/trans-maxnchg-jet","0") useOnePt("/MC_PHOTONJETUE/trans-maxptsum-gamma","0") useOnePt("/MC_PHOTONJETUE/trans-maxptsum-jet","0") useOnePt("/MC_PHOTONJETUE/trans-minnchg-gamma","0") useOnePt("/MC_PHOTONJETUE/trans-minnchg-jet","0") useOnePt("/MC_PHOTONJETUE/trans-minptsum-gamma","0") useOnePt("/MC_PHOTONJETUE/trans-minptsum-jet","0") useOnePt("/MC_PHOTONJETUE/trans-nchg-gamma","0") useOnePt("/MC_PHOTONJETUE/trans-nchg-jet","0") useOnePt("/MC_PHOTONJETUE/trans-ptavg-gamma","0") useOnePt("/MC_PHOTONJETUE/trans-ptavg-jet","0") useOnePt("/MC_PHOTONJETUE/trans-ptsum-gamma","0") useOnePt("/MC_PHOTONJETUE/trans-ptsum-jet","0") # Choose output file name = args[0]+"-Photon.yoda" yoda.writeYODA(outhistos,name) sys.exit(0) diff --git a/Tests/python/merge-SppS b/Tests/python/merge-SppS --- a/Tests/python/merge-SppS +++ b/Tests/python/merge-SppS @@ -1,165 +1,167 @@ #! /usr/bin/env python # import lighthisto import logging import sys +import math if sys.version_info[:3] < (2,4,0): print "rivet scripts require Python version >= 2.4.0... exiting" sys.exit(1) import os, yoda, copy # # ############################################# def useOne(hpath, sqrts): global inhistos global outhistos try: outhistos[hpath] = inhistos[hpath][float(sqrts)] except: pass if __name__ == "__main__": import logging from optparse import OptionParser, OptionGroup parser = OptionParser(usage="%prog name") verbgroup = OptionGroup(parser, "Verbosity control") verbgroup.add_option("-v", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL", default=logging.INFO, help="print debug (very verbose) messages") verbgroup.add_option("-q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL", default=logging.INFO, help="be very quiet") parser.add_option_group(verbgroup) (opts, args) = parser.parse_args() logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s") ## Check args if len(args) < 1: logging.error("Must specify at least the name of the files") sys.exit(1) ####################################### yodafiles=["ISR-44-UE.yoda","ISR-62-UE.yoda",args[0]+"-63-UE.yoda","ISR-30-UE.yoda", \ "ISR-53-UE.yoda",args[0]+"-200-UE.yoda",args[0]+"-500-UE.yoda",args[0]+"-900-UE.yoda", \ - args[0]+"-546-UE.yoda",args[0]+"-53-UE.yoda"] + args[0]+"-546-UE.yoda",args[0]+"-53-UE.yoda","EHS-UE.yoda"] ## Get histos inhistos = {} outhistos={} for file in yodafiles: file = 'Rivet-'+file if(file.find("44")>0) : sqrts=44 elif(file.find("63")>0) : sqrts=63 elif(file.find("30")>0) : sqrts=30 elif(file.find("53")>0) : sqrts=53 elif(file.find("200")>0) : sqrts=200 elif(file.find("500")>0) : sqrts=500 elif(file.find("900")>0) : sqrts=900 elif(file.find("546")>0) : sqrts=546 elif(file.find("53")>0) : sqrts=53 - + elif(file.find("EHS")>0) : + sqrts=math.sqrt(2.*.938*250.) if not os.access(file, os.R_OK): logging.error("%s can not be read" % file) continue try: aos = yoda.read(file) except: logging.error("%s can not be parsed as yoda" % file) continue ## Get histos from this YODA file for aopath, ao in aos.iteritems() : if("RAW" in aopath) :continue if(aopath.find("1926373")>0 or aopath.find("1867512")>0 or aopath.find("1583476")>0 or aopath.find("2044935")>0 or aopath.find("1178091")>0 ) : if not inhistos.has_key(aopath): inhistos[aopath] = {} if not inhistos[aopath].has_key(sqrts): inhistos[aopath][sqrts] = ao else: raise Exception("A set with sqrts = %s already exists" % ( sqrts)) else : outhistos[aopath] = ao # UA5_1989_S1926373 useOne("/UA5_1989_S1926373/d01-x01-y01","200") useOne("/UA5_1989_S1926373/d02-x01-y01","900") useOne("/UA5_1989_S1926373/d03-x01-y01","200") useOne("/UA5_1989_S1926373/d04-x01-y01","200") useOne("/UA5_1989_S1926373/d05-x01-y01","200") useOne("/UA5_1989_S1926373/d06-x01-y01","200") useOne("/UA5_1989_S1926373/d07-x01-y01","900") useOne("/UA5_1989_S1926373/d08-x01-y01","900") useOne("/UA5_1989_S1926373/d09-x01-y01","900") useOne("/UA5_1989_S1926373/d10-x01-y01","900") useOne("/UA5_1989_S1926373/d11-x01-y01","200") useOne("/UA5_1989_S1926373/d12-x01-y01","900") # UA5_1988_S1867512 useOne("/UA5_1988_S1867512/d02-x01-y01","200") useOne("/UA5_1988_S1867512/d02-x01-y02","546") useOne("/UA5_1988_S1867512/d02-x01-y03","900") useOne("/UA5_1988_S1867512/d03-x01-y01","200") useOne("/UA5_1988_S1867512/d03-x01-y02","546") useOne("/UA5_1988_S1867512/d03-x01-y03","900") # UA5_1986_S1583476 useOne("/UA5_1986_S1583476/d01-x01-y01","200") useOne("/UA5_1986_S1583476/d01-x01-y02","200") useOne("/UA5_1986_S1583476/d01-x01-y03","900") useOne("/UA5_1986_S1583476/d01-x01-y04","900") useOne("/UA5_1986_S1583476/d02-x01-y01","200") useOne("/UA5_1986_S1583476/d02-x01-y02","200") useOne("/UA5_1986_S1583476/d02-x01-y03","200") useOne("/UA5_1986_S1583476/d02-x01-y04","200") useOne("/UA5_1986_S1583476/d02-x01-y05","200") useOne("/UA5_1986_S1583476/d02-x01-y06","200") useOne("/UA5_1986_S1583476/d03-x01-y01","900") useOne("/UA5_1986_S1583476/d03-x01-y02","900") useOne("/UA5_1986_S1583476/d03-x01-y03","900") useOne("/UA5_1986_S1583476/d03-x01-y04","900") useOne("/UA5_1986_S1583476/d03-x01-y05","900") useOne("/UA5_1986_S1583476/d03-x01-y06","900") useOne("/UA5_1986_S1583476/d03-x01-y07","900") useOne("/UA5_1986_S1583476/d03-x01-y08","900") useOne("/UA5_1986_S1583476/d03-x01-y09","900") # UA1_1990_S2044935 useOne("/UA1_1990_S2044935/d01-x01-y01","200") useOne("/UA1_1990_S2044935/d01-x01-y02","500") useOne("/UA1_1990_S2044935/d01-x01-y03","900") useOne("/UA1_1990_S2044935/d02-x01-y01","200") useOne("/UA1_1990_S2044935/d02-x01-y02","500") useOne("/UA1_1990_S2044935/d02-x01-y03","900") useOne("/UA1_1990_S2044935/d03-x01-y01","900") useOne("/UA1_1990_S2044935/d04-x01-y01","900") useOne("/UA1_1990_S2044935/d05-x01-y01","900") useOne("/UA1_1990_S2044935/d06-x01-y01","200") useOne("/UA1_1990_S2044935/d07-x01-y01","900") useOne("/UA1_1990_S2044935/d08-x01-y01","63") useOne("/UA1_1990_S2044935/d09-x01-y01","200") useOne("/UA1_1990_S2044935/d10-x01-y01","500") useOne("/UA1_1990_S2044935/d11-x01-y01","900") useOne("/UA1_1990_S2044935/d12-x01-y01","200") useOne("/UA1_1990_S2044935/d12-x01-y02","500") useOne("/UA1_1990_S2044935/d12-x01-y03","900") # SFM_1984_S1178091 useOne("/SFM_1984_S1178091/d01-x01-y01","30") useOne("/SFM_1984_S1178091/d01-x01-y02","44") useOne("/SFM_1984_S1178091/d01-x01-y03","53") useOne("/SFM_1984_S1178091/d01-x01-y04","63") useOne("/SFM_1984_S1178091/d02-x01-y01","30") useOne("/SFM_1984_S1178091/d02-x01-y02","44") useOne("/SFM_1984_S1178091/d02-x01-y03","53") useOne("/SFM_1984_S1178091/d02-x01-y04","63") # Choose output file name = args[0]+".yoda" # output the yoda file yoda.writeYODA(outhistos,name) sys.exit(0) diff --git a/Tests/python/merge-Star b/Tests/python/merge-Star --- a/Tests/python/merge-Star +++ b/Tests/python/merge-Star @@ -1,168 +1,174 @@ #! /usr/bin/env python import logging import sys if sys.version_info[:3] < (2,4,0): print "rivet scripts require Python version >= 2.4.0... exiting" sys.exit(1) import os, yoda # ############################################# def fillAbove(desthisto, sourcehistosbyptmin): pthigh= 1e100 ptlow =-1e100 for pt, h in sorted(sourcehistosbyptmin.iteritems(),reverse=True): ptlow=pt if(type(desthisto)==yoda.core.Scatter2D) : - for i in range(0,h.numPoints) : - xMin = h.points[i].x-h.points[i].xErrs.minus + for i in range(0,h.numPoints()) : + xMin = h.points()[i].x-h.points()[i].xErrs().minus if( xMin >= ptlow and xMin < pthigh ) : - desthisto.addPoint(h.points[i]) + desthisto.addPoint(h.points()[i]) elif(type(desthisto)==yoda.core.Profile1D) : - for i in range(0,h.numBins) : - if(h.bins[i].xMin >= ptlow and - h.bins[i].xMin < pthigh ) : - desthisto.bins[i] += h.bins[i] + for i in range(0,h.numBins()) : + if(h.bins()[i].xMin() >= ptlow and + h.bins()[i].xMin() < pthigh ) : + desthisto.bins()[i] += h.bins()[i] elif(type(desthisto)==yoda.core.Histo1D) : - for i in range(0,h.numBins) : - if(h.bins[i].xMin >= ptlow and - h.bins[i].xMin < pthigh ) : - desthisto.bins[i] += h.bins[i] + for i in range(0,h.numBins()) : + if(h.bins()[i].xMin() >= ptlow and + h.bins()[i].xMin() < pthigh ) : + desthisto.bins()[i] += h.bins()[i] else : logging.error("Can't merge %s, unknown type" % desthisto.path) sys.exit(1) pthigh=pt def mergeByPt(hpath, sqrts): global inhistos global outhistos try: fillAbove(outhistos[hpath], inhistos[hpath][float(sqrts)]) except: pass def useOnePt(hpath, sqrts, ptmin): global inhistos global outhistos try: ## Find best pT_min match ptmins = inhistos[hpath][float(sqrts)].keys() closest_ptmin = None for ptm in ptmins: if closest_ptmin is None or \ abs(ptm-float(ptmin)) < abs(closest_ptmin-float(ptmin)): closest_ptmin = ptm if closest_ptmin != float(ptmin): logging.warning("Inexact match for requested pTmin=%s: " % ptmin + \ "using pTmin=%e instead" % closest_ptmin) outhistos[hpath] = inhistos[hpath][float(sqrts)][closest_ptmin] except: pass # ####################################### if __name__ == "__main__": import logging from optparse import OptionParser, OptionGroup parser = OptionParser(usage="%prog name") verbgroup = OptionGroup(parser, "Verbosity control") verbgroup.add_option("-v", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL", default=logging.INFO, help="print debug (very verbose) messages") verbgroup.add_option("-q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL", default=logging.INFO, help="be very quiet") parser.add_option_group(verbgroup) (opts, args) = parser.parse_args() logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s") ## Check args if len(args) < 1: logging.error("Must specify at least the name of the files") sys.exit(1) yodafiles=["-UE.yoda","-Jets-1.yoda","-Jets-2.yoda","-Jets-3.yoda","-Jets-4.yoda"] ## Get histos inhistos = {} outhistos={} weights = {} for f in yodafiles: file='Rivet-'+args[0]+f + print file if(file.find("-UE")>0) : sqrts=200 ptmin=0. elif(file.find("-Jets-1")>0) : sqrts=200 ptmin=2. elif(file.find("-Jets-2")>0) : sqrts=200 ptmin=5. elif(file.find("-Jets-3")>0) : sqrts=200 ptmin=26. elif(file.find("-Jets-4")>0) : sqrts=200 ptmin=15. if not os.access(file, os.R_OK): logging.error("%s can not be read" % file) continue try: aos = yoda.read(file) except: logging.error("%s can not be parsed as YODA" % file) continue ## Get histos from this YODA file for aopath, ao in aos.iteritems() : + print aopath if("RAW" in aopath) :continue if(aopath.find("6870392")>0 or aopath.find("HELEN")>0) : if not inhistos.has_key(aopath): inhistos[aopath] = {} tmpE = inhistos[aopath] if not tmpE.has_key(sqrts): tmpE[sqrts] = {} tmpP = tmpE[sqrts] if not tmpP.has_key(ptmin): tmpP[ptmin] = ao else: raise Exception("A set with ptmin = %s already exists" % ( ptmin)) else : outhistos[aopath] = ao ## Make empty output histos if needed for hpath,hsets in inhistos.iteritems(): if( (hpath.find("6870392")>0 and hpath.find("d02-x01-y01" )>0 ) or hpath.find("HELEN")>0 ) : - if(type(hsets.values()[0].values()[0])==yoda.core.Scatter2D) : - outhistos[hpath] = yoda.core.Scatter2D(hsets.values()[0].values()[0].path, - hsets.values()[0].values()[0].title) - elif(type(hsets.values()[0].values()[0])==yoda.core.Profile1D) : - outhistos[hpath] = yoda.core.Profile1D(hsets.values()[0].values()[0].path, - hsets.values()[0].values()[0].title) - for i in range(0,hsets.values()[0].values()[0].numBins) : - outhistos[hpath].addBin(hsets.values()[0].values()[0].bins[i].xMin, - hsets.values()[0].values()[0].bins[i].xMax) - elif(type(hsets.values()[0].values()[0])==yoda.core.Histo1D) : - outhistos[hpath] = yoda.core.Histo1D(hsets.values()[0].values()[0].path, - hsets.values()[0].values()[0].title) - for i in range(0,hsets.values()[0].values()[0].numBins) : - outhistos[hpath].addBin(hsets.values()[0].values()[0].bins[i].xMin, - hsets.values()[0].values()[0].bins[i].xMax) + title="" + path="" + histo = hsets.values()[0].values()[0] + if hasattr(histo, 'title'): + title=histo.title() + if hasattr(histo, 'path'): + path=histo.path() + if(type(histo)==yoda.core.Scatter2D) : + outhistos[hpath] = yoda.core.Scatter2D(path,title) + elif(type(histo)==yoda.core.Profile1D) : + outhistos[hpath] = yoda.core.Profile1D(path,title) + for i in range(0,histo.numBins()) : + outhistos[hpath].addBin(histo.bins()[i].xMin(), + histo.bins()[i].xMax()) + elif(type(histo)==yoda.core.Histo1D) : + outhistos[hpath] = yoda.core.Histo1D(path,title) + for i in range(0,histo.numBins()) : + outhistos[hpath].addBin(histo.bins()[i].xMin(), + histo.bins()[i].xMax()) else : logging.error("Histogram %s is of unknown type" % hpath) - print hpath,type(hsets.values()[0].values()[0]) + print hpath,type(histo) sys.exit(1) useOnePt("/STAR_2006_S6870392/d01-x01-y01","200","2") mergeByPt("/STAR_2006_S6870392/d02-x01-y01","200") mergeByPt("/STAR_2009_UE_HELEN/d01-x01-y01","200") mergeByPt("/STAR_2009_UE_HELEN/d02-x01-y01","200") mergeByPt("/STAR_2009_UE_HELEN/d03-x01-y01","200") # Choose output file name = args[0]+".yoda" print "write to ",name yoda.writeYODA(outhistos,name) sys.exit(0) diff --git a/Tests/python/merge-TVT-Jets b/Tests/python/merge-TVT-Jets --- a/Tests/python/merge-TVT-Jets +++ b/Tests/python/merge-TVT-Jets @@ -1,633 +1,636 @@ #! /usr/bin/env python import logging import sys import math if sys.version_info[:3] < (2,4,0): print "rivet scripts require Python version >= 2.4.0... exiting" sys.exit(1) import os, yoda # Divide two profile histograms with different nos of bins def divide(name,numer,denom) : output = yoda.Scatter2D(name,name) - size = min(numer.numBins,denom.numBins) + size = min(numer.numBins(),denom.numBins()) for i in range(0,size) : b1 = numer.bin(i) b2 = denom.bin(i) # Assemble the x value and error - x = b1.xMid - exminus = x - b1.xMin - explus = b1.xMax - x + x = b1.xMid() + exminus = x - b1.xMin() + explus = b1.xMax() - x # Assemble the y value and error # numerator yupp=0. relerr_1=0. try : - yupp = b1.mean + yupp = b1.mean() try : if b1.stdErr() != 0 : relerr_1 = b1.stdErr()/b1.mean() except: relerr_1=0. except : yupp = 0. relerr_1 =0. # denominator ylow=0. relerr_2 = 0. try : - ylow = b2.mean + ylow = b2.mean() try : if b2.stdErr() != 0 : relerr_2 = b2.stdErr()/b2.mean() except: relerr_2=0. except : ylow = 0. relerr_2 = 0. if yupp==0. or ylow== 0. : y=0. else : y = yupp / ylow ey = y * math.sqrt(relerr_1**2 + relerr_2**2) output.addPoint(x, y, (exminus,explus), (ey,ey)) return output def fillAbove(desthisto, sourcehistosbyptmin): pthigh= 1e100 ptlow =-1e100 for pt, h in sorted(sourcehistosbyptmin.iteritems(),reverse=True): ptlow=pt if(type(desthisto)==yoda.core.Scatter2D) : for i in range(0,h.numPoints) : xMin = h.points[i].x-h.points[i].xErrs.minus if( xMin >= ptlow and xMin < pthigh ) : desthisto.addPoint(h.points[i]) elif(type(desthisto)==yoda.core.Profile1D) : - for i in range(0,h.numBins) : - if(h.bins[i].xMin >= ptlow and - h.bins[i].xMin < pthigh ) : - desthisto.bins[i] += h.bins[i] + for i in range(0,h.numBins()) : + if(h.bins()[i].xMin() >= ptlow and + h.bins()[i].xMin() < pthigh ) : + desthisto.bins()[i] += h.bins()[i] elif(type(desthisto)==yoda.core.Histo1D) : - for i in range(0,h.numBins) : - if(h.bins[i].xMin >= ptlow and - h.bins[i].xMin < pthigh ) : - desthisto.bins[i] += h.bins[i] + for i in range(0,h.numBins()) : + if(h.bins()[i].xMin() >= ptlow and + h.bins()[i].xMin() < pthigh ) : + desthisto.bins()[i] += h.bins()[i] elif(type(desthisto)==yoda.core.Counter) : desthisto += h else : logging.error("Can't merge %s, unknown type" % desthisto.path) sys.exit(1) pthigh=pt def mergeByPt(hpath, sqrts): global inhistos global outhistos try: fillAbove(outhistos[hpath], inhistos[hpath][float(sqrts)]) except: pass def useOnePt(hpath, sqrts, ptmin): global inhistos global outhistos try: ## Find best pT_min match ptmins = inhistos[hpath][float(sqrts)].keys() closest_ptmin = None for ptm in ptmins: if closest_ptmin is None or \ abs(ptm-float(ptmin)) < abs(closest_ptmin-float(ptmin)): closest_ptmin = ptm if closest_ptmin != float(ptmin): logging.warning("Inexact match for requested pTmin=%s: " % ptmin + \ "using pTmin=%e instead" % closest_ptmin) outhistos[hpath] = inhistos[hpath][float(sqrts)][closest_ptmin] except: pass # ####################################### if __name__ == "__main__": import logging from optparse import OptionParser, OptionGroup parser = OptionParser(usage="%progbase") verbgroup = OptionGroup(parser, "Verbosity control") verbgroup.add_option("-v", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL", default=logging.INFO, help="print debug (very verbose) messages") verbgroup.add_option("-q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL", default=logging.INFO, help="be very quiet") parser.add_option("--with-ue", action='store_true' , dest="ue", default=True, help="Include UE analyses") parser.add_option("--without-ue", action='store_false', dest="ue", default=True, help="Don\'t include UE analyses") parser.add_option_group(verbgroup) (opts, args) = parser.parse_args() logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s") ## Check args if len(args) < 1: logging.error("Must specify at least the name of the files") sys.exit(1) yodafiles=["-Run-II-Jets-0.yoda","-Run-II-Jets-1.yoda",\ "-Run-II-Jets-2.yoda",\ "-Run-II-Jets-3.yoda","-Run-II-Jets-4.yoda","-Run-II-Jets-5.yoda",\ "-Run-II-Jets-6.yoda","-Run-II-Jets-7.yoda",\ "-Run-I-Jets-1.yoda","-Run-I-Jets-2.yoda",\ "-Run-I-Jets-3.yoda","-Run-I-Jets-4.yoda","-Run-I-Jets-5.yoda",\ "-630-Jets-1.yoda" ,"-630-Jets-2.yoda" ,\ "-630-Jets-3.yoda", "-300-UE.yoda", "-900-UE.yoda"] if(opts.ue) : yodafiles += ["-Run-II-UE.yoda" ,"-Run-I-UE.yoda" ,"-630-UE.yoda" ,\ "-300-Jets-1.yoda", "-900-Jets-1.yoda"] ## Get histos inhistos = {} outhistos={} for f in yodafiles: file='Rivet-'+args[0]+f if(file.find("Run-II-UE")>0) : sqrts=1960 ptmin=0. elif(file.find("Run-II-Jets-0")>0) : sqrts=1960 ptmin=20. elif(file.find("Run-II-Jets-1")>0) : sqrts=1960 ptmin=36. elif(file.find("Run-II-Jets-2")>0) : sqrts=1960 ptmin=55. elif(file.find("Run-II-Jets-3")>0) : sqrts=1960 ptmin=75. elif(file.find("Run-II-Jets-4")>0) : sqrts=1960 ptmin=100. elif(file.find("Run-II-Jets-5")>0) : sqrts=1960 ptmin=125. elif(file.find("Run-II-Jets-6")>0) : ptmin=175. sqrts=1960 elif(file.find("Run-II-Jets-7")>0) : sqrts=1960 ptmin=265. elif(file.find("300-UE")>0) : sqrts=300 ptmin=0. elif(file.find("300-Jets-1")>0) : sqrts=300 ptmin=6. elif(file.find("900-UE")>0) : sqrts=900 ptmin=0. elif(file.find("900-Jets-1")>0) : sqrts=900 ptmin=10. elif(file.find("630-UE")>0) : sqrts=630 ptmin=0. elif(file.find("630-Jets-1")>0) : sqrts=630 ptmin=30. elif(file.find("630-Jets-2")>0) : sqrts=630 ptmin=55. elif(file.find("630-Jets-3")>0) : sqrts=630 ptmin=90. elif(file.find("Run-I-UE")>0) : sqrts=1800 ptmin=0. elif(file.find("Run-I-Jets-1")>0) : sqrts=1800 ptmin=30. elif(file.find("Run-I-Jets-2")>0) : sqrts=1800 ptmin=55. elif(file.find("Run-I-Jets-3")>0) : sqrts=1800 ptmin=80. elif(file.find("Run-I-Jets-4")>0) : sqrts=1800 ptmin=105. elif(file.find("Run-I-Jets-5")>0) : sqrts=1800 ptmin=175. if not os.access(file, os.R_OK): logging.error("%s can not be read" % file) continue try: aos = yoda.read(file) except: logging.error("%s can not be parsed as YODA" % file) continue ## Get histos from this YODA file for aopath, ao in aos.iteritems() : if("RAW" in aopath) :continue # di-jet decorrelations # jet shapes if(aopath.find("5992206")>0 or aopath.find("6217184")>0 or aopath.find("LEADINGJETS")>0 or aopath.find("7662670")>0 or aopath.find("7057202")>0 or aopath.find("6450792")>0 or aopath.find("7828950")>0 or aopath.find("4751469")>0 or aopath.find("5839831")>0 or aopath.find("4563131")>0 or aopath.find("4517016")>0 or aopath.find("3618439")>0 or aopath.find("8591881")>0 or aopath.find("1388868")>0 or aopath.find("NOTE10874")>0 or aopath.find("398175")>0) : if not inhistos.has_key(aopath): inhistos[aopath] = {} tmpE = inhistos[aopath] if not tmpE.has_key(sqrts): tmpE[sqrts] = {} tmpP = tmpE[sqrts] if not tmpP.has_key(ptmin): tmpP[ptmin] = ao else: raise Exception("A set with ptmin = %s already exists" % ( ptmin)) elif(aopath.find("8233977")>0 or aopath.find("NOTE_9936")>0 or aopath.find("3905616")>0 or aopath.find("3324664")>0 or aopath.find("4796047")>0 or aopath.find("1865951")>0 or aopath.find("2089246")>0 or aopath.find("3108457")>0 or aopath.find("3349578")>0 or aopath.find("3541940")>0 or aopath.find("3214044")>0 or aopath.find("2952106")>0 or aopath.find("895662")>0 ) : outhistos[aopath] = ao else : if(aopath.find("/_EVTCOUNT")>=0 or aopath.find("/_XSEC" )>=0 ) : continue print aopath quit() yodafiles=["-Run-II-Jets-8.yoda","-Run-II-Jets-9.yoda","-Run-II-Jets-10.yoda","-Run-II-Jets-11.yoda",\ "-Run-I-Jets-6.yoda","-Run-I-Jets-7.yoda","-Run-I-Jets-8.yoda"] for f in yodafiles: file='Rivet-'+args[0]+f if(file.find("Run-II-Jets-8")>0) : sqrts=1960 ptmin=0.150 elif(file.find("Run-II-Jets-9")>0) : sqrts=1960 ptmin=0.400 elif(file.find("Run-II-Jets-10")>0) : sqrts=1960 ptmin=0.600 elif(file.find("Run-II-Jets-11")>0) : sqrts=1960 ptmin=1.000 elif(file.find("Run-I-Jets-6")>0) : sqrts=1800 ptmin=0.150 elif(file.find("Run-I-Jets-7")>0) : sqrts=1800 ptmin=0.5 elif(file.find("Run-I-Jets-8")>0) : sqrts=1800 ptmin=0.8 if not os.access(file, os.R_OK): logging.error("%s can not be read" % file) continue try: aos = yoda.read(file) except: logging.error("%s can not be parsed as YODA" % file) continue ## Get histos from this yoda file for aopath, ao in aos.iteritems() : if("RAW" in aopath) :continue if(aopath.find("8566488")>0 or aopath.find("8320160")>0) : if not inhistos.has_key(aopath): inhistos[aopath] = {} tmpE = inhistos[aopath] if not tmpE.has_key(sqrts): tmpE[sqrts] = {} tmpP = tmpE[sqrts] if not tmpP.has_key(ptmin): tmpP[ptmin] = ao else: raise Exception("A set with ptmin = %s already exists" % ( ptmin)) elif(aopath.find("8093652")>0 or aopath.find("3418421")>0 or aopath.find("4266730")>0) : if not inhistos.has_key(aopath): inhistos[aopath] = {} tmpE = inhistos[aopath] if not tmpE.has_key(sqrts): tmpE[sqrts] = {} tmpP = tmpE[sqrts] if not tmpP.has_key(1000.*ptmin): tmpP[1000.*ptmin] = ao else: raise Exception("A set with ptmin = %s already exists" % ( 1000.*ptmin)) ## Make empty output histos if needed for hpath,hsets in inhistos.iteritems(): if( (hpath.find("6217184")>0 and hpath.find("d13-x01-y01")>0 ) or hpath.find("LEADINGJETS")>0 or hpath.find("7662670")>0 or hpath.find("7057202")>0 or hpath.find("6450792")>0 or hpath.find("7828950")>0 or hpath.find("8566488")>0 or hpath.find("8320160")>0 or hpath.find("8093652")>0 or hpath.find("4751469")>0 or hpath.find("5839831")>0 or hpath.find("4563131")>0 or hpath.find("4517016")>0 or hpath.find("3618439")>0 or hpath.find("4266730")>0 or hpath.find("3418421")>0 or hpath.find("8591881")>0 or hpath.find("1388868")>0 or hpath.find("NOTE10874")>0) : - if(type(hsets.values()[0].values()[0])==yoda.core.Counter) : - outhistos[hpath] = yoda.core.Counter(hsets.values()[0].values()[0].path, - hsets.values()[0].values()[0].title) - elif(type(hsets.values()[0].values()[0])==yoda.core.Scatter2D) : - outhistos[hpath] = yoda.core.Scatter2D(hsets.values()[0].values()[0].path, - hsets.values()[0].values()[0].title) - elif(type(hsets.values()[0].values()[0])==yoda.core.Profile1D) : - outhistos[hpath] = yoda.core.Profile1D(hsets.values()[0].values()[0].path, - hsets.values()[0].values()[0].title) - for i in range(0,hsets.values()[0].values()[0].numBins) : - outhistos[hpath].addBin(hsets.values()[0].values()[0].bins[i].xMin, - hsets.values()[0].values()[0].bins[i].xMax) - elif(type(hsets.values()[0].values()[0])==yoda.core.Histo1D) : - outhistos[hpath] = yoda.core.Histo1D(hsets.values()[0].values()[0].path, - hsets.values()[0].values()[0].title) - for i in range(0,hsets.values()[0].values()[0].numBins) : - outhistos[hpath].addBin(hsets.values()[0].values()[0].bins[i].xMin, - hsets.values()[0].values()[0].bins[i].xMax) + title="" + path="" + histo = hsets.values()[0].values()[0] + if hasattr(histo, 'title'): + title=histo.title() + if hasattr(histo, 'path'): + path=histo.path() + if(type(histo)==yoda.core.Counter) : + outhistos[hpath] = yoda.core.Counter(path,title) + elif(type(histo)==yoda.core.Scatter2D) : + outhistos[hpath] = yoda.core.Scatter2D(path,title) + elif(type(histo)==yoda.core.Profile1D) : + outhistos[hpath] = yoda.core.Profile1D(path,title) + for i in range(0,histo.numBins()) : + outhistos[hpath].addBin(histo.bins()[i].xMin(), + histo.bins()[i].xMax()) + elif(type(histo)==yoda.core.Histo1D) : + outhistos[hpath] = yoda.core.Histo1D(path,title) + for i in range(0,histo.numBins()) : + outhistos[hpath].addBin(histo.bins()[i].xMin(), + histo.bins()[i].xMax()) else : logging.error("Histogram %s is of unknown type" % hpath) - print hpath,type(hsets.values()[0].values()[0]) + print hpath,type(histo) sys.exit(1) ## Field analysis logging.info("Processing CDF_2001_S4751469") ## Angular distributions in different pT bins if(opts.ue) : useOnePt("/CDF_2001_S4751469/d01-x01-y01", "1800", "0") useOnePt("/CDF_2001_S4751469/d01-x01-y02", "1800", "0") useOnePt("/CDF_2001_S4751469/d02-x01-y01", "1800", "0") useOnePt("/CDF_2001_S4751469/d02-x01-y02", "1800", "0") useOnePt("/CDF_2001_S4751469/d01-x01-y03", "1800", "30") useOnePt("/CDF_2001_S4751469/d02-x01-y03", "1800", "30") ## Number, profile in pT_lead (True?) if(opts.ue) : useOnePt("/CDF_2001_S4751469/d03-x01-y01", "1800", "0") useOnePt("/CDF_2001_S4751469/d03-x01-y02", "1800", "0") useOnePt("/CDF_2001_S4751469/d03-x01-y03", "1800", "0") useOnePt("/CDF_2001_S4751469/d04-x01-y01", "1800", "30") useOnePt("/CDF_2001_S4751469/d04-x01-y02", "1800", "30") useOnePt("/CDF_2001_S4751469/d04-x01-y03", "1800", "30") ## pT sums, profile in pT_lead (True?) if(opts.ue) : useOnePt("/CDF_2001_S4751469/d05-x01-y01", "1800", "0") useOnePt("/CDF_2001_S4751469/d05-x01-y02", "1800", "0") useOnePt("/CDF_2001_S4751469/d05-x01-y03", "1800", "0") useOnePt("/CDF_2001_S4751469/d06-x01-y01", "1800", "30") useOnePt("/CDF_2001_S4751469/d06-x01-y02", "1800", "30") useOnePt("/CDF_2001_S4751469/d06-x01-y03", "1800", "30") ## pT distributions (use a specific pT cut run) if(opts.ue) : useOnePt("/CDF_2001_S4751469/d07-x01-y01", "1800", "0") useOnePt("/CDF_2001_S4751469/d07-x01-y02", "1800", "0") useOnePt("/CDF_2001_S4751469/d07-x01-y03", "1800", "30") ## Acosta analysis logging.info("Processing CDF_2004_S5839831") ## Mean pT, profile in ET_lead mergeByPt("/CDF_2004_S5839831/d01-x01-y01", "1800") mergeByPt("/CDF_2004_S5839831/d01-x01-y02", "1800") ## pT_max,min, profiles in ET_lead mergeByPt("/CDF_2004_S5839831/d02-x01-y01", "1800") mergeByPt("/CDF_2004_S5839831/d02-x01-y02", "1800") mergeByPt("/CDF_2004_S5839831/d02-x01-y03", "1800") ## pT distributions (want to use a specific pT cut run) useOnePt("/CDF_2004_S5839831/d03-x01-y01", "1800", "30") useOnePt("/CDF_2004_S5839831/d03-x01-y02", "1800", "80") useOnePt("/CDF_2004_S5839831/d03-x01-y03", "1800", "105") useOnePt("/CDF_2004_S5839831/d03-x01-y04", "1800", "105") useOnePt("/CDF_2004_S5839831/d03-x01-y05", "1800", "175") ## N_max,min, profiles in ET_lead mergeByPt("/CDF_2004_S5839831/d04-x01-y01", "1800") mergeByPt("/CDF_2004_S5839831/d04-x01-y02", "1800") ## Min bias dbs (want to use min bias pT cut) if(opts.ue) : useOnePt("/CDF_2004_S5839831/d05-x01-y01", "1800", "0") useOnePt("/CDF_2004_S5839831/d06-x01-y01", "1800", "0") ## Swiss Cheese, profile in ET_lead mergeByPt("/CDF_2004_S5839831/d07-x01-y01", "1800") mergeByPt("/CDF_2004_S5839831/d07-x01-y02", "1800") ## pT_max,min, profiles in ET_lead mergeByPt("/CDF_2004_S5839831/d08-x01-y01", "630") mergeByPt("/CDF_2004_S5839831/d08-x01-y02", "630") mergeByPt("/CDF_2004_S5839831/d08-x01-y03", "630") ## Swiss Cheese, profile in ET_lead mergeByPt("/CDF_2004_S5839831/d09-x01-y01", "630") mergeByPt("/CDF_2004_S5839831/d09-x01-y02", "630") ## Min bias dbs (want to use min bias pT cut) if(opts.ue) : useOnePt("/CDF_2004_S5839831/d10-x01-y01", "630", "0") useOnePt("/CDF_2004_S5839831/d11-x01-y01", "630", "0") ## CDF jet shape analysis logging.info("Processing CDF_2005_S6217184") useOnePt("/CDF_2005_S6217184/d01-x01-y01", "1960", "36" ) useOnePt("/CDF_2005_S6217184/d01-x01-y02", "1960", "36" ) useOnePt("/CDF_2005_S6217184/d01-x01-y03", "1960", "55" ) useOnePt("/CDF_2005_S6217184/d02-x01-y01", "1960", "55" ) useOnePt("/CDF_2005_S6217184/d02-x01-y02", "1960", "55" ) useOnePt("/CDF_2005_S6217184/d02-x01-y03", "1960", "75" ) useOnePt("/CDF_2005_S6217184/d03-x01-y01", "1960", "75" ) useOnePt("/CDF_2005_S6217184/d03-x01-y02", "1960", "100") useOnePt("/CDF_2005_S6217184/d03-x01-y03", "1960", "100") useOnePt("/CDF_2005_S6217184/d04-x01-y01", "1960", "125") useOnePt("/CDF_2005_S6217184/d04-x01-y02", "1960", "125") useOnePt("/CDF_2005_S6217184/d04-x01-y03", "1960", "175") useOnePt("/CDF_2005_S6217184/d05-x01-y01", "1960", "175") useOnePt("/CDF_2005_S6217184/d05-x01-y02", "1960", "175") useOnePt("/CDF_2005_S6217184/d05-x01-y03", "1960", "175") useOnePt("/CDF_2005_S6217184/d06-x01-y01", "1960", "265") useOnePt("/CDF_2005_S6217184/d06-x01-y02", "1960", "265") useOnePt("/CDF_2005_S6217184/d06-x01-y03", "1960", "265") useOnePt("/CDF_2005_S6217184/d07-x01-y01", "1960", "36" ) useOnePt("/CDF_2005_S6217184/d07-x01-y02", "1960", "36" ) useOnePt("/CDF_2005_S6217184/d07-x01-y03", "1960", "55" ) useOnePt("/CDF_2005_S6217184/d08-x01-y01", "1960", "55" ) useOnePt("/CDF_2005_S6217184/d08-x01-y02", "1960", "55" ) useOnePt("/CDF_2005_S6217184/d08-x01-y03", "1960", "75" ) useOnePt("/CDF_2005_S6217184/d09-x01-y01", "1960", "75" ) useOnePt("/CDF_2005_S6217184/d09-x01-y02", "1960", "100") useOnePt("/CDF_2005_S6217184/d09-x01-y03", "1960", "100") useOnePt("/CDF_2005_S6217184/d10-x01-y01", "1960", "125") useOnePt("/CDF_2005_S6217184/d10-x01-y02", "1960", "125") useOnePt("/CDF_2005_S6217184/d10-x01-y03", "1960", "175") useOnePt("/CDF_2005_S6217184/d11-x01-y01", "1960", "175") useOnePt("/CDF_2005_S6217184/d11-x01-y02", "1960", "175") useOnePt("/CDF_2005_S6217184/d11-x01-y03", "1960", "175") useOnePt("/CDF_2005_S6217184/d12-x01-y01", "1960", "265") useOnePt("/CDF_2005_S6217184/d12-x01-y02", "1960", "265") useOnePt("/CDF_2005_S6217184/d12-x01-y03", "1960", "265") mergeByPt("/CDF_2005_S6217184/d13-x01-y01", "1960") # CDF dijet mass spectrum mergeByPt("/CDF_2008_S8093652/d01-x01-y01", "1960") # ## Rick Field Run-II Leading Jets analysis # logging.info("Processing CDF_2008_LEADINGJETS") # ## charged particle density # mergeByPt("/CDF_2008_LEADINGJETS/d01-x01-y01", "1960") # mergeByPt("/CDF_2008_LEADINGJETS/d02-x01-y01", "1960") # mergeByPt("/CDF_2008_LEADINGJETS/d03-x01-y01", "1960") # mergeByPt("/CDF_2008_LEADINGJETS/d04-x01-y01", "1960") # ## pT sum density # mergeByPt("/CDF_2008_LEADINGJETS/d05-x01-y01", "1960") # mergeByPt("/CDF_2008_LEADINGJETS/d06-x01-y01", "1960") # mergeByPt("/CDF_2008_LEADINGJETS/d07-x01-y01", "1960") # mergeByPt("/CDF_2008_LEADINGJETS/d08-x01-y01", "1960") # ## mean pT # mergeByPt("/CDF_2008_LEADINGJETS/d09-x01-y01", "1960") ## newer version logging.info("Processing CDF_2010_S8591881_QCD") mergeByPt("/CDF_2010_S8591881_QCD/d10-x01-y01", "1960") mergeByPt("/CDF_2010_S8591881_QCD/d10-x01-y02", "1960") mergeByPt("/CDF_2010_S8591881_QCD/d10-x01-y03", "1960") mergeByPt("/CDF_2010_S8591881_QCD/d11-x01-y01", "1960") mergeByPt("/CDF_2010_S8591881_QCD/d11-x01-y02", "1960") mergeByPt("/CDF_2010_S8591881_QCD/d11-x01-y03", "1960") mergeByPt("/CDF_2010_S8591881_QCD/d12-x01-y01", "1960") mergeByPt("/CDF_2010_S8591881_QCD/d12-x01-y02", "1960") mergeByPt("/CDF_2010_S8591881_QCD/d12-x01-y03", "1960") mergeByPt("/CDF_2010_S8591881_QCD/d13-x01-y01", "1960") mergeByPt("/CDF_2010_S8591881_QCD/d13-x01-y02", "1960") mergeByPt("/CDF_2010_S8591881_QCD/d13-x01-y03", "1960") mergeByPt("/CDF_2010_S8591881_QCD/d14-x01-y01", "1960") mergeByPt("/CDF_2010_S8591881_QCD/d15-x01-y01", "1960") ## D0 dijet correlation analysis logging.info("Processing D0_2004_S5992206") useOnePt("/D0_2004_S5992206/d01-x02-y01", "1960", "75") useOnePt("/D0_2004_S5992206/d02-x02-y01", "1960", "100") useOnePt("/D0_2004_S5992206/d03-x02-y01", "1960", "125") useOnePt("/D0_2004_S5992206/d04-x02-y01", "1960", "175") ## D0 incl jet cross-section analysis logging.info("Processing D0_2008_S7662670") mergeByPt("/D0_2008_S7662670/d01-x01-y01", "1960") mergeByPt("/D0_2008_S7662670/d02-x01-y01", "1960") mergeByPt("/D0_2008_S7662670/d03-x01-y01", "1960") mergeByPt("/D0_2008_S7662670/d04-x01-y01", "1960") mergeByPt("/D0_2008_S7662670/d05-x01-y01", "1960") mergeByPt("/D0_2008_S7662670/d06-x01-y01", "1960") mergeByPt("/D0_2010_S8566488/d01-x01-y01", "1960") mergeByPt("/D0_2010_S8566488/d02-x01-y01", "1960") mergeByPt("/D0_2010_S8566488/d03-x01-y01", "1960") mergeByPt("/D0_2010_S8566488/d04-x01-y01", "1960") mergeByPt("/D0_2010_S8566488/d05-x01-y01", "1960") mergeByPt("/D0_2010_S8566488/d06-x01-y01", "1960") # CDF jet cross section mergeByPt("/CDF_2001_S4563131/d01-x01-y01", "1800") mergeByPt("/CDF_2001_S4517016/d01-x01-y01", "1800") mergeByPt("/CDF_2001_S4517016/d02-x01-y01", "1800") mergeByPt("/CDF_2001_S4517016/d03-x01-y01", "1800") mergeByPt("/CDF_2001_S4517016/d04-x01-y01", "1800") useOnePt("/CDF_1998_S3618439/d01-x01-y01", "1800","105") useOnePt("/CDF_1998_S3618439/d01-x01-y02", "1800","105") mergeByPt("/CDF_2008_S7828950/d01-x01-y01", "1960") mergeByPt("/CDF_2008_S7828950/d02-x01-y01", "1960") mergeByPt("/CDF_2008_S7828950/d03-x01-y01", "1960") mergeByPt("/CDF_2008_S7828950/d04-x01-y01", "1960") mergeByPt("/CDF_2008_S7828950/d05-x01-y01", "1960") mergeByPt("/CDF_2007_S7057202/d01-x01-y01", "1960") mergeByPt("/CDF_2007_S7057202/d02-x01-y01", "1960") mergeByPt("/CDF_2007_S7057202/d03-x01-y01", "1960") mergeByPt("/CDF_2007_S7057202/d04-x01-y01", "1960") mergeByPt("/CDF_2007_S7057202/d05-x01-y01", "1960") mergeByPt("/CDF_2007_S7057202/d06-x01-y01", "1960") mergeByPt("/CDF_2007_S7057202/d07-x01-y01", "1960") mergeByPt("/CDF_2006_S6450792/d01-x01-y01", "1960") mergeByPt("/CDF_2000_S4266730/d01-x01-y01", "1800") useOnePt("/CDF_1996_S3418421/d01-x01-y01","1800","150") useOnePt("/CDF_1996_S3418421/d01-x01-y02","1800","150") useOnePt("/CDF_1996_S3418421/d01-x01-y03","1800","150") useOnePt("/CDF_1996_S3418421/d01-x01-y04","1800","500") useOnePt("/CDF_1996_S3418421/d01-x01-y05","1800","500") mergeByPt("/CDF_1996_S3418421/d02-x01-y01","1800") useOnePt("/D0_2009_S8320160/d01-x01-y01", "1960", "0.15" ) useOnePt("/D0_2009_S8320160/d02-x01-y01", "1960", "0.15" ) useOnePt("/D0_2009_S8320160/d03-x01-y01", "1960", "0.4" ) useOnePt("/D0_2009_S8320160/d04-x01-y01", "1960", "0.4" ) useOnePt("/D0_2009_S8320160/d05-x01-y01", "1960", "0.6" ) useOnePt("/D0_2009_S8320160/d06-x01-y01", "1960", "0.6" ) useOnePt("/D0_2009_S8320160/d07-x01-y01", "1960", "0.6" ) useOnePt("/D0_2009_S8320160/d08-x01-y01", "1960", "0.6" ) useOnePt("/D0_2009_S8320160/d09-x01-y01", "1960", "1.0" ) useOnePt("/D0_2009_S8320160/d10-x01-y01", "1960", "1.0" ) logging.info("Processing CDF_2015_I1388868") for d in range(1,25) : if d <=8 : energy="1960" elif d <=16 : energy = "900" else : energy = "300" useOnePt("/CDF_2015_I1388868/d%02d-x01-y01" % d , energy, "0" ) # D0 jet shape logging.info("Processing D0_1995_I398175") useOnePt("/D0_1995_I398175/d01-x01-y01", "1800", "30" ) useOnePt("/D0_1995_I398175/d02-x01-y01", "1800", "55" ) useOnePt("/D0_1995_I398175/d03-x01-y01", "1800", "105" ) useOnePt("/D0_1995_I398175/d04-x01-y01", "1800", "105" ) useOnePt("/D0_1995_I398175/d05-x01-y01", "1800", "30" ) useOnePt("/D0_1995_I398175/d06-x01-y01", "1800", "55" ) logging.info("CDF_2012_NOTE10874") mergeByPt("/CDF_2012_NOTE10874/d01-x01-y01", "300") mergeByPt("/CDF_2012_NOTE10874/d01-x01-y02", "900") mergeByPt("/CDF_2012_NOTE10874/d01-x01-y03","1960") mergeByPt("/CDF_2012_NOTE10874/d02-x01-y01", "300") mergeByPt("/CDF_2012_NOTE10874/d02-x01-y02", "900") mergeByPt("/CDF_2012_NOTE10874/d02-x01-y03","1960") mergeByPt("/CDF_2012_NOTE10874/d03-x01-y01", "300") mergeByPt("/CDF_2012_NOTE10874/d03-x01-y02", "900") mergeByPt("/CDF_2012_NOTE10874/d03-x01-y03","1960") for i in range(1,4) : names = ["/CDF_2012_NOTE10874/d0%s-x01-y01" % i, "/CDF_2012_NOTE10874/d0%s-x01-y02" % i, "/CDF_2012_NOTE10874/d0%s-x01-y03" % i] # ratio 1960/300 if names[0] in outhistos and names[2] in outhistos : outhistos["/CDF_2012_NOTE10874/d0%s-x01-y04" % i] = \ divide("/CDF_2012_NOTE10874/d0%s-x01-y04" % i,outhistos[names[2]],outhistos[names[0]]) # ratio 900/300 if names[0] in outhistos and names[1] in outhistos : outhistos["/CDF_2012_NOTE10874/d0%s-x01-y05" % i]= \ divide("/CDF_2012_NOTE10874/d0%s-x01-y05" % i,outhistos[names[1]],outhistos[names[0]]) # ratio 1960/900 if names[1] in outhistos and names[2] in outhistos : outhistos["/CDF_2012_NOTE10874/d0%s-x01-y06" % i]= \ divide("/CDF_2012_NOTE10874/d0%s-x01-y06" %i,outhistos[names[2]],outhistos[names[1]]) # Choose output file name = args[0]+"-Jets.yoda" yoda.writeYODA(outhistos,name) sys.exit(0) diff --git a/UnderlyingEvent/MPIHandler.cc b/UnderlyingEvent/MPIHandler.cc --- a/UnderlyingEvent/MPIHandler.cc +++ b/UnderlyingEvent/MPIHandler.cc @@ -1,874 +1,848 @@ // -*- C++ -*- // // MPIHandler.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 MPIHandler class. // #include "MPIHandler.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Handlers/StandardXComb.h" #include "ThePEG/Handlers/SubProcessHandler.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/RefVector.h" #include "ThePEG/Interface/ParVector.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/MatrixElement/MEBase.h" #include "ThePEG/Handlers/CascadeHandler.h" #include "ThePEG/Cuts/Cuts.h" #include "ThePEG/Cuts/JetCuts.h" #include "ThePEG/Cuts/SimpleKTCut.h" #include "ThePEG/PDF/PartonExtractor.h" #include "gsl/gsl_sf_bessel.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; MPIHandler * MPIHandler::currentHandler_ = 0; bool MPIHandler::beamOK() const { return (HadronMatcher::Check(*eventHandler()->incoming().first) && HadronMatcher::Check(*eventHandler()->incoming().second) ); } tStdXCombPtr MPIHandler::generate(unsigned int sel) { //generate a certain process if(sel+1 > processHandlers().size()) throw Exception() << "MPIHandler::generate called with argument out of range" << Exception::runerror; return processHandlers()[sel]->generate(); } IBPtr MPIHandler::clone() const { return new_ptr(*this); } IBPtr MPIHandler::fullclone() const { return new_ptr(*this); } void MPIHandler::finalize() { if( beamOK() ){ statistics(); } } void MPIHandler::initialize() { currentHandler_ = this; useMe(); theHandler = generator()->currentEventHandler(); //stop if the EventHandler is not present: assert(theHandler); //check if MPI is wanted if( !beamOK() ){ throw Exception() << "You have requested multiple parton-parton scattering,\n" << "but the model is not forseen for the beam setup you chose.\n" << "You should therefore disable that by setting XXXGenerator:EventHandler:" << "CascadeHandler:MPIHandler to NULL" << Exception::runerror; } numSubProcs_ = subProcesses().size(); if( numSubProcs_ != cuts().size() ) throw Exception() << "MPIHandler::each SubProcess needs a Cuts Object" << "ReferenceVectors are not equal in size" << Exception::runerror; if( additionalMultiplicities_.size()+1 != numSubProcs_ ) throw Exception() << "MPIHandler: each additional SubProcess needs " << "a multiplicity assigned. This can be done in with " << "insert MPIHandler:additionalMultiplicities 0 1" << Exception::runerror; //identicalToUE_ = 0 hard process is identical to ue, -1 no one if( identicalToUE_ > (int)numSubProcs_ || identicalToUE_ < -1 ) throw Exception() << "MPIHandler:identicalToUE has disallowed value" << Exception::runerror; // override the cuts for the additional scatters if energyExtrapolation_ is // set if (energyExtrapolation_ != 0 ) { overrideUECuts(); } tcPDPtr gluon=getParticleData(ParticleID::g); //determine ptmin Ptmin_ = cuts()[0]->minKT(gluon); if(identicalToUE_ == -1){ algorithm_ = 2; }else{ if(identicalToUE_ == 0){ //Need to work a bit, in case of LesHouches events for QCD2to2 Ptr::pointer eH = dynamic_ptr_cast::pointer>(eventHandler()); if( eH ) { PtOfQCDProc_ = eH->cuts()->minKT(gluon); // find the jet cut in the new style cuts for(unsigned int ix=0;ixcuts()->multiCuts().size();++ix) { Ptr::pointer jetCuts = dynamic_ptr_cast::pointer>(eH->cuts()->multiCuts()[ix]); if(jetCuts) { Energy ptMin=1e30*GeV; for(unsigned int iy=0;iyjetRegions().size();++iy) { ptMin = min(ptMin,jetCuts->jetRegions()[iy]->ptMin()); } if(ptMin<1e29*GeV&&ptMin>PtOfQCDProc_) PtOfQCDProc_ = ptMin; } } } else { if(PtOfQCDProc_ == -1.0*GeV) throw Exception() << "MPIHandler: You need to specify the pt cutoff " << "used to in the LesHouches file for QCD2to2 events" << Exception::runerror; } } else { PtOfQCDProc_ = cuts()[identicalToUE_]->minKT(gluon); } if(PtOfQCDProc_ > 2*Ptmin_) algorithm_ = 1; else algorithm_ = 0; if(PtOfQCDProc_ == ZERO)//pure MinBias mode algorithm_ = -1; } //Init all subprocesses for(unsigned int i=0; iinitialize(subProcesses()[i], cuts()[i], eventHandler()); processHandlers().back()->initrun(); } //now calculate the individual Probabilities XSVector UEXSecs; UEXSecs.push_back(processHandlers()[0]->integratedXSec()); //save the hard cross section hardXSec_ = UEXSecs.front(); //determine sigma_soft and beta if(softInt_){//check that soft ints are requested GSLBisection rootFinder; if(twoComp_){ //two component model /* GSLMultiRoot eqSolver; slopeAndTotalXSec eq(this); pair res = eqSolver.value(eq, 10*millibarn, 0.6*GeV2); softXSec_ = res.first; softMu2_ = res.second; */ slopeBisection fs(this); try{ softMu2_ = rootFinder.value(fs, 0.3*GeV2, 1.*GeV2); softXSec_ = fs.softXSec(); }catch(GSLBisection::IntervalError){ try{ // Very low energies (e.g. 200 GeV) need this. // Very high energies (e.g. 100 TeV) produce issues with // this choice. This is a temp. fix. softMu2_ = rootFinder.value(fs, 0.25*GeV2, 1.3*GeV2); softXSec_ = fs.softXSec(); }catch(GSLBisection::IntervalError){ throw Exception() << "\n**********************************************************\n" "* Inconsistent MPI parameter choice for this beam energy *\n" "**********************************************************\n" "MPIHandler parameter choice is unable to reproduce\n" "the total cross section. Please check arXiv:0806.2949\n" "for the allowed parameter space." << Exception::runerror; } } }else{ //single component model TotalXSecBisection fn(this); try{ softXSec_ = rootFinder.value(fn, 0*millibarn, 5000*millibarn); }catch(GSLBisection::IntervalError){ throw Exception() << "\n**********************************************************\n" "* Inconsistent MPI parameter choice for this beam energy *\n" "**********************************************************\n" "MPIHandler parameter choice is unable to reproduce\n" "the total cross section. Please check arXiv:0806.2949\n" "for the allowed parameter space." << Exception::runerror; } } //now get the differential cross section at ptmin ProHdlPtr qcd = new_ptr(ProcessHandler()); Energy eps = 0.1*GeV; Energy ptminPlus = Ptmin_ + eps; Ptr::pointer ktCut = new_ptr(SimpleKTCut(ptminPlus)); ktCut->init(); ktCut->initrun(); CutsPtr qcdCut = new_ptr(Cuts(2*ptminPlus)); qcdCut->add(dynamic_ptr_cast(ktCut)); qcdCut->init(); qcdCut->initrun(); qcd->initialize(subProcesses()[0], qcdCut, eventHandler()); qcd->initrun(); // ds/dp_T^2 = 1/2/p_T ds/dp_T DiffXSec hardPlus = (hardXSec_-qcd->integratedXSec())/(2*Ptmin_*eps); betaBisection fn2(softXSec_, hardPlus, Ptmin_); try{ beta_ = rootFinder.value(fn2, -10/GeV2, 2/GeV2); }catch(GSLBisection::IntervalError){ try{ // Very low energies (e.g. 200 GeV) need this. // Very high energies (e.g. 100 TeV) produce issues with // this choice. This is a temp. fix. beta_ = rootFinder.value(fn2, -5/GeV2, 8./GeV2); }catch(GSLBisection::IntervalError){ throw Exception() << "MPIHandler: slope of soft pt spectrum couldn't be " << "determined." << Exception::runerror; } } } Probs(UEXSecs); //MultDistribution("probs.test"); UEXSecs.clear(); } void MPIHandler::MultDistribution(string filename) const { ofstream file; double p(0.0), pold(0.0); file.open(filename.c_str()); //theMultiplicities Selector::const_iterator it = theMultiplicities.begin(); while(it != theMultiplicities.end()){ p = it->first; file << it->second.first << " " << it->second.second << " " << p-pold << '\n'; it++; pold = p; } file << "sum of all probabilities: " << theMultiplicities.sum() << endl; file.close(); } void MPIHandler::statistics() const { ostream & file = generator()->misc(); string line = "=======================================" "=======================================\n"; for(unsigned int i=0; istatistics(file, tot); file << "\n"; } if(softInt_){ file << line << "Eikonalized and soft cross sections:\n\n" << "Model parameters: " << "ptmin: " << Ptmin_/GeV << " GeV" << ", mu2: " << invRadius_/sqr(1.*GeV) << " GeV2\n" << " " << "DL mode: " << DLmode_ << ", CMenergy: " << generator()->maximumCMEnergy()/GeV << " GeV" << '\n' << "hard inclusive cross section (mb): " << hardXSec_/millibarn << '\n' << "soft inclusive cross section (mb): " << softXSec_/millibarn << '\n' << "total cross section (mb): " << totalXSecExp()/millibarn << '\n' << "inelastic cross section (mb): " << inelXSec_/millibarn << '\n' - << "diffractive cross section (mb): " - << diffratio_*totalXSecExp()/millibarn << '\n' + // TODO: Include diffrative Cross Section in calculation + // << "diffractive cross section (mb): " + // << diffratio_*totalXSecExp()/millibarn << '\n' << "soft inv radius (GeV2): " << softMu2_/GeV2 << '\n' << "slope of soft pt spectrum (1/GeV2): " << beta_*sqr(1.*GeV) << '\n' << "Average hard multiplicity: " << avgNhard_ << '\n' << "Average soft multiplicity: " << avgNsoft_ << '\n' << line << endl; }else{ file << line << "Eikonalized and soft cross sections:\n\n" << "Model parameters: " << "ptmin: " << Ptmin_/GeV << " GeV" << ", mu2: " << invRadius_/sqr(1.*GeV) << " GeV2\n" << " " << ", CMenergy: " << generator()->maximumCMEnergy()/GeV << " GeV" << '\n' << "hard inclusive cross section (mb): " << hardXSec_/millibarn << '\n' << "Average hard multiplicity: " << avgNhard_ << '\n' << line << endl; } } unsigned int MPIHandler::multiplicity(unsigned int sel){ if(sel==0){//draw from the pretabulated distribution MPair m = theMultiplicities.select(UseRandom::rnd()); softMult_ = m.second; return m.first; } else{ //fixed multiplicities for the additional hard scatters if(additionalMultiplicities_.size() < sel) throw Exception() << "MPIHandler::multiplicity: process index " << "is out of range" << Exception::runerror; return additionalMultiplicities_[sel-1]; } } void MPIHandler::Probs(XSVector UEXSecs) { GSLIntegrator integrator; unsigned int iH(1), iS(0); double P(0.0); double P0(0.0);//the probability for i hard and zero soft scatters Length bmax(500.0*sqrt(millibarn)); //only one UE process will be drawn from a probability distribution, //so check that. assert(UEXSecs.size() == 1); for ( XSVector::const_iterator it = UEXSecs.begin(); it != UEXSecs.end(); ++it ) { iH = 0; //get the inel xsec Eikonalization inelint(this, -1, *it, softXSec_, softMu2_); - - - auto nondiffXS=integrator.value(inelint, ZERO, bmax); - inelXSec_ = nondiffXS+diffratio_*totalXSecExp(); + inelXSec_ = integrator.value(inelint, ZERO, bmax); avgNhard_ = 0.0; avgNsoft_ = 0.0; bmax = 10.0*sqrt(millibarn); do{//loop over hard ints if(Algorithm()>-1 && iH==0){ iH++; continue; } iS = 0; do{//loop over soft ints if( ( Algorithm() == -1 && iS==0 && iH==0 ) ){ iS++; continue; } Eikonalization integrand(this, iH*100+iS, *it, softXSec_, softMu2_); if(Algorithm() > 0){ P = integrator.value(integrand, ZERO, bmax) / *it; }else{ - P = integrator.value(integrand, ZERO, bmax) / nondiffXS; + P = integrator.value(integrand, ZERO, bmax) / inelXSec_; } //store the probability if(Algorithm()>-1){ theMultiplicities.insert(P, make_pair(iH-1, iS)); avgNhard_ += P*(iH-1); }else{ theMultiplicities.insert(P, make_pair(iH, iS)); avgNhard_ += P*(iH); } avgNsoft_ += P*iS; if(iS==0) P0 = P; iS++; } while ( (iS < maxScatters_) && (iS < 5 || P > 1.e-15 ) && softInt_ ); iH++; } while ( (iH < maxScatters_) && (iH < 5 || P0 > 1.e-15) ); } } // calculate the integrand Length Eikonalization::operator() (Length b) const { unsigned int Nhard(0), Nsoft(0); //fac is just: d^2b=fac*db despite that large number Length fac(Constants::twopi*b); double chiTot(( theHandler->OverlapFunction(b)*hardXSec_ + theHandler->OverlapFunction(b, softMu2_)*softXSec_ ) / 2.0); //total cross section wanted if(theoption == -2) return 2 * fac * ( 1 - exp(-chiTot) ); //inelastic cross section if(theoption == -1) return fac * ( 1 - exp(- 2.0 * chiTot) ); if(theoption >= 0){ //encode multiplicities as: N_hard*100 + N_soft Nhard = theoption/100; Nsoft = theoption%100; if(theHandler->Algorithm() > 0){ //P_n*sigma_hard: n-1 extra scatters + 1 hard scatterer != hardXSec_ return fac * Nhard * theHandler->poisson(b, hardXSec_, Nhard) * theHandler->poisson(b, softXSec_, Nsoft, softMu2_); }else{ //P_n*sigma_inel: n extra scatters return fac * theHandler->poisson(b, hardXSec_, Nhard) * theHandler->poisson(b, softXSec_, Nsoft, softMu2_); } }else{ throw Exception() << "Parameter theoption in Struct Eikonalization in " << "MPIHandler.cc has not allowed value" << Exception::runerror; return 0.0*meter; } } InvEnergy2 slopeBisection::operator() (Energy2 softMu2) const { GSLBisection root; //single component model TotalXSecBisection fn(handler_, softMu2); try{ softXSec_ = root.value(fn, 0*millibarn, 5000*millibarn); }catch(GSLBisection::IntervalError){ throw Exception() << "MPIHandler 2-Component model didn't work out." << Exception::runerror; } return handler_->slopeDiff(softXSec_, softMu2); } LengthDiff slopeInt::operator() (Length b) const { //fac is just: d^2b=fac*db Length fac(Constants::twopi*b); double chiTot(( handler_->OverlapFunction(b)*hardXSec_ + handler_->OverlapFunction(b, softMu2_)*softXSec_ ) / 2.0); InvEnergy2 b2 = sqr(b/hbarc); //B*sigma_tot return fac * b2 * ( 1 - exp(-chiTot) ); } -double MPIHandler::factorial (unsigned int n) const { - - static double f[] = {1.,1.,2.,6.,24.,120.,720.,5040.,40320.,362880.,3.6288e6, - 3.99168e7,4.790016e8,6.2270208e9,8.71782912e10,1.307674368e12, - 2.0922789888e13,3.55687428096e14,6.402373705728e15,1.21645100408832e17, - 2.43290200817664e18,5.10909421717094e19,1.12400072777761e21, - 2.5852016738885e22,6.20448401733239e23,1.5511210043331e25, - 4.03291461126606e26,1.08888694504184e28,3.04888344611714e29, - 8.8417619937397e30,2.65252859812191e32,8.22283865417792e33, - 2.63130836933694e35,8.68331761881189e36,2.95232799039604e38, - 1.03331479663861e40,3.71993326789901e41,1.37637530912263e43, - 5.23022617466601e44,2.03978820811974e46,8.15915283247898e47, - 3.34525266131638e49,1.40500611775288e51,6.04152630633738e52, - 2.65827157478845e54,1.1962222086548e56,5.50262215981209e57, - 2.58623241511168e59,1.24139155925361e61,6.08281864034268e62, - 3.04140932017134e64,1.55111875328738e66,8.06581751709439e67, - 4.27488328406003e69,2.30843697339241e71,1.26964033536583e73, - 7.10998587804863e74,4.05269195048772e76,2.35056133128288e78, - 1.3868311854569e80,8.32098711274139e81,5.07580213877225e83, - 3.14699732603879e85,1.98260831540444e87,1.26886932185884e89, - 8.24765059208247e90,5.44344939077443e92,3.64711109181887e94, - 2.48003554243683e96,1.71122452428141e98,1.19785716699699e100, - 8.50478588567862e101,6.12344583768861e103,4.47011546151268e105, - 3.30788544151939e107,2.48091408113954e109,1.88549470166605e111, - 1.45183092028286e113,1.13242811782063e115,8.94618213078298e116, - 7.15694570462638e118,5.79712602074737e120,4.75364333701284e122, - 3.94552396972066e124,3.31424013456535e126,2.81710411438055e128, - 2.42270953836727e130,2.10775729837953e132,1.85482642257398e134, - 1.65079551609085e136,1.48571596448176e138,1.3520015276784e140, - 1.24384140546413e142,1.15677250708164e144,1.08736615665674e146, - 1.03299784882391e148,9.9167793487095e149,9.61927596824821e151, - 9.42689044888325e153,9.33262154439442e155,9.33262154439442e157}; - - if(n > maxScatters_) - throw Exception() << "MPIHandler::factorial called with too large argument" - << Exception::runerror; - else - return f[n]; -} - InvArea MPIHandler::OverlapFunction(Length b, Energy2 mu2) const { if(mu2 == ZERO) mu2 = invRadius_; InvLength mu = sqrt(mu2)/hbarc; return (sqr(mu)/96/Constants::pi)*pow(mu*b, 3)*(gsl_sf_bessel_Kn(3, mu*b)); } double MPIHandler::poisson(Length b, CrossSection sigma, unsigned int N, Energy2 mu2) const { if(sigma > 0*millibarn){ return pow(OverlapFunction(b, mu2)*sigma, (double)N)/factorial(N) *exp(-OverlapFunction(b, mu2)*sigma); }else{ return (N==0) ? 1.0 : 0.0; } } CrossSection MPIHandler::totalXSecDiff(CrossSection softXSec, Energy2 softMu2) const { GSLIntegrator integrator; Eikonalization integrand(this, -2, hardXSec_, softXSec, softMu2); Length bmax = 500.0*sqrt(millibarn); - CrossSection minbiasXS = integrator.value(integrand, ZERO, bmax); - - auto totalXS=totalXSecExp(); - CrossSection tot=minbiasXS+diffratio_*totalXS; - - return (tot-totalXS); + CrossSection tot = integrator.value(integrand, ZERO, bmax); + return (tot-totalXSecExp()); } InvEnergy2 MPIHandler::slopeDiff(CrossSection softXSec, Energy2 softMu2) const { GSLIntegrator integrator; Eikonalization integrand(this, -2, hardXSec_, softXSec, softMu2); Length bmax = 500.0*sqrt(millibarn); CrossSection tot = integrator.value(integrand, ZERO, bmax); slopeInt integrand2(this, hardXSec_, softXSec, softMu2); return integrator.value(integrand2, ZERO, bmax)/tot - slopeExp(); } CrossSection MPIHandler::totalXSecExp() const { if(totalXSecExp_ != 0*millibarn) return totalXSecExp_; double pom_old = 0.0808; CrossSection coef_old = 21.7*millibarn; double pom_new_hard = 0.452; CrossSection coef_new_hard = 0.0139*millibarn; double pom_new_soft = 0.0667; CrossSection coef_new_soft = 24.22*millibarn; Energy energy(generator()->maximumCMEnergy()); switch(DLmode_){ case 1://old DL extrapolation return coef_old * pow(energy/GeV, 2*pom_old); break; case 2://old DL extrapolation fixed to CDF return 81.8*millibarn * pow(energy/1800.0/GeV, 2*pom_old); break; case 3://new DL extrapolation - return coef_new_hard * pow(energy/GeV, 2*pom_new_hard) + + return 0.8*coef_new_hard * pow(energy/GeV, 2*pom_new_hard) + coef_new_soft * pow(energy/GeV, 2*pom_new_soft); break; default: throw Exception() << "MPIHandler::totalXSecExp non-existing mode selected" << Exception::runerror; } } InvEnergy2 MPIHandler::slopeExp() const{ //Currently return the slope as calculated in the pomeron fit by //Donnachie & Landshoff Energy energy(generator()->maximumCMEnergy()); //slope at Energy e_0 = 1800*GeV; InvEnergy2 b_0 = 17/GeV2; return b_0 + log(energy/e_0)/GeV2; } void MPIHandler::overrideUECuts() { if(energyExtrapolation_==1) Ptmin_ = EEparamA_ * log(generator()->maximumCMEnergy() / EEparamB_); - else if(energyExtrapolation_==2) + else if(energyExtrapolation_==2){ + // For small CME <900GeV the old power law does not work (hard cross section diverges) Ptmin_ = pT0_*pow(double(generator()->maximumCMEnergy()/refScale_),b_); + }else if(energyExtrapolation_==3){ + // New parametrization that works for small CME: pTmin0*((c+sqrt(s))/E0)^b + Ptmin_ = pT0_*pow(double((offset_+generator()->maximumCMEnergy())/refScale_),b_); + } else assert(false); // create a new SimpleKTCut object with the calculated ptmin value Ptr::pointer newUEktCut = new_ptr(SimpleKTCut(Ptmin_)); newUEktCut->init(); newUEktCut->initrun(); // create a new Cuts object with MHatMin = 2 * Ptmin_ CutsPtr newUEcuts = new_ptr(Cuts(2*Ptmin_)); newUEcuts->add(dynamic_ptr_cast(newUEktCut)); newUEcuts->init(); newUEcuts->initrun(); // replace the old Cuts object cuts()[0] = newUEcuts; } void MPIHandler::persistentOutput(PersistentOStream & os) const { os << theMultiplicities << theHandler << theSubProcesses << theCuts << theProcessHandlers << additionalMultiplicities_ << identicalToUE_ << ounit(PtOfQCDProc_, GeV) << ounit(Ptmin_, GeV) << ounit(hardXSec_, millibarn) << ounit(softXSec_, millibarn) << ounit(beta_, 1/GeV2) << algorithm_ << ounit(invRadius_, GeV2) << numSubProcs_ << colourDisrupt_ << softInt_ << twoComp_ << DLmode_ << ounit(totalXSecExp_, millibarn) << energyExtrapolation_ << ounit(EEparamA_, GeV) << ounit(EEparamB_, GeV) - << ounit(refScale_,GeV) << ounit(pT0_,GeV) << b_ + << ounit(refScale_,GeV) << ounit(pT0_,GeV) << b_ << ounit(offset_,GeV) << avgNhard_ << avgNsoft_ << softMult_ << ounit(inelXSec_, millibarn) << ounit(softMu2_, GeV2) << diffratio_; } void MPIHandler::persistentInput(PersistentIStream & is, int) { is >> theMultiplicities >> theHandler >> theSubProcesses >> theCuts >> theProcessHandlers >> additionalMultiplicities_ >> identicalToUE_ >> iunit(PtOfQCDProc_, GeV) >> iunit(Ptmin_, GeV) >> iunit(hardXSec_, millibarn) >> iunit(softXSec_, millibarn) >> iunit(beta_, 1/GeV2) >> algorithm_ >> iunit(invRadius_, GeV2) >> numSubProcs_ >> colourDisrupt_ >> softInt_ >> twoComp_ >> DLmode_ >> iunit(totalXSecExp_, millibarn) >> energyExtrapolation_ >> iunit(EEparamA_, GeV) >> iunit(EEparamB_, GeV) - >> iunit(refScale_,GeV) >> iunit(pT0_,GeV) >> b_ + >> iunit(refScale_,GeV) >> iunit(pT0_,GeV) >> b_ >> iunit(offset_,GeV) >> avgNhard_ >> avgNsoft_ >> softMult_ >> iunit(inelXSec_, millibarn) >> iunit(softMu2_, GeV2) >> diffratio_; currentHandler_ = this; } void MPIHandler::clean() { // ThePEG's event handler's usual event cleanup doesn't reach these // XCombs. Need to do it by hand here. for ( size_t i = 0; i < theSubProcesses.size(); ++i ) { theSubProcesses[i]->pExtractor()->lastXCombPtr()->clean(); } } // The following static variable is needed for the type // description system in ThePEG. DescribeClass describeHerwigMPIHandler("Herwig::MPIHandler", "JetCuts.so SimpleKTCut.so HwMPI.so"); void MPIHandler::Init() { static ClassDocumentation documentation ("The MPIHandler class is the main administrator of the multiple interaction model", "The underlying event was simulated with an eikonal model for multiple partonic interactions." "Details can be found in Ref.~\\cite{Bahr:2008dy,Bahr:2009ek}.", "%\\cite{Bahr:2008dy}\n" "\\bibitem{Bahr:2008dy}\n" " M.~Bahr, S.~Gieseke and M.~H.~Seymour,\n" " ``Simulation of multiple partonic interactions in Herwig,''\n" " JHEP {\\bf 0807}, 076 (2008)\n" " [arXiv:0803.3633 [hep-ph]].\n" " %%CITATION = JHEPA,0807,076;%%\n" "\\bibitem{Bahr:2009ek}\n" " M.~Bahr, J.~M.~Butterworth, S.~Gieseke and M.~H.~Seymour,\n" " ``Soft interactions in Herwig,''\n" " arXiv:0905.4671 [hep-ph].\n" " %%CITATION = ARXIV:0905.4671;%%\n" ); static RefVector interfaceSubhandlers ("SubProcessHandlers", "The list of sub-process handlers used in this EventHandler. ", &MPIHandler::theSubProcesses, -1, false, false, true, false, false); static RefVector interfaceCuts ("Cuts", "List of cuts used for the corresponding list of subprocesses. These cuts " "should not be overidden in individual sub-process handlers.", &MPIHandler::theCuts, -1, false, false, true, false, false); static Parameter interfaceInvRadius ("InvRadius", "The inverse hadron radius squared used in the overlap function", &MPIHandler::invRadius_, GeV2, 2.0*GeV2, 0.2*GeV2, 4.0*GeV2, true, false, Interface::limited); static ParVector interfaceadditionalMultiplicities ("additionalMultiplicities", "specify the multiplicities of secondary hard processes (multiple parton scattering)", &MPIHandler::additionalMultiplicities_, -1, 0, 0, 3, false, false, true); static Parameter interfaceIdenticalToUE ("IdenticalToUE", "Specify which of the hard processes is identical to the UE one (QCD dijets)", &MPIHandler::identicalToUE_, -1, 0, 0, false, false, Interface::nolimits); static Parameter interfacePtOfQCDProc ("PtOfQCDProc", "Specify the value of the pt cutoff for the process that is identical to the UE one", &MPIHandler::PtOfQCDProc_, GeV, -1.0*GeV, ZERO, ZERO, false, false, Interface::nolimits); static Parameter interfacecolourDisrupt ("colourDisrupt", "Fraction of connections to additional subprocesses, which are colour disrupted.", &MPIHandler::colourDisrupt_, 0.0, 0.0, 1.0, false, false, Interface::limited); static Parameter interfaceDiffRatio ("DiffractiveRatio", - "Fraction of diffractive cross section in total cross section.", + "Fraction of diffractive cross section in inelastic cross section.", &MPIHandler::diffratio_, 0.2, 0.0, 1.0, false, false, Interface::limited); static Switch interfacesoftInt ("softInt", "Switch to enable soft interactions", &MPIHandler::softInt_, true, false, false); static SwitchOption interfacesoftIntYes (interfacesoftInt, "Yes", "enable the two component model", true); static SwitchOption interfacesoftIntNo (interfacesoftInt, "No", "disable the model", false); static Switch interEnergyExtrapolation ("EnergyExtrapolation", "Switch to ignore the cuts object at MPIHandler:Cuts[0]. " "Instead, extrapolate the pt cut.", &MPIHandler::energyExtrapolation_, 2, false, false); static SwitchOption interEnergyExtrapolationLog (interEnergyExtrapolation, "Log", "Use logarithmic dependence, ptmin = A * log (sqrt(s) / B).", 1); static SwitchOption interEnergyExtrapolationPower (interEnergyExtrapolation, "Power", "Use power law, ptmin = pt_0 * (sqrt(s) / E_0)^b.", 2); + static SwitchOption interEnergyExtrapolationPowerModified + (interEnergyExtrapolation, + "PowerModified", + "Use modified power law with offset to work for small center of mass energies." + "ptmin = pt_0 * ((offset+sqrt(s)) / E_0)^b.", + 3); + static SwitchOption interEnergyExtrapolationNo (interEnergyExtrapolation, "No", "Use manually set value for the minimal pt, " "specified in MPIHandler:Cuts[0]:OneCuts[0]:MinKT.", 0); static Parameter interfaceEEparamA ("EEparamA", "Parameter A in the empirical parametrization " "ptmin = A * log (sqrt(s) / B)", &MPIHandler::EEparamA_, GeV, 0.6*GeV, ZERO, Constants::MaxEnergy, false, false, Interface::limited); static Parameter interfaceEEparamB ("EEparamB", "Parameter B in the empirical parametrization " "ptmin = A * log (sqrt(s) / B)", &MPIHandler::EEparamB_, GeV, 39.0*GeV, ZERO, Constants::MaxEnergy, false, false, Interface::limited); static Switch interfacetwoComp ("twoComp", "switch to enable the model with a different radius for soft interactions", &MPIHandler::twoComp_, true, false, false); static SwitchOption interfacetwoCompYes (interfacetwoComp, "Yes", "enable the two component model", true); static SwitchOption interfacetwoCompNo (interfacetwoComp, "No", "disable the model", false); static Parameter interfaceMeasuredTotalXSec ("MeasuredTotalXSec", "Value for the total cross section (assuming rho=0). If non-zero, this " "overwrites the Donnachie-Landshoff parametrizations.", &MPIHandler::totalXSecExp_, millibarn, 0.0*millibarn, 0.0*millibarn, 0*millibarn, false, false, Interface::lowerlim); static Switch interfaceDLmode ("DLmode", "Choice of Donnachie-Landshoff parametrization for the total cross section.", &MPIHandler::DLmode_, 2, false, false); static SwitchOption interfaceDLmodeStandard (interfaceDLmode, "Standard", "Standard parametrization with s**0.08", 1); static SwitchOption interfaceDLmodeCDF (interfaceDLmode, "CDF", "Standard parametrization but normalization fixed to CDF's measured value", 2); static SwitchOption interfaceDLmodeNew (interfaceDLmode, "New", "Parametrization taking hard and soft pomeron contributions into account", 3); static Parameter interfaceReferenceScale ("ReferenceScale", "The reference energy for power law energy extrapolation of pTmin", &MPIHandler::refScale_, GeV, 7000.0*GeV, 0.0*GeV, 20000.*GeV, false, false, Interface::limited); static Parameter interfacepTmin0 ("pTmin0", "The pTmin at the reference scale for power law extrapolation of pTmin.", &MPIHandler::pT0_, GeV, 3.11*GeV, 0.0*GeV, 10.0*GeV, false, false, Interface::limited); static Parameter interfacePower ("Power", "The power for power law extrapolation of the pTmin cut-off.", &MPIHandler::b_, 0.21, 0.0, 10.0, false, false, Interface::limited); + + static Parameter interfaceOffset + ("Offset", + "The offset used in the modified power law extrapolation of the pTmin cut-off.", + &MPIHandler::offset_, GeV, 622.0*GeV, 500.0*GeV, 1000.0*GeV, + false, false, Interface::limited); + } + diff --git a/UnderlyingEvent/MPIHandler.h b/UnderlyingEvent/MPIHandler.h --- a/UnderlyingEvent/MPIHandler.h +++ b/UnderlyingEvent/MPIHandler.h @@ -1,895 +1,898 @@ // -*- C++ -*- // // MPIHandler.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_MPIHandler_H #define HERWIG_MPIHandler_H // // This is the declaration of the MPIHandler class. // #include "ThePEG/Interface/Interfaced.h" #include "ThePEG/Handlers/StandardEventHandler.h" #include "ThePEG/Repository/EventGenerator.h" #include "Herwig/PDT/StandardMatchers.h" #include "Herwig/Utilities/GSLBisection.h" //#include "Herwig/Utilities/GSLMultiRoot.h" #include "Herwig/Utilities/GSLIntegrator.h" #include "Herwig/Shower/UEBase.h" #include #include "ProcessHandler.h" #include "MPIHandler.fh" namespace Herwig { using namespace ThePEG; /** \ingroup UnderlyingEvent * \class MPIHandler * This class is responsible for generating additional * semi hard partonic interactions. * * \author Manuel B\"ahr * * @see \ref MPIHandlerInterfaces "The interfaces" * defined for MPIHandler. * @see ProcessHandler * @see ShowerHandler * @see HwRemDecayer */ class MPIHandler: public UEBase { /** * Maximum number of scatters */ static const unsigned int maxScatters_ = 99; /** * Class for the integration is a friend to access private members */ friend struct Eikonalization; friend struct TotalXSecBisection; friend struct slopeAndTotalXSec; friend struct slopeInt; friend struct slopeBisection; public: /** A vector of SubProcessHandlers. */ typedef vector SubHandlerList; /** A vector of Cuts. */ typedef vector CutsList; /** A vector of ProcessHandlers. */ typedef vector ProcessHandlerList; /** A vector of cross sections. */ typedef vector XSVector; /** A pair of multiplicities: hard, soft. */ typedef pair MPair; /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ MPIHandler(): softMult_(0), identicalToUE_(-1), PtOfQCDProc_(-1.0*GeV), Ptmin_(-1.0*GeV), hardXSec_(0*millibarn), softXSec_(0*millibarn), totalXSecExp_(0*millibarn), softMu2_(ZERO), beta_(100.0/GeV2), algorithm_(2), numSubProcs_(0), colourDisrupt_(0.0), softInt_(true), twoComp_(true), DLmode_(2), avgNhard_(0.0), avgNsoft_(0.0), - energyExtrapolation_(2), EEparamA_(0.6*GeV), + energyExtrapolation_(3), EEparamA_(0.6*GeV), EEparamB_(37.5*GeV), refScale_(7000.*GeV), - pT0_(3.11*GeV), b_(0.21) {} + pT0_(2.875*GeV), b_(0.3101), offset_(622.204*GeV) {} /** * The destructor. */ virtual ~MPIHandler(){} //@} public: /** @name Methods for the MPI generation. */ //@{ /* * @return true if for this beam setup MPI can be generated */ virtual bool beamOK() const; /** * Return true or false depending on whether soft interactions are enabled. */ virtual bool softInt() const {return softInt_;} /** * Get the soft multiplicity from the pretabulated multiplicity * distribution. Generated in multiplicity in the first place. * @return the number of extra soft events in this collision */ virtual unsigned int softMultiplicity() const {return softMult_;} /** * Sample from the pretabulated multiplicity distribution. * @return the number of extra events in this collision */ virtual unsigned int multiplicity(unsigned int sel=0); /** * Select a StandardXComb according to it's weight * @return that StandardXComb Object * @param sel is the subprocess that should be returned, * if more than one is specified. */ virtual tStdXCombPtr generate(unsigned int sel=0); //@} /** @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(); /** * Initialize this Multiple Interaction handler and all related objects needed to * generate additional events. */ virtual void initialize(); /** * Finalize this Multiple Interaction handler and all related objects needed to * generate additional events. */ virtual void finalize(); /** * Clean up the XCombs from our subprocesses after each event. * ThePEG cannot see them, so the usual cleaning misses these. */ virtual void clean(); /** * Write out accumulated statistics about integrated cross sections. */ void statistics() const; /** * The level of statistics. Controlls the amount of statistics * written out after each run to the EventGenerators * .out file. Simply the EventHandler method is called here. */ int statLevel() const {return eventHandler()->statLevel();} /** * Return the hard cross section above ptmin */ CrossSection hardXSec() const { return hardXSec_; } /** * Return the soft cross section below ptmin */ CrossSection softXSec() const { return softXSec_; } /** * Return the inelastic cross section */ CrossSection inelasticXSec() const { return inelXSec_; } + /** + * Return the non-diffractive cross section assumed by the model. + * TODO: See comment at diffractiveXSec. + */ + CrossSection nonDiffractiveXSec() const { + return (1.-diffratio_)*inelXSec_; + } /** * Return the diffractive cross section assumed by the model. - * The diffractive cross section is seen as part of the + * For now the diffractive cross section is seen as a fixed part of the * inelastic cross section. + * TODO: Energy dependence and/or Include diffraction in Eikonalisation. */ CrossSection diffractiveXSec() const { - static auto totalXS=totalXSecExp(); - return diffratio_*totalXS; + return diffratio_*inelXSec_; } /** @name Simple access functions. */ //@{ /** * Return the ThePEG::EventHandler assigned to this handler. * This methods shadows ThePEG::StepHandler::eventHandler(), because * it is not virtual in ThePEG::StepHandler. This is ok, because this * method would give a null-pointer at some stages, whereas this method * gives access to the explicitely copied pointer (in initialize()) * to the ThePEG::EventHandler. */ tEHPtr eventHandler() const {return theHandler;} /** * Return the current handler */ static const MPIHandler * currentHandler() { return currentHandler_; } /** * Return theAlgorithm. */ virtual int Algorithm() const {return algorithm_;} /** * Return the ptmin parameter of the model */ virtual Energy Ptmin() const { if(Ptmin_ > ZERO) return Ptmin_; else throw Exception() << "MPIHandler::Ptmin called without initialize before" << Exception::runerror; } /** * Return the slope of the soft pt spectrum as calculated. */ virtual InvEnergy2 beta() const { if(beta_ != 100.0/GeV2) return beta_; else throw Exception() << "MPIHandler::beta called without initialization" << Exception::runerror; } /** * Return the pt Cutoff of the Interaction that is identical to the UE * one. */ virtual Energy PtForVeto() const {return PtOfQCDProc_;} /** * Return the number of additional "hard" processes ( = multiple * parton scattering) */ virtual unsigned int additionalHardProcs() const {return numSubProcs_-1;} /** * Return the fraction of colour disrupted connections to the * suprocesses. */ virtual double colourDisrupt() const {return colourDisrupt_;} 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: /** * Access the list of sub-process handlers. */ const SubHandlerList & subProcesses() const {return theSubProcesses;} /** * Access the list of sub-process handlers. */ SubHandlerList & subProcesses() {return theSubProcesses;} /** * Access the list of cuts. */ const CutsList & cuts() const {return theCuts;} /** * Access the list of cuts. */ CutsList & cuts() {return theCuts;} /** * Access the list of sub-process handlers. */ const ProcessHandlerList & processHandlers() const {return theProcessHandlers;} /** * Access the list of sub-process handlers. */ ProcessHandlerList & processHandlers() {return theProcessHandlers;} /** * Method to calculate the individual probabilities for N scatters in the event. * @param UEXSecs is(are) the inclusiv cross section(s) for the UE process(es). */ void Probs(XSVector UEXSecs); /** * Debug method to check the individual probabilities. * @param filename is the file the output gets written to */ void MultDistribution(string filename) const; /** * Return the value of the Overlap function A(b) for a given impact * parameter \a b. * @param b impact parameter * @param mu2 = inv hadron radius squared. 0 will use the value of * invRadius_ * @return inverse area. */ InvArea OverlapFunction(Length b, Energy2 mu2=ZERO) const; /** * Method to calculate the poisson probability for expectation value * \f$ = A(b)\sigma\f$, and multiplicity N. */ double poisson(Length b, CrossSection sigma, unsigned int N, Energy2 mu2=ZERO) const; /** - * Return n! - */ - double factorial (unsigned int n) const; - - /** * Returns the total cross section for the current CMenergy. The * decision which parametrization will be used is steered by a * external parameter of this class. */ CrossSection totalXSecExp() const; /** * Difference of the calculated total cross section and the * experimental one from totalXSecExp. * @param softXSec = the soft cross section that is used * @param softMu2 = the soft radius, if 0 the hard radius will be used */ CrossSection totalXSecDiff(CrossSection softXSec, Energy2 softMu2=ZERO) const; /** * Difference of the calculated elastic slope and the * experimental one from slopeExp. * @param softXSec = the soft cross section that is used * @param softMu2 = the soft radius, if 0 the hard radius will be used */ InvEnergy2 slopeDiff(CrossSection softXSec, Energy2 softMu2=ZERO) const; /** * Returns the value of the elastic slope for the current CMenergy. * The decision which parametrization will be used is steered by a * external parameter of this class. */ InvEnergy2 slopeExp() const; /** * Calculate the minimal transverse momentum from the extrapolation */ void overrideUECuts(); private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ MPIHandler & operator=(const MPIHandler &) = delete; /** * A pointer to the EventHandler that calls us. Has to be saved, because the * method eventHandler() inherited from ThePEG::StepHandler returns a null-pointer * sometimes. Leif changed that in r1053 so that a valid pointer is present, when * calling doinitrun(). */ tEHPtr theHandler; /** * The list of SubProcessHandlers. */ SubHandlerList theSubProcesses; /** * The kinematical cuts used for this collision handler. */ CutsList theCuts; /** * List of ProcessHandler used to sample different processes independently */ ProcessHandlerList theProcessHandlers; /** * A ThePEG::Selector where the individual Probabilities P_N are stored * and the actual Multiplicities can be selected. */ Selector theMultiplicities; /** * Variable to store the soft multiplicity generated for a event. This * has to be stored as it is generated at the time of the hard * additional interactions but used later on. */ unsigned int softMult_; /** * Variable to store the multiplicity of the second hard process */ vector additionalMultiplicities_; /** * Variable to store the information, which process is identical to * the UE one (QCD dijets). * 0 means "real" hard one * n>0 means the nth additional hard scatter * -1 means no one! */ int identicalToUE_; /** * Variable to store the minimal pt of the process that is identical * to the UE one. This only has to be set, if it can't be determined * automatically (i.e. when reading QCD LesHouches files in). */ Energy PtOfQCDProc_; /** * Variable to store the parameter ptmin */ Energy Ptmin_; /** * Variable to store the hard cross section above ptmin */ CrossSection hardXSec_; /** * Variable to store the final soft cross section below ptmin */ CrossSection softXSec_; /** * Variable to store the inelastic cross section */ CrossSection inelXSec_; /** * Variable to store the total pp cross section (assuming rho=0!) as * measured at LHC. If this variable is set, this value is used in the * subsequent run instead of any of the Donnachie-Landshoff * parametrizations. */ CrossSection totalXSecExp_; /** * Variable to store the soft radius, that is calculated during * initialization for the two-component model. */ Energy2 softMu2_; /** * slope to the non-perturbative pt spectrum: \f$d\sigma/dp_T^2 = A \exp * (- beta p_T^2)\f$. Its value is determined durint initialization. */ InvEnergy2 beta_; /** * Switch to be set from outside to determine the algorithm used for * UE activity. */ int algorithm_; /** * Inverse hadron Radius squared \f$ (\mu^2) \f$. Used inside the overlap function. */ Energy2 invRadius_; /** * Member variable to store the actual number of separate SubProcesses */ unsigned int numSubProcs_; /** * Variable to store the relative number of colour disrupted * connections to additional subprocesses. This variable is used in * Herwig::HwRemDecayer but store here, to have access to all * parameters through one Object. */ double colourDisrupt_; /** * Flag to store whether soft interactions, i.e. pt < ptmin should be * simulated. */ bool softInt_; /** * Flag to steer wheather the soft part has a different radius, that * will be dynamically fixed. */ bool twoComp_; /** * Switch to determine which Donnachie & Landshoff parametrization * should be used. */ unsigned int DLmode_; /** * Variable to store the average hard multiplicity. */ double avgNhard_; /** * Variable to store the average soft multiplicity. */ double avgNsoft_; /** * The current handler */ static MPIHandler * currentHandler_; /** * Flag to store whether to calculate the minimal UE pt according to an * extrapolation formula or whether to use MPIHandler:Cuts[0]:OneCuts[0]:MinKT */ unsigned int energyExtrapolation_; /** * Parameters for the energy extrapolation formula */ Energy EEparamA_; Energy EEparamB_; Energy refScale_; Energy pT0_; double b_; + Energy offset_; /** - * Parameters to set the fraction of diffractive cross section in the total cross section. + * Parameters to set the fraction of diffractive cross section in the inelastic cross section. */ double diffratio_=0.2; protected: /** @cond EXCEPTIONCLASSES */ /** * Exception class used by the MultipleInteractionHandler, when something * during initialization went wrong. * \todo understand!!! */ class InitError: public Exception {}; /** @endcond */ }; } namespace Herwig { /** * A struct for the 2D root finding that is necessary to determine the * soft cross section and the soft radius that is needed to describe * the total cross section correctly. * NOT IN USE CURRENTLY */ struct slopeAndTotalXSec : public GSLHelper { public: /** * Constructor */ slopeAndTotalXSec(tcMPIHPtr handler): handler_(handler) {} /** second argument type */ typedef Energy2 ArgType2; /** second value type */ typedef InvEnergy2 ValType2; /** first element of the vector like function to find root for * @param softXSec soft cross-section * @param softMu2 \f$\mu^2\f$ */ CrossSection f1(ArgType softXSec, ArgType2 softMu2) const { return handler_->totalXSecDiff(softXSec, softMu2); } /** second element of the vector like function to find root for * @param softXSec soft cross-section * @param softMu2 \f$\mu^2\f$ */ InvEnergy2 f2(ArgType softXSec, ArgType2 softMu2) const { return handler_->slopeDiff(softXSec, softMu2); } /** provide the actual units of use */ virtual ValType vUnit() const {return 1.0*millibarn;} /** otherwise rounding errors may get significant */ virtual ArgType aUnit() const {return 1.0*millibarn;} /** provide the actual units of use */ ValType2 vUnit2() const {return 1.0/GeV2;} /** otherwise rounding errors may get significant */ ArgType2 aUnit2() const {return GeV2;} private: /** * Pointer to the handler */ tcMPIHPtr handler_; }; /** * A struct for the root finding that is necessary to determine the * slope of the soft pt spectrum to match the soft cross section */ struct betaBisection : public GSLHelper{ public: /** * Constructor. * @param soft = soft cross section, i.e. the integral of the soft * pt spectrum f(u=p_T^2) = dsig exp(-beta*u/u_min) * @param dsig = dsigma_hard/dp_T^2 at the p_T cutoff * @param ptmin = p_T cutoff */ betaBisection(CrossSection soft, DiffXSec dsig, Energy ptmin) : softXSec_(soft), dsig_(dsig), ptmin_(ptmin) {} /** * Operator that is used inside the GSLBisection class */ virtual Energy2 operator ()(InvEnergy2 beta) const { if( fabs(beta*GeV2) < 1.E-4 ) beta = (beta > ZERO) ? 1.E-4/GeV2 : -1.E-4/GeV2; return (exp(beta*sqr(ptmin_)) - 1.0)/beta - softXSec_/dsig_; } /** provide the actual units of use */ virtual ValType vUnit() const {return 1.0*GeV2;} /** provide the actual units of use */ virtual ArgType aUnit() const {return 1.0/GeV2;} private: /** soft cross section */ CrossSection softXSec_; /** dsigma/dp_T^2 at ptmin */ DiffXSec dsig_; /** pt cutoff */ Energy ptmin_; }; /** * A struct for the root finding that is necessary to determine the * soft cross section and soft mu2 that are needed to describe the * total cross section AND elastic slope correctly. */ struct slopeBisection : public GSLHelper { public: /** Constructor */ slopeBisection(tcMPIHPtr handler) : handler_(handler) {} /** * Return the difference of the calculated elastic slope to the * experimental one for a given value of the soft mu2. During that, * the soft cross section get fixed. */ InvEnergy2 operator ()(Energy2 arg) const; /** Return the soft cross section that has been calculated */ CrossSection softXSec() const {return softXSec_;} private: /** const pointer to the MPIHandler to give access to member functions.*/ tcMPIHPtr handler_; /** soft cross section that is determined on the fly.*/ mutable CrossSection softXSec_; }; /** * A struct for the root finding that is necessary to determine the * soft cross section that is needed to describe the total cross * section correctly. */ struct TotalXSecBisection : public GSLHelper { public: /** * Constructor * @param handler The handler * @param softMu2 \f$\mu^2\f$ */ TotalXSecBisection(tcMPIHPtr handler, Energy2 softMu2=ZERO): handler_(handler), softMu2_(softMu2) {} /** * operator to return the cross section * @param argument input cross section */ CrossSection operator ()(CrossSection argument) const { return handler_->totalXSecDiff(argument, softMu2_); } /** provide the actual units of use */ virtual ValType vUnit() const {return 1.0*millibarn;} /** otherwise rounding errors may get significant */ virtual ArgType aUnit() const {return 1.0*millibarn;} private: /** * The handler */ tcMPIHPtr handler_; /** * \f$\mu^2\f$ */ Energy2 softMu2_; }; /** * Typedef for derivative of the length */ typedef decltype(mm/GeV2) LengthDiff; /** * A struct for the integrand for the slope */ struct slopeInt : public GSLHelper{ public: /** Constructor * @param handler The handler * @param hard The hard cross section * @param soft The soft cross section * @param softMu2 \f$\mu^2\f$ */ slopeInt(tcMPIHPtr handler, CrossSection hard, CrossSection soft=0*millibarn, Energy2 softMu2=ZERO) : handler_(handler), hardXSec_(hard), softXSec_(soft), softMu2_(softMu2) {} /** * Operator to return the answer * @param arg The argument */ ValType operator ()(ArgType arg) const; private: /** * Pointer to the Handler that calls this integrand */ tcMPIHPtr handler_; /** * The hard cross section to be eikonalized */ CrossSection hardXSec_; /** * The soft cross section to be eikonalized. Default is zero */ CrossSection softXSec_; /** * The inv radius^2 of the soft interactions. */ Energy2 softMu2_; }; /** * A struct for the eikonalization of the inclusive cross section. */ struct Eikonalization : public GSLHelper{ /** * The constructor * @param handler is the pointer to the MPIHandler to get access to * MPIHandler::OverlapFunction and member variables of the MPIHandler. * @param option is a flag, whether the inelastic or the total * @param handler The handler * @param hard The hard cross section * @param soft The soft cross section * @param softMu2 \f$\mu^2\f$ * cross section should be returned (-2 or -1). For option = N > 0 the integrand * is N*(A(b)*sigma)^N/N! exp(-A(b)*sigma) this is the P_N*sigma where * P_N is the Probability of having exactly N interaction (including the hard one) * This is equation 14 from "Jimmy4: Multiparton Interactions in HERWIG for the LHC" */ Eikonalization(tcMPIHPtr handler, int option, CrossSection hard, CrossSection soft=0*millibarn, Energy2 softMu2=ZERO) : theHandler(handler), theoption(option), hardXSec_(hard), softXSec_(soft), softMu2_(softMu2) {} /** * Get the function value */ Length operator ()(Length argument) const; private: /** * Pointer to the Handler that calls this integrand */ tcMPIHPtr theHandler; /** * A flag to switch between the calculation of total and inelastic cross section * or calculations for the individual probabilities. See the constructor */ int theoption; /** * The hard cross section to be eikonalized */ CrossSection hardXSec_; /** * The soft cross section to be eikonalized. Default is zero */ CrossSection softXSec_; /** * The inv radius^2 of the soft interactions. */ Energy2 softMu2_; }; } #endif /* HERWIG_MPIHandler_H */ diff --git a/Utilities/GaussianIntegrator.h b/Utilities/GaussianIntegrator.h --- a/Utilities/GaussianIntegrator.h +++ b/Utilities/GaussianIntegrator.h @@ -1,132 +1,125 @@ // -*- C++ -*- // // GaussianIntegrator.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2017 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_GaussianIntegrator_H #define HERWIG_GaussianIntegrator_H // // This is the declaration of the GaussianIntegrator class. // #include "ThePEG/Pointer/ReferenceCounted.h" #include "ThePEG/Repository/CurrentGenerator.h" #include namespace Herwig { using namespace ThePEG; /** \ingroup Utilities * \author Peter Richardson * This class is designed to perform the integral of a function * using Gaussian quadrature.The method is adaptive based on using 6th,12th, * 24th,48th, or 96th order Gaussian quadrature combined with * subdivision of the integral if this is insufficient. * * The class is templated on a simple class which should provide a * T::operator () (double) const which provides the integrand for the function. */ class GaussianIntegrator : public Pointer::ReferenceCounted { public: /** @name Standard constructors and destructors. */ //@{ /** * Default Constructor */ GaussianIntegrator() - : _abserr(1.E-35), _relerr(5.E-5), _binwidth(1.E-5), - _maxint(100), _maxeval(100000) { + : _abserr(1.E-35), _relerr(5.E-5), _binwidth(1.E-5), _maxeval(100000) { // setup the weights and abscissae Init(); } /** * Specify all the parameters. * @param abserr Absolute error. * @param relerr Relative error. * @param binwidth Width of the bin as a fraction of the integration region. - * @param maxint Maximum number of intervals * @param maxeval Maximum number of function evaluations */ GaussianIntegrator(double abserr, double relerr, double binwidth, - int maxint, int maxeval) + int maxeval) : _abserr(abserr), _relerr(relerr), - _binwidth(binwidth), _maxint(maxint), + _binwidth(binwidth), _maxeval(maxeval) { // setup the weights and abscissae Init(); } /// helper type for the integration result template using ValT = decltype(std::declval() * std::declval()); /** * The value of the integral * @param lower The lower limit of integration. * @param upper The upper limit of integration. */ template inline ValT value(const T &, const typename T::ArgType lower, const typename T::ArgType upper) const; private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ GaussianIntegrator & operator=(const GaussianIntegrator &) = delete; /** * Initialise the weights and abscissae. */ void Init(); private: /** * The weights for the gaussian quadrature. */ std::vector< std::vector > _weights; /** * The abscissae. */ std::vector< std::vector > _abscissae; /** * The parameters controlling the error. */ double _abserr,_relerr; /** * The minimum width of a bin as a fraction of the integration region. */ double _binwidth; /** - * Maximum number of bins. - */ - int _maxint; - - /** * Maximum number of function evaluations. */ int _maxeval; }; } #include "GaussianIntegrator.tcc" #endif /* HERWIG_GaussianIntegrator_H */ diff --git a/configure.ac b/configure.ac --- a/configure.ac +++ b/configure.ac @@ -1,246 +1,245 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ([2.63]) AC_INIT([Herwig],[7.2.0],[herwig@projects.hepforge.org],[Herwig]) AC_CONFIG_SRCDIR([Utilities/HerwigStrategy.cc]) AC_CONFIG_AUX_DIR([Config]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_HEADERS([Config/config.h]) dnl AC_PRESERVE_HELP_ORDER AC_CANONICAL_HOST dnl === disable debug symbols by default ===== if test "x$CXXFLAGS" = "x"; then - CXXFLAGS=-O2 + CXXFLAGS="-O2 -DBOOST_UBLAS_NDEBUG" fi if test "x$CFLAGS" = "x"; then CFLAGS=-O2 fi AC_LANG([C++]) AM_INIT_AUTOMAKE([1.11 subdir-objects gnu dist-bzip2 no-dist-gzip -Wall -Wno-portability]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) dnl Checks for C++ compiler. Handle C++11 flags. AC_PROG_CXX AX_CXX_COMPILE_STDCXX([11],[noext],[mandatory]) dnl check for POSIX AC_CHECK_HEADER([unistd.h],[], [AC_MSG_ERROR([Herwig needs "unistd.h". Non-POSIX systems are not supported.])]) AC_CHECK_HEADER([sys/stat.h],[], [AC_MSG_ERROR([Herwig needs "sys/stat.h". Non-POSIX systems are not supported.])]) dnl Checks for programs. AC_PROG_INSTALL AC_PROG_MAKE_SET AC_PROG_LN_S dnl modified search order AC_PROG_FC([gfortran g95 g77]) dnl xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn xlf90 f90 pgf90 pghpf epcf90 xlf f77 frt pgf77 cf77 fort77 fl32 af77]) AC_LANG_PUSH([Fortran]) AC_MSG_CHECKING([if the Fortran compiler ($FC) works]) AC_COMPILE_IFELSE( AC_LANG_PROGRAM([],[ print *[,]"Hello"]), [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]) AC_MSG_ERROR([A Fortran compiler is required to build Herwig.]) ] ) AC_LANG_POP([Fortran]) AC_FC_WRAPPERS LT_PREREQ([2.2.6]) LT_INIT([disable-static dlopen pic-only]) dnl #################################### dnl #################################### dnl for Doc/fixinterfaces.pl AC_PATH_PROG(PERL, perl) dnl for Models/Feynrules AM_PATH_PYTHON([2.6],, [:]) AM_CONDITIONAL([HAVE_PYTHON], [test "x$PYTHON" != "x:"]) HERWIG_CHECK_GSL HERWIG_CHECK_THEPEG BOOST_REQUIRE([1.41]) BOOST_FIND_HEADER([boost/numeric/ublas/io.hpp]) dnl Boost 1.64 is missing a required header to make these work dnl we just assume they're there if io.hpp has been found OK above dnl BOOST_FIND_HEADER([boost/numeric/ublas/matrix.hpp]) dnl BOOST_FIND_HEADER([boost/numeric/ublas/matrix_proxy.hpp]) dnl BOOST_FIND_HEADER([boost/numeric/ublas/matrix_sparse.hpp]) dnl BOOST_FIND_HEADER([boost/numeric/ublas/symmetric.hpp]) dnl BOOST_FIND_HEADER([boost/numeric/ublas/vector.hpp]) BOOST_FIND_HEADER([boost/operators.hpp]) BOOST_TEST() HERWIG_CHECK_VBFNLO HERWIG_CHECK_NJET HERWIG_CHECK_GOSAM HERWIG_CHECK_GOSAM_CONTRIB HERWIG_CHECK_OPENLOOPS HERWIG_CHECK_MADGRAPH HERWIG_CHECK_EVTGEN HERWIG_CHECK_PYTHIA HERWIG_COMPILERFLAGS HERWIG_LOOPTOOLS FASTJET_CHECK_FASTJET HERWIG_ENABLE_MODELS SHARED_FLAG=-shared AM_CONDITIONAL(NEED_APPLE_FIXES, [test "xx${host/darwin/foundit}xx" != "xx${host}xx"]) if test "xx${host/darwin/foundit}xx" != "xx${host}xx"; then APPLE_DSO_FLAGS=-Wl,-undefined,dynamic_lookup SHARED_FLAG=-bundle fi AC_SUBST([APPLE_DSO_FLAGS]) AC_SUBST([SHARED_FLAG]) AC_CONFIG_FILES([UnderlyingEvent/Makefile Models/Makefile Models/StandardModel/Makefile Models/RSModel/Makefile Models/General/Makefile Models/Susy/Makefile Models/Susy/NMSSM/Makefile Models/Susy/RPV/Makefile Models/UED/Makefile Models/LH/Makefile Models/LHTP/Makefile Models/Transplanckian/Makefile Models/Leptoquarks/Makefile Models/Zprime/Makefile Models/TTbAsymm/Makefile Models/Feynrules/Makefile Models/Feynrules/python/Makefile-FR Models/ADD/Makefile Models/Sextet/Makefile Decay/Makefile Decay/FormFactors/Makefile Decay/Tau/Makefile Decay/Baryon/Makefile Decay/VectorMeson/Makefile Decay/Perturbative/Makefile Decay/ScalarMeson/Makefile Decay/TensorMeson/Makefile Decay/WeakCurrents/Makefile Decay/Partonic/Makefile Decay/General/Makefile Decay/Radiation/Makefile Decay/EvtGen/Makefile Doc/refman.conf Doc/refman.h PDT/Makefile PDF/Makefile MatrixElement/Makefile MatrixElement/General/Makefile MatrixElement/Lepton/Makefile MatrixElement/Hadron/Makefile MatrixElement/DIS/Makefile MatrixElement/Powheg/Makefile MatrixElement/Gamma/Makefile MatrixElement/Reweighters/Makefile MatrixElement/Matchbox/Makefile MatrixElement/Matchbox/Base/Makefile MatrixElement/Matchbox/Utility/Makefile MatrixElement/Matchbox/Phasespace/Makefile MatrixElement/Matchbox/Dipoles/Makefile MatrixElement/Matchbox/InsertionOperators/Makefile MatrixElement/Matchbox/Matching/Makefile MatrixElement/Matchbox/Cuts/Makefile MatrixElement/Matchbox/Scales/Makefile MatrixElement/Matchbox/ColorFull/Makefile MatrixElement/Matchbox/CVolver/Makefile MatrixElement/Matchbox/Builtin/Makefile MatrixElement/Matchbox/Builtin/Amplitudes/Makefile MatrixElement/Matchbox/Tests/Makefile MatrixElement/Matchbox/External/Makefile MatrixElement/Matchbox/External/BLHAGeneric/Makefile MatrixElement/Matchbox/External/VBFNLO/Makefile MatrixElement/Matchbox/External/NJet/Makefile MatrixElement/Matchbox/External/GoSam/Makefile MatrixElement/Matchbox/External/OpenLoops/Makefile MatrixElement/Matchbox/External/MadGraph/Makefile MatrixElement/Matchbox/External/MadGraph/mg2herwig MatrixElement/FxFx/Makefile Sampling/Makefile Sampling/CellGrids/Makefile Shower/Makefile Shower/QTilde/Makefile Shower/QTilde/Matching/Makefile Shower/Dipole/Makefile Shower/Dipole/Base/Makefile Shower/Dipole/Kernels/Makefile Shower/Dipole/Kinematics/Makefile Shower/Dipole/Utility/Makefile Shower/Dipole/AlphaS/Makefile Shower/Dipole/SpinCorrelations/Makefile Utilities/Makefile Utilities/XML/Makefile Utilities/Statistics/Makefile Hadronization/Makefile lib/Makefile include/Makefile src/Makefile src/defaults/Makefile src/snippets/Makefile src/Matchbox/Makefile src/herwig-config Doc/Makefile Doc/HerwigDefaults.in Looptools/Makefile Analysis/Makefile API/Makefile src/Makefile-UserModules src/defaults/Analysis.in src/defaults/MatchboxDefaults.in src/defaults/Decays.in src/defaults/decayers.in src/defaults/setup.gosam.in src/Matchbox/LO-DefaultShower.in src/Matchbox/LO-DipoleShower.in src/Matchbox/MCatLO-DefaultShower.in src/Matchbox/MCatLO-DipoleShower.in src/Matchbox/LO-NoShower.in src/Matchbox/MCatNLO-DefaultShower.in src/Matchbox/MCatNLO-DipoleShower.in src/Matchbox/NLO-NoShower.in src/Matchbox/Powheg-DefaultShower.in src/Matchbox/Powheg-DipoleShower.in src/Merging/Makefile Shower/Dipole/Merging/Makefile - Shower/Dipole/Colorea/Makefile src/defaults/MatchboxMergingDefaults.in Contrib/Makefile Contrib/make_makefiles.sh Tests/Makefile Makefile]) AC_CONFIG_LINKS([Doc/BSMlibs.in:Doc/BSMlibs.in]) AC_CONFIG_FILES([Doc/fixinterfaces.pl],[chmod +x Doc/fixinterfaces.pl]) AC_CONFIG_HEADERS([PDF/SaSPhotonPDF.cc]) HERWIG_OVERVIEW AC_CONFIG_COMMANDS([summary],[cat config.herwig]) AC_OUTPUT diff --git a/m4/boost.m4 b/m4/boost.m4 --- a/m4/boost.m4 +++ b/m4/boost.m4 @@ -1,1696 +1,1779 @@ # boost.m4: Locate Boost headers and libraries for autoconf-based projects. # Copyright (C) 2007-2011, 2014 Benoit Sigoure # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Additional permission under section 7 of the GNU General Public # License, version 3 ("GPLv3"): # # If you convey this file as part of a work that contains a # configuration script generated by Autoconf, you may do so under # terms of your choice. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . m4_define([_BOOST_SERIAL], [m4_translit([ -# serial 27 +# serial 30 ], [# ], [])]) # Original sources can be found at http://github.com/tsuna/boost.m4 # You can fetch the latest version of the script by doing: # wget http://github.com/tsuna/boost.m4/raw/master/build-aux/boost.m4 # ------ # # README # # ------ # # This file provides several macros to use the various Boost libraries. # The first macro is BOOST_REQUIRE. It will simply check if it's possible to # find the Boost headers of a given (optional) minimum version and it will # define BOOST_CPPFLAGS accordingly. It will add an option --with-boost to # your configure so that users can specify non standard locations. # If the user's environment contains BOOST_ROOT and --with-boost was not # specified, --with-boost=$BOOST_ROOT is implicitly used. # For more README and documentation, go to http://github.com/tsuna/boost.m4 # Note: THESE MACROS ASSUME THAT YOU USE LIBTOOL. If you don't, don't worry, # simply read the README, it will show you what to do step by step. m4_pattern_forbid([^_?(BOOST|Boost)_]) # _BOOST_SED_CPP(SED-PROGRAM, PROGRAM, # [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # -------------------------------------------------------- # Same as AC_EGREP_CPP, but leave the result in conftest.i. # # SED-PROGRAM is *not* overquoted, as in AC_EGREP_CPP. It is expanded # in double-quotes, so escape your double quotes. # # It could be useful to turn this into a macro which extracts the # value of any macro. m4_define([_BOOST_SED_CPP], [AC_LANG_PUSH([C++])dnl AC_LANG_PREPROC_REQUIRE()dnl AC_REQUIRE([AC_PROG_SED])dnl AC_LANG_CONFTEST([AC_LANG_SOURCE([[$2]])]) AS_IF([dnl eval is necessary to expand ac_cpp. dnl Ultrix and Pyramid sh refuse to redirect output of eval, so use subshell. dnl Beware of Windows end-of-lines, for instance if we are running dnl some Windows programs under Wine. In that case, boost/version.hpp dnl is certainly using "\r\n", but the regular Unix shell will only dnl strip `\n' with backquotes, not the `\r'. This results in dnl boost_cv_lib_version='1_37\r' for instance, which breaks dnl everything else. dnl Cannot use 'dnl' after [$4] because a trailing dnl may break AC_CACHE_CHECK dnl dnl Beware that GCC 5, when expanding macros, may embed # line directives dnl a within single line: dnl dnl # 1 "conftest.cc" dnl # 1 "" dnl # 1 "" dnl # 1 "conftest.cc" dnl # 1 "/opt/local/include/boost/version.hpp" 1 3 dnl # 2 "conftest.cc" 2 dnl boost-lib-version = dnl # 2 "conftest.cc" 3 dnl "1_56" dnl dnl So get rid of the # and empty lines, and glue the remaining ones together. (eval "$ac_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD | grep -v '#' | grep -v '^[[[:space:]]]*$' | tr -d '\r' | tr -s '\n' ' ' | $SED -n -e "$1" >conftest.i 2>&1], [$3], [$4]) rm -rf conftest* AC_LANG_POP([C++])dnl ])# _BOOST_SED_CPP # BOOST_REQUIRE([VERSION], [ACTION-IF-NOT-FOUND]) # ----------------------------------------------- # Look for Boost. If version is given, it must either be a literal of the form # "X.Y.Z" where X, Y and Z are integers (the ".Z" part being optional) or a # variable "$var". # Defines the value BOOST_CPPFLAGS. This macro only checks for headers with # the required version, it does not check for any of the Boost libraries. # On # success, defines HAVE_BOOST. On failure, calls the optional # ACTION-IF-NOT-FOUND action if one was supplied. # Otherwise aborts with an error message. AC_DEFUN_ONCE([BOOST_REQUIRE], [AC_REQUIRE([AC_PROG_CXX])dnl AC_REQUIRE([AC_PROG_GREP])dnl echo "$as_me: this is boost.m4[]_BOOST_SERIAL" >&AS_MESSAGE_LOG_FD boost_save_IFS=$IFS boost_version_req=$1 IFS=. set x $boost_version_req 0 0 0 IFS=$boost_save_IFS shift boost_version_req=`expr "$[1]" '*' 100000 + "$[2]" '*' 100 + "$[3]"` boost_version_req_string=$[1].$[2].$[3] AC_ARG_WITH([boost], [AS_HELP_STRING([--with-boost=DIR], [prefix of Boost $1 @<:@guess@:>@])])dnl AC_ARG_VAR([BOOST_ROOT],[Location of Boost installation])dnl # If BOOST_ROOT is set and the user has not provided a value to # --with-boost, then treat BOOST_ROOT as if it the user supplied it. if test x"$BOOST_ROOT" != x; then if test x"$with_boost" = x; then AC_MSG_NOTICE([Detected BOOST_ROOT; continuing with --with-boost=$BOOST_ROOT]) with_boost=$BOOST_ROOT else AC_MSG_NOTICE([Detected BOOST_ROOT=$BOOST_ROOT, but overridden by --with-boost=$with_boost]) fi fi AC_SUBST([DISTCHECK_CONFIGURE_FLAGS], ["$DISTCHECK_CONFIGURE_FLAGS '--with-boost=$with_boost'"])dnl boost_save_CPPFLAGS=$CPPFLAGS AC_CACHE_CHECK([for Boost headers version >= $boost_version_req_string], [boost_cv_inc_path], [boost_cv_inc_path=no AC_LANG_PUSH([C++])dnl m4_pattern_allow([^BOOST_VERSION$])dnl AC_LANG_CONFTEST([AC_LANG_PROGRAM([[#include #if !defined BOOST_VERSION # error BOOST_VERSION is not defined #elif BOOST_VERSION < $boost_version_req # error Boost headers version < $boost_version_req #endif ]])]) # If the user provided a value to --with-boost, use it and only it. case $with_boost in #( ''|yes) set x '' /opt/local/include /usr/local/include /opt/include \ /usr/include C:/Boost/include;; #( *) set x "$with_boost/include" "$with_boost";; esac shift for boost_dir do # Without --layout=system, Boost (or at least some versions) installs # itself in /include/boost-. This inner loop helps to # find headers in such directories. # # Any ${boost_dir}/boost-x_xx directories are searched in reverse version # order followed by ${boost_dir}. The final '.' is a sentinel for # searching $boost_dir" itself. Entries are whitespace separated. # # I didn't indent this loop on purpose (to avoid over-indented code) boost_layout_system_search_list=`cd "$boost_dir" 2>/dev/null \ && ls -1 | "${GREP}" '^boost-' | sort -rn -t- -k2 \ && echo .` for boost_inc in $boost_layout_system_search_list do if test x"$boost_inc" != x.; then boost_inc="$boost_dir/$boost_inc" else boost_inc="$boost_dir" # Uses sentinel in boost_layout_system_search_list fi if test x"$boost_inc" != x; then # We are going to check whether the version of Boost installed # in $boost_inc is usable by running a compilation that # #includes it. But if we pass a -I/some/path in which Boost # is not installed, the compiler will just skip this -I and # use other locations (either from CPPFLAGS, or from its list # of system include directories). As a result we would use # header installed on the machine instead of the /some/path # specified by the user. So in that precise case (trying # $boost_inc), make sure the version.hpp exists. # # Use test -e as there can be symlinks. test -e "$boost_inc/boost/version.hpp" || continue CPPFLAGS="$CPPFLAGS -I$boost_inc" fi AC_COMPILE_IFELSE([], [boost_cv_inc_path=yes], [boost_cv_version=no]) if test x"$boost_cv_inc_path" = xyes; then if test x"$boost_inc" != x; then boost_cv_inc_path=$boost_inc fi break 2 fi done done AC_LANG_POP([C++])dnl ]) case $boost_cv_inc_path in #( no) boost_errmsg="cannot find Boost headers version >= $boost_version_req_string" m4_if([$2], [], [AC_MSG_ERROR([$boost_errmsg])], [AC_MSG_NOTICE([$boost_errmsg])]) $2 ;;#( yes) BOOST_CPPFLAGS= ;;#( *) AC_SUBST([BOOST_CPPFLAGS], ["-I$boost_cv_inc_path"])dnl ;; esac if test x"$boost_cv_inc_path" != xno; then AC_DEFINE([HAVE_BOOST], [1], [Defined if the requested minimum BOOST version is satisfied]) AC_CACHE_CHECK([for Boost's header version], [boost_cv_lib_version], [m4_pattern_allow([^BOOST_LIB_VERSION$])dnl _BOOST_SED_CPP([[/^boost-lib-version = /{s///;s/[\" ]//g;p;q;}]], [#include boost-lib-version = BOOST_LIB_VERSION], [boost_cv_lib_version=`cat conftest.i`])]) # e.g. "134" for 1_34_1 or "135" for 1_35 boost_major_version=`echo "$boost_cv_lib_version" | sed 's/_//;s/_.*//'` case $boost_major_version in #( '' | *[[!0-9]]*) AC_MSG_ERROR([invalid value: boost_major_version='$boost_major_version']) ;; esac fi CPPFLAGS=$boost_save_CPPFLAGS ])# BOOST_REQUIRE # BOOST_STATIC() # -------------- # Add the "--enable-static-boost" configure argument. If this argument is given # on the command line, static versions of the libraries will be looked up. AC_DEFUN([BOOST_STATIC], [AC_ARG_ENABLE([static-boost], [AS_HELP_STRING([--enable-static-boost], [Prefer the static boost libraries over the shared ones [no]])], [enable_static_boost=yes], [enable_static_boost=no])])# BOOST_STATIC # BOOST_FIND_HEADER([HEADER-NAME], [ACTION-IF-NOT-FOUND], [ACTION-IF-FOUND]) # -------------------------------------------------------------------------- # Wrapper around AC_CHECK_HEADER for Boost headers. Useful to check for # some parts of the Boost library which are only made of headers and don't # require linking (such as Boost.Foreach). # # Default ACTION-IF-NOT-FOUND: Fail with a fatal error unless Boost couldn't be # found in the first place, in which case by default a notice is issued to the # user. Presumably if we haven't died already it's because it's OK to not have # Boost, which is why only a notice is issued instead of a hard error. # # Default ACTION-IF-FOUND: define the preprocessor symbol HAVE_ in # case of success # (where HEADER-NAME is written LIKE_THIS, e.g., # HAVE_BOOST_FOREACH_HPP). AC_DEFUN([BOOST_FIND_HEADER], [AC_REQUIRE([BOOST_REQUIRE])dnl if test x"$boost_cv_inc_path" = xno; then m4_default([$2], [AC_MSG_NOTICE([Boost not available, not searching for $1])]) else AC_LANG_PUSH([C++])dnl boost_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" AC_CHECK_HEADER([$1], [m4_default([$3], [AC_DEFINE(AS_TR_CPP([HAVE_$1]), [1], [Define to 1 if you have <$1>])])], [m4_default([$2], [AC_MSG_ERROR([cannot find $1])])]) CPPFLAGS=$boost_save_CPPFLAGS AC_LANG_POP([C++])dnl fi ])# BOOST_FIND_HEADER # BOOST_FIND_LIBS([COMPONENT-NAME], [CANDIDATE-LIB-NAMES], # [PREFERRED-RT-OPT], [HEADER-NAME], [CXX-TEST], -# [CXX-PROLOGUE]) +# [CXX-PROLOGUE], [CXX-POST-INCLUDE-PROLOGUE], +# [ERROR_ON_UNUSABLE]) # -------------------------------------------------------------- # Look for the Boost library COMPONENT-NAME (e.g., `thread', for # libboost_thread) under the possible CANDIDATE-LIB-NAMES (e.g., # "thread_win32 thread"). Check that HEADER-NAME works and check that # libboost_LIB-NAME can link with the code CXX-TEST. The optional # argument CXX-PROLOGUE can be used to include some C++ code before -# the `main' function. +# the `main' function. The CXX-POST-INCLUDE-PROLOGUE can be used to +# include some code before the `main' function, but after the +# `#include '. # # Invokes BOOST_FIND_HEADER([HEADER-NAME]) (see above). # # Boost libraries typically come compiled with several flavors (with different # runtime options) so PREFERRED-RT-OPT is the preferred suffix. A suffix is one # or more of the following letters: sgdpn (in that order). s = static # runtime, d = debug build, g = debug/diagnostic runtime, p = STLPort build, # n = (unsure) STLPort build without iostreams from STLPort (it looks like `n' # must always be used along with `p'). Additionally, PREFERRED-RT-OPT can # start with `mt-' to indicate that there is a preference for multi-thread # builds. Some sample values for PREFERRED-RT-OPT: (nothing), mt, d, mt-d, gdp # ... If you want to make sure you have a specific version of Boost # (eg, >= 1.33) you *must* invoke BOOST_REQUIRE before this macro. +# +# ERROR_ON_UNUSABLE can be set to "no" if the caller does not want their +# configure to fail AC_DEFUN([BOOST_FIND_LIBS], [AC_REQUIRE([BOOST_REQUIRE])dnl AC_REQUIRE([_BOOST_FIND_COMPILER_TAG])dnl AC_REQUIRE([BOOST_STATIC])dnl AC_REQUIRE([_BOOST_GUESS_WHETHER_TO_USE_MT])dnl if test x"$boost_cv_inc_path" = xno; then AC_MSG_NOTICE([Boost not available, not searching for the Boost $1 library]) else dnl The else branch is huge and wasn't indented on purpose. AC_LANG_PUSH([C++])dnl AS_VAR_PUSHDEF([Boost_lib], [boost_cv_lib_$1])dnl AS_VAR_PUSHDEF([Boost_lib_LDFLAGS], [boost_cv_lib_$1_LDFLAGS])dnl AS_VAR_PUSHDEF([Boost_lib_LDPATH], [boost_cv_lib_$1_LDPATH])dnl AS_VAR_PUSHDEF([Boost_lib_LIBS], [boost_cv_lib_$1_LIBS])dnl -BOOST_FIND_HEADER([$4]) +AS_IF([test x"$8" = "xno"], [not_found_header='true']) +BOOST_FIND_HEADER([$4], [$not_found_header]) boost_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" AC_CACHE_CHECK([for the Boost $1 library], [Boost_lib], [_BOOST_FIND_LIBS($@)]) case $Boost_lib in #( (yes) _AC_MSG_LOG_CONFTEST AC_DEFINE(AS_TR_CPP([HAVE_BOOST_$1]), [1], [Defined if the Boost $1 library is available])dnl AC_SUBST(AS_TR_CPP([BOOST_$1_LDFLAGS]), [$Boost_lib_LDFLAGS])dnl AC_SUBST(AS_TR_CPP([BOOST_$1_LDPATH]), [$Boost_lib_LDPATH])dnl AC_SUBST([BOOST_LDPATH], [$Boost_lib_LDPATH])dnl AC_SUBST(AS_TR_CPP([BOOST_$1_LIBS]), [$Boost_lib_LIBS])dnl ;; (no) _AC_MSG_LOG_CONFTEST - AC_MSG_ERROR([cannot find flags to link with the Boost $1 library (libboost-$1)]) + AS_IF([test x"$8" != "xno"], [ + AC_MSG_ERROR([cannot find flags to link with the Boost $1 library (libboost-$1)]) + ]) ;; esac CPPFLAGS=$boost_save_CPPFLAGS AS_VAR_POPDEF([Boost_lib])dnl AS_VAR_POPDEF([Boost_lib_LDFLAGS])dnl AS_VAR_POPDEF([Boost_lib_LDPATH])dnl AS_VAR_POPDEF([Boost_lib_LIBS])dnl AC_LANG_POP([C++])dnl fi ]) # BOOST_FIND_LIB([LIB-NAME], # [PREFERRED-RT-OPT], [HEADER-NAME], [CXX-TEST], -# [CXX-PROLOGUE]) +# [CXX-PROLOGUE], [CXX-POST-INCLUDE-PROLOGUE], +# [ERROR_ON_UNUSABLE]) # -------------------------------------------------------------- # Backward compatibility wrapper for BOOST_FIND_LIBS. +# ERROR_ON_UNUSABLE can be set to "no" if the caller does not want their +# configure to fail AC_DEFUN([BOOST_FIND_LIB], [BOOST_FIND_LIBS([$1], $@)]) # _BOOST_FIND_LIBS([LIB-NAME], [CANDIDATE-LIB-NAMES], # [PREFERRED-RT-OPT], [HEADER-NAME], [CXX-TEST], -# [CXX-PROLOGUE]) +# [CXX-PROLOGUE], [CXX-POST-INCLUDE-PROLOGUE], +# [ERROR_ON_UNUSABLE]) # -------------------------------------------------------------- # Real implementation of BOOST_FIND_LIBS: rely on these local macros: # Boost_lib, Boost_lib_LDFLAGS, Boost_lib_LDPATH, Boost_lib_LIBS # # The algorithm is as follows: first look for a given library name # according to the user's PREFERRED-RT-OPT. For each library name, we # prefer to use the ones that carry the tag (toolset name). Each # library is searched through the various standard paths were Boost is # usually installed. If we can't find the standard variants, we try # to enforce -mt (for instance on MacOSX, libboost_thread.dylib # doesn't exist but there's -obviously- libboost_thread-mt.dylib). +# +# ERROR_ON_UNUSABLE can be set to "no" if the caller does not want their +# configure to fail AC_DEFUN([_BOOST_FIND_LIBS], [Boost_lib=no case "$3" in #( (mt | mt-) boost_mt=-mt; boost_rtopt=;; #( (mt* | mt-*) boost_mt=-mt; boost_rtopt=`expr "X$3" : 'Xmt-*\(.*\)'`;; #( (*) boost_mt=; boost_rtopt=$3;; esac if test $enable_static_boost = yes; then boost_rtopt="s$boost_rtopt" fi # Find the proper debug variant depending on what we've been asked to find. case $boost_rtopt in #( (*d*) boost_rt_d=$boost_rtopt;; #( (*[[sgpn]]*) # Insert the `d' at the right place (in between `sg' and `pn') boost_rt_d=`echo "$boost_rtopt" | sed 's/\(s*g*\)\(p*n*\)/\1\2/'`;; #( (*) boost_rt_d='-d';; esac # If the PREFERRED-RT-OPT are not empty, prepend a `-'. test -n "$boost_rtopt" && boost_rtopt="-$boost_rtopt" $boost_guess_use_mt && boost_mt=-mt # Look for the abs path the static archive. # $libext is computed by Libtool but let's make sure it's non empty. test -z "$libext" && AC_MSG_ERROR([the libext variable is empty, did you invoke Libtool?]) boost_save_ac_objext=$ac_objext # Generate the test file. AC_LANG_CONFTEST([AC_LANG_PROGRAM([$7 #include <$4> $6], [$5])]) dnl Optimization hacks: compiling C++ is slow, especially with Boost. What dnl we're trying to do here is guess the right combination of link flags dnl (LIBS / LDFLAGS) to use a given library. This can take several dnl iterations before it succeeds and is thus *very* slow. So what we do dnl instead is that we compile the code first (and thus get an object file, dnl typically conftest.o). Then we try various combinations of link flags dnl until we succeed to link conftest.o in an executable. The problem is dnl that the various TRY_LINK / COMPILE_IFELSE macros of Autoconf always dnl remove all the temporary files including conftest.o. So the trick here dnl is to temporarily change the value of ac_objext so that conftest.o is dnl preserved accross tests. This is obviously fragile and I will burn in dnl hell for not respecting Autoconf's documented interfaces, but in the dnl mean time, it optimizes the macro by a factor of 5 to 30. dnl Another small optimization: the first argument of AC_COMPILE_IFELSE left dnl empty because the test file is generated only once above (before we dnl start the for loops). AC_COMPILE_IFELSE([], [ac_objext=do_not_rm_me_plz], - [AC_MSG_ERROR([cannot compile a test that uses Boost $1])]) + [AS_IF([test x"$8" != x"no"], [ + AC_MSG_ERROR([cannot compile a test that uses Boost $1]) + ]) + ]) ac_objext=$boost_save_ac_objext boost_failed_libs= # Don't bother to ident the following nested for loops, only the 2 # innermost ones matter. for boost_lib_ in $2; do for boost_tag_ in -$boost_cv_lib_tag ''; do for boost_ver_ in -$boost_cv_lib_version ''; do for boost_mt_ in $boost_mt -mt ''; do +for boost_x64_ in -x64 ''; do for boost_rtopt_ in $boost_rtopt '' -d; do for boost_full_suffix in \ $boost_last_suffix \ x$boost_tag_$boost_mt_$boost_rtopt_$boost_ver_ \ x$boost_tag_$boost_rtopt_$boost_ver_ \ x$boost_tag_$boost_mt_$boost_ver_ \ + x$boost_tag_$boost_mt_$boost_x64_$boost_ver_ \ x$boost_tag_$boost_ver_ do boost_real_suffix=`echo "$boost_full_suffix" | sed 's/^x//'` boost_lib="boost_$boost_lib_$boost_real_suffix" # Avoid testing twice the same lib case $boost_failed_libs in #( (*@$boost_lib@*) continue;; esac # If with_boost is empty, we'll search in /lib first, which is not quite # right so instead we'll try to a location based on where the headers are. boost_tmp_lib=$with_boost test x"$with_boost" = x && boost_tmp_lib=${boost_cv_inc_path%/include} for boost_ldpath in "$boost_tmp_lib/lib" '' \ /opt/local/lib* /usr/local/lib* /opt/lib* /usr/lib* \ "$with_boost" C:/Boost/lib /lib* do # Don't waste time with directories that don't exist. if test x"$boost_ldpath" != x && test ! -e "$boost_ldpath"; then continue fi boost_save_LDFLAGS=$LDFLAGS # Are we looking for a static library? case $boost_ldpath:$boost_rtopt_ in #( (*?*:*s*) # Yes (Non empty boost_ldpath + s in rt opt) Boost_lib_LIBS="$boost_ldpath/lib$boost_lib.$libext" test -e "$Boost_lib_LIBS" || continue;; #( (*) # No: use -lboost_foo to find the shared library. Boost_lib_LIBS="-l$boost_lib";; esac boost_save_LIBS=$LIBS LIBS="$Boost_lib_LIBS $LIBS" test x"$boost_ldpath" != x && LDFLAGS="$LDFLAGS -L$boost_ldpath" dnl First argument of AC_LINK_IFELSE left empty because the test file is dnl generated only once above (before we start the for loops). _BOOST_AC_LINK_IFELSE([], [Boost_lib=yes], [Boost_lib=no]) ac_objext=$boost_save_ac_objext LDFLAGS=$boost_save_LDFLAGS LIBS=$boost_save_LIBS if test x"$Boost_lib" = xyes; then # Check or used cached result of whether or not using -R or # -rpath makes sense. Some implementations of ld, such as for # Mac OSX, require -rpath but -R is the flag known to work on # other systems. https://github.com/tsuna/boost.m4/issues/19 AC_CACHE_VAL([boost_cv_rpath_link_ldflag], [case $boost_ldpath in '') # Nothing to do. boost_cv_rpath_link_ldflag= boost_rpath_link_ldflag_found=yes;; *) for boost_cv_rpath_link_ldflag in -Wl,-R, -Wl,-rpath,; do LDFLAGS="$boost_save_LDFLAGS -L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" LIBS="$Boost_lib_LIBS $boost_save_LIBS" _BOOST_AC_LINK_IFELSE([], [boost_rpath_link_ldflag_found=yes break], [boost_rpath_link_ldflag_found=no]) done ;; esac AS_IF([test "x$boost_rpath_link_ldflag_found" != "xyes"], [AC_MSG_ERROR([Unable to determine whether to use -R or -rpath])]) LDFLAGS=$boost_save_LDFLAGS LIBS=$boost_save_LIBS ]) test x"$boost_ldpath" != x && Boost_lib_LDFLAGS="-L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" Boost_lib_LDPATH="$boost_ldpath" boost_last_suffix="$boost_full_suffix" break 7 else boost_failed_libs="$boost_failed_libs@$boost_lib@" fi done done done done done done +done done # boost_lib_ rm -f conftest.$ac_objext ]) # --------------------------------------- # # Checks for the various Boost libraries. # # --------------------------------------- # # List of boost libraries: http://www.boost.org/libs/libraries.htm # The page http://beta.boost.org/doc/libs is useful: it gives the first release # version of each library (among other things). # BOOST_DEFUN(LIBRARY, CODE) # -------------------------- # Define BOOST_ as a macro that runs CODE. # # Use indir to avoid the warning on underquoted macro name given to AC_DEFUN. m4_define([BOOST_DEFUN], [m4_indir([AC_DEFUN], m4_toupper([BOOST_$1]), [m4_pushdef([BOOST_Library], [$1])dnl $2 m4_popdef([BOOST_Library])dnl ]) ]) # BOOST_ANY() # ------------ # Look for Boost.Any BOOST_DEFUN([Any], [BOOST_FIND_HEADER([boost/any.hpp])]) # BOOST_ARRAY() # ------------- # Look for Boost.Array BOOST_DEFUN([Array], [BOOST_FIND_HEADER([boost/array.hpp])]) # BOOST_ASIO() # ------------ # Look for Boost.Asio (new in Boost 1.35). BOOST_DEFUN([Asio], [AC_REQUIRE([BOOST_SYSTEM])dnl BOOST_FIND_HEADER([boost/asio.hpp])]) # BOOST_BIMAP() # ------------ # Look for Boost.Bimap BOOST_DEFUN([Bimap], [BOOST_FIND_HEADER([boost/bimap.hpp])]) # BOOST_ASSIGN() # ------------- # Look for Boost.Assign BOOST_DEFUN([Assign], [BOOST_FIND_HEADER([boost/assign.hpp])]) -# BOOST_ATOMIC([PREFERRED-RT-OPT]) +# BOOST_ATOMIC([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # ------------------------------- # Look for Boost.Atomic. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Atomic], [BOOST_FIND_LIB([atomic], [$1], [boost/atomic.hpp], [boost::atomic a;], [ ], [#ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_STDINT_H #include -#endif]) +#endif], [$2]) ])# BOOST_ATOMIC # BOOST_BIND() # ------------ # Look for Boost.Bind. BOOST_DEFUN([Bind], [BOOST_FIND_HEADER([boost/bind.hpp])]) # BOOST_CAST() # ------------ # Look for Boost.Cast BOOST_DEFUN([Cast], [BOOST_FIND_HEADER([boost/cast.hpp])]) -# BOOST_CHRONO() +# BOOST_CHRONO([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # -------------- # Look for Boost.Chrono. BOOST_DEFUN([Chrono], [# Do we have to check for Boost.System? This link-time dependency was # added as of 1.35.0. If we have a version <1.35, we must not attempt to # find Boost.System as it didn't exist by then. if test $boost_major_version -ge 135; then - BOOST_SYSTEM([$1]) + BOOST_SYSTEM([$1], [$2]) fi # end of the Boost.System check. boost_filesystem_save_LIBS=$LIBS boost_filesystem_save_LDFLAGS=$LDFLAGS m4_pattern_allow([^BOOST_SYSTEM_(LIBS|LDFLAGS)$])dnl LIBS="$LIBS $BOOST_SYSTEM_LIBS" LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS" BOOST_FIND_LIB([chrono], [$1], [boost/chrono.hpp], - [boost::chrono::thread_clock d;]) + [boost::chrono::thread_clock d;], [], [], [$2]) if test $enable_static_boost = yes && test $boost_major_version -ge 135; then BOOST_CHRONO_LIBS="$BOOST_CHRONO_LIBS $BOOST_SYSTEM_LIBS" fi LIBS=$boost_filesystem_save_LIBS LDFLAGS=$boost_filesystem_save_LDFLAGS ])# BOOST_CHRONO -# BOOST_CONTEXT([PREFERRED-RT-OPT]) +# BOOST_CONTEXT([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # ----------------------------------- # Look for Boost.Context. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. # # * This library was introduced in Boost 1.51.0 # * The signatures of make_fcontext() and jump_fcontext were changed in 1.56.0 # * A dependency on boost_thread appears in 1.57.0 +# * The implementation details were moved to boost::context::detail in 1.61.0 BOOST_DEFUN([Context], [boost_context_save_LIBS=$LIBS boost_context_save_LDFLAGS=$LDFLAGS if test $boost_major_version -ge 157; then - BOOST_THREAD([$1]) + BOOST_THREAD([$1], [$2]) m4_pattern_allow([^BOOST_THREAD_(LIBS|LDFLAGS)$])dnl LIBS="$LIBS $BOOST_THREAD_LIBS" LDFLAGS="$LDFLAGS $BOOST_THREAD_LDFLAGS" fi + +if test $boost_major_version -ge 161; then +BOOST_FIND_LIB([context], [$1], + [boost/context/continuation.hpp], [[ +namespace ctx=boost::context; +int a; +ctx::continuation source=ctx::callcc( + [&a](ctx::continuation && sink){ + a=0; + int b=1; + for(;;){ + sink=sink.resume(); + int next=a+b; + a=b; + b=next; + } + return std::move(sink); + }); +for (int j=0;j<10;++j) { + source=source.resume(); +} +return a == 34; +]], [], [], [$2]) + +else + BOOST_FIND_LIB([context], [$1], [boost/context/fcontext.hpp],[[ // creates a stack void * stack_pointer = new void*[4096]; std::size_t const size = sizeof(void*[4096]); #if BOOST_VERSION <= 105100 ctx::make_fcontext(&fc, f); return ctx::jump_fcontext(&fcm, &fc, 3) == 6; #else fc = ctx::make_fcontext(stack_pointer, size, f); return ctx::jump_fcontext(&fcm, fc, 3) == 6; #endif ]],[dnl #include #if BOOST_VERSION <= 105100 namespace ctx = boost::ctx; static ctx::fcontext_t fcm, fc; static void f(intptr_t i) { ctx::jump_fcontext(&fc, &fcm, i * 2); } #elif BOOST_VERSION <= 105500 namespace ctx = boost::context; // context static ctx::fcontext_t fcm, *fc; // context-function static void f(intptr_t i) { ctx::jump_fcontext(fc, &fcm, i * 2); } #else namespace ctx = boost::context; // context static ctx::fcontext_t fcm, fc; // context-function static void f(intptr_t i) { ctx::jump_fcontext(&fc, fcm, i * 2); } #endif -]) +], [], [], [$2]) + +fi + LIBS=$boost_context_save_LIBS LDFLAGS=$boost_context_save_LDFLAGS ])# BOOST_CONTEXT # BOOST_CONVERSION() # ------------------ # Look for Boost.Conversion (cast / lexical_cast) BOOST_DEFUN([Conversion], [BOOST_FIND_HEADER([boost/cast.hpp]) BOOST_FIND_HEADER([boost/lexical_cast.hpp]) ])# BOOST_CONVERSION -# BOOST_COROUTINE([PREFERRED-RT-OPT]) +# BOOST_COROUTINE([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # ----------------------------------- # Look for Boost.Coroutine. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. This library was introduced in Boost # 1.53.0 BOOST_DEFUN([Coroutine], [ boost_coroutine_save_LIBS=$LIBS boost_coroutine_save_LDFLAGS=$LDFLAGS # Link-time dependency from coroutine to context -BOOST_CONTEXT([$1]) +BOOST_CONTEXT([$1], [$2]) # Starting from Boost 1.55 a dependency on Boost.System is added if test $boost_major_version -ge 155; then - BOOST_SYSTEM([$1]) + BOOST_SYSTEM([$1], [$2]) fi m4_pattern_allow([^BOOST_(CONTEXT|SYSTEM)_(LIBS|LDFLAGS)]) LIBS="$LIBS $BOOST_CONTEXT_LIBS $BOOST_SYSTEM_LIBS" LDFLAGS="$LDFLAGS $BOOST_CONTEXT_LDFLAGS" # in 1.53 coroutine was a header only library if test $boost_major_version -eq 153; then - BOOST_FIND_HEADER([boost/coroutine/coroutine.hpp]) + AS_IF([test x"$2" = "xno"], [not_found_header='true']) + BOOST_FIND_HEADER([boost/coroutine/coroutine.hpp], [$not_found_header]) else BOOST_FIND_LIB([coroutine], [$1], [boost/coroutine/coroutine.hpp], [ #include #if BOOST_VERSION <= 105500 boost::coroutines::coroutine coro; coro.get(); #else boost::coroutines::asymmetric_coroutine::pull_type coro; coro.get(); #endif - ]) + ], [], [], [$2]) fi # Link-time dependency from coroutine to context, existed only in 1.53, in 1.54 # coroutine doesn't use context from its headers but from its library. if test $boost_major_version -eq 153 || test $enable_static_boost = yes && test $boost_major_version -ge 154; then BOOST_COROUTINE_LIBS="$BOOST_COROUTINE_LIBS $BOOST_CONTEXT_LIBS" BOOST_COROUTINE_LDFLAGS="$BOOST_COROUTINE_LDFLAGS $BOOST_CONTEXT_LDFLAGS" fi if test $enable_static_boost = yes && test $boost_major_version -ge 155; then BOOST_COROUTINE_LIBS="$BOOST_COROUTINE_LIBS $BOOST_SYSTEM_LIBS" BOOST_COROUTINE_LDFLAGS="$BOOST_COROUTINE_LDFLAGS $BOOST_SYSTEM_LDFLAGS" fi LIBS=$boost_coroutine_save_LIBS LDFLAGS=$boost_coroutine_save_LDFLAGS ])# BOOST_COROUTINE # BOOST_CRC() # ----------- # Look for Boost.CRC BOOST_DEFUN([CRC], [BOOST_FIND_HEADER([boost/crc.hpp]) ])# BOOST_CRC -# BOOST_DATE_TIME([PREFERRED-RT-OPT]) +# BOOST_DATE_TIME([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # ----------------------------------- # Look for Boost.Date_Time. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Date_Time], [BOOST_FIND_LIB([date_time], [$1], [boost/date_time/posix_time/posix_time.hpp], - [boost::posix_time::ptime t;]) + [boost::posix_time::ptime t;], [], [], [$2]) ])# BOOST_DATE_TIME # BOOST_EXCEPTION() # ------------ # Look for Boost.Exception BOOST_DEFUN([Exception], [BOOST_FIND_HEADER([boost/exception/all.hpp])]) -# BOOST_FILESYSTEM([PREFERRED-RT-OPT]) +# BOOST_FILESYSTEM([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # ------------------------------------ # Look for Boost.Filesystem. For the documentation of PREFERRED-RT-OPT, see # the documentation of BOOST_FIND_LIB above. # Do not check for boost/filesystem.hpp because this file was introduced in # 1.34. BOOST_DEFUN([Filesystem], [# Do we have to check for Boost.System? This link-time dependency was # added as of 1.35.0. If we have a version <1.35, we must not attempt to # find Boost.System as it didn't exist by then. if test $boost_major_version -ge 135; then - BOOST_SYSTEM([$1]) + BOOST_SYSTEM([$1], [$2]) fi # end of the Boost.System check. boost_filesystem_save_LIBS=$LIBS boost_filesystem_save_LDFLAGS=$LDFLAGS m4_pattern_allow([^BOOST_SYSTEM_(LIBS|LDFLAGS)$])dnl LIBS="$LIBS $BOOST_SYSTEM_LIBS" LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS" BOOST_FIND_LIB([filesystem], [$1], - [boost/filesystem/path.hpp], [boost::filesystem::path p;]) + [boost/filesystem/path.hpp], [boost::filesystem::path p;], + [], [], [$2]) if test $enable_static_boost = yes && test $boost_major_version -ge 135; then BOOST_FILESYSTEM_LIBS="$BOOST_FILESYSTEM_LIBS $BOOST_SYSTEM_LIBS" fi LIBS=$boost_filesystem_save_LIBS LDFLAGS=$boost_filesystem_save_LDFLAGS ])# BOOST_FILESYSTEM # BOOST_FLYWEIGHT() # ----------------- # Look for Boost.Flyweight. BOOST_DEFUN([Flyweight], [dnl There's a hidden dependency on pthreads. AC_REQUIRE([_BOOST_PTHREAD_FLAG])dnl BOOST_FIND_HEADER([boost/flyweight.hpp]) AC_SUBST([BOOST_FLYWEIGHT_LIBS], [$boost_cv_pthread_flag]) ]) # BOOST_FOREACH() # --------------- # Look for Boost.Foreach. BOOST_DEFUN([Foreach], [BOOST_FIND_HEADER([boost/foreach.hpp])]) # BOOST_FORMAT() # -------------- # Look for Boost.Format. # Note: we can't check for boost/format/format_fwd.hpp because the header isn't # standalone. It can't be compiled because it triggers the following error: # boost/format/detail/config_macros.hpp:88: error: 'locale' in namespace 'std' # does not name a type BOOST_DEFUN([Format], [BOOST_FIND_HEADER([boost/format.hpp])]) # BOOST_FUNCTION() # ---------------- # Look for Boost.Function BOOST_DEFUN([Function], [BOOST_FIND_HEADER([boost/function.hpp])]) # BOOST_FUSION() # ----------------- # Look for Boost.Fusion BOOST_DEFUN([Fusion], [BOOST_FIND_HEADER([boost/fusion/sequence.hpp])]) # BOOST_GEOMETRY() # ---------------- # Look for Boost.Geometry (new since 1.47.0). BOOST_DEFUN([Geometry], [BOOST_FIND_HEADER([boost/geometry.hpp]) ])# BOOST_GEOMETRY -# BOOST_GRAPH([PREFERRED-RT-OPT]) +# BOOST_GRAPH([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # ------------------------------- # Look for Boost.Graphs. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Graph], [boost_graph_save_LIBS=$LIBS boost_graph_save_LDFLAGS=$LDFLAGS # Link-time dependency from graph to regex was added as of 1.40.0. if test $boost_major_version -ge 140; then - BOOST_REGEX([$1]) + BOOST_REGEX([$1], [$2]) m4_pattern_allow([^BOOST_REGEX_(LIBS|LDFLAGS)$])dnl LIBS="$LIBS $BOOST_REGEX_LIBS" LDFLAGS="$LDFLAGS $BOOST_REGEX_LDFLAGS" fi BOOST_FIND_LIB([graph], [$1], - [boost/graph/adjacency_list.hpp], [boost::adjacency_list<> g;]) + [boost/graph/adjacency_list.hpp], [boost::adjacency_list<> g;], + [], [], [$2]) LIBS=$boost_graph_save_LIBS LDFLAGS=$boost_graph_save_LDFLAGS ])# BOOST_GRAPH # BOOST_HASH() # ------------ # Look for Boost.Functional/Hash BOOST_DEFUN([Hash], [BOOST_FIND_HEADER([boost/functional/hash.hpp])]) -# BOOST_IOSTREAMS([PREFERRED-RT-OPT]) +# BOOST_IOSTREAMS([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # ----------------------------------- # Look for Boost.IOStreams. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([IOStreams], [BOOST_FIND_LIB([iostreams], [$1], [boost/iostreams/device/file_descriptor.hpp], - [boost::iostreams::file_descriptor fd; fd.close();]) + [boost::iostreams::file_descriptor fd; fd.close();], + [], [], [$2]) ])# BOOST_IOSTREAMS # BOOST_ITERATOR() # ------------ # Look for Boost.Iterator BOOST_DEFUN([Iterator], [BOOST_FIND_HEADER([boost/iterator/iterator_adaptor.hpp])]) # BOOST_LAMBDA() # -------------- # Look for Boost.Lambda BOOST_DEFUN([Lambda], [BOOST_FIND_HEADER([boost/lambda/lambda.hpp])]) -# BOOST_LOCALE() +# BOOST_LOCALE([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # -------------- # Look for Boost.Locale BOOST_DEFUN([Locale], [ boost_locale_save_LIBS=$LIBS boost_locale_save_LDFLAGS=$LDFLAGS # require SYSTEM for boost-1.50.0 and up if test $boost_major_version -ge 150; then - BOOST_SYSTEM([$1]) + BOOST_SYSTEM([$1], [$2]) m4_pattern_allow([^BOOST_SYSTEM_(LIBS|LDFLAGS)$])dnl LIBS="$LIBS $BOOST_SYSTEM_LIBS" LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS" fi # end of the Boost.System check. BOOST_FIND_LIB([locale], [$1], [boost/locale.hpp], - [[boost::locale::generator gen; std::locale::global(gen(""));]]) + [[boost::locale::generator gen; std::locale::global(gen(""));]], [], [], [$2]) LIBS=$boost_locale_save_LIBS LDFLAGS=$boost_locale_save_LDFLAGS ])# BOOST_LOCALE -# BOOST_LOG([PREFERRED-RT-OPT]) +# BOOST_LOG([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # ----------------------------- # Look for Boost.Log. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Log], [boost_log_save_LIBS=$LIBS boost_log_save_LDFLAGS=$LDFLAGS -BOOST_SYSTEM([$1]) -BOOST_FILESYSTEM([$1]) -BOOST_DATE_TIME([$1]) +BOOST_SYSTEM([$1], [$2]) +BOOST_FILESYSTEM([$1], [$2]) +BOOST_DATE_TIME([$1], [$2]) m4_pattern_allow([^BOOST_(SYSTEM|FILESYSTEM|DATE_TIME)_(LIBS|LDFLAGS)$])dnl LIBS="$LIBS $BOOST_DATE_TIME_LIBS $BOOST_FILESYSTEM_LIBS $BOOST_SYSTEM_LIBS" LDFLAGS="$LDFLAGS $BOOST_DATE_TIME_LDFLAGS $BOOST_FILESYSTEM_LDFLAGS $BOOST_SYSTEM_LDFLAGS" BOOST_FIND_LIB([log], [$1], [boost/log/core/core.hpp], - [boost::log::attribute a; a.get_value();]) + [boost::log::attribute a; a.get_value();], [], [], [$2]) LIBS=$boost_log_save_LIBS LDFLAGS=$boost_log_save_LDFLAGS ])# BOOST_LOG -# BOOST_LOG_SETUP([PREFERRED-RT-OPT]) +# BOOST_LOG_SETUP([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # ----------------------------------- # Look for Boost.Log. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Log_Setup], [boost_log_setup_save_LIBS=$LIBS boost_log_setup_save_LDFLAGS=$LDFLAGS BOOST_LOG([$1]) m4_pattern_allow([^BOOST_LOG_(LIBS|LDFLAGS)$])dnl LIBS="$LIBS $BOOST_LOG_LIBS" LDFLAGS="$LDFLAGS $BOOST_LOG_LDFLAGS" BOOST_FIND_LIB([log_setup], [$1], [boost/log/utility/setup/from_settings.hpp], - [boost::log::basic_settings bs; bs.empty();]) + [boost::log::basic_settings bs; bs.empty();], [], [], [$2]) LIBS=$boost_log_setup_save_LIBS LDFLAGS=$boost_log_setup_save_LDFLAGS ])# BOOST_LOG_SETUP # BOOST_MATH() # ------------ # Look for Boost.Math # TODO: This library isn't header-only but it comes in multiple different # flavors that don't play well with BOOST_FIND_LIB (e.g, libboost_math_c99, # libboost_math_c99f, libboost_math_c99l, libboost_math_tr1, # libboost_math_tr1f, libboost_math_tr1l). This macro must be fixed to do the # right thing anyway. BOOST_DEFUN([Math], [BOOST_FIND_HEADER([boost/math/special_functions.hpp])]) -# BOOST_MPI([PREFERRED-RT-OPT]) +# BOOST_MPI([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # ------------------------------- # Look for Boost MPI. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. Uses MPICXX variable if it is # set, otherwise tries CXX # BOOST_DEFUN([MPI], [boost_save_CXX=${CXX} boost_save_CXXCPP=${CXXCPP} if test x"${MPICXX}" != x; then CXX=${MPICXX} CXXCPP="${MPICXX} -E" fi BOOST_FIND_LIB([mpi], [$1], [boost/mpi.hpp], [int argc = 0; char **argv = 0; - boost::mpi::environment env(argc,argv);]) + boost::mpi::environment env(argc,argv);], + [], [], [$2]) CXX=${boost_save_CXX} CXXCPP=${boost_save_CXXCPP} ])# BOOST_MPI # BOOST_MPL() # ------------------ # Look for Boost.MPL BOOST_DEFUN([MPL], [BOOST_FIND_HEADER([boost/mpl/for_each.hpp])]) # BOOST_MULTIARRAY() # ------------------ # Look for Boost.MultiArray BOOST_DEFUN([MultiArray], [BOOST_FIND_HEADER([boost/multi_array.hpp])]) # BOOST_MULTIINDEXCCONTAINER() # ------------------ # Look for Boost.MultiIndexContainer BOOST_DEFUN([MultiIndexContainer], [BOOST_FIND_HEADER([boost/multi_index_container.hpp])]) # BOOST_NUMERIC_UBLAS() # -------------------------- # Look for Boost.NumericUblas (Basic Linear Algebra) BOOST_DEFUN([Numeric_Ublas], [BOOST_FIND_HEADER([boost/numeric/ublas/vector.hpp]) ])# BOOST_NUMERIC_UBLAS # BOOST_NUMERIC_CONVERSION() # -------------------------- # Look for Boost.NumericConversion (policy-based numeric conversion) BOOST_DEFUN([Numeric_Conversion], [BOOST_FIND_HEADER([boost/numeric/conversion/converter.hpp]) ])# BOOST_NUMERIC_CONVERSION # BOOST_OPTIONAL() # ---------------- # Look for Boost.Optional BOOST_DEFUN([Optional], [BOOST_FIND_HEADER([boost/optional.hpp])]) # BOOST_PREPROCESSOR() # -------------------- # Look for Boost.Preprocessor BOOST_DEFUN([Preprocessor], [BOOST_FIND_HEADER([boost/preprocessor/repeat.hpp])]) -# BOOST_PROPERTY_TREE([PREFERRED-RT-OPT]) +# BOOST_PROPERTY_TREE([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # ----------------------------------------- # Look for Boost.Property_Tree. For the documentation of PREFERRED-RT-OPT, # see the documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Property_Tree], [BOOST_FIND_LIB([property_tree], [$1], [boost/property_tree/ptree.hpp], - [boost::property_tree::ptree pt; boost::property_tree::read_xml d("test", pt);]) + [boost::property_tree::ptree pt; boost::property_tree::read_xml d("test", pt);], + [], [], [$2]) ])# BOOST_PROPERTY_TREE # BOOST_RANDOM() # -------------------- # Look for Boost.Random BOOST_DEFUN([Random], [BOOST_FIND_HEADER([boost/random/random_number_generator.hpp])]) # BOOST_RANGE() # -------------------- # Look for Boost.Range BOOST_DEFUN([Range], [BOOST_FIND_HEADER([boost/range/adaptors.hpp])]) # BOOST_UNORDERED() # ----------------- # Look for Boost.Unordered BOOST_DEFUN([Unordered], [BOOST_FIND_HEADER([boost/unordered_map.hpp])]) # BOOST_UUID() # ------------ # Look for Boost.Uuid BOOST_DEFUN([Uuid], [BOOST_FIND_HEADER([boost/uuid/uuid.hpp])]) -# BOOST_PROGRAM_OPTIONS([PREFERRED-RT-OPT]) +# BOOST_PROGRAM_OPTIONS([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # ----------------------------------------- # Look for Boost.Program_options. For the documentation of PREFERRED-RT-OPT, # see the documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Program_Options], [BOOST_FIND_LIB([program_options], [$1], [boost/program_options.hpp], - [boost::program_options::options_description d("test");]) + [boost::program_options::options_description d("test");], + [], [], [$2]) ])# BOOST_PROGRAM_OPTIONS # _BOOST_PYTHON_CONFIG(VARIABLE, FLAG) # ------------------------------------ # Save VARIABLE, and define it via `python-config --FLAG`. # Substitute BOOST_PYTHON_VARIABLE. m4_define([_BOOST_PYTHON_CONFIG], [AC_SUBST([BOOST_PYTHON_$1], [`python-config --$2 2>/dev/null`])dnl boost_python_save_$1=$$1 $1="$$1 $BOOST_PYTHON_$1"]) -# BOOST_PYTHON([PREFERRED-RT-OPT]) +# BOOST_PYTHON([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # -------------------------------- # Look for Boost.Python. For the documentation of PREFERRED-RT-OPT, # see the documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Python], [_BOOST_PYTHON_CONFIG([CPPFLAGS], [includes]) _BOOST_PYTHON_CONFIG([LDFLAGS], [ldflags]) _BOOST_PYTHON_CONFIG([LIBS], [libs]) m4_pattern_allow([^BOOST_PYTHON_MODULE$])dnl BOOST_FIND_LIBS([python], [python python3], [$1], [boost/python.hpp], - [], [BOOST_PYTHON_MODULE(empty) {}]) + [], [BOOST_PYTHON_MODULE(empty) {}], [], [$2]) CPPFLAGS=$boost_python_save_CPPFLAGS LDFLAGS=$boost_python_save_LDFLAGS LIBS=$boost_python_save_LIBS ])# BOOST_PYTHON # BOOST_REF() # ----------- # Look for Boost.Ref BOOST_DEFUN([Ref], [BOOST_FIND_HEADER([boost/ref.hpp])]) -# BOOST_REGEX([PREFERRED-RT-OPT]) +# BOOST_REGEX([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # ------------------------------- # Look for Boost.Regex. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Regex], [BOOST_FIND_LIB([regex], [$1], [boost/regex.hpp], - [boost::regex exp("*"); boost::regex_match("foo", exp);]) + [boost::regex exp("*"); boost::regex_match("foo", exp);], + [], [], [$2]) ])# BOOST_REGEX -# BOOST_SERIALIZATION([PREFERRED-RT-OPT]) +# BOOST_SCOPE_EXIT() +# ------------ +# Look for Boost.ScopeExit. +BOOST_DEFUN([SCOPE_EXIT], +[BOOST_FIND_HEADER([boost/scope_exit.hpp])]) + + +# BOOST_SERIALIZATION([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # --------------------------------------- # Look for Boost.Serialization. For the documentation of PREFERRED-RT-OPT, see # the documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Serialization], [BOOST_FIND_LIB([serialization], [$1], [boost/archive/text_oarchive.hpp], [std::ostream* o = 0; // Cheap way to get an ostream... - boost::archive::text_oarchive t(*o);]) + boost::archive::text_oarchive t(*o);], + [], [], [$2]) ])# BOOST_SERIALIZATION -# BOOST_SIGNALS([PREFERRED-RT-OPT]) +# BOOST_SIGNALS([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # --------------------------------- # Look for Boost.Signals. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Signals], [BOOST_FIND_LIB([signals], [$1], [boost/signal.hpp], - [boost::signal s;]) + [boost::signal s;], + [], [], [$2]) ])# BOOST_SIGNALS # BOOST_SIGNALS2() # ---------------- # Look for Boost.Signals2 (new since 1.39.0). BOOST_DEFUN([Signals2], [BOOST_FIND_HEADER([boost/signals2.hpp]) ])# BOOST_SIGNALS2 # BOOST_SMART_PTR() # ----------------- # Look for Boost.SmartPtr BOOST_DEFUN([Smart_Ptr], [BOOST_FIND_HEADER([boost/scoped_ptr.hpp]) BOOST_FIND_HEADER([boost/shared_ptr.hpp]) ]) # BOOST_STATICASSERT() # -------------------- # Look for Boost.StaticAssert BOOST_DEFUN([StaticAssert], [BOOST_FIND_HEADER([boost/static_assert.hpp])]) # BOOST_STRING_ALGO() # ------------------- # Look for Boost.StringAlgo BOOST_DEFUN([String_Algo], [BOOST_FIND_HEADER([boost/algorithm/string.hpp]) ]) -# BOOST_SYSTEM([PREFERRED-RT-OPT]) +# BOOST_SYSTEM([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # -------------------------------- # Look for Boost.System. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. This library was introduced in Boost # 1.35.0. BOOST_DEFUN([System], [BOOST_FIND_LIB([system], [$1], [boost/system/error_code.hpp], - [boost::system::error_code e; e.clear();]) + [boost::system::error_code e; e.clear();], [], [], [$2]) ])# BOOST_SYSTEM -# BOOST_TEST([PREFERRED-RT-OPT]) +# BOOST_TEST([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # ------------------------------ # Look for Boost.Test. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Test], [m4_pattern_allow([^BOOST_CHECK$])dnl BOOST_FIND_LIB([unit_test_framework], [$1], [boost/test/unit_test.hpp], [BOOST_CHECK(2 == 2);], [using boost::unit_test::test_suite; test_suite* init_unit_test_suite(int argc, char ** argv) - { return NULL; }]) + { return NULL; }], [], [$2]) ])# BOOST_TEST -# BOOST_THREAD([PREFERRED-RT-OPT]) +# BOOST_THREAD([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # --------------------------------- # Look for Boost.Thread. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Thread], [dnl Having the pthread flag is required at least on GCC3 where dnl boost/thread.hpp would complain if we try to compile without dnl -pthread on GNU/Linux. AC_REQUIRE([_BOOST_PTHREAD_FLAG])dnl boost_thread_save_LIBS=$LIBS boost_thread_save_LDFLAGS=$LDFLAGS boost_thread_save_CPPFLAGS=$CPPFLAGS # Link-time dependency from thread to system was added as of 1.49.0. if test $boost_major_version -ge 149; then -BOOST_SYSTEM([$1]) +BOOST_SYSTEM([$1], [$2]) fi # end of the Boost.System check. m4_pattern_allow([^BOOST_SYSTEM_(LIBS|LDFLAGS)$])dnl LIBS="$LIBS $BOOST_SYSTEM_LIBS $boost_cv_pthread_flag" LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS" CPPFLAGS="$CPPFLAGS $boost_cv_pthread_flag" # When compiling for the Windows platform, the threads library is named # differently. This suffix doesn't exist in new versions of Boost, or # possibly new versions of GCC on mingw I am assuming it's Boost's change for # now and I am setting version to 1.48, for lack of knowledge as to when this # change occurred. if test $boost_major_version -lt 148; then case $host_os in (*mingw*) boost_thread_lib_ext=_win32;; esac fi BOOST_FIND_LIBS([thread], [thread$boost_thread_lib_ext], [$1], - [boost/thread.hpp], [boost::thread t; boost::mutex m;]) + [boost/thread.hpp], [boost::thread t; boost::mutex m;], [], [], [$2]) case $host_os in (*mingw*) boost_thread_w32_socket_link=-lws2_32;; esac BOOST_THREAD_LIBS="$BOOST_THREAD_LIBS $BOOST_SYSTEM_LIBS $boost_cv_pthread_flag $boost_thread_w32_socket_link" BOOST_THREAD_LDFLAGS="$BOOST_SYSTEM_LDFLAGS" BOOST_CPPFLAGS="$BOOST_CPPFLAGS $boost_cv_pthread_flag" LIBS=$boost_thread_save_LIBS LDFLAGS=$boost_thread_save_LDFLAGS CPPFLAGS=$boost_thread_save_CPPFLAGS ])# BOOST_THREAD AU_ALIAS([BOOST_THREADS], [BOOST_THREAD]) # BOOST_TOKENIZER() # ----------------- # Look for Boost.Tokenizer BOOST_DEFUN([Tokenizer], [BOOST_FIND_HEADER([boost/tokenizer.hpp])]) # BOOST_TRIBOOL() # --------------- # Look for Boost.Tribool BOOST_DEFUN([Tribool], [BOOST_FIND_HEADER([boost/logic/tribool_fwd.hpp]) BOOST_FIND_HEADER([boost/logic/tribool.hpp]) ]) # BOOST_TUPLE() # ------------- # Look for Boost.Tuple BOOST_DEFUN([Tuple], [BOOST_FIND_HEADER([boost/tuple/tuple.hpp])]) # BOOST_TYPETRAITS() # -------------------- # Look for Boost.TypeTraits BOOST_DEFUN([TypeTraits], [BOOST_FIND_HEADER([boost/type_traits.hpp])]) # BOOST_UTILITY() # --------------- # Look for Boost.Utility (noncopyable, result_of, base-from-member idiom, # etc.) BOOST_DEFUN([Utility], [BOOST_FIND_HEADER([boost/utility.hpp])]) # BOOST_VARIANT() # --------------- # Look for Boost.Variant. BOOST_DEFUN([Variant], [BOOST_FIND_HEADER([boost/variant/variant_fwd.hpp]) BOOST_FIND_HEADER([boost/variant.hpp])]) # BOOST_POINTER_CONTAINER() # ------------------------ # Look for Boost.PointerContainer BOOST_DEFUN([Pointer_Container], [BOOST_FIND_HEADER([boost/ptr_container/ptr_deque.hpp]) BOOST_FIND_HEADER([boost/ptr_container/ptr_list.hpp]) BOOST_FIND_HEADER([boost/ptr_container/ptr_vector.hpp]) BOOST_FIND_HEADER([boost/ptr_container/ptr_array.hpp]) BOOST_FIND_HEADER([boost/ptr_container/ptr_set.hpp]) BOOST_FIND_HEADER([boost/ptr_container/ptr_map.hpp]) ])# BOOST_POINTER_CONTAINER -# BOOST_WAVE([PREFERRED-RT-OPT]) +# BOOST_WAVE([PREFERRED-RT-OPT], [ERROR_ON_UNUSABLE]) # ------------------------------ # NOTE: If you intend to use Wave/Spirit with thread support, make sure you # call BOOST_THREAD first. # Look for Boost.Wave. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Wave], [AC_REQUIRE([BOOST_FILESYSTEM])dnl AC_REQUIRE([BOOST_DATE_TIME])dnl boost_wave_save_LIBS=$LIBS boost_wave_save_LDFLAGS=$LDFLAGS m4_pattern_allow([^BOOST_((FILE)?SYSTEM|DATE_TIME|THREAD)_(LIBS|LDFLAGS)$])dnl LIBS="$LIBS $BOOST_SYSTEM_LIBS $BOOST_FILESYSTEM_LIBS $BOOST_DATE_TIME_LIBS \ $BOOST_THREAD_LIBS" LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS $BOOST_FILESYSTEM_LDFLAGS \ $BOOST_DATE_TIME_LDFLAGS $BOOST_THREAD_LDFLAGS" BOOST_FIND_LIB([wave], [$1], [boost/wave.hpp], - [boost::wave::token_id id; get_token_name(id);]) + [boost::wave::token_id id; get_token_name(id);], [], [], [$2]) LIBS=$boost_wave_save_LIBS LDFLAGS=$boost_wave_save_LDFLAGS ])# BOOST_WAVE # BOOST_XPRESSIVE() # ----------------- # Look for Boost.Xpressive (new since 1.36.0). BOOST_DEFUN([Xpressive], [BOOST_FIND_HEADER([boost/xpressive/xpressive.hpp])]) # ----------------- # # Internal helpers. # # ----------------- # # _BOOST_PTHREAD_FLAG() # --------------------- # Internal helper for BOOST_THREAD. Computes boost_cv_pthread_flag # which must be used in CPPFLAGS and LIBS. # # Yes, we *need* to put the -pthread thing in CPPFLAGS because with GCC3, # boost/thread.hpp will trigger a #error if -pthread isn't used: # boost/config/requires_threads.hpp:47:5: #error "Compiler threading support # is not turned on. Please set the correct command line options for # threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)" # # Based on ACX_PTHREAD: http://autoconf-archive.cryp.to/acx_pthread.html AC_DEFUN([_BOOST_PTHREAD_FLAG], [AC_REQUIRE([AC_PROG_CXX])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_LANG_PUSH([C++])dnl AC_CACHE_CHECK([for the flags needed to use pthreads], [boost_cv_pthread_flag], [ boost_cv_pthread_flag= # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # (none): in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -lpthreads: AIX (must check this before -lpthread) # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # -llthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: GNU Linux/GCC (kernel threads), BSD/GCC (userland threads) # -pthreads: Solaris/GCC # -mthreads: MinGW32/GCC, Lynx/GCC # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # -lpthread: GNU Linux, etc. # --thread-safe: KAI C++ case $host_os in #( *solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: boost_pthread_flags="-pthreads -lpthread -mt -pthread";; #( *) boost_pthread_flags="-lpthreads -Kthread -kthread -llthread -pthread \ -pthreads -mthreads -lpthread --thread-safe -mt";; esac # Generate the test file. AC_LANG_CONFTEST([AC_LANG_PROGRAM([#include ], [pthread_t th; pthread_join(th, 0); pthread_attr_init(0); pthread_cleanup_push(0, 0); pthread_create(0,0,0,0); pthread_cleanup_pop(0);])]) for boost_pthread_flag in '' $boost_pthread_flags; do boost_pthread_ok=false dnl Re-use the test file already generated. boost_pthreads__save_LIBS=$LIBS LIBS="$LIBS $boost_pthread_flag" AC_LINK_IFELSE([], [if grep ".*$boost_pthread_flag" conftest.err; then echo "This flag seems to have triggered warnings" >&AS_MESSAGE_LOG_FD else boost_pthread_ok=:; boost_cv_pthread_flag=$boost_pthread_flag fi]) LIBS=$boost_pthreads__save_LIBS $boost_pthread_ok && break done ]) AC_LANG_POP([C++])dnl ])# _BOOST_PTHREAD_FLAG # _BOOST_gcc_test(MAJOR, MINOR) # ----------------------------- # Internal helper for _BOOST_FIND_COMPILER_TAG. m4_define([_BOOST_gcc_test], ["defined __GNUC__ && __GNUC__ == $1 && __GNUC_MINOR__ == $2 && !defined __ICC @ gcc$1$2"])dnl # _BOOST_mingw_test(MAJOR, MINOR) # ----------------------------- # Internal helper for _BOOST_FIND_COMPILER_TAG. m4_define([_BOOST_mingw_test], ["defined __GNUC__ && __GNUC__ == $1 && __GNUC_MINOR__ == $2 && !defined __ICC && \ (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw$1$2"])dnl # _BOOST_FIND_COMPILER_TAG() # -------------------------- # Internal. When Boost is installed without --layout=system, each library # filename will hold a suffix that encodes the compiler used during the # build. The Boost build system seems to call this a `tag'. AC_DEFUN([_BOOST_FIND_COMPILER_TAG], [AC_REQUIRE([AC_PROG_CXX])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_CACHE_CHECK([for the toolset name used by Boost for $CXX], [boost_cv_lib_tag], [boost_cv_lib_tag=unknown if test x$boost_cv_inc_path != xno; then AC_LANG_PUSH([C++])dnl # The following tests are mostly inspired by boost/config/auto_link.hpp # The list is sorted to most recent/common to oldest compiler (in order # to increase the likelihood of finding the right compiler with the # least number of compilation attempt). # Beware that some tests are sensible to the order (for instance, we must # look for MinGW before looking for GCC3). # I used one compilation test per compiler with a #error to recognize # each compiler so that it works even when cross-compiling (let me know # if you know a better approach). # Known missing tags (known from Boost's tools/build/v2/tools/common.jam): # como, edg, kcc, bck, mp, sw, tru, xlc # I'm not sure about my test for `il' (be careful: Intel's ICC pre-defines # the same defines as GCC's). for i in \ + "defined __clang__ && __clang_major__ == 8 && __clang_minor__ == 0 @ clang80" \ + "defined __clang__ && __clang_major__ == 7 && __clang_minor__ == 0 @ clang70" \ + "defined __clang__ && __clang_major__ == 6 && __clang_minor__ == 0 @ clang60" \ + "defined __clang__ && __clang_major__ == 5 && __clang_minor__ == 0 @ clang50" \ + "defined __clang__ && __clang_major__ == 4 && __clang_minor__ == 0 @ clang40" \ + "defined __clang__ && __clang_major__ == 3 && __clang_minor__ == 9 @ clang39" \ + "defined __clang__ && __clang_major__ == 3 && __clang_minor__ == 8 @ clang38" \ + "defined __clang__ && __clang_major__ == 3 && __clang_minor__ == 7 @ clang37" \ + _BOOST_mingw_test(9, 1) \ + _BOOST_gcc_test(9, 1) \ + _BOOST_mingw_test(9, 0) \ + _BOOST_gcc_test(9, 0) \ + _BOOST_mingw_test(8, 3) \ + _BOOST_gcc_test(8, 3) \ _BOOST_mingw_test(8, 2) \ _BOOST_gcc_test(8, 2) \ _BOOST_mingw_test(8, 1) \ _BOOST_gcc_test(8, 1) \ _BOOST_mingw_test(8, 0) \ _BOOST_gcc_test(8, 0) \ _BOOST_mingw_test(7, 3) \ _BOOST_gcc_test(7, 3) \ _BOOST_mingw_test(7, 2) \ _BOOST_gcc_test(7, 2) \ _BOOST_mingw_test(7, 1) \ _BOOST_gcc_test(7, 1) \ _BOOST_mingw_test(7, 0) \ _BOOST_gcc_test(7, 0) \ _BOOST_mingw_test(6, 4) \ _BOOST_gcc_test(6, 4) \ _BOOST_mingw_test(6, 3) \ _BOOST_gcc_test(6, 3) \ _BOOST_mingw_test(6, 2) \ _BOOST_gcc_test(6, 2) \ _BOOST_mingw_test(6, 1) \ _BOOST_gcc_test(6, 1) \ _BOOST_mingw_test(6, 0) \ _BOOST_gcc_test(6, 0) \ _BOOST_mingw_test(5, 5) \ _BOOST_gcc_test(5, 5) \ _BOOST_mingw_test(5, 4) \ _BOOST_gcc_test(5, 4) \ _BOOST_mingw_test(5, 3) \ _BOOST_gcc_test(5, 3) \ _BOOST_mingw_test(5, 2) \ _BOOST_gcc_test(5, 2) \ _BOOST_mingw_test(5, 1) \ _BOOST_gcc_test(5, 1) \ _BOOST_mingw_test(5, 0) \ _BOOST_gcc_test(5, 0) \ _BOOST_mingw_test(4, 10) \ _BOOST_gcc_test(4, 10) \ _BOOST_mingw_test(4, 9) \ _BOOST_gcc_test(4, 9) \ _BOOST_mingw_test(4, 8) \ _BOOST_gcc_test(4, 8) \ _BOOST_mingw_test(4, 7) \ _BOOST_gcc_test(4, 7) \ _BOOST_mingw_test(4, 6) \ _BOOST_gcc_test(4, 6) \ _BOOST_mingw_test(4, 5) \ _BOOST_gcc_test(4, 5) \ _BOOST_mingw_test(4, 4) \ _BOOST_gcc_test(4, 4) \ _BOOST_mingw_test(4, 3) \ _BOOST_gcc_test(4, 3) \ _BOOST_mingw_test(4, 2) \ _BOOST_gcc_test(4, 2) \ _BOOST_mingw_test(4, 1) \ _BOOST_gcc_test(4, 1) \ _BOOST_mingw_test(4, 0) \ _BOOST_gcc_test(4, 0) \ "defined __GNUC__ && __GNUC__ == 3 && !defined __ICC \ && (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw" \ _BOOST_gcc_test(3, 4) \ _BOOST_gcc_test(3, 3) \ "defined _MSC_VER && _MSC_VER >= 1500 @ vc90" \ "defined _MSC_VER && _MSC_VER == 1400 @ vc80" \ _BOOST_gcc_test(3, 2) \ "defined _MSC_VER && _MSC_VER == 1310 @ vc71" \ _BOOST_gcc_test(3, 1) \ _BOOST_gcc_test(3, 0) \ "defined __BORLANDC__ @ bcb" \ "defined __ICC && (defined __unix || defined __unix__) @ il" \ "defined __ICL @ iw" \ "defined _MSC_VER && _MSC_VER == 1300 @ vc7" \ _BOOST_gcc_test(2, 95) \ "defined __MWERKS__ && __MWERKS__ <= 0x32FF @ cw9" \ "defined _MSC_VER && _MSC_VER < 1300 && !defined UNDER_CE @ vc6" \ "defined _MSC_VER && _MSC_VER < 1300 && defined UNDER_CE @ evc4" \ "defined __MWERKS__ && __MWERKS__ <= 0x31FF @ cw8" do boost_tag_test=`expr "X$i" : 'X\([[^@]]*\) @ '` boost_tag=`expr "X$i" : 'X[[^@]]* @ \(.*\)'` AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #if $boost_tag_test /* OK */ #else # error $boost_tag_test #endif ]])], [boost_cv_lib_tag=$boost_tag; break], []) done AC_LANG_POP([C++])dnl case $boost_cv_lib_tag in #( # Some newer (>= 1.35?) versions of Boost seem to only use "gcc" as opposed # to "gcc41" for instance. *-gcc | *'-gcc ') :;; #( Don't re-add -gcc: it's already in there. gcc*) boost_tag_x= case $host_os in #( darwin*) if test $boost_major_version -ge 136; then # The `x' added in r46793 of Boost. boost_tag_x=x fi;; esac # We can specify multiple tags in this variable because it's used by # BOOST_FIND_LIB that does a `for tag in -$boost_cv_lib_tag' ... boost_cv_lib_tag="$boost_tag_x$boost_cv_lib_tag -${boost_tag_x}gcc" ;; #( unknown) AC_MSG_WARN([[could not figure out which toolset name to use for $CXX]]) boost_cv_lib_tag= ;; esac fi])dnl end of AC_CACHE_CHECK ])# _BOOST_FIND_COMPILER_TAG # _BOOST_GUESS_WHETHER_TO_USE_MT() # -------------------------------- # Compile a small test to try to guess whether we should favor MT (Multi # Thread) flavors of Boost. Sets boost_guess_use_mt accordingly. AC_DEFUN([_BOOST_GUESS_WHETHER_TO_USE_MT], [# Check whether we do better use `mt' even though we weren't ask to. AC_LANG_PUSH([C++])dnl AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #if defined _REENTRANT || defined _MT || defined __MT__ /* use -mt */ #else # error MT not needed #endif ]])], [boost_guess_use_mt=:], [boost_guess_use_mt=false]) AC_LANG_POP([C++])dnl ]) # _BOOST_AC_LINK_IFELSE(PROGRAM, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) # ------------------------------------------------------------------- # Fork of _AC_LINK_IFELSE that preserves conftest.o across calls. Fragile, # will break when Autoconf changes its internals. Requires that you manually # rm -f conftest.$ac_objext in between to really different tests, otherwise # you will try to link a conftest.o left behind by a previous test. # Used to aggressively optimize BOOST_FIND_LIB (see the big comment in this # macro). # # Don't use "break" in the actions, as it would short-circuit some code # this macro runs after the actions. m4_define([_BOOST_AC_LINK_IFELSE], [m4_ifvaln([$1], [AC_LANG_CONFTEST([$1])])dnl rm -f conftest$ac_exeext boost_save_ac_ext=$ac_ext boost_use_source=: # If we already have a .o, re-use it. We change $ac_ext so that $ac_link # tries to link the existing object file instead of compiling from source. test -f conftest.$ac_objext && ac_ext=$ac_objext && boost_use_source=false && _AS_ECHO_LOG([re-using the existing conftest.$ac_objext]) AS_IF([_AC_DO_STDERR($ac_link) && { test -z "$ac_[]_AC_LANG_ABBREV[]_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_executable_p conftest$ac_exeext dnl FIXME: use AS_TEST_X instead when 2.61 is widespread enough. }], [$2], [if $boost_use_source; then _AC_MSG_LOG_CONFTEST fi $3]) ac_objext=$boost_save_ac_objext ac_ext=$boost_save_ac_ext dnl Delete also the IPA/IPO (Inter Procedural Analysis/Optimization) dnl information created by the PGI compiler (conftest_ipa8_conftest.oo), dnl as it would interfere with the next link command. rm -f core conftest.err conftest_ipa8_conftest.oo \ conftest$ac_exeext m4_ifval([$1], [conftest.$ac_ext])[]dnl ])# _BOOST_AC_LINK_IFELSE # Local Variables: # mode: autoconf # End: diff --git a/src/Matchbox/LO-DipoleShower.in.in b/src/Matchbox/LO-DipoleShower.in.in --- a/src/Matchbox/LO-DipoleShower.in.in +++ b/src/Matchbox/LO-DipoleShower.in.in @@ -1,24 +1,24 @@ # -*- ThePEG-repository -*- read Matchbox/LO.in cd /Herwig/EventHandlers set EventHandler:CascadeHandler /Herwig/DipoleShower/DipoleShowerHandler -read snippets/Dipole_AutoTune_prel.in +read snippets/Dipole_AutoTunes_gss.in cd /Herwig/Analysis @CREATE_RIVET@ ThePEG::RivetAnalysis Rivet RivetAnalysis.so @CREATE_HEPMC@ ThePEG::HepMCFile HepMC HepMCAnalysis.so cd /Herwig/Particles do c:UnsetHardProcessMass do cbar:UnsetHardProcessMass set c:NominalMass 0*GeV set cbar:NominalMass 0*GeV cd /Herwig/UnderlyingEvent set MEQCD2to2Fast:StrictFlavourScheme Yes diff --git a/src/Matchbox/MCatLO-DipoleShower.in.in b/src/Matchbox/MCatLO-DipoleShower.in.in --- a/src/Matchbox/MCatLO-DipoleShower.in.in +++ b/src/Matchbox/MCatLO-DipoleShower.in.in @@ -1,28 +1,28 @@ # -*- ThePEG-repository -*- read Matchbox/LO.in cd /Herwig/EventHandlers set EventHandler:CascadeHandler /Herwig/DipoleShower/DipoleShowerHandler -read snippets/Dipole_AutoTune_prel.in +read snippets/Dipole_AutoTunes_gss.in set /Herwig/DipoleShower/DipoleShowerHandler:RestrictPhasespace Yes set /Herwig/DipoleShower/DipoleShowerHandler:MaxPtIsMuF Yes set /Herwig/DipoleShower/DipoleShowerHandler:HardScaleProfile /Herwig/MatrixElements/Matchbox/HardScaleProfile cd /Herwig/Analysis @CREATE_RIVET@ ThePEG::RivetAnalysis Rivet RivetAnalysis.so @CREATE_HEPMC@ ThePEG::HepMCFile HepMC HepMCAnalysis.so cd /Herwig/Particles do c:UnsetHardProcessMass do cbar:UnsetHardProcessMass set c:NominalMass 0*GeV set cbar:NominalMass 0*GeV cd /Herwig/UnderlyingEvent set MEQCD2to2Fast:StrictFlavourScheme Yes diff --git a/src/Matchbox/MCatNLO-DipoleShower.in.in b/src/Matchbox/MCatNLO-DipoleShower.in.in --- a/src/Matchbox/MCatNLO-DipoleShower.in.in +++ b/src/Matchbox/MCatNLO-DipoleShower.in.in @@ -1,32 +1,32 @@ # -*- ThePEG-repository -*- cd /Herwig/EventHandlers set EventHandler:CascadeHandler /Herwig/DipoleShower/DipoleShowerHandler set /Herwig/DipoleShower/DipoleShowerHandler:RestrictPhasespace Yes set /Herwig/DipoleShower/DipoleShowerHandler:MaxPtIsMuF Yes set /Herwig/DipoleShower/DipoleShowerHandler:HardScaleProfile /Herwig/MatrixElements/Matchbox/HardScaleProfile cd /Herwig/MatrixElements/Matchbox set Factory:ShowerApproximation DipoleMatching # tunes -read snippets/Dipole_AutoTune_prel.in +read snippets/Dipole_AutoTunes_gss.in cd /Herwig/Analysis @CREATE_RIVET@ ThePEG::RivetAnalysis Rivet RivetAnalysis.so @CREATE_HEPMC@ ThePEG::HepMCFile HepMC HepMCAnalysis.so cd /Herwig/Particles do c:UnsetHardProcessMass do cbar:UnsetHardProcessMass set c:NominalMass 0*GeV set cbar:NominalMass 0*GeV cd /Herwig/UnderlyingEvent set MEQCD2to2Fast:StrictFlavourScheme Yes diff --git a/src/Matchbox/Powheg-DipoleShower.in.in b/src/Matchbox/Powheg-DipoleShower.in.in --- a/src/Matchbox/Powheg-DipoleShower.in.in +++ b/src/Matchbox/Powheg-DipoleShower.in.in @@ -1,30 +1,30 @@ # -*- ThePEG-repository -*- read Matchbox/Powheg.in set /Herwig/MatrixElements/Matchbox/MEMatching:TruncatedShower No cd /Herwig/EventHandlers set EventHandler:CascadeHandler /Herwig/DipoleShower/DipoleShowerHandler set /Herwig/DipoleShower/DipoleShowerHandler:RestrictPhasespace Yes set /Herwig/DipoleShower/DipoleShowerHandler:MaxPtIsMuF Yes set /Herwig/DipoleShower/DipoleShowerHandler:HardScaleProfile NULL # tunes -read snippets/Dipole_AutoTune_prel.in +read snippets/Dipole_AutoTunes_gss.in cd /Herwig/Analysis @CREATE_RIVET@ ThePEG::RivetAnalysis Rivet RivetAnalysis.so @CREATE_HEPMC@ ThePEG::HepMCFile HepMC HepMCAnalysis.so cd /Herwig/Particles do c:UnsetHardProcessMass do cbar:UnsetHardProcessMass set c:NominalMass 0*GeV set cbar:NominalMass 0*GeV cd /Herwig/UnderlyingEvent set MEQCD2to2Fast:StrictFlavourScheme Yes diff --git a/src/Merging/LEP-Merging.in b/src/Merging/LEP-Merging.in --- a/src/Merging/LEP-Merging.in +++ b/src/Merging/LEP-Merging.in @@ -1,155 +1,155 @@ # -*- ThePEG-repository -*- ################################################## ## Herwig/Merging example input file ################################################## ################################################## ## Collider type ################################################## read snippets/DipoleMerging.in read snippets/EECollider.in read snippets/MonacoSampler.in ################################################## ## Beam energy sqrt(s) ################################################## cd /Herwig/EventHandlers set EventHandler:LuminosityFunction:Energy 91.2*GeV ################################################## ## Process selection ################################################## ## Note that event generation may fail if no matching matrix element has ## been found. Coupling orders are with respect to the Born process, ## i.e. NLO QCD does not require an additional power of alphas. ## Model assumptions read Matchbox/StandardModelLike.in read Matchbox/DiagonalCKM.in ## Set the order of the couplings cd /Herwig/Merging set MergingFactory:OrderInAlphaS 0 set MergingFactory:OrderInAlphaEW 2 ## Select the process ## You may use identifiers such as p, pbar, j, l, mu+, h0 etc. do MergingFactory:Process e- e+ -> j j [ j j ] set MergingFactory:NLOProcesses 2 set Merger:MergingScale 4.*GeV set Merger:MergingScaleSmearing 0.1 cd /Herwig/MatrixElements/Matchbox/Utility insert DiagramGenerator:ExcludeInternal 0 /Herwig/Particles/gamma ## Special settings required for on-shell production of unstable particles ## enable for on-shell top production # read Matchbox/OnShellTopProduction.in ## enable for on-shell W, Z or h production # read Matchbox/OnShellWProduction.in # read Matchbox/OnShellZProduction.in # read Matchbox/OnShellHProduction.in ################################################## ## Matrix element library selection ################################################## ## Select a generic tree/loop combination or a ## specialized NLO package ## As massive b-quarks are currently not supported by the ## build in ME an external ME-Provider is needed (e.g. MG+OL). # read Matchbox/MadGraph-GoSam.in # read Matchbox/MadGraph-MadGraph.in # read Matchbox/MadGraph-NJet.in #read Matchbox/MadGraph-OpenLoops.in ################################################## ## Cut selection ## See the documentation for more options ################################################## ## cuts on additional jets cd /Herwig/Cuts # read Matchbox/DefaultEEJets.in # set NJetsCut:NJetsMin 3 ################################################## ## Scale choice ## See the documentation for more options ################################################## cd /Herwig/MatrixElements/Matchbox/Scales/ set /Herwig/Merging/MergingFactory:ScaleChoice SHatScale ################################################## ## Scale uncertainties ################################################## # read Matchbox/MuDown.in # read Matchbox/MuUp.in ################################################## ## Shower scale uncertainties ################################################## # read Matchbox/MuQDown.in # read Matchbox/MuQUp.in ################################################## ## CMW - Scheme ################################################## -read snippets/Dipole_AutoTune_prel.in +read snippets/Dipole_AutoTunes_gss.in ### Use factor in alpha_s argument: alpha_s(q) -> alpha_s(fac*q) ### with fac=exp(-(67-3pi^2-10/3*Nf)/(33-2Nf)) read Merging/FactorCMWScheme.in ### Linear CMW multiplication: ### alpha_s(q) -> alpha_s(q)(1+K_g*alpha_s(q)/2pi ) # read Merging/LinearCMWScheme.in ################################################## ## Analyses ################################################## cd /Herwig/Analysis ## Write HepMC events. Modify the PrintEvent interface for your needs. # insert /Herwig/Generators/EventGenerator:AnalysisHandlers 0 HepMCFile ## Setup the Rivet analysis: #read snippets/Rivet.in #insert Rivet:Analyses 0 XXX_2017_ABC123 ## Here we collected a various Rivet analysis for LEP ## at the Z Mass. (The collection might not be complete.) # read Merging/LEP91-Analysis.in ################################################## ## Do not apply profile scales for LEP as hard ## scale coincides with kinematic limit ################################################## set /Herwig/Shower/ShowerHandler:HardScaleProfile NULL set /Herwig/DipoleShower/DipoleShowerHandler:HardScaleProfile NULL ################################################## ## Save the generator ################################################## do /Herwig/Merging/MergingFactory:ProductionMode cd /Herwig/Generators saverun LEP-Merging EventGenerator diff --git a/src/Merging/LHC-H-Merging.in b/src/Merging/LHC-H-Merging.in --- a/src/Merging/LHC-H-Merging.in +++ b/src/Merging/LHC-H-Merging.in @@ -1,195 +1,195 @@ # -*- ThePEG-repository -*- ################################################## ## Herwig/Merging example input file ################################################## ################################################## ## Collider type ################################################## read snippets/DipoleMerging.in read snippets/PPCollider.in read snippets/MonacoSampler.in ################################################## ## Beam energy sqrt(s) ################################################## cd /Herwig/EventHandlers set EventHandler:LuminosityFunction:Energy 8000*GeV ################################################## ## Process selection ################################################## ## Note that event generation may fail if no matching matrix element has ## been found. Coupling orders are with respect to the Born process, ## i.e. NLO QCD does not require an additional power of alphas. ## Model assumptions read Matchbox/StandardModelLike.in read Matchbox/DiagonalCKM.in ## Set the order of the couplings cd /Herwig/Merging set MergingFactory:OrderInAlphaS 2 set MergingFactory:OrderInAlphaEW 1 ## Select the process ## You may use identifiers such as p, pbar, j, l, mu+, h0 etc. do MergingFactory:Process p p -> h0 [ j j ] set MergingFactory:NLOProcesses 2 # Set the merging scale deviding the parton shower # from the matrix element region in phase space. set Merger:MergingScale 15.*GeV set Merger:MergingScaleSmearing 0.1 # The following line clear a preweighter # that is not working for Higgs as here # pt and HT are 0 before the shower. # See other merging files for more information. clear MergingFactory:Preweighters # The next line can switch of hadronization # and MPI modelling. Use with care!! # read Matchbox/PQCDLevel.in ## Special settings required for on-shell production of unstable particles ## enable for on-shell top production # read Matchbox/OnShellTopProduction.in ## enable for on-shell W, Z or h production # read Matchbox/OnShellWProduction.in # read Matchbox/OnShellZProduction.in read Matchbox/OnShellHProduction.in set /Herwig/Particles/h0:Stable Stable # Special settings for the VBF approximation # read Matchbox/VBFDiagramsOnly.in ################################################## ## Matrix element library selection ################################################## ## Select a generic tree/loop combination or a ## specialized NLO package # read Matchbox/MadGraph-GoSam.in # read Matchbox/MadGraph-MadGraph.in # read Matchbox/MadGraph-NJet.in read Matchbox/MadGraph-OpenLoops.in #read Matchbox/HJets.in # read Matchbox/VBFNLO.in ## Uncomment this to use ggh effective couplings ## currently only supported by MadGraph-GoSam and ## MadGraph-Openloops #read Matchbox/HiggsEffective.in cd /Herwig/MatrixElements/Matchbox/Amplitudes set OpenLoops:HiggsEff Yes set MadGraph:Model heft ################################################## ## Cut selection ## See the documentation for more options ################################################## cd /Herwig/Cuts/ set ChargedLeptonPairMassCut:MinMass 60*GeV set ChargedLeptonPairMassCut:MaxMass 120*GeV cd /Herwig/MatrixElements/Matchbox/Utility insert DiagramGenerator:ExcludeInternal 0 /Herwig/Particles/gamma ## cuts on additional jets cd /Herwig/Cuts/ # read Matchbox/DefaultPPJets.in # insert JetCuts:JetRegions 0 FirstJet # insert JetCuts:JetRegions 1 SecondJet # insert JetCuts:JetRegions 2 ThirdJet # insert JetCuts:JetRegions 3 FourthJet ################################################## ## Scale choice ## See the documentation for more options ################################################## cd /Herwig/MatrixElements/Matchbox/Scales/ set /Herwig/Merging/MergingFactory:ScaleChoice FixedScale set FixedScale:FixedScale 125.*GeV ################################################## ## Scale uncertainties ################################################## # read Matchbox/MuDown.in # read Matchbox/MuUp.in ################################################## ## Shower scale uncertainties ################################################## # read Matchbox/MuQDown.in # read Matchbox/MuQUp.in ################################################## ## CMW - Scheme ################################################## -read snippets/Dipole_AutoTune_prel.in +read snippets/Dipole_AutoTunes_gss.in ### Use factor in alpha_s argument: alpha_s(q) -> alpha_s(fac*q) ### with fac=exp(-(67-3pi^2-10/3*Nf)/(33-2Nf)) read Merging/FactorCMWScheme.in ### Linear CMW multiplication: ### alpha_s(q) -> alpha_s(q)(1+K_g*alpha_s(q)/2pi ) # read Merging/LinearCMWScheme.in ################################################## ## PDF choice ################################################## read Matchbox/FiveFlavourNoBMassScheme.in read Matchbox/CT14.in #read Matchbox/MMHT2014.in ################################################## ## Analyses ################################################## cd /Herwig/Analysis ## Write HepMC events. Modify the PrintEvent interface for your needs. # insert /Herwig/Generators/EventGenerator:AnalysisHandlers 0 HepMCFile ## Setup the Rivet analysis: #read snippets/Rivet.in #insert Rivet:Analyses 0 XXX_2017_ABC123 ## Here we collected a various Rivet analysis for Higgs at LHC ## at the 8 TeV. (The collection might not be complete.) # read Merging/LHC8-H-Analysis.in ################################################## ## Save the generator ################################################## do /Herwig/Merging/MergingFactory:ProductionMode set /Herwig/Generators/EventGenerator:IntermediateOutput Yes cd /Herwig/Generators saverun LHC-H-Merging EventGenerator diff --git a/src/Merging/LHC-J-Merging.in b/src/Merging/LHC-J-Merging.in --- a/src/Merging/LHC-J-Merging.in +++ b/src/Merging/LHC-J-Merging.in @@ -1,192 +1,192 @@ # -*- ThePEG-repository -*- ################################################## ## Herwig/Merging example input file ################################################## ################################################## ## Collider type ################################################## read snippets/DipoleMerging.in read snippets/PPCollider.in read snippets/MonacoSampler.in ################################################## ## Beam energy sqrt(s) ################################################## cd /Herwig/EventHandlers set EventHandler:LuminosityFunction:Energy 7000*GeV ################################################## ## Process selection ################################################## ## Note that event generation may fail if no matching matrix element has ## been found. Coupling orders are with respect to the Born process, ## i.e. NLO QCD does not require an additional power of alphas. ## Model assumptions read Matchbox/StandardModelLike.in read Matchbox/DiagonalCKM.in ## Set the order of the couplings cd /Herwig/Merging set MergingFactory:OrderInAlphaS 2 set MergingFactory:OrderInAlphaEW 0 ## Select the process ## You may use identifiers such as p, pbar, j, l, mu+, h0 etc. do MergingFactory:Process p p -> j j [ j ] set MergingFactory:NLOProcesses 1 # Set the merging scale deviding the parton shower # from the matrix element region in phase space. set Merger:MergingScale 20.*GeV set Merger:MergingScaleSmearing 0.1 # The following lines control a preweighter, # that can be used to force more events in higher # HT or pt regions. The unweighted events are accepted # with a enhanced probability W, that is divided fron the # event weight once the event is accepted. # W = ((HT/scale)^HTPower + (pt_max/scale)^MaxPTPower) # with scale = MZ (can be changed) # Note that the weights will therefore differ from "1" # if the powers are not zero. set MPreWeight:HTPower 0 set MPreWeight:MaxPTPower 0 set MPreWeight:OnlyColoured No # The next line can switch of hadronization # and MPI modelling. Use with care!! # read Matchbox/PQCDLevel.in ## Special settings required for on-shell production of unstable particles ## enable for on-shell top production # read Matchbox/OnShellTopProduction.in ## enable for on-shell W, Z or h production # read Matchbox/OnShellWProduction.in # read Matchbox/OnShellZProduction.in # read Matchbox/OnShellHProduction.in # Special settings for the VBF approximation # read Matchbox/VBFDiagramsOnly.in ################################################## ## Matrix element library selection ################################################## ## Select a generic tree/loop combination or a ## specialized NLO package # read Matchbox/MadGraph-GoSam.in # read Matchbox/MadGraph-MadGraph.in # read Matchbox/MadGraph-NJet.in read Matchbox/MadGraph-OpenLoops.in # read Matchbox/HJets.in # read Matchbox/VBFNLO.in ## Uncomment this to use ggh effective couplings ## currently only supported by MadGraph-GoSam ## and MadGraph-OpenLoops # read Matchbox/HiggsEffective.in ################################################## ## Cut selection ## See the documentation for more options ################################################## cd /Herwig/Cuts/ set ChargedLeptonPairMassCut:MinMass 60*GeV set ChargedLeptonPairMassCut:MaxMass 120*GeV cd /Herwig/MatrixElements/Matchbox/Utility insert DiagramGenerator:ExcludeInternal 0 /Herwig/Particles/gamma ## cuts on additional jets cd /Herwig/Cuts/ read Matchbox/DefaultPPJets.in insert JetCuts:JetRegions 0 FirstJet # insert JetCuts:JetRegions 1 SecondJet # insert JetCuts:JetRegions 2 ThirdJet # insert JetCuts:JetRegions 3 FourthJet ################################################## ## Scale choice ## See the documentation for more options ################################################## cd /Herwig/MatrixElements/Matchbox/Scales/ set /Herwig/Merging/MergingFactory:ScaleChoice MaxJetPtScale ################################################## ## Scale uncertainties ################################################## # read Matchbox/MuDown.in # read Matchbox/MuUp.in ################################################## ## Shower scale uncertainties ################################################## # read Matchbox/MuQDown.in # read Matchbox/MuQUp.in ################################################## ## CMW - Scheme ################################################## -read snippets/Dipole_AutoTune_prel.in +read snippets/Dipole_AutoTunes_gss.in ### Use factor in alpha_s argument: alpha_s(q) -> alpha_s(fac*q) ### with fac=exp(-(67-3pi^2-10/3*Nf)/(33-2Nf)) read Merging/FactorCMWScheme.in ### Linear CMW multiplication: ### alpha_s(q) -> alpha_s(q)(1+K_g*alpha_s(q)/2pi ) # read Merging/LinearCMWScheme.in ################################################## ## PDF choice ################################################## read Matchbox/FiveFlavourNoBMassScheme.in read Matchbox/CT14.in # read Matchbox/MMHT2014.in ################################################## ## Analyses ################################################## cd /Herwig/Analysis ## Write HepMC events. Modify the PrintEvent interface for your needs. # insert /Herwig/Generators/EventGenerator:AnalysisHandlers 0 HepMCFile ## Setup the Rivet analysis: #read snippets/Rivet.in #insert Rivet:Analyses 0 XXX_2017_ABC123 ## Here we collected a various Rivet analysis for Jets at LHC ## at the 7 TeV. (The collection might not be complete.) # read Merging/LHC7-J-Analysis.in ################################################## ## Save the generator ################################################## do /Herwig/Merging/MergingFactory:ProductionMode set /Herwig/Generators/EventGenerator:IntermediateOutput Yes cd /Herwig/Generators saverun LHC-J-Merging EventGenerator diff --git a/src/Merging/LHC-T-Merging.in b/src/Merging/LHC-T-Merging.in --- a/src/Merging/LHC-T-Merging.in +++ b/src/Merging/LHC-T-Merging.in @@ -1,194 +1,194 @@ # -*- ThePEG-repository -*- ################################################## ## Herwig/Merging example input file ################################################## ################################################## ## Collider type ################################################## read snippets/DipoleMerging.in read snippets/PPCollider.in read snippets/MonacoSampler.in ################################################## ## Beam energy sqrt(s) ################################################## cd /Herwig/EventHandlers set EventHandler:LuminosityFunction:Energy 7000*GeV ################################################## ## Process selection ################################################## ## Note that event generation may fail if no matching matrix element has ## been found. Coupling orders are with respect to the Born process, ## i.e. NLO QCD does not require an additional power of alphas. ## Model assumptions read Matchbox/StandardModelLike.in read Matchbox/DiagonalCKM.in ## Set the order of the couplings cd /Herwig/Merging set MergingFactory:OrderInAlphaS 2 set MergingFactory:OrderInAlphaEW 0 ## Select the process ## You may use identifiers such as p, pbar, j, l, mu+, h0 etc. do MergingFactory:Process p p -> t tbar [ j] set MergingFactory:NLOProcesses 1 # Set the merging scale deviding the parton shower # from the matrix element region in phase space. set Merger:MergingScale 20.*GeV set Merger:MergingScaleSmearing 0.1 # The following lines control a preweighter, # that can be used to force more events in higher # HT or pt regions. The unweighted events are accepted # with a enhanced probability W, that is divided fron the # event weight once the event is accepted. # W = ((HT/scale)^HTPower + (pt_max/scale)^MaxPTPower) # with scale = MZ (can be changed) # Note that the weights will therefore differ from "1" # if the powers are not zero. set MPreWeight:HTPower 0 set MPreWeight:MaxPTPower 0 set MPreWeight:OnlyColoured No # The next line can switch of hadronization # and MPI modelling. Use with care!! # read Matchbox/PQCDLevel.in ## Special settings required for on-shell production of unstable particles ## enable for on-shell top production read Matchbox/OnShellTopProduction.in ## enable for on-shell W, Z or h production # read Matchbox/OnShellWProduction.in # read Matchbox/OnShellZProduction.in # read Matchbox/OnShellHProduction.in # Special settings for the VBF approximation # read Matchbox/VBFDiagramsOnly.in ################################################## ## Matrix element library selection ################################################## ## Select a generic tree/loop combination or a ## specialized NLO package # read Matchbox/MadGraph-GoSam.in # read Matchbox/MadGraph-MadGraph.in # read Matchbox/MadGraph-NJet.in read Matchbox/MadGraph-OpenLoops.in # read Matchbox/HJets.in # read Matchbox/VBFNLO.in ## Uncomment this to use ggh effective couplings ## currently only supported by MadGraph-GoSam and ## MadGraph-Openloops # read Matchbox/HiggsEffective.in ################################################## ## Cut selection ## See the documentation for more options ################################################## cd /Herwig/Cuts/ set ChargedLeptonPairMassCut:MinMass 60*GeV set ChargedLeptonPairMassCut:MaxMass 120*GeV cd /Herwig/MatrixElements/Matchbox/Utility insert DiagramGenerator:ExcludeInternal 0 /Herwig/Particles/gamma ## cuts on additional jets cd /Herwig/Cuts/ # read Matchbox/DefaultPPJets.in # insert JetCuts:JetRegions 0 FirstJet # insert JetCuts:JetRegions 1 SecondJet # insert JetCuts:JetRegions 2 ThirdJet # insert JetCuts:JetRegions 3 FourthJet ################################################## ## Scale choice ## See the documentation for more options ################################################## cd /Herwig/MatrixElements/Matchbox/Scales/ set /Herwig/Merging/MergingFactory:ScaleChoice TopPairMassScale ################################################## ## Scale uncertainties ################################################## # read Matchbox/MuDown.in # read Matchbox/MuUp.in ################################################## ## Shower scale uncertainties ################################################## # read Matchbox/MuQDown.in # read Matchbox/MuQUp.in ################################################## ## CMW - Scheme ################################################## -read snippets/Dipole_AutoTune_prel.in +read snippets/Dipole_AutoTunes_gss.in ### Use factor in alpha_s argument: alpha_s(q) -> alpha_s(fac*q) ### with fac=exp(-(67-3pi^2-10/3*Nf)/(33-2Nf)) read Merging/FactorCMWScheme.in ### Linear CMW multiplication: ### alpha_s(q) -> alpha_s(q)(1+K_g*alpha_s(q)/2pi ) # read Merging/LinearCMWScheme.in ################################################## ## PDF choice ################################################## read Matchbox/FiveFlavourNoBMassScheme.in read Matchbox/CT14.in # read Matchbox/MMHT2014.in ################################################## ## Analyses ################################################## cd /Herwig/Analysis ## Write HepMC events. Modify the PrintEvent interface for your needs. # insert /Herwig/Generators/EventGenerator:AnalysisHandlers 0 HepMCFile ## Setup the Rivet analysis: #read snippets/Rivet.in #insert Rivet:Analyses 0 XXX_2017_ABC123 ## Here we collected a various Rivet analysis for Tops at LHC ## at the 7 TeV. (The collection might not be complete.) # read Merging/LHC7-T-Analysis.in ################################################## ## Save the generator ################################################## do /Herwig/Merging/MergingFactory:ProductionMode set /Herwig/Generators/EventGenerator:IntermediateOutput Yes cd /Herwig/Generators saverun LHC-T-Merging EventGenerator diff --git a/src/Merging/LHC-W-Merging.in b/src/Merging/LHC-W-Merging.in --- a/src/Merging/LHC-W-Merging.in +++ b/src/Merging/LHC-W-Merging.in @@ -1,195 +1,195 @@ # -*- ThePEG-repository -*- ################################################## ## Herwig/Merging example input file ################################################## ################################################## ## Collider type ################################################## read snippets/DipoleMerging.in read snippets/PPCollider.in read snippets/MonacoSampler.in ################################################## ## Beam energy sqrt(s) ################################################## cd /Herwig/EventHandlers set EventHandler:LuminosityFunction:Energy 7000*GeV ################################################## ## Process selection ################################################## ## Note that event generation may fail if no matching matrix element has ## been found. Coupling orders are with respect to the Born process, ## i.e. NLO QCD does not require an additional power of alphas. ## Model assumptions read Matchbox/StandardModelLike.in read Matchbox/DiagonalCKM.in ## Set the order of the couplings cd /Herwig/Merging set MergingFactory:OrderInAlphaS 0 set MergingFactory:OrderInAlphaEW 2 ## Select the process ## You may use identifiers such as p, pbar, j, l, mu+, h0 etc. do MergingFactory:Process p p -> l nu [ j j ] set MergingFactory:NLOProcesses 2 # Set the merging scale deviding the parton shower # from the matrix element region in phase space. set Merger:MergingScale 15.*GeV set Merger:MergingScaleSmearing 0.1 # The following lines control a preweighter, # that can be used to force more events in higher # HT or pt regions. The unweighted events are accepted # with a enhanced probability W, that is divided fron the # event weight once the event is accepted. # W = ((HT/scale)^HTPower + (pt_max/scale)^MaxPTPower) # with scale = MZ (can be changed) # Note that the weights will therefore differ from "1" # if the powers are not zero. set MPreWeight:HTPower 0 set MPreWeight:MaxPTPower 0 set MPreWeight:OnlyColoured No # The next line can switch of hadronization # and MPI modelling. Use with care!! # read Matchbox/PQCDLevel.in ## Special settings required for on-shell production of unstable particles ## enable for on-shell top production # read Matchbox/OnShellTopProduction.in ## enable for on-shell W, Z or h production # read Matchbox/OnShellWProduction.in # read Matchbox/OnShellZProduction.in # read Matchbox/OnShellHProduction.in # Special settings for the VBF approximation # read Matchbox/VBFDiagramsOnly.in ################################################## ## Matrix element library selection ################################################## ## Select a generic tree/loop combination or a ## specialized NLO package # read Matchbox/MadGraph-GoSam.in # read Matchbox/MadGraph-MadGraph.in # read Matchbox/MadGraph-NJet.in # read Matchbox/MadGraph-OpenLoops.in # read Matchbox/HJets.in # read Matchbox/VBFNLO.in ## Uncomment this to use ggh effective couplings ## currently only supported by MadGraph-GoSam and ## MadGraph-Openloops # read Matchbox/HiggsEffective.in ################################################## ## Cut selection ## See the documentation for more options ################################################## cd /Herwig/Cuts/ set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV set /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV cd /Herwig/MatrixElements/Matchbox/Utility insert DiagramGenerator:ExcludeInternal 0 /Herwig/Particles/gamma ## cuts on additional jets cd /Herwig/Cuts/ # read Matchbox/DefaultPPJets.in # insert JetCuts:JetRegions 0 FirstJet # insert JetCuts:JetRegions 1 SecondJet # insert JetCuts:JetRegions 2 ThirdJet # insert JetCuts:JetRegions 3 FourthJet ################################################## ## Scale choice ## See the documentation for more options ################################################## cd /Herwig/MatrixElements/Matchbox/Scales/ set /Herwig/Merging/MergingFactory:ScaleChoice LeptonPairMassScale ################################################## ## Scale uncertainties ################################################## # read Matchbox/MuDown.in # read Matchbox/MuUp.in ################################################## ## Shower scale uncertainties ################################################## # read Matchbox/MuQDown.in # read Matchbox/MuQUp.in ################################################## ## CMW - Scheme ################################################## -read snippets/Dipole_AutoTune_prel.in +read snippets/Dipole_AutoTunes_gss.in ### Use factor in alpha_s argument: alpha_s(q) -> alpha_s(fac*q) ### with fac=exp(-(67-3pi^2-10/3*Nf)/(33-2Nf)) read Merging/FactorCMWScheme.in ### Linear CMW multiplication: ### alpha_s(q) -> alpha_s(q)(1+K_g*alpha_s(q)/2pi ) # read Merging/LinearCMWScheme.in ################################################## ## PDF choice ################################################## read Matchbox/FiveFlavourNoBMassScheme.in read Matchbox/CT14.in # read Matchbox/MMHT2014.in ################################################## ## Analyses ################################################## cd /Herwig/Analysis ## Write HepMC events. Modify the PrintEvent interface for your needs. # insert /Herwig/Generators/EventGenerator:AnalysisHandlers 0 HepMCFile ## Setup the Rivet analysis: #read snippets/Rivet.in #insert Rivet:Analyses 0 XXX_2017_ABC123 ## Here we collected a various Rivet analysis for Ws at LHC ## at the 7 TeV. (The collection might not be complete.) # read Merging/LHC7-W-Analysis.in ################################################## ## Save the generator ################################################## do /Herwig/Merging/MergingFactory:ProductionMode set /Herwig/Generators/EventGenerator:IntermediateOutput Yes cd /Herwig/Generators saverun LHC-W-Merging EventGenerator diff --git a/src/Merging/LHC-Z-Merging.in b/src/Merging/LHC-Z-Merging.in --- a/src/Merging/LHC-Z-Merging.in +++ b/src/Merging/LHC-Z-Merging.in @@ -1,195 +1,195 @@ # -*- ThePEG-repository -*- ################################################## ## Herwig/Merging example input file ################################################## ################################################## ## Collider type ################################################## read snippets/DipoleMerging.in read snippets/PPCollider.in read snippets/MonacoSampler.in ################################################## ## Beam energy sqrt(s) ################################################## cd /Herwig/EventHandlers set EventHandler:LuminosityFunction:Energy 7000*GeV ################################################## ## Process selection ################################################## ## Note that event generation may fail if no matching matrix element has ## been found. Coupling orders are with respect to the Born process, ## i.e. NLO QCD does not require an additional power of alphas. ## Model assumptions read Matchbox/StandardModelLike.in read Matchbox/DiagonalCKM.in ## Set the order of the couplings cd /Herwig/Merging set MergingFactory:OrderInAlphaS 0 set MergingFactory:OrderInAlphaEW 2 ## Select the process ## You may use identifiers such as p, pbar, j, l, mu+, h0 etc. do MergingFactory:Process p p -> e+ e- [ j j ] set MergingFactory:NLOProcesses 2 # Set the merging scale deviding the parton shower # from the matrix element region in phase space. set Merger:MergingScale 15.*GeV set Merger:MergingScaleSmearing 0.1 # The following lines control a preweighter, # that can be used to force more events in higher # HT or pt regions. The unweighted events are accepted # with a enhanced probability W, that is divided fron the # event weight once the event is accepted. # W = ((HT/scale)^HTPower + (pt_max/scale)^MaxPTPower) # with scale = MZ (can be changed) # Note that the weights will therefore differ from "1" # if the powers are not zero. set MPreWeight:HTPower 0 set MPreWeight:MaxPTPower 0 set MPreWeight:OnlyColoured No # The next line can switch of hadronization # and MPI modelling. Use with care!! # read Matchbox/PQCDLevel.in ## Special settings required for on-shell production of unstable particles ## enable for on-shell top production # read Matchbox/OnShellTopProduction.in ## enable for on-shell W, Z or h production # read Matchbox/OnShellWProduction.in # read Matchbox/OnShellZProduction.in # read Matchbox/OnShellHProduction.in # Special settings for the VBF approximation # read Matchbox/VBFDiagramsOnly.in ################################################## ## Matrix element library selection ################################################## ## Select a generic tree/loop combination or a ## specialized NLO package # read Matchbox/MadGraph-GoSam.in # read Matchbox/MadGraph-MadGraph.in # read Matchbox/MadGraph-NJet.in # read Matchbox/MadGraph-OpenLoops.in # read Matchbox/HJets.in # read Matchbox/VBFNLO.in ## Uncomment this to use ggh effective couplings ## currently only supported by MadGraph-GoSam and ## MadGraph-Openloops # read Matchbox/HiggsEffective.in ################################################## ## Cut selection ## See the documentation for more options ################################################## cd /Herwig/Cuts/ set ChargedLeptonPairMassCut:MinMass 60*GeV set ChargedLeptonPairMassCut:MaxMass 120*GeV cd /Herwig/MatrixElements/Matchbox/Utility insert DiagramGenerator:ExcludeInternal 0 /Herwig/Particles/gamma ## cuts on additional jets cd /Herwig/Cuts/ # read Matchbox/DefaultPPJets.in # insert JetCuts:JetRegions 0 FirstJet # insert JetCuts:JetRegions 1 SecondJet # insert JetCuts:JetRegions 2 ThirdJet # insert JetCuts:JetRegions 3 FourthJet ################################################## ## Scale choice ## See the documentation for more options ################################################## cd /Herwig/MatrixElements/Matchbox/Scales/ set /Herwig/Merging/MergingFactory:ScaleChoice LeptonPairMassScale ################################################## ## Scale uncertainties ################################################## # read Matchbox/MuDown.in # read Matchbox/MuUp.in ################################################## ## Shower scale uncertainties ################################################## # read Matchbox/MuQDown.in # read Matchbox/MuQUp.in ################################################## ## CMW - Scheme ################################################## -read snippets/Dipole_AutoTune_prel.in +read snippets/Dipole_AutoTunes_gss.in ### Use factor in alpha_s argument: alpha_s(q) -> alpha_s(fac*q) ### with fac=exp(-(67-3pi^2-10/3*Nf)/(33-2Nf)) read Merging/FactorCMWScheme.in ### Linear CMW multiplication: ### alpha_s(q) -> alpha_s(q)(1+K_g*alpha_s(q)/2pi ) # read Merging/LinearCMWScheme.in ################################################## ## PDF choice ################################################## read Matchbox/FiveFlavourNoBMassScheme.in read Matchbox/CT14.in #read Matchbox/MMHT2014.in ################################################## ## Analyses ################################################## cd /Herwig/Analysis ## Write HepMC events. Modify the PrintEvent interface for your needs. # insert /Herwig/Generators/EventGenerator:AnalysisHandlers 0 HepMCFile ## Setup the Rivet analysis: #read snippets/Rivet.in #insert Rivet:Analyses 0 XXX_2017_ABC123 ## Here we collected a various Rivet analysis for Zs at LHC ## at the 8 TeV. (The collection might not be complete.) # read Merging/LHC7-Z-Analysis.in ################################################## ## Save the generator ################################################## do /Herwig/Merging/MergingFactory:ProductionMode set /Herwig/Generators/EventGenerator:IntermediateOutput Yes cd /Herwig/Generators saverun LHC-Z-Merging EventGenerator diff --git a/src/Merging/Makefile.am b/src/Merging/Makefile.am --- a/src/Merging/Makefile.am +++ b/src/Merging/Makefile.am @@ -1,34 +1,33 @@ BUILT_SOURCES = done-all-links Matchboxdir = ${pkgdatadir}/Merging INPUTFILES = \ \ LEP91-Analysis.in \ LHC7-Z-Analysis.in \ LHC7-W-Analysis.in \ LHC7-J-Analysis.in \ LHC7-T-Analysis.in \ LHC8-H-Analysis.in \ \ FactorCMWScheme.in \ LinearCMWScheme.in \ -Merging-Dipole-FactorCMWSchemeTune.in \ \ LEP-Merging.in \ LHC-W-Merging.in \ LHC-Z-Merging.in \ LHC-H-Merging.in \ LHC-T-Merging.in \ LHC-J-Merging.in dist_Matchbox_DATA = $(INPUTFILES) CLEANFILES = done-all-links done-all-links: $(INPUTFILES) @echo "Linking input files" @for i in $(INPUTFILES); do \ if test -f $(srcdir)/$$i -a ! -e $$i; then \ $(LN_S) -f $(srcdir)/$$i; fi; done @touch done-all-links diff --git a/src/Merging/Merging-Dipole-FactorCMWSchemeTune.in b/src/Merging/Merging-Dipole-FactorCMWSchemeTune.in deleted file mode 100644 --- a/src/Merging/Merging-Dipole-FactorCMWSchemeTune.in +++ /dev/null @@ -1,73 +0,0 @@ -# -*- ThePEG-repository -*- - -################################################## -## CMW Scheme with alpha_S=0.118 -################################################## - -read Merging/FactorCMWScheme.in - - -################################################## -## intrinsic pt -################################################## -set /Herwig/DipoleShower/IntrinsicPtGenerator:ValenceIntrinsicPtScale 1.67 -set /Herwig/DipoleShower/IntrinsicPtGenerator:SeaIntrinsicPtScale 1.67 - -################################################## -## (two-loop) alpha_s -################################################## -set /Herwig/DipoleShower/NLOAlphaS:input_alpha_s 0.118 -set /Herwig/DipoleShower/NLOAlphaS:input_scale 91.18*GeV -set /Herwig/Couplings/NLOAlphaS:input_alpha_s 0.118 -set /Herwig/Couplings/NLOAlphaS:input_scale 91.18*GeV - - -################################################## -## cutoffs -################################################## -set /Herwig/DipoleShower/Kinematics/FFMassiveKinematics:IRCutoff 0.604 -set /Herwig/DipoleShower/Kinematics/FFLightKinematics:IRCutoff 0.604 -set /Herwig/DipoleShower/Kinematics/FIMassiveKinematics:IRCutoff 0.604 -set /Herwig/DipoleShower/Kinematics/FILightKinematics:IRCutoff 0.604 -set /Herwig/DipoleShower/Kinematics/IFMassiveKinematics:IRCutoff 0.604 -set /Herwig/DipoleShower/Kinematics/IFLightKinematics:IRCutoff 0.604 -set /Herwig/DipoleShower/Kinematics/IILightKinematics:IRCutoff 0.604 - -################################################## -## hadronization parameters -################################################## - -set /Herwig/Particles/g:ConstituentMass 0.80 -set /Herwig/Hadronization/ClusterDecayer:ClSmrBottom 0.1 -set /Herwig/Hadronization/ClusterDecayer:ClSmrLight 0.26 -set /Herwig/Hadronization/ClusterDecayer:ClSmrCharm 0.16 - -set /Herwig/Hadronization/ClusterFissioner:ClPowBottom 0.7 -set /Herwig/Hadronization/ClusterFissioner:ClPowLight 0.9 -set /Herwig/Hadronization/ClusterFissioner:ClPowCharm 0.7 - -set /Herwig/Hadronization/ClusterFissioner:ClMaxBottom 5.8 -set /Herwig/Hadronization/ClusterFissioner:ClMaxCharm 2.9 -set /Herwig/Hadronization/ClusterFissioner:ClMaxLight 2.7 - -set /Herwig/Hadronization/ClusterFissioner:PSplitLight 1.0 -set /Herwig/Hadronization/ClusterFissioner:PSplitCharm 1.1 -set /Herwig/Hadronization/ClusterFissioner:PSplitBottom 0.9 - -set /Herwig/Hadronization/HadronSelector:SingleHadronLimitBottom 0.13 -set /Herwig/Hadronization/HadronSelector:SingleHadronLimitCharm 0.0 - -set /Herwig/Hadronization/HadronSelector:PwtUquark 0.65 -set /Herwig/Hadronization/HadronSelector:PwtDquark 0.65 -set /Herwig/Hadronization/HadronSelector:PwtSquark 0.74 -set /Herwig/Hadronization/HadronSelector:PwtCquark 0.30 -set /Herwig/Hadronization/HadronSelector:PwtBquark 0.40 -set /Herwig/Hadronization/HadronSelector:PwtDIquark 0.24 -set /Herwig/Hadronization/HadronSelector:SngWt 0.59 -set /Herwig/Hadronization/HadronSelector:DecWt 0.50 - -set /Herwig/Particles/b:NominalMass 5.3 -set /Herwig/Particles/b:ConstituentMass 4.8 - - -cd / diff --git a/src/defaults/Hadronization.in b/src/defaults/Hadronization.in --- a/src/defaults/Hadronization.in +++ b/src/defaults/Hadronization.in @@ -1,98 +1,98 @@ # -*- ThePEG-repository -*- ############################################################ # Setup of default hadronization # # There are no user servicable parts inside. # # Anything that follows below should only be touched if you # know what you're doing. ############################################################# cd /Herwig/Particles create ThePEG::ParticleData Cluster setup Cluster 81 Cluster 0.00990 0.0 0.0 0.0 0 0 0 1 create ThePEG::ParticleData Remnant setup Remnant 82 Remnant 0.00990 0.0 0.0 0.0 0 0 0 1 mkdir /Herwig/Hadronization cd /Herwig/Hadronization create Herwig::ClusterHadronizationHandler ClusterHadHandler create Herwig::PartonSplitter PartonSplitter create Herwig::ClusterFinder ClusterFinder create Herwig::ColourReconnector ColourReconnector create Herwig::ClusterFissioner ClusterFissioner create Herwig::LightClusterDecayer LightClusterDecayer create Herwig::ClusterDecayer ClusterDecayer create Herwig::HwppSelector HadronSelector newdef ClusterHadHandler:PartonSplitter PartonSplitter newdef ClusterHadHandler:ClusterFinder ClusterFinder newdef ClusterHadHandler:ColourReconnector ColourReconnector newdef ClusterHadHandler:ClusterFissioner ClusterFissioner newdef ClusterHadHandler:LightClusterDecayer LightClusterDecayer newdef ClusterHadHandler:ClusterDecayer ClusterDecayer newdef ClusterHadHandler:MinVirtuality2 0.1*GeV2 newdef ClusterHadHandler:MaxDisplacement 1.0e-10*millimeter newdef ClusterHadHandler:UnderlyingEventHandler NULL newdef ClusterFissioner:HadronSelector HadronSelector newdef LightClusterDecayer:HadronSelector HadronSelector newdef ClusterDecayer:HadronSelector HadronSelector newdef ColourReconnector:ColourReconnection Yes -newdef ColourReconnector:ReconnectionProbabilityBaryonic 0.57 -newdef ColourReconnector:ReconnectionProbability 0.89 +newdef ColourReconnector:ReconnectionProbabilityBaryonic 0.7 +newdef ColourReconnector:ReconnectionProbability 0.95 newdef ColourReconnector:Algorithm Baryonic newdef ColourReconnector:OctetTreatment All # Clustering parameters for light quarks newdef ClusterFissioner:ClMaxLight 3.649 newdef ClusterFissioner:ClPowLight 2.780 newdef ClusterFissioner:PSplitLight 0.899 newdef ClusterDecayer:ClDirLight 1 newdef ClusterDecayer:ClSmrLight 0.78 # Clustering parameters for b-quarks newdef ClusterFissioner:ClMaxBottom 3.757 newdef ClusterFissioner:ClPowBottom 0.547 newdef ClusterFissioner:PSplitBottom 0.625 newdef ClusterDecayer:ClDirBottom 1 newdef ClusterDecayer:ClSmrBottom 0.078 newdef HadronSelector:SingleHadronLimitBottom 0.000 # Clustering parameters for c-quarks newdef ClusterFissioner:ClMaxCharm 3.950 newdef ClusterFissioner:ClPowCharm 2.559 newdef ClusterFissioner:PSplitCharm 0.994 newdef ClusterDecayer:ClDirCharm 1 newdef ClusterDecayer:ClSmrCharm 0.163 newdef HadronSelector:SingleHadronLimitCharm 0.000 # Clustering parameters for exotic quarks # (e.g. hadronizing Susy particles) newdef ClusterFissioner:ClMaxExotic 2.7*GeV newdef ClusterFissioner:ClPowExotic 1.46 newdef ClusterFissioner:PSplitExotic 1.00 newdef ClusterDecayer:ClDirExotic 1 newdef ClusterDecayer:ClSmrExotic 0. newdef HadronSelector:SingleHadronLimitExotic 0. # newdef PartonSplitter:SplitPwtSquark 0.824135 newdef PartonSplitter:Split uds # newdef HadronSelector:PwtDquark 1.0 newdef HadronSelector:PwtUquark 1.0 newdef HadronSelector:PwtSquark 0.291717 newdef HadronSelector:PwtCquark 0.0 newdef HadronSelector:PwtBquark 0.0 newdef HadronSelector:PwtDIquark 0.298 newdef HadronSelector:SngWt 0.74 newdef HadronSelector:DecWt 0.62 newdef HadronSelector:Mode 1 newdef HadronSelector:BelowThreshold All create Herwig::SpinHadronizer SpinHadronizer diff --git a/src/defaults/UnderlyingEvent.in b/src/defaults/UnderlyingEvent.in --- a/src/defaults/UnderlyingEvent.in +++ b/src/defaults/UnderlyingEvent.in @@ -1,88 +1,89 @@ # -*- ThePEG-repository -*- ################################################ # Set up the handler for the underlying event. ################################################ mkdir /Herwig/UnderlyingEvent cd /Herwig/UnderlyingEvent ######## cuts ################################################# library SimpleKTCut.so # cut on pt. Without a specific matcher object, it works on all # particles create ThePEG::SimpleKTCut KtCut newdef KtCut:MinKT 3.06 # create the cuts object for the Underlying Event create ThePEG::Cuts UECuts # This should always be 2*MinKT!! newdef UECuts:MHatMin 6.12 insert UECuts:OneCuts 0 KtCut ######## subprocess ########################################### create ThePEG::SubProcessHandler FastQCD create Herwig::MEQCD2to2Fast MEQCD2to2Fast HwMEHadronFast.so insert FastQCD:MatrixElements 0 MEQCD2to2Fast cp /Herwig/Partons/PPExtractor /Herwig/Partons/MPIExtractor newdef /Herwig/Partons/MPIExtractor:FlatSHatY 1 newdef FastQCD:PartonExtractor /Herwig/Partons/MPIExtractor # always use LO PDF for MPI and remnants newdef /Herwig/Partons/MPIExtractor:FirstPDF /Herwig/Partons/MPIPDF newdef /Herwig/Partons/MPIExtractor:SecondPDF /Herwig/Partons/MPIPDF ######## MPI Handler ########################################## library JetCuts.so library HwMPI.so create Herwig::MPIHandler MPIHandler # set the subprocesses and corresponding cuts insert MPIHandler:SubProcessHandlers 0 FastQCD insert MPIHandler:Cuts 0 UECuts # energy extrapolation for the MinKT cut -newdef MPIHandler:EnergyExtrapolation Power -newdef MPIHandler:Power 0.322 -newdef MPIHandler:pTmin0 2.55 +newdef MPIHandler:EnergyExtrapolation PowerModified +newdef MPIHandler:Power 0.31 +newdef MPIHandler:pTmin0 2.87 +newdef MPIHandler:Offset 622.203*GeV newdef MPIHandler:ReferenceScale 7000.*GeV newdef MPIHandler:EEparamA 0.585*GeV newdef MPIHandler:EEparamB 37.45*GeV # MultiPeriph model as default. newdef /Herwig/Partons/RemnantDecayer:MultiPeriph Yes # Paramters for the ladders for soft MPIs -newdef /Herwig/Partons/RemnantDecayer:ladderMult 0.466 -newdef /Herwig/Partons/RemnantDecayer:ladderbFactor 0.46 +newdef /Herwig/Partons/RemnantDecayer:ladderMult 0.6 +newdef /Herwig/Partons/RemnantDecayer:ladderbFactor 0.0 # Set gaussian width of longitudinal momentum fraction fluctuation newdef /Herwig/Partons/RemnantDecayer:gaussWidth 0.03 # Ratio of diffractive events in MinBias runs -newdef MPIHandler:DiffractiveRatio 0.133 +newdef MPIHandler:DiffractiveRatio 0.25 # The inverse hadron radius -newdef MPIHandler:InvRadius 1.58 +newdef MPIHandler:InvRadius 1.1 # Set the details of the soft model # Flag to decide whether additional soft interactions (i.e. pt < ptmin) # should be simulated at all newdef MPIHandler:softInt Yes # Flag to decide whether to use the 2 component model. In this model, # the hadron radius (or better: mean parton-parton separation) can be # different for hard and soft scatters. The radius for the soft scatters # is computed during the run startup so that the elastic t-slope, B_el, # coincides with current measurements (for CMenergy < 1.8 TeV) or # Donnachie-Landshoff pomeron fit (CMenergy > 1.8 TeV). If this model is # disabled one has to take care that this observable is correctly # described by adjusting InvRadius properly. newdef MPIHandler:twoComp Yes newdef MPIHandler:DLmode 2 diff --git a/src/snippets/Dipole_AutoTune_prel.in b/src/snippets/Dipole_AutoTune_prel.in deleted file mode 100644 --- a/src/snippets/Dipole_AutoTune_prel.in +++ /dev/null @@ -1,139 +0,0 @@ -# This is a preliminary Tune. -# With this version (7.1.3) various changes to the dipole shower are done. -# The dipole shower will be retuned for version 7.1.4. - -# Note: The gluon ConstituentMass is lower than the strange quark -# threshold assumed in the BaryonicReconnection. -# Using both snippets will produce no resonable results. - -set /Herwig/DipoleShower/NLOAlphaS:input_alpha_s 0.118 -set /Herwig/DipoleShower/NLOAlphaS:input_scale 91.18*GeV -set /Herwig/Couplings/NLOAlphaS:input_alpha_s 0.118 -set /Herwig/Couplings/NLOAlphaS:input_scale 91.18*GeV - -set /Herwig/DipoleShower/Kinematics/FFMassiveKinematics:IRCutoff 0.80399886545 -set /Herwig/DipoleShower/Kinematics/FFLightKinematics:IRCutoff 0.80399886545 -set /Herwig/DipoleShower/Kinematics/FIMassiveKinematics:IRCutoff 0.80399886545 -set /Herwig/DipoleShower/Kinematics/FILightKinematics:IRCutoff 0.80399886545 -set /Herwig/DipoleShower/Kinematics/IFMassiveKinematics:IRCutoff 0.80399886545 -set /Herwig/DipoleShower/Kinematics/IFLightKinematics:IRCutoff 0.80399886545 -set /Herwig/DipoleShower/Kinematics/IILightKinematics:IRCutoff 0.80399886545 - -set /Herwig/Particles/g:ConstituentMass 0.762996296601 - -set /Herwig/Hadronization/ClusterDecayer:ClSmrLight 0.342544255421 -set /Herwig/Hadronization/ClusterDecayer:ClSmrCharm 0.237545842862 -set /Herwig/Hadronization/ClusterDecayer:ClSmrBottom 0.0620545338048 - -set /Herwig/Hadronization/ClusterFissioner:ClPowLight 0.950949552153 -set /Herwig/Hadronization/ClusterFissioner:ClPowCharm 0.725163909065 -set /Herwig/Hadronization/ClusterFissioner:ClPowBottom 0.809774254452 - -set /Herwig/Hadronization/ClusterFissioner:ClMaxLight 2.80478186219 -set /Herwig/Hadronization/ClusterFissioner:ClMaxCharm 3.13483791689 -set /Herwig/Hadronization/ClusterFissioner:ClMaxBottom 5.79181302131 - -set /Herwig/Hadronization/ClusterFissioner:PSplitLight 0.995391682928 -set /Herwig/Hadronization/ClusterFissioner:PSplitCharm 0.769749617516 -set /Herwig/Hadronization/ClusterFissioner:PSplitBottom 0.479199412481 - -set /Herwig/Hadronization/HadronSelector:SingleHadronLimitCharm 0.0485533655422 -set /Herwig/Hadronization/HadronSelector:SingleHadronLimitBottom 0.0968582906399 - -set /Herwig/Hadronization/HadronSelector:PwtUquark 0.718641969264 -set /Herwig/Hadronization/HadronSelector:PwtDquark 0.674967529289 -set /Herwig/Hadronization/HadronSelector:PwtSquark 0.542042947191 -set /Herwig/Hadronization/HadronSelector:PwtCquark 0.251544496683 -set /Herwig/Hadronization/HadronSelector:PwtBquark 0.426714635544 -set /Herwig/Hadronization/HadronSelector:PwtDIquark 0.296781084091 -set /Herwig/Hadronization/HadronSelector:SngWt 0.541287379336 -set /Herwig/Hadronization/HadronSelector:DecWt 0.569933528697 - -set /Herwig/Particles/b:NominalMass 5.38329996032 -set /Herwig/Particles/b:ConstituentMass 4.84231667563 - -####### -# CMW scheme: -# Tune was done with CMW for all kernels, as merging currently only is consistent if applied to all. -####### - - -cd /Herwig/DipoleShower/Kernels -set FFgx2ggxDipoleKernel:CMWScheme Factor -set FFqx2qgxDipoleKernel:CMWScheme Factor -set FFgx2ddxDipoleKernel:CMWScheme Factor -set FFgx2uuxDipoleKernel:CMWScheme Factor -set FFgx2ccxDipoleKernel:CMWScheme Factor -set FFgx2ssxDipoleKernel:CMWScheme Factor -set FFgx2bbxDipoleKernel:CMWScheme Factor -set FFMgx2ggxDipoleKernel:CMWScheme Factor -set FFMdx2dgxDipoleKernel:CMWScheme Factor -set FFMux2ugxDipoleKernel:CMWScheme Factor -set FFMcx2cgxDipoleKernel:CMWScheme Factor -set FFMsx2sgxDipoleKernel:CMWScheme Factor -set FFMbx2bgxDipoleKernel:CMWScheme Factor -set FFMtx2tgxDipoleKernel:CMWScheme Factor -set FFMgx2ddxDipoleKernel:CMWScheme Factor -set FFMgx2uuxDipoleKernel:CMWScheme Factor -set FFMgx2ccxDipoleKernel:CMWScheme Factor -set FFMgx2ssxDipoleKernel:CMWScheme Factor -set FFMgx2bbxDipoleKernel:CMWScheme Factor -set FIgx2ggxDipoleKernel:CMWScheme Factor -set FIqx2qgxDipoleKernel:CMWScheme Factor -set FIgx2ddxDipoleKernel:CMWScheme Factor -set FIgx2uuxDipoleKernel:CMWScheme Factor -set FIgx2ccxDipoleKernel:CMWScheme Factor -set FIgx2ssxDipoleKernel:CMWScheme Factor -set FIgx2bbxDipoleKernel:CMWScheme Factor -set FIMdx2dgxDipoleKernel:CMWScheme Factor -set FIMux2ugxDipoleKernel:CMWScheme Factor -set FIMcx2cgxDipoleKernel:CMWScheme Factor -set FIMsx2sgxDipoleKernel:CMWScheme Factor -set FIMbx2bgxDipoleKernel:CMWScheme Factor -set FIMtx2tgxDipoleKernel:CMWScheme Factor -set FIMgx2ddxDipoleKernel:CMWScheme Factor -set FIMgx2uuxDipoleKernel:CMWScheme Factor -set FIMgx2ccxDipoleKernel:CMWScheme Factor -set FIMgx2ssxDipoleKernel:CMWScheme Factor -set FIMgx2bbxDipoleKernel:CMWScheme Factor -#set FIMgx2ttxDipoleKernel:CMWScheme Factor -set IFgx2ggxDipoleKernel:CMWScheme Factor -set IFqx2qgxDipoleKernel:CMWScheme Factor -set IFqx2gqxDipoleKernel:CMWScheme Factor -set IFgx2ddbarxDipoleKernel:CMWScheme Factor -set IFgx2dbardxDipoleKernel:CMWScheme Factor -set IFgx2uubarxDipoleKernel:CMWScheme Factor -set IFgx2ubaruxDipoleKernel:CMWScheme Factor -set IFgx2ccbarxDipoleKernel:CMWScheme Factor -set IFgx2cbarcxDipoleKernel:CMWScheme Factor -set IFgx2ssbarxDipoleKernel:CMWScheme Factor -set IFgx2sbarsxDipoleKernel:CMWScheme Factor -set IFMgx2ggxDipoleKernel:CMWScheme Factor -set IFMqx2qgxDipoleKernel:CMWScheme Factor -set IFMqx2gqxDipoleKernel:CMWScheme Factor -set IFMgx2ddbarxDipoleKernel:CMWScheme Factor -set IFMgx2dbardxDipoleKernel:CMWScheme Factor -set IFMgx2uubarxDipoleKernel:CMWScheme Factor -set IFMgx2ubaruxDipoleKernel:CMWScheme Factor -set IFMgx2ccbarxDipoleKernel:CMWScheme Factor -set IFMgx2cbarcxDipoleKernel:CMWScheme Factor -set IFMgx2ssbarxDipoleKernel:CMWScheme Factor -set IFMgx2sbarsxDipoleKernel:CMWScheme Factor -set IIgx2ggxDipoleKernel:CMWScheme Factor -set IIqx2qgxDipoleKernel:CMWScheme Factor -set IIqx2gqxDipoleKernel:CMWScheme Factor -set IIgx2ddbarxDipoleKernel:CMWScheme Factor -set IIgx2dbardxDipoleKernel:CMWScheme Factor -set IIgx2uubarxDipoleKernel:CMWScheme Factor -set IIgx2ubaruxDipoleKernel:CMWScheme Factor -set IIgx2ccbarxDipoleKernel:CMWScheme Factor -set IIgx2cbarcxDipoleKernel:CMWScheme Factor -set IIgx2ssbarxDipoleKernel:CMWScheme Factor -set IIgx2sbarsxDipoleKernel:CMWScheme Factor -set IFgx2bbbarxDipoleKernel:CMWScheme Factor -set IFgx2bbarbxDipoleKernel:CMWScheme Factor -set IFMgx2bbbarxDipoleKernel:CMWScheme Factor -set IFMgx2bbarbxDipoleKernel:CMWScheme Factor -set IIgx2bbbarxDipoleKernel:CMWScheme Factor -set IIgx2bbarbxDipoleKernel:CMWScheme Factor - diff --git a/src/snippets/Dipole_AutoTunes_gss.in b/src/snippets/Dipole_AutoTunes_gss.in new file mode 100644 --- /dev/null +++ b/src/snippets/Dipole_AutoTunes_gss.in @@ -0,0 +1,119 @@ +set /Herwig/Shower/AlphaQCD:AlphaIn 0.118 +set /Herwig/Couplings/NLOAlphaS:input_alpha_s 0.118 +set /Herwig/DipoleShower/NLOAlphaS:input_alpha_s 0.118 +cd /Herwig/Particles/ +set g:ConstituentMass 0.95 +set b:NominalMass 4.700501 +set b:ConstituentMass 4.084889 +cd /Herwig/Hadronization/ +set ClusterDecayer:ClSmrBottom 0.085964 +set ClusterDecayer:ClSmrLight 0.698877 +set ClusterDecayer:ClSmrCharm 0.246296 +set ClusterFissioner:ClPowBottom 0.591646 +set ClusterFissioner:ClPowLight 0.99945 +set ClusterFissioner:ClPowCharm 3.386187 +set ClusterFissioner:ClMaxBottom 3.771649 +set ClusterFissioner:ClMaxCharm 4.780456 +set ClusterFissioner:ClMaxLight 3.055256 +set ClusterFissioner:PSplitLight 0.7779 +set ClusterFissioner:PSplitCharm 0.628766 +set ClusterFissioner:PSplitBottom 0.662911 +set HadronSelector:SingleHadronLimitBottom 0.000446 +set HadronSelector:SingleHadronLimitCharm 0.000508 +set HadronSelector:SngWt 0.927141 +set HadronSelector:DecWt 0.630787 + +set /Herwig/DipoleShower/Kinematics/FFMassiveKinematics:IRCutoff 1.000896 +set /Herwig/DipoleShower/Kinematics/FFLightKinematics:IRCutoff 1.000896 +set /Herwig/DipoleShower/Kinematics/FIMassiveKinematics:IRCutoff 1.000896 +set /Herwig/DipoleShower/Kinematics/FILightKinematics:IRCutoff 1.000896 +set /Herwig/DipoleShower/Kinematics/IFMassiveKinematics:IRCutoff 1.000896 +set /Herwig/DipoleShower/Kinematics/IFLightKinematics:IRCutoff 1.000896 +set /Herwig/DipoleShower/Kinematics/IILightKinematics:IRCutoff 1.000896 + + +####### +# CMW scheme: +# Tune was done with CMW for all kernels, as merging currently only is consistent if applied to all. +####### + +cd /Herwig/DipoleShower/Kernels +set FFgx2ggxDipoleKernel:CMWScheme Factor +set FFqx2qgxDipoleKernel:CMWScheme Factor +set FFgx2ddxDipoleKernel:CMWScheme Factor +set FFgx2uuxDipoleKernel:CMWScheme Factor +set FFgx2ccxDipoleKernel:CMWScheme Factor +set FFgx2ssxDipoleKernel:CMWScheme Factor +set FFgx2bbxDipoleKernel:CMWScheme Factor +set FFMgx2ggxDipoleKernel:CMWScheme Factor +set FFMdx2dgxDipoleKernel:CMWScheme Factor +set FFMux2ugxDipoleKernel:CMWScheme Factor +set FFMcx2cgxDipoleKernel:CMWScheme Factor +set FFMsx2sgxDipoleKernel:CMWScheme Factor +set FFMbx2bgxDipoleKernel:CMWScheme Factor +set FFMtx2tgxDipoleKernel:CMWScheme Factor +set FFMgx2ddxDipoleKernel:CMWScheme Factor +set FFMgx2uuxDipoleKernel:CMWScheme Factor +set FFMgx2ccxDipoleKernel:CMWScheme Factor +set FFMgx2ssxDipoleKernel:CMWScheme Factor +set FFMgx2bbxDipoleKernel:CMWScheme Factor +set FIgx2ggxDipoleKernel:CMWScheme Factor +set FIqx2qgxDipoleKernel:CMWScheme Factor +set FIgx2ddxDipoleKernel:CMWScheme Factor +set FIgx2uuxDipoleKernel:CMWScheme Factor +set FIgx2ccxDipoleKernel:CMWScheme Factor +set FIgx2ssxDipoleKernel:CMWScheme Factor +set FIgx2bbxDipoleKernel:CMWScheme Factor +set FIMdx2dgxDipoleKernel:CMWScheme Factor +set FIMux2ugxDipoleKernel:CMWScheme Factor +set FIMcx2cgxDipoleKernel:CMWScheme Factor +set FIMsx2sgxDipoleKernel:CMWScheme Factor +set FIMbx2bgxDipoleKernel:CMWScheme Factor +set FIMtx2tgxDipoleKernel:CMWScheme Factor +set FIMgx2ddxDipoleKernel:CMWScheme Factor +set FIMgx2uuxDipoleKernel:CMWScheme Factor +set FIMgx2ccxDipoleKernel:CMWScheme Factor +set FIMgx2ssxDipoleKernel:CMWScheme Factor +set FIMgx2bbxDipoleKernel:CMWScheme Factor +#set FIMgx2ttxDipoleKernel:CMWScheme Factor +set IFgx2ggxDipoleKernel:CMWScheme Factor +set IFqx2qgxDipoleKernel:CMWScheme Factor +set IFqx2gqxDipoleKernel:CMWScheme Factor +set IFgx2ddbarxDipoleKernel:CMWScheme Factor +set IFgx2dbardxDipoleKernel:CMWScheme Factor +set IFgx2uubarxDipoleKernel:CMWScheme Factor +set IFgx2ubaruxDipoleKernel:CMWScheme Factor +set IFgx2ccbarxDipoleKernel:CMWScheme Factor +set IFgx2cbarcxDipoleKernel:CMWScheme Factor +set IFgx2ssbarxDipoleKernel:CMWScheme Factor +set IFgx2sbarsxDipoleKernel:CMWScheme Factor +set IFMgx2ggxDipoleKernel:CMWScheme Factor +set IFMqx2qgxDipoleKernel:CMWScheme Factor +set IFMqx2gqxDipoleKernel:CMWScheme Factor +set IFMgx2ddbarxDipoleKernel:CMWScheme Factor +set IFMgx2dbardxDipoleKernel:CMWScheme Factor +set IFMgx2uubarxDipoleKernel:CMWScheme Factor +set IFMgx2ubaruxDipoleKernel:CMWScheme Factor +set IFMgx2ccbarxDipoleKernel:CMWScheme Factor +set IFMgx2cbarcxDipoleKernel:CMWScheme Factor +set IFMgx2ssbarxDipoleKernel:CMWScheme Factor +set IFMgx2sbarsxDipoleKernel:CMWScheme Factor +set IIgx2ggxDipoleKernel:CMWScheme Factor +set IIqx2qgxDipoleKernel:CMWScheme Factor +set IIqx2gqxDipoleKernel:CMWScheme Factor +set IIgx2ddbarxDipoleKernel:CMWScheme Factor +set IIgx2dbardxDipoleKernel:CMWScheme Factor +set IIgx2uubarxDipoleKernel:CMWScheme Factor +set IIgx2ubaruxDipoleKernel:CMWScheme Factor +set IIgx2ccbarxDipoleKernel:CMWScheme Factor +set IIgx2cbarcxDipoleKernel:CMWScheme Factor +set IIgx2ssbarxDipoleKernel:CMWScheme Factor +set IIgx2sbarsxDipoleKernel:CMWScheme Factor +set IFgx2bbbarxDipoleKernel:CMWScheme Factor +set IFgx2bbarbxDipoleKernel:CMWScheme Factor +set IFMgx2bbbarxDipoleKernel:CMWScheme Factor +set IFMgx2bbarbxDipoleKernel:CMWScheme Factor +set IIgx2bbbarxDipoleKernel:CMWScheme Factor +set IIgx2bbarbxDipoleKernel:CMWScheme Factor + + diff --git a/src/snippets/Makefile.am b/src/snippets/Makefile.am --- a/src/snippets/Makefile.am +++ b/src/snippets/Makefile.am @@ -1,48 +1,48 @@ BUILT_SOURCES = done-all-links snippetsdir = ${pkgdatadir}/snippets INPUTFILES = \ CellGridSampler.in \ Diffraction.in \ DipoleMerging.in \ DipoleShowerFiveFlavours.in \ DipoleShowerFourFlavours.in \ EECollider.in \ EPCollider.in \ HepMCFixedOrder.in \ HepMC.in \ Matchbox.in \ MB-DipoleShower.in \ MB.in \ MonacoSampler.in \ Particles-SetLonglivedParticlesStable.in \ PDF-CT10.in \ PDF-NNPDF30NLO.in \ PPCollider.in \ RivetFixedOrder.in \ Rivet.in \ YFS.in \ CMWinQtiledShower.in \ -Dipole_AutoTune_prel.in \ +Dipole_AutoTunes_gss.in \ Tune-DotProduct.in \ Tune-DotProduct-Veto.in \ Tune-pT.in \ Tune-Q2.in \ EvolutionScheme-DotProduct.in \ EvolutionScheme-DotProduct-Veto.in \ EvolutionScheme-pT.in \ EvolutionScheme-Q2.in \ FixedTarget.in \ FixedTarget-PP.in dist_snippets_DATA = $(INPUTFILES) CLEANFILES = done-all-links done-all-links: $(INPUTFILES) @echo "Linking input files" @for i in $(INPUTFILES); do \ if test -f $(srcdir)/$$i -a ! -e $$i; then \ $(LN_S) -f $(srcdir)/$$i; fi; done @touch done-all-links