Page MenuHomeHEPForge

No OneTemporary

diff --git a/MatrixElement/Powheg/MEPP2VGammaPowheg.cc b/MatrixElement/Powheg/MEPP2VGammaPowheg.cc
--- a/MatrixElement/Powheg/MEPP2VGammaPowheg.cc
+++ b/MatrixElement/Powheg/MEPP2VGammaPowheg.cc
@@ -1,904 +1,2862 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MEPP2VGammaPowheg class.
//
-
+
#include "MEPP2VGammaPowheg.h"
#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Reference.h" // from VGammaHardGenerator
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
+#include "Herwig++/Shower/Base/Evolver.h" // Should have it? from VGammaHardGenerator
+#include "Herwig++/Shower/Base/KinematicsReconstructor.h" //?
+#include "Herwig++/Shower/Base/PartnerFinder.h" //?
+#include "ThePEG/PDT/StandardMatchers.h" //?
+#include "ThePEG/Repository/EventGenerator.h" //?
#include "ThePEG/Handlers/StandardXComb.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
+//#include "ThePEG/Utilities/SimplePhaseSpace.h" // Should we include it like in MEPP2VGammaNewPowheg?
+#include "ThePEG/Cuts/Cuts.h"
+#include "Herwig++/Utilities/GSLIntegrator.h"
#include "Herwig++/Models/StandardModel/StandardModel.h"
#include "Herwig++/Utilities/Maths.h"
#include <numeric>
using namespace Herwig;
using Herwig::Math::ReLi2;
+ //merge
MEPP2VGammaPowheg::MEPP2VGammaPowheg()
: _contrib(1), _scaleopt(0),
- _fixedScale(100.*GeV), _scaleFact(1.)
-{}
+ _fixedScale(100.*GeV), _scaleFact(1.),
+ //pTmin_(2.*GeV), qqgFactor_(1.), qgFactor_g(2.),
+ //qgFactor_p(0.1), gqbarFactor_g(2.), gqbarFactor_p(0.1), power_(2.), power_photon(2.5)
+ pTmin_(2.*GeV), qqgFactor_(800.), qgFactor_g(800.),
+ qgFactor_p(2.3), gqbarFactor_g(800.), gqbarFactor_p(2.3), power_(1.6), power_photon(2.4)
+{}
+ //merge
void MEPP2VGammaPowheg::doinit() {
+ // gluon ParticleData object
+ _gluon = getParticleData(ParticleID::g); // for HardestEmission ?
// colour factors
- CF_ = 4./3.;
- TR_ = 0.5;
+ // _CF = 4./3.;
+ // _TR = 0.5;
static const tcHwSMPtr hwsm
= dynamic_ptr_cast<tcHwSMPtr>(generator()->standardModel());
if (!hwsm) throw InitException() << "hwsm pointer is null in"
<< " MEPP2VGamma::doinit()"
- << Exception::abortnow;
+ << Exception::abortnow;
// get pointers to all required Vertex objects
FFZvertex_ = hwsm->vertexFFZ();
FFPvertex_ = hwsm->vertexFFP();
WWWvertex_ = hwsm->vertexWWW();
FFWvertex_ = hwsm->vertexFFW();
FFGvertex_ = hwsm->vertexFFG();
MEPP2VGamma::doinit();
}
-
-
+
+
IBPtr MEPP2VGammaPowheg::clone() const {
return new_ptr(*this);
-}
-
+ }
+
IBPtr MEPP2VGammaPowheg::fullclone() const {
return new_ptr(*this);
}
+//merge
void MEPP2VGammaPowheg::persistentOutput(PersistentOStream & os) const {
- os << _contrib << _scaleopt << ounit(_fixedScale,GeV) << _scaleFact
- << FFPvertex_ << FFWvertex_ << FFZvertex_ << WWWvertex_ << FFGvertex_
- << TR_ << CF_;
+ os << _contrib << _scaleopt << ounit(_fixedScale,GeV) << _scaleFact // ounit exists in both classes!
+ << alphaS_ << _gluon <<alphaQCD_<< ounit(pTmin_,GeV)<< fraccut
+ << FFPvertex_ << FFWvertex_ << FFZvertex_ << WWWvertex_ << FFGvertex_;
}
+//merge
void MEPP2VGammaPowheg::persistentInput(PersistentIStream & is, int) {
- is >> _contrib >> _scaleopt >> iunit(_fixedScale,GeV) >> _scaleFact
- >> FFPvertex_ >> FFWvertex_ >> FFZvertex_ >> WWWvertex_ >> FFGvertex_
- >> TR_ >> CF_;
+ is >> _contrib >> _scaleopt >> iunit(_fixedScale,GeV) >> _scaleFact // iunit exists in both classes!
+ >> alphaS_ >> _gluon >> alphaQCD_>> iunit(pTmin_,GeV) >>fraccut
+ >> FFPvertex_ >> FFWvertex_ >> FFZvertex_ >> WWWvertex_ >> FFGvertex_;
}
ClassDescription<MEPP2VGammaPowheg> MEPP2VGammaPowheg::initMEPP2VGammaPowheg;
// Definition of the static class description member.
+ //merge
void MEPP2VGammaPowheg::Init() {
static ClassDocumentation<MEPP2VGammaPowheg> documentation
("The MEPP2VGammaPowheg class implements the NLO matrix"
" elements for q qbar -> W/Z gamma in the POWHEG scheme.");
static Switch<MEPP2VGammaPowheg,unsigned int> interfaceContribution
("Contribution",
"Which contributions to the cross section to include",
&MEPP2VGammaPowheg::_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<MEPP2VGammaPowheg,unsigned int> interfaceFactorizationScaleOption
("FactorizationScaleOption",
"Option for the scale to be used",
&MEPP2VGammaPowheg::_scaleopt, 0, false, false);
static SwitchOption interfaceScaleOptionFixed
(interfaceFactorizationScaleOption,
"Fixed",
"Use a fixed scale",
0);
static SwitchOption interfaceScaleOptionsHat
(interfaceFactorizationScaleOption,
"Dynamic",
"Used sHat as the scale",
1);
static Parameter<MEPP2VGammaPowheg,Energy> interfaceFactorizationScaleValue
("FactorizationScaleValue",
"The fixed scale to use if required",
&MEPP2VGammaPowheg::_fixedScale, GeV, 100.0*GeV, 10.0*GeV, 1000.0*GeV,
false, false, Interface::limited);
static Parameter<MEPP2VGammaPowheg,double> interfaceScaleFactor
("ScaleFactor",
"The factor used before sHat if using a running scale",
&MEPP2VGammaPowheg::_scaleFact, 1.0, 0.0, 10.0,
false, false, Interface::limited);
+
+ static Parameter<MEPP2VGammaPowheg,double> interfaceAlphaQCD
+ ("AlphaQCD",
+ "The value of alphaS to use if using a fixed alphaS",
+ &MEPP2VGammaPowheg::alphaQCD_, 0.118, 0.0, 0.2,
+ false, false, Interface::limited);
+
+ static Reference<MEPP2VGammaPowheg,ShowerAlpha> interfaceShowerAlphaS
+ ("ShowerAlphaS",
+ "Reference to the object calculating the QCD coupling for the shower",
+ &MEPP2VGammaPowheg::alphaS_, false, false, true, false, false);
+
+ static Parameter<MEPP2VGammaPowheg,double> interfaceFraccut
+ ("Fraccut",
+ "The photon energy fraction cut in the photon cone",
+ &MEPP2VGammaPowheg::fraccut, 0.4, 0.0, 1.0,
+ false, false, Interface::limited);
}
Energy2 MEPP2VGammaPowheg::scale() const {
- return _scaleopt == 0 ? sqr(_fixedScale) : _scaleFact*sHat();
+ //return _scaleopt == 0 ? sqr(_fixedScale) : _scaleFact*sHat();
+ return sHat();
}
int MEPP2VGammaPowheg::nDim() const {
return MEPP2VGamma::nDim()+3;
}
bool MEPP2VGammaPowheg::generateKinematics(const double * r) {
_xtil = *(r +nDim() -1);
_y1 = *(r +nDim() -3);
_y2 = *(r +nDim() -2);
_y3 = *(r +nDim() -1);
return MEPP2VGamma::generateKinematics(r);
}
CrossSection MEPP2VGammaPowheg::dSigHatDR() const {
- // momentum fractions of the incoming partons
+
+ Pi= Constants::pi;
+ _CF= 4.0/3.0;
+ _TR= 1.0/2.0;
_xa= lastX1();
_xb= lastX2();
+ gamnum = 0.5772;
+
//incoming parton ParticleData object and momenta
_partona= mePartonData()[0];
_partonb= mePartonData()[1];
_p_partona= meMomenta()[0];
_p_partonb= meMomenta()[1];
- // outgoing ParticleData object and momenta
- _p_photon= meMomenta()[3];
- _p_boson= meMomenta()[2];
- _photon = mePartonData()[3];
- _boson= mePartonData()[2];
+
// gluon ParticleData object
_gluon = getParticleData(ParticleID::g);
- //_alphas= SM().alphaS(scale());
- _alphas= SM().alphaS(_p_boson.m2());
- sin2w = SM().sin2ThetaW();
- //alphae = SM().alphaEM(_p_boson.m2());
- //alphae = SM().alphaEM(sHat());
- alphae = SM().alphaEM(scale());
+
// BeamParticleData objects for PDF's
_hadron_A= dynamic_ptr_cast<Ptr<BeamParticleData>::transient_const_pointer>
(lastParticles().first->dataPtr());
//assert(_hadron_A);
_hadron_B= dynamic_ptr_cast<Ptr<BeamParticleData>::transient_const_pointer>
(lastParticles().second->dataPtr());
//assert(_hadron_B);
if (_partona->id()<0) {
swap(_partona,_partonb);
swap(_p_partona,_p_partonb);
- swap(_hadron_A,_hadron_B);}
+ swap(_hadron_A,_hadron_B);
+ swap(_xa, _xb);}
// select quark/anti-quark for quark radiation:
_iflagcq = 0;
if(UseRandom::rnd()>0.5) _iflagcq = 1;
if (_iflagcq==0) {
_quark = _partonb;
_quarkpi = _partona->CC();}
else {
_quark = _partona;
_quarkpi = _partonb->CC();}
// calculate CKM matrix square
int iu,id;
iu = abs(_partona->id());
id = abs(_partonb->id());
if(iu%2!=0) swap(iu,id);
iu = (iu-2)/2;
id = (id-1)/2;
- ckm_ = SM().CKM(iu,id);
+ ckm = SM().CKM(iu,id);
+ // the third componet of isospin of the quark when vector boson is Z0
+ I3quark = -double(abs(_partona->id())%2) + 0.5;
+// ParticleData object and momenta of photon and vector boson
+ if(mePartonData()[3]->id()==ParticleID::gamma){
+ _idboson= 2;
+ _p_photon= meMomenta()[3];
+ _p_boson= meMomenta()[2];
+ _photon = mePartonData()[3];
+ _boson= mePartonData()[2];}
+ else{
+ _idboson= 3;
+ _p_photon= meMomenta()[2];
+ _p_boson= meMomenta()[3];
+ _photon = mePartonData()[2];
+ _boson= mePartonData()[3];}
+ _alphas= SM().alphaS(_p_boson.m2());
+ sin2w = SM().sin2ThetaW();
+ alphae = SM().alphaEM(scale());
_muF2= scale();
- CrossSection lo = MEPP2VGamma::dSigHatDR();
double weight = NLOweight();
- return lo*weight;
+ return MEPP2VGamma::dSigHatDR()*weight;
}
-// Transformation from Born+rad phase space configuration to m+1 phase space of final states
+unsigned int MEPP2VGammaPowheg::orderInAlphaS() const {
+ return 0;
+}
+
+unsigned int MEPP2VGammaPowheg::orderInAlphaEW() const {
+ return 2;
+}
+
+
+// Transformation from Born + CS phase space configuration to m+1 phase space of final states
Lorentz5Momentum MEPP2VGammaPowheg::InvLortr(Lorentz5Momentum kbar_a, Lorentz5Momentum kbar_b, double xi,
Lorentz5Momentum k_i, Lorentz5Momentum kbar_j, int fi) const{
Lorentz5Momentum KK, KKbar;
Energy2 K2, Kp2, Kdotkj, Kpdotkj;
KKbar = kbar_a + kbar_b;
if (fi == 0){
KK = kbar_a/xi + kbar_b -k_i;}
else{
KK = kbar_a + kbar_b/xi -k_i;}
K2 = KK.m2();
Kp2 = (KK + KKbar).m2();
Kdotkj = kbar_j.dot(KKbar);
Kpdotkj = kbar_j.dot(KK + KKbar);
return kbar_j -2.0*(Kpdotkj/Kp2)*(KK + KKbar) +2.0*(Kdotkj/K2)*KK;
}
//Transformation from m+1 phase space to Born phase space configuration of final states
Lorentz5Momentum MEPP2VGammaPowheg::Lortr(Lorentz5Momentum k_a, Lorentz5Momentum k_b, double xi,
Lorentz5Momentum k_i, Lorentz5Momentum k_j, int fi) const{
Lorentz5Momentum KK, KKbar;
Energy2 K2, Kp2, Kdotkj, Kpdotkj;
KK = k_a + k_b -k_i;
if (fi == 0){
KKbar = xi*k_a + k_b;}
else{
KKbar = k_a + xi*k_b;}
K2 = KK.m2();
Kp2 = (KK + KKbar).m2();
Kdotkj = k_j.dot(KK);
Kpdotkj = k_j.dot(KK + KKbar);
return k_j -2.0*(Kpdotkj/Kp2)*(KK + KKbar) +2.0*(Kdotkj/K2)*KKbar;
}
// momentum of radiated gluon transformed from Born phase space
Lorentz5Momentum MEPP2VGammaPowheg::radk(Lorentz5Momentum kbar_a, Lorentz5Momentum kbar_b, double xi,
double vi, double phi, int fi) const{
Energy Epi;
double costhei, sinthei, ga;
Lorentz5Momentum CMSk, kpi, ki;
Epi = sqrt(kbar_a.dot(kbar_b)/(2.0*xi))*(1.0-xi);
if (fi == 0){
costhei = (1.0 -2.0*vi -xi)/(1.0-xi);
CMSk = kbar_a/xi + kbar_b;}
else{
costhei = -(1.0 -2.0*vi -xi)/(1.0-xi);
CMSk = kbar_a + kbar_b/xi;}
sinthei = sqrt(1.0 - sqr(costhei));
kpi = Lorentz5Momentum(Epi*sinthei, ZERO, Epi*costhei, Epi, ZERO);
ga = CMSk.e()/CMSk.m();
ki = kpi.boost(0.0, 0.0, tanh(CMSk.rapidity()), ga);
return ki.rotateZ(phi);
-}
+}
+
+// the kinematics of quark radiation from initial gluon is just like the gluon radiation,
+// so we can use the functions radk, InvLortr and Lortr.
// momentum of radiated quark transformed from gq->qV Born phase space
-Lorentz5Momentum MEPP2VGammaPowheg::radkqr(Lorentz5Momentum kbar_ga, Lorentz5Momentum kbar_V, Energy2 MV2,
- double zi, double ui, double phi) const{
+Lorentz5Momentum MEPP2VGammaPowheg::radkqr(Lorentz5Momentum kbar_ga, Lorentz5Momentum kbar_V, Energy2 MassV2,
+ double zi, double ui, double phi, double zcut) const{
Energy Epi;
Energy2 kgadotV;
- double costhei, sinthei, zu, phiga, thega;
- Lorentz5Momentum CMSk, kpi, ki;
+ double costhei, sinthei, zu, phiga, thega, beta;
+ Lorentz5Momentum CMSk, kpi, ki, kga;
zu = (1.0 - zi)*(1.0 - ui);
- kgadotV = kbar_ga.dot(kbar_V);
- Epi = (zu + ui)*kgadotV/sqrt(MV2 + kgadotV);
- costhei = (zu - ui)/(zu + ui)*(MV2 + kgadotV)/(2.0*kgadotV) - MV2/(2.0*kgadotV);
+ if (zi >= zcut){
+ kga = kbar_ga*zi;
+ // kga = kbar_ga;
+ kgadotV = kga.dot(kbar_V);
+ // Epi = (zu + ui)*kgadotV/sqrt(MV2 + 2.0*kgadotV);
+ Epi = (zu + ui*zi)*kgadotV/sqrt(MassV2 + 2.0*kgadotV)/zi;
+ // costhei = (zu - ui)/(zu + ui)*(MV2 + 2.0*kgadotV)/(2.0*kgadotV) - MV2/(2.0*kgadotV);
+ // costhei = ((zu - ui)*kgadotV -ui*MV2)/((zu + ui)*kgadotV);
+ costhei = ((zu - ui*zi)*kgadotV -ui*zi*MassV2)/((zu + ui*zi)*kgadotV); }
+ else {
+ kga = kbar_ga;
+ kgadotV = kga.dot(kbar_V);
+ Epi = (zu + ui)*kgadotV/sqrt(MassV2 + 2.0*kgadotV);
+ costhei = ((zu - ui)*kgadotV -ui*MassV2)/((zu + ui)*kgadotV);}
sinthei = sqrt(1.0 - sqr(costhei));
kpi = Lorentz5Momentum(Epi*sinthei, ZERO, Epi*costhei, Epi, ZERO);
kpi = kpi.rotateZ(phi);
- kpi = Lorentz5Momentum(ZERO, ZERO, kbar_ga.e(), kbar_ga.e(), ZERO);
+ beta = -(1.0-zi)*kgadotV/((1.0+zi)*kgadotV + zi*MassV2);
phiga = kbar_ga.phi();
thega = kbar_ga.theta();
+ if (zi >= zcut) kpi.boost(0., 0., beta);
+
ki = kpi.rotateY(thega);
ki = ki.rotateZ(phiga);
+ // ki.setMass(ZERO);
+ // ki.rescaleEnergy();
+ ki.rescaleMass();
return ki;
}
// Born matrix element
-double MEPP2VGammaPowheg::MatrBorn(Lorentz5Momentum k_a , Lorentz5Momentum k_b,
- Lorentz5Momentum k_ga, Lorentz5Momentum k_V,
- double char0, double char1, Energy2 MV2) const {
- using Constants::pi;
- // kinematic invariants
- Energy2 bs = (k_a + k_b ).m2();
- Energy2 bt = (k_a - k_V ).m2();
- Energy2 bu = (k_a - k_ga).m2();
- double coeff = sqr(4.0*pi*alphae)* ckm_/sin2w;
- double scfact = 1.0/12.0;
- double matr = 4.0*sqr(char0*bt + char1*bu)/(bt*bu*sqr(bt+bu))*(bs*MV2 -bt*bu +sqr(bt+bu)/2.0);
+double MEPP2VGammaPowheg::MatrBorn(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga,
+ Lorentz5Momentum k_V, double char0, double char1, Energy2 MassV2) const{
+ Energy2 bs, bt, bu;
+ double coeff, scfact, matr, sinw, cosw;
+
+ bs = (k_a + k_b).m2();
+ bt = (k_a - k_V).m2();
+ bu = (k_a - k_ga).m2();
+
+ if(_boson->id()!=ParticleID::Z0) {
+ coeff = sqr(4.0*Pi*alphae)* ckm/sin2w;}
+ else {
+ sinw = sqrt(sin2w);
+ cosw = sqrt(1.0-sin2w);
+ coeff = sqr(4.0*Pi*alphae)* 2.0*(sqr(I3quark/(sinw*cosw) -char0*sinw/cosw) +sqr(char0*sinw/cosw));}
+ scfact = 1.0/12.0;
+ matr = 4.0*sqr(char0*bt + char1*bu)/(bt*bu*sqr(bt+bu))*(bs*MassV2 -bt*bu +sqr(bt+bu)/2.0);
return matr*coeff*scfact;
}
-
+
// Tree level matrix element for gq->qV
+ // merge from VGammaHardGenerator
double MEPP2VGammaPowheg::MatrQV(Lorentz5Momentum p_a, Lorentz5Momentum p_b, Lorentz5Momentum k_q,
- Lorentz5Momentum k_V, Energy2 MV2) const {
- using Constants::pi;
+ Lorentz5Momentum k_V, double charqr, Energy2 MassV2, double alphas, int fi) const{
Energy2 bs, bt, bu;
- double coeff, scfact, matr;
+ double coeff, scfact, matr, sinw, cosw;
Lorentz5Momentum k_a, k_b;
- if (_iflagcq==0) {
+ if (fi==0) {
k_a = p_a;
k_b = p_b;}
else {
k_a = p_b;
k_b = p_a;}
bs = (k_a + k_b).m2();
bt = (k_a - k_q).m2();
bu = (k_a - k_V).m2();
- coeff = sqr(4.0*pi)*alphae*_alphas* ckm_/sin2w;
+ if(_boson->id()!=ParticleID::Z0) {
+ coeff = sqr(4.0*Pi)*alphae*alphas* ckm/(2.0*sin2w);}
+ else {
+ sinw = sqrt(sin2w);
+ cosw = sqrt(1.0-sin2w);
+ coeff = sqr(4.0*Pi)*alphae*alphas* (sqr(I3quark/(sinw*cosw) -charqr*sinw/cosw) +sqr(charqr*sinw/cosw));}
// spin = 1/4 colour = 4/(3*8)
scfact = 1.0/24.0;
- matr = 4.0*(bu*MV2 +sqr(bt) +sqr(bs))/(bt*bs);
+ matr = -4.0*(2.0*bu*MassV2 +sqr(bt) +sqr(bs))/(bt*bs);
return matr*coeff*scfact;
}
-
-double MEPP2VGammaPowheg::test2to3(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga,
- Lorentz5Momentum k_1, Lorentz5Momentum k_2) const{
+double MEPP2VGammaPowheg::qgME(Lorentz5Momentum p_a, Lorentz5Momentum p_b, Lorentz5Momentum k_q,
+ Lorentz5Momentum k_V, Energy2 MassV2, bool calc) const {
using namespace ThePEG::Helicity;
using namespace ThePEG;
- double sum(0.), scfact;
- Complex diag;
- vector<SpinorWaveFunction> qin,qbarout;
- vector<SpinorBarWaveFunction> qbarin,qout;
- vector<VectorWaveFunction> pout;
- SpinorWaveFunction q_in(k_a, _partona, incoming);
- SpinorBarWaveFunction qbar_in(k_b, _partonb, incoming);
- SpinorBarWaveFunction q_out(k_1, _partona, outgoing);
- SpinorWaveFunction qbar_out(k_2, _partonb, outgoing);
- VectorWaveFunction p_out(k_ga, _photon, outgoing);
- for(unsigned int ix=0;ix<2;++ix) {
+ vector<SpinorWaveFunction> qin;
+ vector<SpinorBarWaveFunction> qbarin;
+ vector<SpinorBarWaveFunction> qout;
+ vector<SpinorWaveFunction> qbarout;
+ vector<VectorWaveFunction> vout,gin;
+ Lorentz5Momentum k_a, k_b;
+ if (_iflagcq==0) {
+ k_a = p_a;
+ k_b = p_b;}
+ else {
+ k_a = p_b;
+ k_b = p_a;}
+ SpinorWaveFunction q_in(k_b, _quark, incoming);
+ SpinorBarWaveFunction qbar_in(k_b, _quark, incoming);
+ SpinorBarWaveFunction q_out(k_q, _quarkpi, outgoing);
+ SpinorWaveFunction qbar_out(k_q, _quarkpi, outgoing);
+ VectorWaveFunction v_out(k_V, _boson, outgoing);
+ VectorWaveFunction g_in(k_a, _gluon, incoming);
+ for(unsigned int ix=0;ix<3;++ix) {
+ if(ix<2) {
q_in.reset(ix);
qin.push_back(q_in);
qbar_in.reset(ix);
qbarin.push_back(qbar_in);
q_out.reset(ix);
qout.push_back(q_out);
qbar_out.reset(ix);
- qbarout.push_back(qbar_out);
- p_out.reset(2*ix);
- pout.push_back(p_out);
+ qbarout.push_back(qbar_out);
+ g_in.reset(2*ix);
+ gin.push_back(g_in);
+ }
+
+ v_out.reset(ix);
+ vout.push_back(v_out);
}
- Energy2 scaleEM;
+ Energy2 scaleS, scaleEM;
+ scaleS = MassV2;
scaleEM = scale();
+
+ vector<Complex> diag(2,0.0);
+ double output(0.), colspin;
+ AbstractFFVVertexPtr vertex =
+ _boson->id()==ParticleID::Z0 ? FFZvertex_ : FFWvertex_;
+
for(unsigned int ihel1=0;ihel1<2;++ihel1) {
for(unsigned int ihel2=0;ihel2<2;++ihel2) {
- for(unsigned int ihela=0;ihela<2;++ihela) {
- for(unsigned int phel=0;phel<2;++phel) {
- for(unsigned int ihelb=0;ihelb<2;++ihelb) {
- SpinorWaveFunction inters1 =
- FFPvertex_->evaluate(scaleEM,5,_partona,qin[ihela],pout[phel]);
- VectorWaveFunction intersw =
- FFWvertex_->evaluate(scaleEM,3,_boson->CC(),qbarout[ihel2],qout[ihel1]);
- diag = FFWvertex_->evaluate(scaleEM,inters1,qbarin[ihelb],intersw);
- sum += norm(diag);
+ for(unsigned int ohel1=0;ohel1<2;++ohel1) {
+ for(unsigned int ohel2=0;ohel2<3;++ohel2) {
+ // intermediates for the diagrams
+ // suppose parton_b is quark:
+ if (_quark->id()>0){
+
+ SpinorBarWaveFunction interb=FFGvertex_->evaluate(scaleS,5,_quarkpi->CC(),
+ qout[ohel1],gin[ihel2]);
+ SpinorWaveFunction inters=FFGvertex_->evaluate(scaleS,5,_quark,
+ qin[ihel1],gin[ihel2]);
+ diag[0]=vertex->evaluate(scaleEM,qin[ihel1],interb,
+ vout[ohel2] );
+ diag[1]=vertex->evaluate(scaleEM,inters,qout[ohel1],
+ vout[ohel2] );
}
+ else{
+ SpinorWaveFunction interb=FFGvertex_->evaluate(scaleS,5,_quarkpi->CC(),
+ qbarout[ohel1],gin[ihel2]);
+ SpinorBarWaveFunction inters=FFGvertex_->evaluate(scaleS,5,_quark,
+ qbarin[ihel1],gin[ihel2]);
+ diag[0]=vertex->evaluate(scaleEM,interb,qbarin[ihel1],
+ vout[ohel2] );
+ diag[1]=vertex->evaluate(scaleEM,qbarout[ohel1],inters,
+ vout[ohel2] );
+ }
+ // 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
+ // if(calc) me_(ihel1,ihel2,ohel1,ohel2) = diag[0];
}
}
}
}
- // final spin and colour factors
- // spin = 1/4 colour = 3/9
- scfact = 1.0/12.0;
- return sum*scfact;
-}
-double MEPP2VGammaPowheg::test2to3am(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga,
- Lorentz5Momentum k_1, Lorentz5Momentum k_2, Energy2 MV2) const{
- using Constants::pi;
- double scfact, coupfact, part;
- coupfact = sqr(4.0*pi*alphae)*(4.0*pi*alphae)* sqr(ckm_/sin2w)/4.0;
- part = (k_ga.dot(k_1)*k_b.dot(k_2) +k_ga.dot(k_2)*k_b.dot(k_1))/sqr((k_1+k_2).m2()-MV2);
- // final spin and colour factors
- // spin = 1/4 colour = 3/9
- scfact = 1.0/12.0;
- return part/(2.0*k_a.dot(k_ga))*coupfact*scfact*sqr(GeV);
+ //DVector save(3);
+ colspin=1./24./4.;
+ colspin *=4.;
+ //for(size_t ix=0;ix<3;++ix) {
+ // save[ix] = colspin * me[ix];
+ //}
+ //meInfo(save);
+ output *= colspin;
+ return output;
}
+
// Gluon Real radiation matrix element
-InvEnergy2 MEPP2VGammaPowheg::MatrRealGluon(Lorentz5Momentum k_a, Lorentz5Momentum k_b,
- Lorentz5Momentum k_ga,
- Lorentz5Momentum k_V, Lorentz5Momentum k_glu) const{
+double MEPP2VGammaPowheg::MatrRealGluon(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga,
+ Lorentz5Momentum k_V, Lorentz5Momentum k_glu, Energy2 scaleS) const{
using namespace ThePEG::Helicity;
using namespace ThePEG;
double sum(0.), scfact;
- Energy2 bosonMass2_;
+ //Energy2 bosonMass2_;
vector<SpinorWaveFunction> qin;
vector<SpinorBarWaveFunction> qbarin;
vector<VectorWaveFunction> wout,pout,gout;
- SpinorWaveFunction q_in (k_a , _partona, incoming);
- SpinorBarWaveFunction qbar_in(k_b , _partonb, incoming);
- VectorWaveFunction v_out (k_V , _boson , outgoing);
- VectorWaveFunction p_out (k_ga , _photon , outgoing);
- VectorWaveFunction g_out (k_glu, _gluon , outgoing);
- bosonMass2_ = k_V.m2();
+ SpinorWaveFunction q_in(k_a, _partona, incoming);
+ SpinorBarWaveFunction qbar_in(k_b, _partonb, incoming);
+ VectorWaveFunction v_out(k_V ,_boson, outgoing);
+ VectorWaveFunction p_out(k_ga, _photon, outgoing);
+ VectorWaveFunction g_out(k_glu, _gluon, outgoing);
+
+ //bosonMass2_ = k_V.m2();
for(unsigned int ix=0;ix<3;++ix) {
if(ix<2) {
q_in.reset(ix);
qin.push_back(q_in);
qbar_in.reset(ix);
qbarin.push_back(qbar_in);
g_out.reset(2*ix);
- //g_out.reset(10);
gout.push_back(g_out);
p_out.reset(2*ix);
- //p_out.reset(10);
pout.push_back(p_out);
}
v_out.reset(ix);
wout.push_back(v_out);
}
- Energy2 scaleEM, scaleS;
- scaleS = bosonMass2_;
+ Energy2 scaleEM;
scaleEM = scale();
vector<Complex> diag(_boson->id()==ParticleID::Z0 ? 6 : 8, 0.);
AbstractFFVVertexPtr vertex =
_boson->id()==ParticleID::Z0 ? FFZvertex_ : FFWvertex_;
for(unsigned int ihel1=0;ihel1<2;++ihel1) {
for(unsigned int ihel2=0;ihel2<2;++ihel2) {
for(unsigned int whel=0;whel<3;++whel) {
for(unsigned int phel=0;phel<2;++phel) {
for(unsigned int ghel=0;ghel<2;++ghel) {
//
// Diagrams which are the same for W/Z gamma
//
// first diagram
SpinorWaveFunction inters1 =
FFPvertex_->evaluate(scaleEM,5,_partona,qin[ihel1],pout[phel]);
SpinorBarWaveFunction inters2 =
vertex->evaluate(scaleEM,5,_partona->CC(),qbarin[ihel2],wout[whel]);
diag[0] = FFGvertex_->evaluate(scaleS,inters1,inters2,gout[ghel]);
// second diagram
SpinorWaveFunction inters3 =
FFGvertex_->evaluate(scaleS,5,_partona,qin[ihel1],gout[ghel]);
SpinorBarWaveFunction inters4 =
FFPvertex_->evaluate(scaleEM,5,_partonb,qbarin[ihel2],pout[phel]);
diag[1] = vertex->evaluate(scaleEM,inters3,inters4,wout[whel]);
// fourth diagram
diag[2] = FFPvertex_->evaluate(scaleEM,inters3,inters2,pout[phel]);
// fifth diagram
SpinorBarWaveFunction inters5 =
FFGvertex_->evaluate(scaleS,5,_partonb,qbarin[ihel2],gout[ghel]);
diag[3] =
vertex->evaluate(scaleEM,inters1,inters5,wout[whel]);
// sixth diagram
SpinorWaveFunction inters6 =
vertex->evaluate(scaleEM,5,_partonb->CC(),qin[ihel1],wout[whel]);
diag[4] = FFGvertex_->evaluate(scaleS,inters6,inters4,gout[ghel]);
// eighth diagram
diag[5] = FFPvertex_->evaluate(scaleEM,inters6,inters5,pout[phel]);
//
// Diagrams only for W gamma
//
if(_boson->id()!=ParticleID::Z0) {
// third diagram
VectorWaveFunction interv =
WWWvertex_->evaluate(scaleEM,3,_boson->CC(),pout[phel],wout[whel]);
diag[6] = vertex->evaluate(scaleEM,inters3,qbarin[ihel2],interv);
// seventh diagram
diag[7] = vertex->evaluate(scaleEM,qin[ihel1],inters5,interv);
}
// sum
Complex dsum = std::accumulate(diag.begin(),diag.end(),Complex(0.));
-// cerr << "testing"
-// << ihel1 << " " << ihel2 << " "
-// << ghel << " " << phel << " " << whel << " "
-// << dsum/sqrt(norm(diag[0])+norm(diag[1])+norm(diag[2])+norm(diag[3])+
-// norm(diag[4])+norm(diag[5])+norm(diag[6])+norm(diag[7]))<< "\n";
+
sum += norm(dsum);
}
}
}
}
}
// final spin and colour factors
// spin = 1/4 colour = 4/9
- scfact = 1./9.;
- return sum*scfact*UnitRemoval::InvE2;
+ scfact = 1.0/9.0;
+ return sum*scfact*1000000.0;
}
// Quark Real radiation matrix element
double MEPP2VGammaPowheg::MatrRealQuark(Lorentz5Momentum p_a, Lorentz5Momentum p_b, Lorentz5Momentum k_ga,
- Lorentz5Momentum k_V, Lorentz5Momentum k_q) const{
+ Lorentz5Momentum k_V, Lorentz5Momentum k_q, Energy2 scaleS, int flavorflag) const{
using namespace ThePEG::Helicity;
using namespace ThePEG;
double sum(0.), scfact;
- Energy bosonMass_;
+ //Energy bosonMass_;
vector<SpinorWaveFunction> qin;
vector<SpinorBarWaveFunction> qbarin;
vector<SpinorBarWaveFunction> qout;
vector<SpinorWaveFunction> qbarout;
vector<VectorWaveFunction> vout,pout,gin;
Lorentz5Momentum k_a, k_b;
- if (_iflagcq==0) {
+ if (flavorflag%2==0) {
k_a = p_a;
k_b = p_b;}
else {
k_a = p_b;
k_b = p_a;}
SpinorWaveFunction q_in(k_b, _quark, incoming);
SpinorBarWaveFunction qbar_in(k_b, _quark, incoming);
- SpinorBarWaveFunction q_out(k_q, _quarkpi, outgoing); //modify
- SpinorWaveFunction qbar_out(k_q, _quarkpi, outgoing); //modify
- VectorWaveFunction v_out(k_V ,_boson, outgoing);
+ SpinorBarWaveFunction q_out(k_q, _quarkpi, outgoing);
+ SpinorWaveFunction qbar_out(k_q, _quarkpi, outgoing);
+ VectorWaveFunction v_out(k_V, _boson, outgoing);
VectorWaveFunction p_out(k_ga, _photon, outgoing);
VectorWaveFunction g_in(k_a, _gluon, incoming);
- bosonMass_ = k_V.mass();
+ //bosonMass_ = k_V.mass();
for(unsigned int ix=0;ix<3;++ix) {
if(ix<2) {
q_in.reset(ix);
qin.push_back(q_in);
qbar_in.reset(ix);
qbarin.push_back(qbar_in);
q_out.reset(ix);
qout.push_back(q_out);
qbar_out.reset(ix);
qbarout.push_back(qbar_out);
- //g_in.reset(10);
g_in.reset(2*ix);
gin.push_back(g_in);
- //p_out.reset(10);
p_out.reset(2*ix);
pout.push_back(p_out);
}
+
v_out.reset(ix);
vout.push_back(v_out);
}
- Energy2 scaleEM, scaleS;
- scaleS = sqr(bosonMass_);
+
+ Energy2 scaleEM;
scaleEM = scale();
-
vector<Complex> diag(_boson->id()==ParticleID::Z0 ? 6 : 8, 0.);
AbstractFFVVertexPtr vertex =
_boson->id()==ParticleID::Z0 ? FFZvertex_ : FFWvertex_;
for(unsigned int ihel1=0;ihel1<2;++ihel1) { //incoming quark
for(unsigned int ihel2=0;ihel2<2;++ihel2) { //outgoing quark
for(unsigned int vhel=0;vhel<3;++vhel) {
for(unsigned int phel=0;phel<2;++phel) {
for(unsigned int ghel=0;ghel<2;++ghel) {
//
// suppose parton_b is quark:
- if (_quark->id()>0){
+ //if (_quark->id()>0){
+ if (flavorflag%2==1) {
// Diagrams which are the same for W/Z gamma
//
// first diagram
SpinorWaveFunction inters1 =
FFPvertex_->evaluate(scaleEM,5,_quark,qin[ihel1],pout[phel]);
SpinorBarWaveFunction inters2 =
FFGvertex_->evaluate(scaleS,5,_quarkpi->CC(),qout[ihel2],gin[ghel]);
diag[0] = vertex->evaluate(scaleEM,inters1,inters2,vout[vhel]);
// second diagram
SpinorWaveFunction inters3 =
vertex->evaluate(scaleEM,5,_quarkpi,qin[ihel1],vout[vhel]);
SpinorBarWaveFunction inters4 =
FFPvertex_->evaluate(scaleEM,5,_quarkpi->CC(),qout[ihel2],pout[phel]);
diag[1] = FFGvertex_->evaluate(scaleS,inters3,inters4,gin[ghel]);
// third diagram
diag[2] = FFPvertex_->evaluate(scaleEM,inters3,inters2,pout[phel]);
// fourth diagram
SpinorWaveFunction inters5 =
FFGvertex_->evaluate(scaleS,5,_quark,qin[ihel1],gin[ghel]);
diag[3] =
vertex->evaluate(scaleEM,inters5,inters4,vout[vhel]);
// fifth diagram
SpinorBarWaveFunction inters6 =
vertex->evaluate(scaleEM,5,_quark->CC(),qout[ihel2],vout[vhel]);
diag[4] = FFGvertex_->evaluate(scaleS,inters1,inters6,gin[ghel]);
// sixth diagram
diag[5] = FFPvertex_->evaluate(scaleEM,inters5,inters6,pout[phel]);
//
// Diagrams only for W gamma
//
if(_boson->id()!=ParticleID::Z0) {
// seventh diagram
VectorWaveFunction interv =
WWWvertex_->evaluate(scaleEM,3,_boson->CC(),pout[phel],vout[vhel]);
diag[6] = vertex->evaluate(scaleEM,inters5,qout[ihel2],interv);
// eighth diagram
diag[7] = vertex->evaluate(scaleEM,qin[ihel1],inters2,interv);
}
}
- //
+ //
//suppose parton_b is anti-quark:
else {
// Diagrams which are the same for W/Z gamma
//
// first diagram
SpinorBarWaveFunction inters1 =
FFPvertex_->evaluate(scaleEM,5,_quark,qbarin[ihel1],pout[phel]);
SpinorWaveFunction inters2 =
FFGvertex_->evaluate(scaleS,5,_quarkpi->CC(),qbarout[ihel2],gin[ghel]);
diag[0] = vertex->evaluate(scaleEM,inters2,inters1,vout[vhel]);
// second diagram
SpinorBarWaveFunction inters3 =
vertex->evaluate(scaleEM,5,_quarkpi,qbarin[ihel1],vout[vhel]);
SpinorWaveFunction inters4 =
FFPvertex_->evaluate(scaleEM,5,_quarkpi->CC(),qbarout[ihel2],pout[phel]);
diag[1] = FFGvertex_->evaluate(scaleS,inters4,inters3,gin[ghel]);
// third diagram
diag[2] = FFPvertex_->evaluate(scaleEM,inters2,inters3,pout[phel]);
// fourth diagram
SpinorBarWaveFunction inters5 =
FFGvertex_->evaluate(scaleS,5,_quark,qbarin[ihel1],gin[ghel]);
diag[3] =
vertex->evaluate(scaleEM,inters4,inters5,vout[vhel]);
// fifth diagram
SpinorWaveFunction inters6 =
vertex->evaluate(scaleEM,5,_quark->CC(),qbarout[ihel2],vout[vhel]);
diag[4] = FFGvertex_->evaluate(scaleS,inters6,inters1,gin[ghel]);
// sixth diagram
diag[5] = FFPvertex_->evaluate(scaleEM,inters6,inters5,pout[phel]);
//
// Diagrams only for W gamma
//
if(_boson->id()!=ParticleID::Z0) {
// seventh diagram
VectorWaveFunction interv =
WWWvertex_->evaluate(scaleEM,3,_boson->CC(),pout[phel],vout[vhel]);
diag[6] = vertex->evaluate(scaleEM,qbarout[ihel2],inters5,interv);
// eighth diagram
diag[7] = vertex->evaluate(scaleEM,inters2,qbarin[ihel1],interv);
}
}
// sum
Complex dsum = std::accumulate(diag.begin(),diag.end(),Complex(0.));
- /*
- cerr << "testing"
- << ihel1 << " " << ihel2 << " "
- << ghel << " " << phel << " " << whel << " "
- << dsum/sqrt(norm(diag[0])+norm(diag[1])+norm(diag[2])+norm(diag[3])+
- norm(diag[4])+norm(diag[5])+norm(diag[6])+norm(diag[7]))<< "\n";
- */
sum += norm(dsum);
}
}
}
}
}
// final spin and colour factors
// spin = 1/4 colour = 4/(3*8)
scfact = 1.0/24.0;
- return sum*scfact;
+ return sum*scfact*1000000.;
}
// dipole of gluon radiation
-InvEnergy2 MEPP2VGammaPowheg::Dipole(Lorentz5Momentum k_a, Lorentz5Momentum k_b,
- Lorentz5Momentum k_ga,
- Lorentz5Momentum k_V, double char0,double char1,
- Energy2 MV2,Energy2 kig,double xi) const {
- using Constants::pi;
- double coeff = 8.*pi*_alphas*CF_;
- InvEnergy2 fact = 1./(2.0*xi *kig) * ( 1. + sqr(xi) )/(1. - xi);
- return MatrBorn(k_a,k_b,k_ga,k_V,char0,char1,MV2) *coeff*fact;
+ // merge from VGammaHardGenerator
+double MEPP2VGammaPowheg::Dipole(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga,
+ Lorentz5Momentum k_V, double char0, double char1, Energy2 MassV2, Energy2 kig, double alphas, double xi) const{
+ double coeff, fact;
+ coeff = 8.0*Pi*alphas*_CF;
+ fact = (1.0 + sqr(xi))/(1.0 - xi)/(2.0*xi *kig)*sqr(GeV);
+ return MatrBorn(k_a,k_b,k_ga,k_V,char0,char1,MassV2) *coeff*fact;
}
+
+// dipole of quark radiation in the singular region collinear with final state photon
+ // merge from VGammaHardGenerator
+double MEPP2VGammaPowheg::Dipolepqr(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga,
+ Lorentz5Momentum k_V, double chargr, Energy2 MassV2, Energy2 kig, double zi, double alphas, int fi) const{
+ double coeff, fact;
+ coeff = 8.0*Pi*alphae*sqr(chargr);
+ fact = (1.0 + sqr(1.0-zi))/zi/(2.0 *kig)*sqr(GeV);
+ //cerr<<"kig="<<kig/sqr(GeV)<<" coeff="<<coeff<<" fact="<<fact<<"\n";
+ return MatrQV(k_a,k_b,k_ga,k_V,chargr,MassV2,alphas,fi) *coeff*fact;
+}
+
+
+// dipole of quark radiation in the singular region collinear with initial state gluon
+ // merge from VGammaHardGenerator
+double MEPP2VGammaPowheg::Dipolegluqr(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga,
+ Lorentz5Momentum k_V, double char0, double char1, Energy2 MassV2, Energy2 kig, double alphas, double xi) const{
+ double coeff, fact;
+ coeff = 8.0*Pi*alphas*_TR;
+ fact = (1.0 - 2.0*xi*(1.0 - xi))/(2.0*xi *kig)*sqr(GeV);
+ return MatrBorn(k_a,k_b,k_ga,k_V,char0,char1,MassV2) *coeff*fact;
+}
+
+
// parton distribution function of beam partID
-double MEPP2VGammaPowheg::PDFab(double z, int partID) const {
+double MEPP2VGammaPowheg::PDFab(double z, int partID, Energy2 scale, tcBeamPtr hadron_A, tcBeamPtr hadron_B) const {
if(partID==0){
//assert(_hadron_A);
- return _hadron_A->pdf()->xfx(_hadron_A,_partona,_muF2,z);}
+ return hadron_A->pdf()->xfx(_hadron_A,_partona,scale,z);}
else{
//assert(_hadron_B);
- return _hadron_B->pdf()->xfx(_hadron_B,_partonb,_muF2,z);}
+ return hadron_B->pdf()->xfx(_hadron_B,_partonb,scale,z);}
}
+
// parton distribution function ratio
-double MEPP2VGammaPowheg::PDFratio(double z, double x, int partID) const {
+double MEPP2VGammaPowheg::PDFratio(double z, double x, Energy2 scale, int partID, int fi, tcBeamPtr hadron_A, tcBeamPtr hadron_B) const {
double pdfz, pdfx;
+ //quark PDF ratio: z is the new fraction, and x the old fraction
if (partID <3){
- pdfz = PDFab(z, partID);
- pdfx = PDFab(x, partID);}
-
+ pdfz = PDFab(z, partID, scale, hadron_A, hadron_B)/z;
+ pdfx = PDFab(x, partID, scale, hadron_A, hadron_B)/x;}
+ //gluon vs. quark PDF ratio with the same fraction: z and x is the fractions of the two initial states
if (partID ==3){
- if (_iflagcq ==0){
- pdfx = PDFab(z, 0);
- pdfz = _hadron_A->pdf()->xfx(_hadron_A,_gluon,_muF2,z);}
+ if (fi ==0){
+ pdfx = PDFab(z, 0, scale, hadron_A, hadron_B);
+ pdfz = hadron_A->pdf()->xfx(_hadron_A,_gluon,scale,z);}
else {
- pdfx = PDFab(x, 1);
- pdfz = _hadron_A->pdf()->xfx(_hadron_B,_gluon,_muF2,x);}}
+ pdfx = PDFab(x, 1, scale, hadron_A, hadron_B);
+ pdfz = hadron_B->pdf()->xfx(_hadron_B,_gluon,scale,x);}}
+ //gluon vs. quark PDF ratio with the different fraction: z is the new fraction of gluon and x is the old one of quark
+ if (partID ==4){
+ if (fi ==0){
+ pdfx = PDFab(x, 0, scale, hadron_A, hadron_B)/x;
+ pdfz = hadron_A->pdf()->xfx(_hadron_A,_gluon,scale,z)/z;}
+ else {
+ pdfx = PDFab(x, 1, scale, hadron_A, hadron_B)/x;
+ pdfz = hadron_B->pdf()->xfx(_hadron_B,_gluon,scale,z)/z;}}
if (pdfx == 0.0) {
if (pdfz == 0.0){
return 1.0;}
else{
return 0.0;}}
else{
return pdfz/pdfx;}
}
-// functionals of PDFs and energy fractions in the collinear remnants:
+
+// functionals of PDFs and energy fractions in the collinear remnants for gluon radiation:
double MEPP2VGammaPowheg::KP1(double zz, Energy2 shat, Energy2 muF2, int partID) const{
double x, hpart;
- x = 1.0 -_xtil +zz*_xtil;
- //pdfzx= PDFab(zz/x, partID);
- //pdfz= PDFab(zz, partID);
- hpart= log(sqr(1.0-x)*shat/(x*muF2))*
- (2.0/(1.0-x) -(1.0+sqr(x))/(1.0-x)*PDFratio(zz/x,zz,partID)/x) +2.0/(1.0-x)*log(x);
- return (1.0-zz)*hpart;
+ x = 1.0 -_xtil +zz*_xtil;
+ hpart= log(sqr(1.0-x)*shat/(x*muF2))*
+ (2.0/(1.0-x) -(1.0+sqr(x))/(1.0-x)*PDFratio(zz/x,zz,muF2,partID,_iflagcq,_hadron_A,_hadron_B)/x) +2.0/(1.0-x)*log(x);
+ hpart = log(x*muF2/(sqr(1.0-x)*shat))*(PDFratio(zz/x,zz,muF2,partID,_iflagcq,_hadron_A,_hadron_B)/x*(1.0+x*x)/(1.0-x) - 2.0/(1.0-x))
+ -2.0*log(sqr(1.0-x));
+ return (1.0-zz)*hpart;
}
double MEPP2VGammaPowheg::KP2(double zz, Energy2 shat, Energy2 muF2) const{
double x, hpart;
+ /*
x = zz*_xtil;
- hpart= log(sqr(1.0-x)*shat/muF2)*(2.0/(1.0-x));
- return zz*hpart;
+ hpart= log(sqr(1.0-x)*shat/muF2)*(2.0/(1.0-x));
+ return zz*hpart;
+ */
+ hpart = (3.0/2.0 - (zz + zz*zz/2.0))*log(muF2/shat) +4.0*(1.0-zz)*(log(1.0-zz) - 1.0);
+ return hpart;
}
double MEPP2VGammaPowheg::KP3(double zz, int partID) const{
double x, hpart;
- x = 1.0 -_xtil +zz*_xtil;
- //pdfzx= PDFab(zz/x, partID);
- //pdfz= PDFab(zz, partID);
- hpart= (1.0-x)*PDFratio(zz/x,zz,partID)/x;
- return (1.0-zz)*hpart;
+ x = 1.0 -_xtil +zz*_xtil;
+ hpart= (1.0-x)*PDFratio(zz/x,zz,_muF2,partID,_iflagcq,_hadron_A,_hadron_B)/x;
+ return (1.0-zz)*hpart;
}
+// the collinear remnants for quark radiation:
+double MEPP2VGammaPowheg::KPpr(double xx, Energy2 shat, Energy2 muF2) const{
+ double x1, x2, hpart, px1, px2, lnx1, lnx2, part1, part2, part3, pdffact;
+ x1 = 1.0 -_xtil +xx*_xtil;
+ //x2 = xx*_xtil;
+ pdffact= PDFratio(xx/x1,xx,muF2,4,_iflagcq,_hadron_A,_hadron_B)/x1;
+ px1= 1.0 - 2.0*x1*(1.0-x1);
+ /*
+ px2= 1.0 - 2.0*x2*(1.0-x2);
+ lnx1= log(shat*sqr(1.0-x1)/muF2);
+ lnx2= log(shat*sqr(1.0-x2)/muF2);
+ part1= (_TR*(1.0-px1)- gamnum*px1)*pdffact;
+ part2= px1*lnx1*(pdffact -1.0);
+ part3= px2*lnx2;
+ hpart= (1.0-xx)*(part1+part2) - xx*part3;
+ */
+ lnx1 = log(shat*sqr(1.0-x1)/x1/muF2);
+ hpart= (1.0-xx)*_TR*((px1*lnx1 + (1.0-px1))*pdffact - 2.0*log(1.0-x1)*PDFratio(xx,xx,muF2,4,_iflagcq,_hadron_A,_hadron_B)) + _TR*2.0*(1.0-xx)*(log(1.0-xx)-1.0)*PDFratio(xx,xx,muF2,4,_iflagcq,_hadron_A,_hadron_B);
+ return hpart;
+}
+
+
+
// definitions of H, F^V:
double MEPP2VGammaPowheg::Hfunc(Energy2 t, Energy2 s, Energy2 m2) const{
- using Constants::pi;
- return sqr(pi)-sqr(log(s/m2))+sqr(log(-t/s))-sqr(log(-t/m2))
+ return sqr(Pi)-sqr(log(s/m2))+sqr(log(-t/s))-sqr(log(-t/m2))
-2.0*ReLi2(1.0-s/m2)-2.0*ReLi2(1.0-t/m2);
}
-double MEPP2VGammaPowheg::FWfunc(Energy2 t, Energy2 u, Energy2 s, Energy2 m2) const {
- using Constants::pi;
+double MEPP2VGammaPowheg::FWfunc(Energy2 t, Energy2 u, Energy2 s, Energy2 m2) const{
double y1,y2,y3,y4,y5;
y1= 4.0*(2.0*s*s/(t*u) +2.0*s/u +t/u)* Hfunc(u,s,m2);
- y2= -8.0/3.0*sqr(pi)*s*(2.0*s/t +t/s -u/s)/(t+u);
+ y2= -8.0/3.0*sqr(Pi)*s*(2.0*s/t +t/s -u/s)/(t+u);
y3= 4.0*(6.0-10.0*u/(t+u)-10.0*s*s/(u*(t+u))-11.0*s/u-5.0*t/u+2.0*s/(t+u)+s/(s+t));
y4= -4.0*log(s/m2)*(3.0*t/u+2.0*s/u+4.0*s*(t+s)/(u*(t+u))+2.0*t/u*sqr(s/(t+u)));
y5= 4.0*log(-u/m2)*((4.0*s+u)/(s+t)+s*u/sqr(s+t));
return y1+y2+y3+y4+y5;
}
double MEPP2VGammaPowheg::FZfunc(Energy2 t, Energy2 u, Energy2 s, Energy2 m2) const{
- using Constants::pi;
double y1,y2,y3,y4,y5;
y1= 4.0*(2.0*s*s/(t*u) +2.0*s/u +t/u)* Hfunc(u,s,m2);
- y2= -8.0/3.0*sqr(pi)*s*s/(t*u);
+ y2= -8.0/3.0*sqr(Pi)*s*s/(t*u);
y3= 4.0*(1.0-5.0*s*s/(t*u)-11.0*s/u-5.0*t/u+2.0*s/(t+u)+s/(s+t));
y4= 4.0*log(s/m2)*(4.0*s/(t+u)+2.0*sqr(s/(t+u))-3.0*sqr(s+t)/(t*u));
y5= 4.0*log(-u/m2)*((4.0*s+u)/(s+t)+s*u/sqr(s+t));
return y1+y2+y3+y4+y5;
}
double MEPP2VGammaPowheg::FVfunc(Energy2 t, Energy2 u, Energy2 s, Energy2 m2) const {
- if(mePartonData()[2]->id()==ParticleID::Z0) {
+ if(mePartonData()[_idboson]->id()==ParticleID::Z0) {
return FZfunc(t,u,s,m2);
}
else {
return FWfunc(t,u,s,m2);
}
}
// ratio of NLO/LO
double MEPP2VGammaPowheg::NLOweight() const {
- using Constants::pi;
+ // double Pi(3.1415926);
+ double partep, partloop, partc, alfsfact;
+ double smborn0, smborn1, smborn2, smbfact, smloop;
+ Energy2 kadotg, kbdotg, scale_S; //MV2,
+ double sh,shr,ratea,rateb,va,vb,txa,zx,tva,tvb; //charge0,charge1,
+ Lorentz5Momentum k_a, k_b, k_ga, k_V, k_glu, kbarp_ga, kbarp_V;
+ double xiab, vi, phi;
+ double sumdipole, partreal, partdipole, smreala, smrealb, smreal, jacobfact, pdffact, fluxfact;
+ int fi,ida, idb;
// double FV, FW, FZ;
// If only leading order is required return 1:
- if(_contrib==0) return 1.;
- // kinematic invariants
+ if(_contrib==0) return 1.;
+
_ss= sHat();
- _tt= ( _p_partona - _p_boson ).m2();
+ _tt= ( _p_partona - _p_boson).m2();
_uu= ( _p_partona - _p_photon).m2();
- Energy2 MV2= _p_boson.m2();
- // strong coupling piece
- double alfsfact = _alphas*CF_/(2.0*pi);
- // ids of the incoming partons
- int ida = _partona->id();
- int idb = _partonb->id();
- // charges of the quarks for the incoming partons
- double charge0 = _partona->iCharge()/3.*ida/abs(ida);
- double charge1 = _partonb->iCharge()/3.*idb/abs(idb);
- // prefactor for the born matrix element
- InvEnergy4 smbfact= 4.0 * sqr( charge0*_tt + charge1*_uu )/(_tt*_uu*sqr(_tt+_uu));
- // eps^0 term in the expansion of the born ME
- Energy4 smborn0 = (_ss*MV2 -_tt*_uu + 0.5*sqr(_tt+_uu));
- // eps^1 term in the expansion of the born ME
- Energy4 smborn1 = -(_ss*MV2 -_tt*_uu +sqr(_tt+_uu));
- // eps^2 term in the expansion of the born ME
- Energy4 smborn2 = 0.5*sqr(_tt+_uu);
- // divergent Virtual - I(eps) piece
- double partep= 2.0*(5.0-sqr(pi)/3.0) +3.0*smborn1/smborn0 +2.0*smborn2/smborn0;
- // finite virtual piece
- double smloop = 0.5*(charge0*_tt+ charge1*_uu)*
- ( charge0 * FVfunc(_tt,_uu,_ss,MV2) +
- charge1 * FVfunc(_uu,_tt,_ss,MV2) )/(_tt+_uu);
- double partloop = smloop/(smborn0*smbfact);
- // PR checked above here 26/8/09
- // collinear remnant (needs checking)
- double partc = -(KP1(_xa,_ss,_muF2,0)+KP2(_xa,_ss,_muF2)-KP3(_xa,0))
- -(KP1(_xb,_ss,_muF2,1)+KP2(_xb,_ss,_muF2)-KP3(_xb,1))-2.0*(5.0-sqr(pi)/3.0);
- // real radiation
- // azimuthal angle
- double phi = Constants::twopi*_y3;
- // for singularities with parton_a:
- double xiab = 1.0 - _y1*(1.-_xa);
- double vi = (1.0 - xiab )*_y2;
- Lorentz5Momentum k_a = _p_partona/xiab;
- Lorentz5Momentum k_b = _p_partonb;
- Lorentz5Momentum k_glu = radk(_p_partona, _p_partonb, xiab, vi, phi, 0);
- Lorentz5Momentum k_ga = InvLortr(_p_partona, _p_partonb, xiab, k_glu, _p_photon, 0);
- Lorentz5Momentum k_V = InvLortr(_p_partona, _p_partonb, xiab, k_glu, _p_boson , 0);
- // first dipole term for emission from emitter
- Energy2 kadotg = k_a.dot(k_glu);
- InvEnergy2 dipole1 = Dipole(_p_partona, _p_partonb, _p_photon, _p_boson,
- charge0, charge1, MV2, kadotg, xiab);
- // second dipole term for emission from spectator
- Energy2 kbdotg = k_b.dot(k_glu);
- Lorentz5Momentum kbarp_ga = Lortr(k_a, k_b, xiab, k_glu, k_ga, 1);
- Lorentz5Momentum kbarp_V = Lortr(k_a, k_b, xiab, k_glu, k_V , 1);
- InvEnergy2 dipole2 = Dipole(k_a, xiab*k_b, kbarp_ga, kbarp_V,
- charge0, charge1, MV2, kbdotg, xiab);
- // dipole subtracted sum
- InvEnergy2 sumdipole = abs(dipole1) + abs(dipole2);
- double partreal = MatrRealGluon(k_a, k_b, k_ga, k_V, k_glu)/sumdipole
- - dipole1/abs(dipole1);
- Energy2 jacobfact = 2.0*k_a.dot(k_b)*(1.0 - xiab)*(1.0 -_xa)/(16.0*sqr(pi)*xiab);
- double pdffact = PDFratio(_xa/xiab, _xa, 0);
- double fluxfact = _ss/(k_a+k_b).m2();
- double smreala = partreal * abs(dipole1) * jacobfact * pdffact * fluxfact;
- // for singularities with parton_b:
- xiab = 1.0 -_y1*(1.-_xb);
- vi = (1.0 -xiab)*_y2;
+ MV2= _p_boson.m2();
+
+ ida = _partona->id();
+ idb = _partonb->id();
+ charge0= _partona->iCharge()/3.*ida/abs(ida);
+ charge1= _partonb->iCharge()/3.*idb/abs(idb);
+
+ // finite contribution from gluon virtual loop:
+ smbfact= 4.0*sqr(charge0*_tt + charge1*_uu)/(_tt*_uu*sqr(_tt+_uu))*GeV*GeV*GeV*GeV;
+ smborn0= (_ss*MV2 -_tt*_uu +sqr(_tt+_uu)/2.0)/(GeV*GeV*GeV*GeV);
+ smborn1= -(_ss*MV2 -_tt*_uu +sqr(_tt+_uu))/(GeV*GeV*GeV*GeV);
+ smborn2= (sqr(_tt+_uu)/2.0)/(GeV*GeV*GeV*GeV);
+ partep= 2.0*(5.0-sqr(Pi)/3.0)*1.0 +3.0*smborn1/smborn0 +2.0*smborn2/smborn0;
+
+ smloop= (charge0*_tt+ charge1*_uu)*
+ (charge0*FVfunc(_tt,_uu,_ss,MV2) +charge1*FVfunc(_uu,_tt,_ss,MV2))/(_tt+_uu)/2.0;
+ partloop= smloop/(smborn0*smbfact);
+
+ // collinear remnants for gluon radiation:
+ partc= -(KP1(_xa,_ss,_muF2,0)+KP2(_xa,_ss,_muF2)-KP3(_xa,0))
+ -(KP1(_xb,_ss,_muF2,1)+KP2(_xb,_ss,_muF2)-KP3(_xb,1))-2.0*(5.0-2.0*sqr(Pi)/3.0);
+ // coupling factor
+ alfsfact= _alphas*_CF/(2.0*Pi);
+ scale_S = _p_boson.m2();
+
+ //contributions fron real gluon radiation:
+ phi = _y3*(2.0*Pi);
+ // in the singular for gluon soft or collinear with parton_a:
+ fi = 0;
+ if (_xa<=(1.0 - 0.0000001)) {
+ xiab = (1.0 - 0.0000001)*(1.0-_y1) + _xa*_y1;
+ vi = (1.0 -xiab)*_y2 + 0.0000001*(1.0 - _y2);
+ // map to real phase space:
+ k_a = _p_partona/xiab;
+ k_b = _p_partonb;
+ k_glu = radk(_p_partona, _p_partonb, xiab, vi, phi, fi);
+ k_ga = InvLortr(_p_partona, _p_partonb, xiab, k_glu, _p_photon, fi);
+ k_V = InvLortr(_p_partona, _p_partonb, xiab, k_glu, _p_boson, fi);
+
+ kadotg = k_a.dot(k_glu);
+ kbdotg = k_b.dot(k_glu);
+
+ // map to Born phase space for the other (not singular region) dipole in the denominator dipole sum
+ kbarp_ga = Lortr(k_a, k_b, xiab, k_glu, k_ga, 1);
+ kbarp_V = Lortr(k_a, k_b, xiab, k_glu, k_V, 1);
+
+ partdipole = Dipole(_p_partona, _p_partonb, _p_photon, _p_boson, charge0, charge1, MV2, kadotg, _alphas, xiab);
+ sumdipole = partdipole +Dipole(k_a, xiab*k_b, kbarp_ga, kbarp_V, charge0, charge1, MV2, kbdotg, _alphas, xiab);
+
+ partreal = MatrRealGluon(k_a, k_b, k_ga, k_V, k_glu, scale_S)/sumdipole - 1.0;
+ jacobfact = 2.0*k_a.dot(k_b)*(1.0 -xiab)*(1.0 -_xa)/(16.0*sqr(Pi))/sqr(GeV);
+ pdffact = PDFratio(_xa/xiab, _xa, _muF2,0,_iflagcq,_hadron_A,_hadron_B);
+ fluxfact = _ss/(k_a+k_b).m2();
+ smreala = partreal *partdipole*jacobfact*pdffact*fluxfact;
+ }
+ else smreala = 0.0;
+
+ // in the singular for gluon soft or collinear with parton_b:
+ fi = 1;
+ if (_xb<=(1.0 - 0.0000001)) {
+ xiab = (1.0 - 0.0000001)*(1.0-_y1) + _xb*_y1;
+ vi = (1.0 -xiab)*_y2 + 0.0000001*(1.0 - _y2);
+ // map to real phase space:
k_a = _p_partona;
k_b = _p_partonb/xiab;
- k_glu = radk(_p_partona, _p_partonb, xiab, vi, phi, 1);
- k_ga = InvLortr(_p_partona, _p_partonb, xiab, k_glu, _p_photon, 1);
- k_V = InvLortr(_p_partona, _p_partonb, xiab, k_glu, _p_boson, 1);
+ k_glu = radk(_p_partona, _p_partonb, xiab, vi, phi, fi);
+ k_ga = InvLortr(_p_partona, _p_partonb, xiab, k_glu, _p_photon, fi);
+ k_V = InvLortr(_p_partona, _p_partonb, xiab, k_glu, _p_boson, fi);
+
kadotg = k_a.dot(k_glu);
kbdotg = k_b.dot(k_glu);
- // first dipole term for emission from emitter
- dipole1 = Dipole(_p_partona, _p_partonb, _p_photon, _p_boson,
- charge0, charge1, MV2, kbdotg, xiab);
- // second dipole term for emission from the spectator
+
+ // map to Born phase space for the other (not singular region) dipole in the denominator dipole sum
kbarp_ga = Lortr(k_a, k_b, xiab, k_glu, k_ga, 0);
kbarp_V = Lortr(k_a, k_b, xiab, k_glu, k_V, 0);
- dipole2 = Dipole(xiab*k_a, k_b, kbarp_ga, kbarp_V,
- charge0, charge1, MV2, kadotg, xiab);
- // dipole subtracted sum
- sumdipole = abs(dipole1) + abs(dipole2);
- partreal = MatrRealGluon(k_a, k_b, k_ga, k_V, k_glu)/sumdipole
- - dipole1/abs(dipole1);
- jacobfact = 2.0*k_a.dot(k_b)*(1.0 -xiab)*(1.0 -_xb)/(16.0*sqr(pi)*xiab);
- pdffact = PDFratio(_xb/xiab, _xb, 1);
+
+ partdipole = Dipole(_p_partona, _p_partonb, _p_photon, _p_boson, charge0, charge1, MV2, kbdotg, _alphas, xiab);
+ sumdipole = partdipole +Dipole(xiab*k_a, k_b, kbarp_ga, kbarp_V, charge0, charge1, MV2, kadotg, _alphas, xiab);
+
+ partreal = MatrRealGluon(k_a, k_b, k_ga, k_V, k_glu, scale_S)/sumdipole -1.0;
+ jacobfact = 2.0*k_a.dot(k_b)*(1.0 -xiab)*(1.0 -_xb)/(16.0*sqr(Pi))/sqr(GeV);
+ pdffact = PDFratio(_xb/xiab, _xb, _muF2, 1, _iflagcq, _hadron_A, _hadron_B);
fluxfact = _ss/(k_a+k_b).m2();
- double smrealb = partreal * abs(dipole1) * jacobfact * pdffact * fluxfact;
- // sum over two piece of real parts
- double smreal = (smreala + smrealb)/MatrBorn(_p_partona, _p_partonb, _p_photon,
- _p_boson, charge0, charge1, MV2);
+ smrealb = partreal *partdipole*jacobfact*pdffact*fluxfact;
+ }
+ else smrealb = 0.0;
+ // the total subtracted gluon radiation piece
+ smreal = (smreala + smrealb)/MatrBorn(_p_partona, _p_partonb, _p_photon, _p_boson, charge0, charge1, MV2);
+
+ // collinear remnants for quark radiation: d\sigma^A+d\sigma^C
+ double zi, zq, uq, ulim, phiq, zlim, shqr, partinitqr, xip, xiabqr, viqr, sumdipoleqr, smrealqrp, smrealqrg; //chargeqr,
+ double smbornqr, hfs, lnz, pz, lnmf, partqr, smrealqrz_0, pdffactqr, factqr, smcrqr, partrealqr, partdipoleqr, jacobfactqr, smrealqr, conu;
+ double zcut, RDz_0, Rz_0, Dz_0, CAz_0, charge_i, charge_V, charge_q;
+ Lorentz5Momentum plp, plv, plq, kquark, kphoton, kboson, kgluon, kb_photon, kb_boson, kq_z0, kV_z0;
+ Energy QCDcut;
+ Energy2 kpdotq, kgdotq;
+ int idq;
+ double thetacut, Rcut;
+
+ // photon fragmentation function collinear remnant
+ //fraccut = 0.4;
+ //fraccut = 0.3;
+ //thetacut = 1.0 - 0.6;
+ thetacut = 1.0 - 0.4;
+ Rcut = 0.01;
+ QCDcut = 0.14*GeV;
+ //QCDcut = 0.2*GeV;
+ //lnmf = log(_muF2/sqr(QCDcut));
+ //zlim = abs(25.0*GeV/_p_photon.perp());
+ //zlim = (_ss - MV2)/(_ss/(_xa*_xb) - MV2);
+ // boost from Born CM frame to lab frame to calculate the photon fraction constraint
+ tva = (_xa-_xb)/(_xa+_xb);
+ //plp = _p_photon;
+ //plp.boost(0.,0.,tva);
+ //plv = _p_boson;
+ //plv.boost(0.,0.,tva);
+
+ //*******************************************************************************
+ //********** Here is the photon fraction constraint ****************************
+ //********** I impose in fragmantation and real mapping ************************
+ //********** where quark radiate from photon **********************************
+ //********** The first line of zlim is from photon energy constraint ***********
+ //********** the second line is from experimental Kt cut ***********************
+ //*******************************************************************************
+ // zlim = min(max(max(plp.perp()*max(exp(plp.rapidity())+exp(plv.rapidity()),exp(-plp.rapidity())+exp(-plv.rapidity()))/(_ss/(_xa *_xb) - MV2)*
+ // sqrt(_ss/(_xa *_xb)), lastCuts().minKT(_photon)*cosh(plp.rapidity())/plp.e()), 0.5), 1.0-0.0000001);
+ //zlim = 0.1*fraccut;
+ zlim = 0.1;
+ //zlim = min(QCDcut/_p_photon.e(),1.0);
+ //zlim = max(max(plp.perp()*max(exp(plp.rapidity())+exp(plv.rapidity()),exp(-plp.rapidity())+exp(-plv.rapidity()))/(_ss/(_xa *_xb) - MV2)*
+ // sqrt(_ss/(_xa *_xb)), lastCuts().minKT(_photon)*cosh(plp.rapidity())/plp.e()), zcut);
+ // zlim = abs(zlim);
+ //zlim = max(plp.perp()*max(exp(plp.rapidity())+exp(plv.rapidity()),exp(-plp.rapidity())+exp(-plv.rapidity()))/(_ss/(_xa *_xb) - MV2)*sqrt(_ss/(_xa *_xb)), lastCuts().minKT(_photon)/plp.e() );
+ //zlim = min(max(0.3, lastCuts().minKT(_photon)*cosh(plp.rapidity())/plp.e()), 1.0-0.0000001);
+ //zlim = 0.1;
+ //zlim = (_ss - MV2)/_ss;
+
+ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ //+++++++++++++ Here we use FKS subtraction to single out the soft photon ++++++++++++
+ //+++++++++++++ divergence to make calculaton safe from singularities ++++++++++++
+ //+++++++++++++ We have aux photon fracton cut z_cut, but the total cross ++++++++++++
+ //+++++++++++++ section is independent of z_cut. RDz_0 and CAz_0 is defined+++++++++++
+ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ // zlim = 0.0;
+ zcut = 1.0;
+ //zlim = 0.5;
+ //************ photon fraction in fragmantation function where zlim is applied ***********************
+ zi = 1.0 - _y1 + zlim*_y1;
+ //zi = 1.0 - _y1;
+ idq = _quarkpi->id();
+ chargeqr = _quarkpi->iCharge()/3.*idq/abs(idq);
+ charge_q = _quarkpi->iCharge()/3.;
+ charge_i = _quark->iCharge()/3.;
+ charge_V = charge_i - charge_q;
+ smbornqr = MatrQV(_p_partona, _p_partonb, _p_photon, _p_boson, chargeqr, MV2, _alphas, _iflagcq);
+ // the fraction after exchanging the integration
+ //zx = zlim/zi;
+ zx = zi;
+ // another fragmantation function in Baur's paper
+ //hfs = (sqr(chargeqr)*(2.21-1.28*zx+1.29*sqr(zx))/(1.0-1.63*log(1.0-zx))*pow(zx,0.049)+0.002*sqr(1.0-zx)*pow(zx,-1.54))*log(_muF2/sqr(QCDcut));
+ // A-P splitting function
+ pz = (1.0+sqr(1.0-zx))/zx;
+ // the aux function I impose to have right mapping in soft photon region
+ //lnmf= log(1.0+zx)/log(2.0);
+ lnmf = 1.0;
+ // u variable upper limit
+ ulim = 2.0*(1.0-zx)*_p_photon.dot(_p_boson)*lnmf/(MV2+2.0*_p_photon.dot(_p_boson) -2.0*zx*lnmf*_p_photon.dot(_p_boson));
+ // our fragmantation function
+ //lnz = log(2.0*_p_photon.dot(_p_boson)*zx*zx*(1.0-zx)*ulim/_muF2);
+ lnz = log(2.0*_p_photon.dot(_p_boson)*(1.0-zx)*ulim/_muF2);
+ //hfs = pz*log(_muF2/sqr(QCDcut*(1.0-zx))) -13.26;
+ if (zi>0.7) hfs = pz*log(_muF2/sqr(QCDcut*(1.0-zx))) -13.26;
+ //else hfs = pz*log(1.0/sqr(1.0-zx)) -13.26 + pz*log(_muF2/sqr(QCDcut))*(3.0*sqr(zi/0.7) - 2.0*pow(zi/0.7,3));
+ else hfs = pz*log(_muF2/sqr(1.0-zx)/(2.0*_p_photon.dot(_p_boson))) -13.26 + pz*log((2.0*_p_photon.dot(_p_boson))/sqr(QCDcut))*(3.0*sqr(zi/0.7) - 2.0*pow(zi/0.7,3));
+ //hfs = pz*log(_muF2/sqr(QCDcut*(1.0-zx)));
/*
- // d\sigma^A+d\sigma^C quark radiation:
- zz = _y1;
- pn = _p_partona+ _p_partonb -zz*_p_photon;
- smbornqr = MatrQV(_p_partona, _p_partonb, zz*_p_photon, _p_boson);
- pz = (1.0+sqr(1.0-zz))/zz;
- hfs = ;
- chargeqr= ;
- lnz = log(sqr(2.0*(1.0-zz)*zz*_p_photon.dot(pn))/(_muF2*pn.m2()));
- partqr =(sqr(chargeqr)*(pz*lnz +zz) -hfs)/sqr(zz);
- pdffactqr = PDFratio(_xa, _xb, 3);
- factqr = alphae/(2.0*pi);
- smqr = smbornqr*partqr*factqr*pdffactqr/MatrBorn(_p_partona, _p_partonb, _p_photon, _p_boson, charge0, charge1, MV2);
+ // CA(z=0) for cancelling the soft photon singularity
+ CAz_0 = 2.0* log(2.0*_p_photon.dot(_p_boson)*lnmf*2.0*_p_photon.dot(_p_boson)/(sqr(QCDcut)*(MV2+2.0*_p_photon.dot(_p_boson))));
+ // photon fragmentation function collinear remnant piece
+ //partqr =sqr(chargeqr)*(pz*lnz +zx +hfs);
+ if (zi<zcut) {
+ partqr =sqr(chargeqr)*((pz*lnz +zx +hfs)*zi -CAz_0);}
+ else {
+ partqr =sqr(chargeqr)*((pz*lnz +zx +hfs)*zi);}
*/
-// Lorentz5Momentum k_1, k_2, kquark;
-// Energy E2, EV, PV;
-// double testmn, testma;
-// EV = _p_boson.e();
-// PV = sqrt(sqr(EV)-MV2);
-// E2 = (EV + PV);
-// k_1 = Lorentz5Momentum((E2/PV)*_p_boson.vect(), E2);
-// k_2 = _p_boson - k_1;
-// testmn = test2to3(_p_partona, _p_partonb, k_1, _p_photon, k_2);
-// testma = test2to3am(_p_partona, _p_partonb, k_1, _p_photon, k_2, MV2);
-// kquark = radkqr(_p_photon, _p_boson, MV2, 0.5,0.5,1.);
+ // CA(z=0) for cancelling the soft photon singularity
+ CAz_0 = 2.0*log(2.0*_p_photon.dot(_p_boson)*lnmf/(MV2+2.0*_p_photon.dot(_p_boson)));
+ if (zi >= zlim)
+ partqr = sqr(chargeqr)*((pz*lnz +zx +hfs)*zi - CAz_0);
+ //partqr = sqr(chargeqr)*((pz*log((1.0-zx)*ulim) +zx -13.26)*zi - CAz_0);
+ //partqr = sqr(chargeqr)*(-13.26)*zi;
+ // cout <<" zi > zlim: "<<zi<<" partqr= "<<partqr << "\n";}
+ // else if (zi < zlim && zi >=zcut)
+ // partqr = sqr(chargeqr)*((pz*log((1.0-zx)*ulim) +zx)*zi);
+ // cout <<" zi <= zlim && zi >zcut: "<<zi<<" partqr= "<<partqr << "\n";}
+ else
+ partqr = sqr(chargeqr)*((pz*log((1.0-zx)*ulim) +zx)*zi - CAz_0);
+ // cout <<" zi <zcut: "<<zi<<" partqr= "<<partqr << "\n";}
- //double borm1, borm2;
- //borm2= MEPP2VGamma::me2p();
- //borm1= MEPP2VGamma::me2();
- //Lorentz5Momentum loparta, lopartb, lophoton, loboson;
- //loparta= MEPP2VGamma::mompartona();
- //lopartb= MEPP2VGamma::mompartonb();
- //lophoton= MEPP2VGamma::momphoton();
- //loboson = MEPP2VGamma::momboson();
- //return 1.+ alfsfact*(partep+partloop+partc)+ smreal;
- //return 1.+ alfsfact*(partep+partloop+partc);
- return 1.0+ smreal;
+ //separatation cut:
+ if (zi < fraccut) {
+ //cout<<" separatation cut the photon FF remnant: z_frac="<<zi<<" partqr="<<partqr<<"\n";
+ partqr = 0.0;
+ }
+
+ //partqr =sqr(chargeqr)*((pz*lnz +zx +hfs)*zi);
+ pdffactqr = PDFratio(_xa, _xb, _muF2, 3, _iflagcq, _hadron_A, _hadron_B);
+ factqr = alphae/(2.0*Pi)*(1.0 - zlim)/zi;
+ //factqr = alphae/(2.0*Pi)/zi;
+
+ // PDF collinear remnants for quark radiation from initial quark:
+ if (_iflagcq==0){
+ partinitqr = KPpr(_xa,_ss,_muF2)*_alphas/(2.0*Pi);}
+ else {
+ partinitqr = KPpr(_xb,_ss,_muF2)*_alphas/(2.0*Pi);}
+ // sum of collinear remnants for quark radiation
+ //smcrqr = smbornqr*(partqr + sqr(chargeqr)*log(zcut)*CAz_0*zi)*factqr*
+ // pdffactqr/MatrBorn(_p_partona, _p_partonb, _p_photon, _p_boson, charge0, charge1, MV2)+ partinitqr;
+ smcrqr = smbornqr*partqr*factqr*pdffactqr/MatrBorn(_p_partona, _p_partonb, _p_photon, _p_boson, charge0, charge1, MV2)+ partinitqr;
+
+ //smcrqr = partinitqr;
+
+ // contribution from real quark radiation:
+ phiq = 2.0*Pi*_y3;
+
+
+ // in the singular region that quark radiation collinear with final state photon (Dpq):
+
+
+ //************ photon fraction in quark-photon collinear real piece where zlim is applied ***********************
+ //zq = 1.0 - _y1 + zlim*_y1;
+ //zlim = 0.1;
+ zq = (1.0 - MV2/2.0/_p_photon.dot(_p_boson)*1.0e-7/(1.0-1.0e-7))*(1.0 - _y1) + zlim*_y1;
+ //zq = (1.0 - MV2/2.0/_p_photon.dot(_p_boson)*1.0e-7/(1.0-1.0e-7))*(1.0 - _y1);
+ // the aux function I impose to have right mapping in soft photon region
+ // conu = log(1.0+zq)/log(2.0);
+ conu = 1.0;
+ // u variable upper limit
+ ulim = 2.0*(1.0-zq)*_p_photon.dot(_p_boson)*conu/(MV2+2.0*_p_photon.dot(_p_boson) -2.0*zq*conu*_p_photon.dot(_p_boson));
+ // uq = ulim*_y2;
+ // if (ulim > 0.0000001)
+ uq = ulim - (ulim-1.0e-7)*_y2;
+ // else uq = 0.0000001;
+ // cout << " zlim="<<zlim<< " zq="<<zq<<" uq="<<uq<<"\n";
+ // map to real phase space:
+ kquark = radkqr(_p_photon, _p_boson, MV2, zq, uq, phiq, zlim);
+ kphoton = _p_photon*zq;
+ // kphoton.setMass(ZERO);
+ // kphoton.rescaleEnergy();
+ kboson = _p_boson -kquark +(1.0-zq)/zq*kphoton;
+ kboson.rescaleMass();
+ // kboson.setMass(sqrt(MV2));
+ // kboson.rescaleEnergy();
+ kpdotq = kphoton.dot(kquark);
+ // plp = kphoton + kquark;
+ // kpdotq = plp.m2()/2.0;
+
+ //re-map the Born phase space so that no numerical errers sensitivity:
+ zq = kphoton.dot(kquark+kboson)/(kphoton.dot(kquark+kboson)+kquark.dot(kboson));
+ uq = kpdotq/kphoton.dot(kquark+kboson);
+ kb_photon = kphoton/zq;
+ kb_boson = kquark + kboson - (1.0 - zq)/zq*kphoton;
+ kb_boson.rescaleMass();
+ // kb_boson.setMass(sqrt(MV2));
+ // kb_boson.rescaleEnergy();
+ kq_z0 = radkqr(_p_photon, _p_boson, MV2, 0.0, uq, phiq, zlim);
+ kV_z0 = _p_boson -kq_z0 + _p_photon;
+ kV_z0.rescaleMass();
+ //if (uq<0.0000001)
+ //cout <<" zq="<<zq<<" uq="<<uq<<" kqdot="<<kq_z0.dot(_p_photon)/sqr(GeV)<<" kVdot="<<(kV_z0.dot(_p_boson)-MV2)/sqr(GeV)<<" conserve?="<<
+ // _p_partona.isNear(kV_z0+kq_z0-_p_partonb, 0.00000001)<<"\n";
+ // cout <<" ratio of k_q.k_p="<<kpdotq/(uq*zq*_p_boson.dot(_p_photon)) <<"\n";
+ // if (uq!=kpdotq/kphoton.dot(kquark+kboson)) {cout<<" !!!!!!!!!!!!!!!!!!!!!!!!!uq is wrong!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<" uq="<<uq<<" ?="<<kpdotq/kphoton.dot(kquark+kboson)<<"\n";}
+ // if (zq!=kphoton.dot(kquark+kboson)/(kphoton.dot(kquark+kboson)+kquark.dot(kboson)))
+ // {cout<<" !!!!!!!!!!!!!!!!!!!!!!!!!zq is wrong!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<" zq="<<zq<<" ?="
+ // <<kphoton.dot(kquark+kboson)/(kphoton.dot(kquark+kboson)+kquark.dot(kboson))<<"\n";}
+
+ //Born phase space for Dgq in the denominator dipole sum:
+ xip = 1.0- kquark.dot(_p_partona+ _p_partonb)/_p_partona.dot(_p_partonb);
+ if (_iflagcq==0){
+ fi = 0;
+ kgdotq = _p_partona.dot(kquark);
+ }
+ else {
+ fi = 1;
+ kgdotq = _p_partonb.dot(kquark);
+ }
+ kbarp_ga = Lortr(_p_partona, _p_partonb, xip, kquark, kphoton, fi);
+ kbarp_V = Lortr(_p_partona, _p_partonb, xip, kquark, kboson, fi);
+
+ smbornqr = MatrQV(_p_partona, _p_partonb, kq_z0, kV_z0, chargeqr, MV2, _alphas, _iflagcq);
+ partdipoleqr = Dipolepqr(_p_partona, _p_partonb, kb_photon, kb_boson, chargeqr, MV2, kpdotq, zq, _alphas, _iflagcq);
+
+ if (_iflagcq==0){
+ sumdipoleqr = partdipoleqr + Dipolegluqr(xip*_p_partona,_p_partonb,kbarp_ga,kbarp_V,charge0,charge1,MV2,kgdotq,_alphas,xip);
+ RDz_0 = 8.0*Pi*alphae* (((charge_i*charge_q)*_p_partonb.dot(kq_z0)/_p_partonb.dot(kb_photon)/kq_z0.dot(kb_photon)
+ + (charge_V*charge_i)*_p_partonb.dot(kV_z0)/_p_partonb.dot(kb_photon)/kV_z0.dot(kb_photon)
+ - (charge_V*charge_q)*kq_z0.dot(kV_z0)/kV_z0.dot(kb_photon)/kq_z0.dot(kb_photon))*smbornqr
+ - sqr(charge_q)/kq_z0.dot(kb_photon)*MatrQV(_p_partona, _p_partonb, kb_photon, kb_boson, chargeqr, MV2, _alphas, _iflagcq) )
+ *sqr(GeV);
+ Dz_0 = 8.0*Pi*alphae*sqr(charge_q)/kq_z0.dot(kb_photon)*MatrQV(_p_partona, _p_partonb, kb_photon, kb_boson, chargeqr, MV2, _alphas, _iflagcq)
+ *sqr(GeV);
+ Rz_0 = RDz_0 + Dz_0;
+ }
+ else {
+ sumdipoleqr = partdipoleqr + Dipolegluqr(_p_partona,xip*_p_partonb,kbarp_ga,kbarp_V,charge0,charge1,MV2,kgdotq,_alphas,xip);
+ RDz_0 = 8.0*Pi*alphae* (((charge_i*charge_q)*_p_partona.dot(kq_z0)/_p_partona.dot(kb_photon)/kq_z0.dot(kb_photon)
+ + (charge_V*charge_i)*_p_partona.dot(kV_z0)/_p_partona.dot(kb_photon)/kV_z0.dot(kb_photon)
+ - (charge_V*charge_q)*kq_z0.dot(kV_z0)/kV_z0.dot(kb_photon)/kq_z0.dot(kb_photon))*smbornqr
+ - sqr(charge_q)/kq_z0.dot(kb_photon)*MatrQV(_p_partona, _p_partonb, kb_photon, kb_boson, chargeqr, MV2, _alphas, _iflagcq) )
+ *sqr(GeV);
+ Dz_0 = 8.0*Pi*alphae*sqr(charge_q)/kq_z0.dot(kb_photon)*MatrQV(_p_partona, _p_partonb, kb_photon, kb_boson, chargeqr, MV2, _alphas, _iflagcq)
+ *sqr(GeV);
+ Rz_0 = RDz_0 + Dz_0;
+ }
+
+ jacobfactqr = 2.0*kphoton.dot(_p_boson)*ulim*(1.0-zlim)/(16.0*sqr(Pi))/sqr(GeV);
+ //jacobfactqr = 2.0*kb_photon.dot(kb_boson)*ulim/(16.0*sqr(Pi))/sqr(GeV);
+ partrealqr = MatrRealQuark(_p_partona, _p_partonb, kphoton, kboson, kquark, scale_S, _iflagcq)/sumdipoleqr - 1.0;
+ //txa = MatrRealQuark(_p_partona, _p_partonb, kphoton, kboson, kquark);
+ pdffactqr = PDFratio(_xa, _xb, _muF2, 3, _iflagcq, _hadron_A, _hadron_B);
+ //zcut = 1.0;
+ // real piece for quark radiation collinear with final state photon
+ if (zq<zcut) {
+ smrealqrp = pdffactqr*jacobfactqr*(partrealqr*partdipoleqr*zq*zq -RDz_0)/zq;}
+ else {
+ smrealqrp = pdffactqr*jacobfactqr*partrealqr*partdipoleqr*zq;}
+ //cout <<" zq="<<zq<<" uq="<<uq<<" zlim="<<zlim<<" kq_z0="<<kq_z0.e()/GeV<<" smrealqrp="<<smrealqrp<<"\n";
+
+ //separatation cut:
+ plp = kphoton;
+ plv = kboson;
+ plq = kquark;
+ plp.boost(0.,0.,tva);
+ plq.boost(0.,0.,tva);
+ if (sqrt(sqr(plp.rapidity()-plq.rapidity()) + min(min(sqr(plp.phi()-plq.phi()), sqr(plp.phi()-plq.phi()+2.0*Pi)), sqr(plp.phi()-plq.phi()-2.0*Pi)))<Rcut) {
+ if (plp.e()/(plp.e()+plq.e()) <fraccut) {
+
+ //if ((kphoton.dot(kquark)/(kphoton.e()*kquark.e()))<thetacut) {
+ //if (kphoton.e()/(kphoton.e()+kquark.e())<fraccut) {
+ if (zq<zcut) {
+ smrealqrp = smrealqrp - pdffactqr*jacobfactqr*((partrealqr+1.0)*partdipoleqr*zq - Rz_0/zq);
+ //cout<<" separatation cut the real piece: E_frac="<<kphoton.e()/(kphoton.e()+kquark.e())<<" smrealqrp="<<smrealqrp<<"\n";
+ }
+ else {
+ smrealqrp = smrealqrp - pdffactqr*jacobfactqr*(partrealqr+1.0)*partdipoleqr*zq;
+ }
+ }
+ }
+ if (zi < fraccut) {
+ if (zq<zcut) {
+ smrealqrp = smrealqrp + pdffactqr*jacobfactqr*(partdipoleqr*zq - Dz_0/zq);
+ //cout<<" separatation cut the subtracted term: z_frac="<<zq<<" smrealqrp="<<smrealqrp<<"\n";
+ }
+ else {
+ smrealqrp = smrealqrp + pdffactqr*jacobfactqr*partdipoleqr*zq;
+ }
+ }
+
+ // the zcut remnant term in realqr piece after extracting the soft photon singularity
+ ulim = 2.0*_p_photon.dot(_p_boson)*conu/(MV2+2.0*_p_photon.dot(_p_boson));
+ uq = ulim - (ulim-1.0e-7)*_y2;
+ kq_z0 = radkqr(_p_photon, _p_boson, MV2, 0.0, uq, phiq, zlim);
+ kV_z0 = _p_boson -kq_z0 + _p_photon;
+ kV_z0.rescaleMass();
+ smbornqr = MatrQV(_p_partona, _p_partonb, kq_z0, kV_z0, chargeqr, MV2, _alphas, _iflagcq);
+ if (_iflagcq==0){
+ RDz_0 = 8.0*Pi*alphae* (((charge_i*charge_q)*_p_partonb.dot(kq_z0)/_p_partonb.dot(kb_photon)/kq_z0.dot(kb_photon)
+ + (charge_V*charge_i)*_p_partonb.dot(kV_z0)/_p_partonb.dot(kb_photon)/kV_z0.dot(kb_photon)
+ - (charge_V*charge_q)*kq_z0.dot(kV_z0)/kV_z0.dot(kb_photon)/kq_z0.dot(kb_photon))*smbornqr
+ - sqr(charge_q)/kq_z0.dot(kb_photon)*MatrQV(_p_partona, _p_partonb, kb_photon, kb_boson, chargeqr, MV2, _alphas, _iflagcq) )
+ *sqr(GeV);
+ }
+ else {
+ RDz_0 = 8.0*Pi*alphae* (((charge_i*charge_q)*_p_partona.dot(kq_z0)/_p_partona.dot(kb_photon)/kq_z0.dot(kb_photon)
+ + (charge_V*charge_i)*_p_partona.dot(kV_z0)/_p_partona.dot(kb_photon)/kV_z0.dot(kb_photon)
+ - (charge_V*charge_q)*kq_z0.dot(kV_z0)/kV_z0.dot(kb_photon)/kq_z0.dot(kb_photon))*smbornqr
+ - sqr(charge_q)/kq_z0.dot(kb_photon)*MatrQV(_p_partona, _p_partonb, kb_photon, kb_boson, chargeqr, MV2, _alphas, _iflagcq) )
+ *sqr(GeV);
+ }
+ jacobfactqr = 2.0*kb_photon.dot(kb_boson)*ulim/(16.0*sqr(Pi))/sqr(GeV);
+ smrealqrz_0 = pdffactqr*jacobfactqr*log(zcut)*RDz_0;
+ //smrealqrz_0 = 0.0;
+ //separatation cut:
+ // if ((kphoton.dot(kquark)/(kphoton.e()*kquark.e()))<thetacut) {
+ // if (kphoton.e()/(kphoton.e()+kquark.e())<fraccut) {
+ // smrealqrz_0 = 0.0;
+ // }
+ //}
+
+ // in the singular region that quark radiation collinear with initial state gluon (Dgq):
+ if (_iflagcq==0){
+ fi = 0;
+ xiabqr = (1.0 - 0.0000001)*(1.0 - _y1) +_xa*_y1;
+ k_a = _p_partona/xiabqr;
+ k_b = _p_partonb;
+ kgluon = k_a;}
+ else {
+ fi = 1;
+ xiabqr = (1.0 - 0.0000001)*(1.0 - _y1) +_xb*_y1;
+ k_a = _p_partona;
+ k_b = _p_partonb/xiabqr;
+ kgluon = k_b;}
+ viqr = (1.0-xiabqr)*_y2 + 0.0000001*(1.0 - _y2);
+ // map to real phase space:
+ kquark = radk(_p_partona, _p_partonb, xiabqr, viqr, phiq, fi);
+ kphoton = InvLortr(_p_partona, _p_partonb, xiabqr, kquark, _p_photon, fi);
+ kboson = InvLortr(_p_partona, _p_partonb, xiabqr, kquark, _p_boson, fi);
+
+ kgdotq = kgluon.dot(kquark);
+ kpdotq = kphoton.dot(kquark);
+ //Born phase space for Dpq in the denominator dipole sum:
+ zi = 1.0/(1.0 + kquark.dot(kboson)/kphoton.dot(kquark+kboson));
+ kbarp_ga = kphoton/zi;
+ kbarp_V = kboson + kquark -(1.0-zi)*kbarp_ga;
+ kbarp_V.rescaleMass();
+ ulim = 2.0*(1.0-zi)*kbarp_ga.dot(kbarp_V)/(MV2+ 2.0*(1.0-zi)*kbarp_ga.dot(kbarp_V));
+
+ partdipoleqr = Dipolegluqr(_p_partona, _p_partonb, _p_photon, _p_boson,charge0,charge1,MV2,kgdotq,_alphas,xiabqr);
+ if (_iflagcq==0){
+ jacobfactqr = 2.0*k_a.dot(k_b)*(1.0-xiabqr)*(1.0-_xa)/(16.0*sqr(Pi))/sqr(GeV);
+ pdffactqr = PDFratio(_xa/xiabqr, _xa, _muF2, 4, _iflagcq, _hadron_A, _hadron_B);
+ }
+ else {
+ jacobfactqr = 2.0*k_a.dot(k_b)*(1.0-xiabqr)*(1.0-_xb)/(16.0*sqr(Pi))/sqr(GeV);
+ pdffactqr = PDFratio(_xb/xiabqr, _xb, _muF2, 4, _iflagcq, _hadron_A, _hadron_B);
+ }
+ sumdipoleqr = partdipoleqr + Dipolepqr(k_a, k_b, kbarp_ga, kbarp_V, chargeqr, MV2, kpdotq, zi, _alphas, _iflagcq);
+ fluxfact = _ss/(k_a+k_b).m2();
+ partrealqr = MatrRealQuark(k_a, k_b, kphoton, kboson, kquark, scale_S, _iflagcq)/sumdipoleqr - 1.0;
+ // real piece for quark radiation collinear with initial state quark
+ smrealqrg = pdffactqr*jacobfactqr*partrealqr*partdipoleqr*fluxfact;
+ /*
+ plp = kphoton;
+ plp.boost(0.,0.,tva);
+ if ((_iflagcq==0 && _xa>(1.0 - 1.0e-7)) || (_iflagcq==1 && _xb>(1.0 - 1.0e-7)) || plp.e()/(lastCuts().minKT(_photon)*cosh(plp.rapidity()))<1.0)
+ smrealqrg = 0.0;
+ */
+ // if ((_iflagcq==0 && _xa>(1.0 - 1.0e-7)) || (_iflagcq==1 && _xb>(1.0 - 1.0e-7)) || kphoton.e()/(lastCuts().minKT(_photon)*cosh(kphoton.rapidity()))<1.0)
+ //if ((_iflagcq==0 && _xa>(1.0 - 1.0e-7)) || (_iflagcq==1 && _xb>(1.0 - 1.0e-7)) || kphoton.e()/GeV<20.0)
+ //if ((_iflagcq==0 && _xa>(1.0 - 1.0e-7)) || (_iflagcq==1 && _xb>(1.0 - 1.0e-7)))
+ // { cout<< " xa="<<_xa<<" xb="<<_xb<<" xiab="<<xiab<<" vi="<<vi<<" xiabqr="<<xiabqr<<" viqr="<<viqr<<" smreal="<<smreal<<" smrealqr="
+ // <<(smrealqrg)/MatrBorn(_p_partona, _p_partonb, _p_photon, _p_boson, charge0, charge1, MV2)<<" cut="<<lastCuts().minKT(_photon)/GeV<<"\n";
+
+ //separatation cut:
+ //if ((kphoton.dot(kquark)/(kphoton.e()*kquark.e()))<thetacut) {
+ // if (kphoton.e()/(kphoton.e()+kquark.e())<fraccut) {
+ plp = kphoton;
+ plp.boost(0.,0.,tva);
+ plq = kquark;
+ plq.boost(0.,0.,tva);
+ if (sqrt(sqr(plp.rapidity()-plq.rapidity())+min(sqr(plp.phi()-plq.phi()),sqr(2.0*Pi-abs(plp.phi()-plq.phi()))))<Rcut) {
+ if (plp.e()/(plp.e()+plq.e())<fraccut) {
+ //cout<<" cut in Dgq"<<"\n";
+ smrealqrg = 0.0;
+ }
+ }
+
+ // smrealqrg = 0.0;
+ // the total subtracted quark radiation piece
+ //smrealqr = (smrealqrp + smrealqrg + smrealqrz_0)/MatrBorn(_p_partona, _p_partonb, _p_photon, _p_boson, charge0, charge1, MV2);
+ smrealqr = (smrealqrp + smrealqrg)/MatrBorn(_p_partona, _p_partonb, _p_photon, _p_boson, charge0, charge1, MV2);
+
+ //cout <<" zq="<<zq<<" uq="<<uq<<" zlim="<<zlim<<" kq_z0="<<kq_z0.e()/GeV<<" smrealqrp="<<smrealqrp<<" smrealqr="<<smrealqr<<" smcrqr="<<smcrqr<<" RDz_0="<<RDz_0<<"\n";
+ //smrealqr = (smrealqrg)/MatrBorn(_p_partona, _p_partonb, _p_photon, _p_boson, charge0, charge1, MV2);
+ //cout<< " smreal="<<smreal<< " smreala="<<smreala<< " smrealb="<<smrealb<< " smrealqr="<<smrealqr<<" smcrqr="<<smcrqr<<" xiab="<<xiab<<" vi="<<vi<<" smrealqrg="<<smrealqrg<< " smrealqrp="<<smrealqrp<<" whole NLO="<<alfsfact*(partep+partloop+partc)+ smreal+ smcrqr+ smrealqr<<"\n";
+ return 1.0 +alfsfact*(partep+partloop+partc)+ smreal+ smcrqr+ smrealqr;
+ // if (abs(kpdotq/(uq*zq*_p_boson.dot(_p_photon)) - 1.0)>=0.000000001) {
+ // if (zq>= zcut ) {
+ // if (uq<=0.000000001 && abs((partdipoleqr - txa)/txa)>=0.01 )
+ // cout <<" zq="<<zq<< " uq = "<< uq <<" dipole="<<partdipoleqr<<" sumdipole="<<sumdipoleqr<<" realME="<<txa<<" partrealqr="<<partrealqr
+ // <<" ratio of kq.kp="<<plp.m2()/(2.0*uq*zq*kb_boson.dot(kb_photon)) <<" D/R="<<partdipoleqr/txa<<"\n";
+ // return 1.0;}
+ // else {
+ //return 1.0 + alfsfact*(partep+partloop+partc) + smreal + smrealqr;
+ // return 1.0 +alfsfact*(partep+partloop);
}
+
+ //merge from VGammaHardGenerator
+HardTreePtr MEPP2VGammaPowheg::
+generateHardest(ShowerTreePtr tree, vector<ShowerInteraction::Type>) {
+ Energy2 s_;
+ Energy rs_;
+ // get a pointer to the standard model object in the run
+ static const tcHwSMPtr hwsm = dynamic_ptr_cast<tcHwSMPtr>(generator()->standardModel());
+ // get the particles to be showered
+ beams_.clear();
+ partons_.clear();
+ // find the incoming particles
+ ShowerParticleVector incoming;
+ quarkplus_ = true;
+ vector<ShowerProgenitorPtr> particlesToShower;
+ //generator()->log() << " Here is generateHardest \n";
+ //progenitor particles are produced in z direction.
+ for( map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator
+ cit = tree->incomingLines().begin();
+ cit != tree->incomingLines().end(); ++cit ) {
+ incoming.push_back( cit->first->progenitor() );
+ beams_.push_back( cit->first->beam() );
+ partons_.push_back( cit->first->progenitor()->dataPtr() );
+ // check that quark is along +ve z direction
+ //if(cit->first->progenitor()->id() > 0 &&
+ // cit->first->progenitor()->momentum().z() < ZERO )
+ // quarkplus_ = false;
+ particlesToShower.push_back( cit->first );
+ }
+ // find the outgoing particles
+ tShowerParticlePtr boson,photon;
+ for(map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator
+ cjt=tree->outgoingLines().begin();cjt!=tree->outgoingLines().end();++cjt) {
+ if(cjt->first->progenitor()->id()==ParticleID::gamma)
+ photon = cjt->first->progenitor();
+ else if(abs(cjt->first->progenitor()->id())==ParticleID::Wplus||
+ cjt->first->progenitor()->id()==ParticleID::Z0)
+ boson = cjt->first->progenitor();
+ particlesToShower.push_back(cjt->first);
+ }
+ assert(boson&&photon);
+ // we are assuming quark first, swap order to ensure this
+ // if antiquark first
+ if(partons_[0]->id()<partons_[1]->id()) {
+ swap(partons_[0],partons_[1]);
+ swap(beams_[0],beams_[1]);
+ swap(particlesToShower[0],particlesToShower[1]);
+ }
+ quarkplus_ = particlesToShower[0]->progenitor()->momentum().z() > ZERO;
+ // Born variables
+ // Rapidity of the photon
+ _p_photon = photon->momentum();
+ _p_boson = boson->momentum();
+ photonRapidity_ = photon->momentum().rapidity();
+ // Rapidity of the gauge boson
+ bosonRapidity_ = boson->momentum().rapidity();
+ // pT of the photon
+ photonpT_ = photon->momentum().perp();
+ // Azimuth of the photon
+ photonAzimuth_ = photon->momentum().phi();
+ // gauge boson mass
+ //bosonMass_ = boson->mass();
+ MV2 = sqr(boson->mass());
+ // mass of the boson/photon system
+ systemMass_ = (_p_photon+_p_boson).m();
+ // direction flip if needed
+ /*
+ if(!quarkplus_) {
+ photonRapidity_ *= -1.;
+ bosonRapidity_ *= -1.;
+ photonAzimuth_ *= -1.;
+ _p_photon.setZ((-1.)*_p_photon.z());
+ _p_boson.setZ((-1.)*_p_boson.z());
+ }
+ */
+ // ParticleData objects
+ _photon = photon->dataPtr();
+ _boson = boson->dataPtr();
+ // CMS energy of the hadron collision
+ s_ = generator()->currentEvent()->primaryCollision()->m2();
+ rs_ = sqrt(s_);
+ // Borm momentum fractions
+ double systemRapidity = (_p_photon + _p_boson).rapidity();
+ //if(!quarkplus_) systemRapidity *= -1.;
+ x_[0] = systemMass_*exp( systemRapidity)/rs_;
+ x_[1] = systemMass_*exp(-systemRapidity)/rs_;
+ //generator()->log()<<"systemMass_="<<systemMass_/GeV<<" rs_*sqrt(x1x2)="<<rs_*sqrt(x_[0]*x_[1])/GeV;
+ //incoming parton ParticleData object and momenta
+ _partona= partons_[0];
+ _partonb= partons_[1];
+ _p_partona= Lorentz5Momentum(ZERO, ZERO, x_[0]*rs_/2.0, x_[0]*rs_/2.0, ZERO);
+ _p_partonb= Lorentz5Momentum(ZERO, ZERO, -x_[1]*rs_/2.0, x_[1]*rs_/2.0, ZERO);
+ if(!quarkplus_) {
+ swap(_p_partona,_p_partonb);
+ swap(x_[0],x_[1]);}
+
+ //calculate the CKM matrix square
+ int iu, id;
+ iu= abs(_partona->id());
+ id= abs(_partonb->id());
+ if(iu%2!=0) swap(iu,id);
+ iu = (iu-2)/2;
+ id = (id-1)/2;
+
+ ckm = hwsm->CKM(iu,id);
+ // the third componet of isospin of the quark when vector boson is Z0
+ I3quark = -double(abs(_partona->id())%2) + 0.5;
+ // The charges of the quark and anti-quark
+ charge0 = _partona->iCharge()/3.*_partona->id()/abs(_partona->id());
+ charge1 = _partonb->iCharge()/3.*_partonb->id()/abs(_partonb->id());
+ // constants
+ Pi= Constants::pi;
+ _CF= 4.0/3.0;
+ _TR= 1.0/2.0;
+ sin2w = hwsm->sin2ThetaW();
+ alphae = hwsm->alphaEM(sqr(systemMass_));
+ _muF2 = MV2;
+ // generate the new configuration
+ pTqqbar_ = -GeV;
+ pTqg_ = -GeV;
+ pTgqbar_ = -GeV;
+ //generator()->log()
+ //throw InitException()<< " conserve?="<<(sqr((_p_partona+_p_partonb-_p_photon-_p_boson).e())+sqr((_p_partona+_p_partonb-_p_photon-_p_boson).z()))
+ // /sqr(GeV<<" (_p_photon+_p_boson).z=" <<(_p_photon+_p_boson).z()/GeV<<" (_p_photon+_p_boson).e=" <<(_p_photon+_p_boson).e()/GeV
+ // << " x_[0]="<<x_[0]<< " x_[1]="<<x_[1] <<"\n";
+ // <<<<<<<<<<<<<<<<<<< Here we begin to generate the additional partonic radiation >>>>>>>>>>>>>>
+ // generate qq_bar to gluon Vgamma events
+
+ //generator()->log() << " generate qq_bar to gluon Vgamma events" << "\n";
+
+ //throw InitException() << " generate qq_bar to gluon Vgamma events";
+ // << Exception::abortnow;
+ generateQQbarG();
+ // generate qg to q Vgamma events (1) and gq_bar to q_bar Vgamma events (2)
+
+ //generator()->log() << " generate qg to q Vgamma events" << "\n";
+ generateQGQ(1);
+
+ //generator()->log() << " generate gq_bar to q_bar Vgamma events" << "\n";
+ generateQGQ(2);
+
+ if(pTqqbar_<ZERO && pTqg_<ZERO && pTgqbar_<ZERO) {
+ for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
+ particlesToShower[ix]->maximumpT(pTmin_,ShowerInteraction::QED);
+ particlesToShower[ix]->maximumpT(pTmin_,ShowerInteraction::QCD);
+ }
+ return HardTreePtr();
+ }
+ // select the type of emission
+ int emissionType=0;
+ if (pTqqbar_>pTqg_ && pTqqbar_>pTgqbar_ ) emissionType = 1;
+ else if (pTqg_>pTqqbar_ && pTqg_>pTgqbar_ ) emissionType = 2;
+ else if (pTgqbar_>pTqqbar_ && pTgqbar_>pTqg_ ) emissionType = 3;
+ int iemit;
+ ShowerParticleVector newparticles;
+ Lorentz5Momentum pboson,pphoton;
+ Energy pTEmit;
+ // q qbar -> V gamma g
+ if(emissionType==1) {
+ newparticles.push_back(new_ptr(ShowerParticle(partons_[0] ,false)));
+ newparticles.push_back(new_ptr(ShowerParticle(partons_[1] ,false)));
+ newparticles.push_back(new_ptr(ShowerParticle(_gluon , true)));
+ newparticles[0]->set5Momentum(pQqqbar_);
+ newparticles[1]->set5Momentum(pQbarqqbar_);
+ newparticles[2]->set5Momentum(pGqqbar_);
+ pboson = pVqqbar_;
+ pphoton = pGammaqqbar_;
+ iemit = pQqqbar_.z()/pGqqbar_.rapidity()>ZERO ? 0 : 1;
+ pTEmit = pTqqbar_;
+ }
+ // q g -> q V gamma
+ else if(emissionType==2) {
+ iemit=1;
+ newparticles.push_back(new_ptr(ShowerParticle(partons_[0] ,false)));
+ newparticles.push_back(new_ptr(ShowerParticle(_gluon ,false)));
+ newparticles.push_back(new_ptr(ShowerParticle(partons_[1]->CC(), true)));
+ newparticles[0]->set5Momentum(pQinqg_);
+ newparticles[1]->set5Momentum(pGqg_);
+ newparticles[2]->set5Momentum(pQoutqg_);
+ pboson = pVqg_;
+ pphoton = pGammaqg_;
+ pTEmit = pTqg_;
+ QGQISR = QGQISR_qg;
+ }
+ // g qbar -> qbar V gamma
+ else {
+ iemit=0;
+ newparticles.push_back(new_ptr(ShowerParticle(_gluon ,false)));
+ newparticles.push_back(new_ptr(ShowerParticle(partons_[1] ,false)));
+ newparticles.push_back(new_ptr(ShowerParticle(partons_[0]->CC(), true)));
+ newparticles[0]->set5Momentum(pGgqbar_);
+ newparticles[1]->set5Momentum(pQingqbar_);
+ newparticles[2]->set5Momentum(pQoutgqbar_);
+ pboson = pVgqbar_;
+ pphoton = pGammagqbar_;
+ pTEmit = pTgqbar_;
+ QGQISR = QGQISR_gqbar;
+ }
+
+ double labbe;
+ labbe = (x_[0]-x_[1])/(x_[0]+x_[1]);
+ if(!quarkplus_) labbe *= -1.;
+ Lorentz5Momentum ka, kb, kph, kbo, kemit, bpa, bpb, bpV, bpp;
+ //look into the events cut out by the photon pT and rapidity cuts:
+ ka = newparticles[0]->momentum();
+ kb = newparticles[1]->momentum();
+ kemit = newparticles[2]->momentum();
+ kph = pphoton;
+ kbo = pboson;
+ ka.boost(0.,0.,-labbe);
+ kemit.boost(0.,0.,-labbe);
+ kb.boost(0.,0.,-labbe);
+ kph.boost(0.,0.,-labbe);
+ kbo.boost(0.,0.,-labbe);
+ bpa = meMomenta()[0];
+ bpb = meMomenta()[1];
+ bpV = meMomenta()[2];
+ bpp = meMomenta()[3];
+ bpa.boost(0.,0.,labbe);
+ bpb.boost(0.,0.,labbe);
+ bpV.boost(0.,0.,labbe);
+ bpp.boost(0.,0.,labbe);
+ /*
+ if (pphoton.perp()/(20.*GeV)<1. || abs(pphoton.rapidity())>2.7)
+ generator()->log()<<" Investigate events by photon pT cut: "<<" emission="<<emissionType<<"\n pa = "<<newparticles[0]->momentum()/GeV<<"\n"
+ <<" pb = "<<newparticles[1]->momentum()/GeV<<"\n"
+ <<" pemit="<<newparticles[2]->momentum()/GeV<<"\n"<<" pV = "<<pboson/GeV<<"\n"<<" pph = "<<pphoton/GeV<<"\n"
+ <<" x0="<<x_[0]<<" x1="<<x_[1]<<" xa="<<lastX1()<<" quark="<<quarkplus_<<" photon pT="<<pphoton.perp()/GeV
+ <<" in lab="<<kph.perp()/GeV<<" y="<<pphoton.rapidity()<<" Born pT="<<bpp.perp()/GeV<<" Born y="<<bpp.rapidity()<<"\n"
+ <<" BornPa="<<meMomenta()[0]/GeV<<" in lab"<<bpa/GeV<<"\n"<<" BornPb="<<meMomenta()[1]/GeV<<" in lab"<<bpb/GeV<<"\n"
+ <<" BornPV="<<meMomenta()[2]/GeV<<" in lab"<<bpV/GeV<<"\n"<<" BornPph="<<meMomenta()[3]/GeV<<" in lab"<<bpp/GeV<<"\n"
+ <<" ka = "<<ka/GeV<<"\n"<<" kb = "<<kb/GeV<<"\n"<<" kemit="<<kemit/GeV<<"\n"<<" kV = "<<kbo/GeV<<"\n"<<" kph = "<<kph/GeV<<"\n";
+ */
+ /*
+ if (abs(pphoton.rapidity())>2.7)
+ generator()->log()<<" Investigate events by photon rapidity cut:\n pa = "<<newparticles[0]->momentum()/GeV<<"\n"
+ <<" pb = "<<newparticles[1]->momentum()/GeV<<"\n"
+ <<" pemit="<<newparticles[2]->momentum()/GeV<<"\n"<<" pV = "<<pboson/GeV<<"\n"<<" pph = "<<pphoton/GeV<<"\n"
+ <<" x0="<<x_[0]<<" x1="<<x_[1]<<" xa="<<lastX1()<<" quark="<<quarkplus_<<" photon pT="<<pphoton.perp()/GeV
+ <<" in lab="<<kph.perp()/GeV<<" y="<<pphoton.rapidity()<<" Born pT="<<bpp.perp()/GeV<<" Born y="<<bpp.rapidity()<<"\n"
+ <<" BornPa="<<meMomenta()[0]/GeV<<" in lab"<<bpa/GeV<<"\n"<<" BornPb="<<meMomenta()[1]/GeV<<" in lab"<<bpb/GeV<<"\n"
+ <<" BornPV="<<meMomenta()[2]/GeV<<" in lab"<<bpV/GeV<<"\n"<<" BornPph="<<meMomenta()[3]/GeV<<" in lab"<<bpp/GeV<<"\n"
+ <<" ka = "<<ka/GeV<<"\n"<<" kb = "<<kb/GeV<<"\n"<<" kemit="<<kemit/GeV<<"\n"<<" kV = "<<kbo/GeV<<"\n"<<" kph = "<<kph/GeV<<"\n";
+ */
+
+ // QGQISR =1;
+ generator()->log()<<" check the emission type: emissionType="<<emissionType<<" QGQISR="<<QGQISR<<"\n";
+ // create the photon
+ newparticles.push_back(new_ptr(ShowerParticle(photon->dataPtr(),true)));
+ newparticles.back()->set5Momentum(pphoton);
+ // create the boson
+ newparticles.push_back(new_ptr(ShowerParticle(boson ->dataPtr(),true)));
+ newparticles.back()->set5Momentum(pboson);
+ // newparticle[5]
+ Lorentz5Momentum poff;
+ // ISR:
+ if (emissionType==1 || QGQISR==1) {
+ poff = newparticles[iemit]->momentum()-newparticles[2]->momentum();
+ poff.rescaleMass();
+ newparticles.push_back(new_ptr(ShowerParticle(partons_[iemit],false)));
+ newparticles.back()->set5Momentum(poff);}
+ //FSR
+ else {
+ poff = newparticles[2]->momentum() + newparticles[3]->momentum();
+ poff.rescaleMass();
+ newparticles.push_back(new_ptr(ShowerParticle(partons_[iemit]->CC(),false)));
+ newparticles.back()->set5Momentum(poff);}
+
+
+
+ // find the sudakov for the branching
+ //not apply when we merge the Powheg shower class into the matrix element class in the new version of Herwig++ ??
+ /*
+ SudakovPtr sudakov;
+ tEvolverPtr Evolver_;
+ Evolver_ = Evolver();
+ // **********should treat it for different types of emission***************
+ // try to consider ISR in quark/antiquark radiation first:
+ // ISR:
+ if (emissionType==1 || QGQISR==1) {
+ BranchingList branchings=Evolver_->splittingGenerator()->initialStateBranchings();
+ long index = abs(partons_[iemit]->id());
+ IdList br(3);
+ // types of particle in the branching
+ // *********are these types of branching br[] assigned correctly? Only apply for the ISR****************
+ // gqbar to qar V gamma
+ br[0]=newparticles[iemit]->id();
+ br[1]=newparticles[ 5 ]->id();
+ br[2]=newparticles[ 2 ]->id();
+ if(emissionType==1) { //q qbar to g v gamma
+ br[0]=abs(br[0]);
+ br[1]=abs(br[1]);
+ }
+ else if(emissionType==2) { //q g to q V gamma
+ br[1]=-br[1];
+ br[2]=-br[2];
+ }
+ // **********should treat it for different types of emission?***************
+ for(BranchingList::const_iterator cit = branchings.lower_bound(index);
+ cit != branchings.upper_bound(index); ++cit ) {
+ IdList ids = cit->second.second;
+ if(ids[0]==br[0]&&ids[1]==br[1]&&ids[2]==br[2]) {
+ sudakov=cit->second.first;
+ break;
+ }
+ }
+ }
+ // FSR:
+ else {
+ BranchingList branchings=Evolver_->splittingGenerator()->finalStateBranchings();
+ long index = abs(partons_[iemit]->CC()->id());
+ IdList brp(3);
+ brp[0]=index;
+ brp[1]=index;
+ brp[2]=newparticles[3]->id();
+ for(BranchingList::const_iterator cit = branchings.lower_bound(index);
+ cit != branchings.upper_bound(index); ++cit ) {
+ IdList ids = cit->second.second;
+ if(ids[0]==brp[0]&&ids[1]==brp[1]&&ids[2]==brp[2]) {
+ sudakov=cit->second.first;
+ break;
+ }
+ }
+ }
+
+ if(!sudakov) throw Exception() << "Can't find Sudakov for the hard emission in "
+ << "VGammaHardGenerator::generateHardest()"
+ << Exception::runerror;
+
+ */
+
+ vector<HardBranchingPtr> nasonin,nasonhard;
+ // ISR:
+ if (emissionType==1 || QGQISR==1){
+ // create the branchings for the incoming particles
+ nasonin.push_back(new_ptr(HardBranching(newparticles[0], SudakovPtr(),
+ //iemit==0 ? sudakov : SudakovPtr(),
+ HardBranchingPtr(),HardBranching::Incoming)));
+ nasonin.push_back(new_ptr(HardBranching(newparticles[1], SudakovPtr(),
+ //iemit==1 ? sudakov : SudakovPtr(),
+ HardBranchingPtr(),HardBranching::Incoming)));
+ // create the branching for the emitted jet
+ nasonin[iemit]->addChild(new_ptr(HardBranching(newparticles[2],SudakovPtr(),
+ nasonin[iemit],
+ HardBranching::Outgoing)));
+ // intermediate IS particle
+ nasonhard.push_back(new_ptr(HardBranching(newparticles[5],SudakovPtr(),
+ nasonin[iemit],HardBranching::Incoming))); // Only apply for the ISR****************
+ nasonin[iemit]->addChild(nasonhard.back());
+ // set the colour partners
+ nasonhard.back()->colourPartner(nasonin[iemit==0 ? 1 : 0]);
+ nasonin[iemit==0 ? 1 : 0]->colourPartner(nasonhard.back());
+ // add other particle
+ nasonhard.push_back(nasonin[iemit==0 ? 1 : 0]);
+ // outgoing photon
+ nasonhard.push_back(new_ptr(HardBranching(newparticles[3],SudakovPtr(),
+ HardBranchingPtr(),HardBranching::Outgoing)));
+ //outgoing boson
+ nasonhard.push_back(new_ptr(HardBranching(newparticles[4],SudakovPtr(),
+ HardBranchingPtr(),HardBranching::Outgoing)));
+ }
+ // FSR:
+ else {
+ // create the branchings for the incoming particles
+ nasonin.push_back(new_ptr(HardBranching(newparticles[0], SudakovPtr(),
+ HardBranchingPtr(),HardBranching::Incoming)));
+ nasonin.push_back(new_ptr(HardBranching(newparticles[1], SudakovPtr(),
+ HardBranchingPtr(),HardBranching::Incoming)));
+
+ // try to add the initial state hard tree to nansonhard first:
+ nasonhard.push_back(nasonin[0]); // should we add the initial state partons in nasonhard?
+ nasonhard.push_back(nasonin[1]); // should we add the initial state partons in nasonhard?
+ //nasonhard.push_back(new_ptr(HardBranching(newparticles[4],SudakovPtr(),
+ // HardBranchingPtr(),HardBranching::Outgoing)));
+
+ // intermediate FS particle
+ nasonhard.push_back(new_ptr(HardBranching(newparticles[5], SudakovPtr(), //sudakov,
+ HardBranchingPtr(),HardBranching::Outgoing)));
+ nasonhard.back()->addChild(new_ptr(HardBranching(newparticles[2],SudakovPtr(),
+ nasonhard[2],HardBranching::Outgoing)));
+ /*
+ nasonhard.push_back(new_ptr(HardBranching(newparticles[3],SudakovPtr(),
+ nasonhard[0],HardBranching::Outgoing)));
+ nasonhard[0]->addChild(nasonhard.back());
+ */
+ nasonhard.back()->addChild(new_ptr(HardBranching(newparticles[3],SudakovPtr(),
+ nasonhard[2],HardBranching::Outgoing)));
+ //try to set the colour partners, suspect it relates to "Failed to make colour connections in PartnerFinder::setQCDInitialEvolutionScales":
+ nasonhard.back()->colourPartner(nasonhard[iemit==0 ? 1 : 0]);
+ //nasonhard[iemit==0 ? 1 : 0]->colourPartner(nasonhard[iemit]);
+ nasonhard[iemit==0 ? 1 : 0]->colourPartner(nasonhard.back());
+ //nasonhard.back()->colourPartner(nasonhard[iemit]);
+ //nasonhard[iemit]->colourPartner(nasonhard.back());
+ nasonhard[iemit==0 ? 1 : 0]->colourPartner(nasonhard[iemit]);
+ nasonhard[iemit]->colourPartner(nasonhard[iemit==0 ? 1 : 0]);
+
+
+ //nasonhard.push_back(nasonin[0]); // should we add the initial state partons in nasonhard?
+ //nasonhard.push_back(nasonin[1]); // should we add the initial state partons in nasonhard?
+ nasonhard.push_back(new_ptr(HardBranching(newparticles[4],SudakovPtr(),
+ HardBranchingPtr(),HardBranching::Outgoing)));
+
+ // we set the colour lines later:
+ /*
+ // set the colour line: two color lines: initial q/qbar-gluon and gluon-q/qbar radiation
+ ColinePtr cline1(new_ptr(ColourLine())), cline2(new_ptr(ColourLine()));
+ bool antiq=newparticles[iemit==0 ? 1 : 0]->dataPtr()->iColour()!=PDT::Colour3;
+ cline1->addColoured(newparticles[iemit==0 ? 1 : 0], antiq);
+ cline1->addColoured(newparticles[iemit], !antiq);
+ cline2->addColoured(newparticles[iemit], antiq);
+ cline2->addColoured(newparticles[2], antiq);
+ */
+ }
+
+ // make the tree
+ // try to separate the ISR (QCD) emission and FSR (QED) cases:
+ HardTreePtr hardTree;
+ if (emissionType==1 || QGQISR==1)
+ hardTree=new_ptr(HardTree(nasonhard,nasonin,ShowerInteraction::QCD));
+ else
+ hardTree=new_ptr(HardTree(nasonhard,nasonin,ShowerInteraction::QED));
+ // connect the ShowerParticles with the branchings
+ // and set the maximum pt for the radiation
+ set<HardBranchingPtr> hard=hardTree->branchings();
+ for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
+ if( pTEmit < pTmin_ ) {
+ particlesToShower[ix]->maximumpT(pTmin_,ShowerInteraction::QED);
+ particlesToShower[ix]->maximumpT(pTmin_,ShowerInteraction::QCD);
+ }
+ else {
+ particlesToShower[ix]->maximumpT(pTEmit,ShowerInteraction::QED);
+ particlesToShower[ix]->maximumpT(pTEmit,ShowerInteraction::QCD);
+ }
+ for(set<HardBranchingPtr>::const_iterator mit=hard.begin();
+ mit!=hard.end();++mit) {
+ if(particlesToShower[ix]->progenitor()->id()==(*mit)->branchingParticle()->id()&&
+ (( (**mit).status()==HardBranching::Incoming &&
+ !particlesToShower[ix]->progenitor()->isFinalState())||
+ ( (**mit).status()==HardBranching::Outgoing&&
+ particlesToShower[ix]->progenitor()->isFinalState()))) {
+ hardTree->connect(particlesToShower[ix]->progenitor(),*mit);
+ if((**mit).status()==HardBranching::Incoming) {
+ (*mit)->beam(particlesToShower[ix]->original()->parents()[0]);
+ }
+ HardBranchingPtr parent=(*mit)->parent();
+ while(parent) {
+ parent->beam(particlesToShower[ix]->original()->parents()[0]);
+ parent=parent->parent();
+ };
+ }
+ }
+ }
+
+ //generator()->log()<<" ****after connecting the ShowerParticles with the branchings\n";
+ // set the colour line:color lines: initial q/qbar-gluon newline and gluon-q/qbar radiation cline1 & cline2
+ ColinePtr cline1(new_ptr(ColourLine())), cline2(new_ptr(ColourLine()));
+ ColinePtr newline=new_ptr(ColourLine());
+ if (emissionType==1 || QGQISR==1){
+ for(set<HardBranchingPtr>::const_iterator cit=hardTree->branchings().begin();
+ cit!=hardTree->branchings().end();++cit) {
+ if((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour3)
+ newline->addColoured((**cit).branchingParticle());
+ else if((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour3bar)
+ newline->addAntiColoured((**cit).branchingParticle());
+ }
+ }
+ else {
+ for(set<HardBranchingPtr>::const_iterator cit=hardTree->branchings().begin();
+ cit!=hardTree->branchings().end();++cit) {
+ if((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour8) {
+ if((**cit).status()==HardBranching::Incoming) {
+ cline1->addColoured ((**cit).branchingParticle());
+ cline2->addAntiColoured((**cit).branchingParticle());
+ }
+
+ }
+ else if((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour3) {
+ if((**cit).status()==HardBranching::Incoming)
+ cline2->addColoured((**cit).branchingParticle());
+ else
+ cline1->addColoured((**cit).branchingParticle());
+ }
+ else if((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour3bar) {
+ if((**cit).status()==HardBranching::Incoming)
+ cline1->addAntiColoured((**cit).branchingParticle());
+ else
+ cline2->addAntiColoured((**cit).branchingParticle());
+ }
+ }
+ }
+
+ ShowerParticleVector particles;
+ for(set<HardBranchingPtr>::iterator cit=hardTree->branchings().begin();
+ cit!=hardTree->branchings().end();++cit) {
+ particles.push_back((*cit)->branchingParticle());
+ if (particles.back()->partner())
+ generator()->log() << " ***hardTree particle: p="<<particles.back()->data().id()<<" partner="<<particles.back()->partner()->data().id()<<" cline="<<particles.back()->colourLine()<<" InitScale="<<particles.back()->evolutionScale()/GeV<<"\n";
+ else
+ generator()->log() << " ***hardTree particle: p="<<particles.back()->data().id()<<" no partner"<<" cline="<<particles.back()->colourLine()<<" InitScale="<<particles.back()->evolutionScale()/GeV<<"\n";
+ }
+
+ generator()->log() <<" check the nasonin scales: "<<nasonin[0]->scale()/GeV<<" "<< nasonin[1]->scale()/GeV<<" nasonhard: "<<nasonhard[0]->scale()/GeV<<
+ " "<<nasonhard[1]->scale()/GeV<<" "<<nasonhard[2]->scale()/GeV<<" "<<nasonhard[3]->scale()/GeV<<"\n";
+ // here we try to set the initial evolution scale of the initial partons for the FSR by hand:
+ pair<Energy,Energy> initscalepair;
+ initscalepair = pair<Energy,Energy>(ZERO,ZERO);
+ ShowerParticleVector initpart;
+ if (!(emissionType==1 || QGQISR==1)){
+ for(set<HardBranchingPtr>::iterator cit=hardTree->branchings().begin();
+ cit!=hardTree->branchings().end();++cit) {
+ if ((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour8 && (**cit).status()==HardBranching::Incoming) {
+ initpart.push_back((*cit)->branchingParticle());
+ }
+ else if(((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour3 || (**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour3bar) && (**cit).status()==HardBranching::Incoming) {
+ initpart.push_back((*cit)->branchingParticle());
+ }
+ }
+ Lorentz5Momentum psum;
+ psum = initpart[0]->momentum() + initpart[1]->momentum();
+ psum.boost(psum.findBoostToCM());
+ int InitConditions (3);
+ Energy Qinit = sqrt(psum.m2());
+ if(InitConditions==1) {
+ initscalepair = pair<Energy,Energy>(sqrt(2.0)*Qinit,sqrt(0.5)*Qinit);
+ } else if(InitConditions==2) {
+ initscalepair = pair<Energy,Energy>(sqrt(0.5)*Qinit,sqrt(2.0)*Qinit);
+ } else {
+ initscalepair = pair<Energy,Energy>(Qinit,Qinit);
+ }
+ initpart[0]->setEvolutionScale(initscalepair.first);
+ initpart[1]->setEvolutionScale(initscalepair.second);
+ }
+
+ generator()->log() << " ***hardTree particle: p0="<<particles[0]->data().id()<<" scale="<<particles[0]->evolutionScale()/GeV<<//"\n";<<particles[0]->colourLine()<<
+ "; p1="<<particles[1]->data().id()<<" scale="<<particles[1]->evolutionScale()/GeV<<" initscale="<<initscalepair.second/GeV<<"\n";
+ //"; p2="<<particles[2]->data().id()<<" "<<particles[2]->partner()->data().id()<<particles[2]->colourLine()<<
+ //"; p3="<<particles[3]->data().id()<<" "<<particles[3]->partner()->data().id()<<particles[3]->colourLine()<<
+ //"; p4="<<particles[4]->data().id()<<" "<<particles[4]->partner()->data().id()<<particles[4]->colourLine()<<
+ //"; p5="<<particles[5]->data().id()<<" "<<particles[5]->partner()->data().id()<<//particles[5]->colourLine()<<
+ //"\n";
+
+ //not apply when we merge the Powheg shower class into the matrix element class in the new version of Herwig++ ??
+ /*
+ Herwig::Evolver::Evolver().showerModel()->partnerFinder()->
+ setInitialEvolutionScales(particles,true,ShowerInteraction::QCD,true);
+
+ // calculate the shower variables
+ Evolver_->showerModel()->kinematicsReconstructor()->
+ deconstructHardJets(hardTree,Evolver_,ShowerInteraction::QCD);
+ for(set<HardBranchingPtr>::const_iterator cit=hardTree->branchings().begin();
+ cit!=hardTree->branchings().end();++cit) {
+ for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
+ if((((**cit).status()==HardBranching::Incoming &&
+ !particlesToShower[ix]->progenitor()->isFinalState())||
+ ((**cit).status()==HardBranching::Outgoing &&
+ particlesToShower[ix]->progenitor()->isFinalState()))&&
+ particlesToShower[ix]->progenitor()->id()==(**cit).branchingParticle()->id()) {
+ particlesToShower[ix]->progenitor()->set5Momentum((**cit).showerMomentum());
+ }
+ }
+ }
+ */
+
+ if(hardTree->interaction()==ShowerInteraction::QCD)
+ generator()->log() << "INTERACTION = QCD\n";
+ else
+ generator()->log() << "INTERACTION = QED\n";
+ for(set<HardBranchingPtr>::const_iterator cit=hardTree->branchings().begin();
+ cit!=hardTree->branchings().end();++cit) {
+ generator()->log() << "testing partners"
+ << *cit << " " << (**cit).colourPartner() << "\n";
+ }
+ generator()->log() << *hardTree << "\n";
+
+
+
+
+ return hardTree;
+}
+
+// generate qq_bar to gluon Vgamma events
+ // merge from VGammaHardGenerator
+void MEPP2VGammaPowheg::generateQQbarG() {
+ Energy2 sHat, scale, kadotg, kbdotg;
+ Energy rsHat, rsub;
+ // storage of pt and rapidity of the gluon
+ Energy pTa, pTb, pTV, mTV;
+ double yj,x1,x2,wgta, wgtb, estimatefact, pdffact, jacobfact, partdipole, sumdipole;
+ // radiation phase space variables:
+ double phi, xiab, vi, rho, rhomx;
+ // double charge0,charge1,sh,shr,ratea,rateb,va,vb,txa,txb,tva,tvb;
+ Lorentz5Momentum k_a_a, k_b_a, k_ga_a, k_V_a, k_glu_a, k_a_b, k_b_b, k_ga_b, k_V_b, k_glu_b, kbarp_ga, kbarp_V;
+ // limits on the rapidity of the jet
+ double minyj = -8.0,maxyj = 8.0, myjpr, exymin, exymax;
+ //cout<<" start generateQQbarG \n";
+ // PDFs for the Born cross section
+ double pdf[4];
+ int emitflag= 0;
+ pdf[0]=beams_[0]->pdf()->xfx(beams_[0],partons_[0],_muF2,x_[0]);
+ pdf[1]=beams_[1]->pdf()->xfx(beams_[1],partons_[1],_muF2,x_[1]);
+ // prefactor for veto algorithm
+ //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+ //double c = alphaS_->overestimateValue()/Constants::twopi*
+ // qqgFactor_*(maxyj-minyj)/(power_-1.);
+ double c = alphaS_->overestimateValue()/Constants::twopi*qqgFactor_*(maxyj-minyj);
+
+ // for the initial state singularity with parton_a:
+ rhomx = (1.0 -x_[0])/(2.0*sqrt(x_[0]));
+ rho = rhomx;
+ pTa = rho*systemMass_;
+ rsub = systemMass_;
+ //throw InitException() <<" for the initial state singularity with parton_a \n";
+ do {
+ // generate pT
+ //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+ //pTa = rsub*pow(pow(double(pTa/rsub),1.-power_)-log(UseRandom::rnd())/c,1./(1.-power_));
+ pTa *= pow(UseRandom::rnd(),1./c);
+ // generate rapidity of the jet
+ //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+ minyj = -8.0;
+ maxyj = 8.0;
+ rho = pTa/systemMass_;
+ /*
+ exymin= (rhomx/rho - sqrt(sqr(rhomx/rho)-1.0))/sqrt(x_[0]);
+ //exymin= (rhomx/rho - sqrt(sqr(rhomx/rho)-1.0))*sqrt(x_[0]);
+ if (exymin<rho) exymin = rho;
+ myjpr = log(exymin*sqrt(x_[0]/x_[1]));
+ //myjpr = log(exymin/sqrt(x_[0]/x_[1]));
+ if (myjpr>minyj) minyj = myjpr;
+ exymax= (rhomx/rho + sqrt(sqr(rhomx/rho)-1.0))/sqrt(x_[0]);
+ //exymax= (rhomx/rho + sqrt(sqr(rhomx/rho)-1.0))*sqrt(x_[0]);
+ myjpr = log(exymax*sqrt(x_[0]/x_[1]));
+ //myjpr = log(exymax/sqrt(x_[0]/x_[1]));
+ if (myjpr<maxyj) maxyj = myjpr;
+ */
+ yj = UseRandom::rnd()*(maxyj-minyj)+ minyj;
+ // generate phi
+ phi = 2.0*Pi*UseRandom::rnd();
+ // transform to CS variables:
+ vi = rho *exp(-yj) *sqrt(x_[0]/x_[1]);
+ xiab = vi*(1.0-vi)/(sqr(rho)+vi);
+
+ //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+ if (xiab>1.|| xiab<x_[0]) continue;
+ if (vi<0. || vi>(1.-xiab)) continue;
+
+ //generator()->log() <<" the rapidity of gluon_a: y="<<yj<<" exymin="<<exymin<<" rho="<<rho<<" exymax="<<exymax<<" myjpr="<<myjpr<<" pTa="<<pTa/GeV<<"\n";
+ /*
+ // pT of the W/Z
+ pTV = sqrt(sqr(photonpT_*sin(photonAzimuth_)+pT*sin(phi))+
+ sqr(photonpT_*cos(photonAzimuth_)+pT*cos(phi)));
+ mTV = sqrt(sqr(pTV)+sqr(bosonMass_));
+ // azimuth of W/Z
+ phiV = Constants::pi+atan2(photonpT_*sin(photonAzimuth_)+pT*sin(phi),
+ photonpT_*cos(photonAzimuth_)+pT*cos(phi));
+ // calculate x_1 and x_2
+ x1 = 0.5/rs_*(photonpT_*exp( photonRapidity_)+mTV*exp( bosonRapidity_)+pT*exp( yj)); //why there is a 0.5 factor here?
+ x2 = 0.5/rs_*(photonpT_*exp(-photonRapidity_)+mTV*exp(-bosonRapidity_)+pT*exp(-yj));
+ */
+ // calculate x_1 and x_2
+ x1 = x_[0]/xiab;
+ x2 = x_[1];
+ // throw InitException() << " x1="<< x1<< " xiab="<<xiab<<" vi="<<vi<<Exception::abortnow;
+ // sHat
+ sHat = sqr(systemMass_)/xiab; //sHat = x1*x2*s_;
+ rsHat = sqrt(sHat);
+
+ if(!quarkplus_) yj *= -1.;
+ // real radiation phase space:
+ k_glu_a= Lorentz5Momentum (pTa *cos(phi ),pTa *sin(phi ),
+ pTa *sinh( yj ),
+ pTa *cosh( yj ),ZERO);
+ //throw InitException() << "x_[0]="<<x_[0]<<" x1="<< x1<<" vi="<<vi<<" xiab="<<xiab<<" yj="<<yj<<" rho="<<rho<<" rho_0="<<(1.0 -x_[0])/(2.0*sqrt(x_[0]))
+ // <<" k_glu_a.e="<<k_glu_a.e()/GeV<<" k_glu_a.z="<<k_glu_a.z()/GeV<<"\n"
+ // << Exception::abortnow;
+ // Suppose we have construct the pT and C-S variables, and then we can generate the n+1 events according to the R/B ratios
+ // of the two singular regions using the highest-kT bid technique:
+ k_a_a = _p_partona/xiab;
+ k_b_a = _p_partonb;
+ //throw InitException() << " x1="<< x1<<"x_[0]="<<x_[0]<<" vi="<<vi<<" xiab="<<xiab<<" k_glu_a.e="<<k_glu_a.e()/GeV<<" k_a_a.e="<<k_a_a.e()/GeV<<
+ // " k_b_a.e="<<k_b_a.e()/GeV<< Exception::abortnow;
+ k_ga_a = InvLortr(_p_partona, _p_partonb, xiab, k_glu_a, _p_photon, 0);
+ k_V_a = InvLortr(_p_partona, _p_partonb, xiab, k_glu_a, _p_boson, 0);
+
+ if (abs(xiab -(1.-k_glu_a.dot(k_a_a+k_b_a)/k_a_a.dot(k_b_a)))>0.0001 || abs(vi -(k_glu_a.dot(k_a_a)/k_a_a.dot(k_b_a)))> 0.0001) {
+ generator()->log() <<" At gluon_a singular region CS-mapping is wrong: "<<" xiab="<<1.-k_glu_a.dot(k_a_a+k_b_a)/k_a_a.dot(k_b_a)<<" ?= "<<xiab<<" vi="<<k_glu_a.dot(k_a_a)/k_a_a.dot(k_b_a)<<" ?= "<<vi<<" xlim="<<x_[0]
+ <<" vlim="<<k_glu_a.dot(k_a_a+k_b_a)/k_a_a.dot(k_b_a)<<" quarkplus="<<quarkplus_<<"\n";
+ continue;}
+
+ // throw InitException() << " x1="<< x1<<" k_ga_a.e="<<k_ga_a.e()/GeV<<" k_V_a.e="<<k_V_a.e()/GeV
+ // <<" conserve?="<<k_glu_a.isNear(k_a_a+k_b_a-k_ga_a-k_V_a, 0.000000000001)<<"\n"
+ // << Exception::abortnow;
+ kadotg = k_a_a.dot(k_glu_a);
+ // kadotg = vi*k_a_a.dot(k_b_a);
+ kbdotg = k_b_a.dot(k_glu_a);
+
+ kbarp_ga = Lortr(k_a_a, k_b_a, xiab, k_glu_a, k_ga_a, 1);
+ kbarp_V = Lortr(k_a_a, k_b_a, xiab, k_glu_a, k_V_a, 1);
+ //throw InitException() << " x1="<< x1<<" k_ga_a.e="<<k_ga_a.e()/GeV<<" k_V_a.e="<<k_V_a.e()/GeV<<" kbarp_ga.e="<<kbarp_ga.e()/GeV<<
+ // " kbarp_V.e="<<kbarp_V.e()/GeV<<" conserve?="<<k_glu_a.isNear(k_a_a+k_b_a-k_ga_a-k_V_a, 0.000000000001)<<"\n"
+ // << Exception::abortnow;
+ scale = sqr(systemMass_)+ sqr(pTa);
+ partdipole = Dipole(_p_partona, _p_partonb, _p_photon, _p_boson, charge0, charge1, MV2, kadotg, alphaS_->value(scale), xiab);
+ sumdipole = partdipole +Dipole(k_a_a, xiab*k_b_a, kbarp_ga, kbarp_V, charge0, charge1, MV2, kbdotg, alphaS_->value(scale), xiab);
+
+ //jacobfact = sHat/(16.0*sqr(Pi)*xiab)/(1.0-vi)*sqr(xiab)/sqr(systemMass_);
+ //jacobfact = sHat/(16.0*sqr(Pi))/(1.0-vi)*sqr(xiab)/systemMass_;
+ //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+ jacobfact = xiab/(16.0*sqr(Pi))/(1.0-vi);
+ //estimatefact = alphaS_->overestimateValue()/(4.0*Pi)*
+ // qqgFactor_/sqr(pTa/GeV)*pow(rsub/pTa,(power_-1.0))*(2.*8./(maxyj-minyj));
+ estimatefact = _alphas/alphaS_->ratio(scale)/(4.0*Pi)*qqgFactor_/sqr(pTa/GeV);
+ pdffact = PDFratio(x1, x_[0], scale, 0, 0, beams_[0], beams_[1]);
+ // now for the weight
+ // first kinematical factors
+ //wgt = 0.5*pow<4,1>(systemMass_)/sqr(sHat);
+ // pdf bit
+ //Energy2 scale = sqr(systemMass_)+sqr(pT);
+ pdf[2]=beams_[0]->pdf()->xfx(beams_[0],partons_[0],scale,x1);
+ pdf[3]=beams_[1]->pdf()->xfx(beams_[1],partons_[1],scale,x2);
+ if(pdf[0]<=0.||pdf[1]<=0.||pdf[2]<=0.||pdf[3]<=0.) {
+ wgta=0.;
+ continue;
+ }
+ //throw InitException() <<" about to QQbarGratio() at gluon_a singular region\n"
+ // << Exception::abortnow;
+ // final bit
+ wgta = QQbarGratio(k_a_a, k_b_a, k_ga_a, k_V_a, k_glu_a, scale)*partdipole/sumdipole*pdffact/estimatefact*jacobfact;
+ // correct the y's Jacobian:
+ //wgta *= 2.*8.0/(maxyj-minyj)*1000000.;
+ //generator()->log() <<" QQbarG weight at gluon_a singular region: "<< wgta<<"\n";
+ if(wgta>1.) generator()->log() << "Weight greater than one for gluon_a emission, Weight = " << wgta << "\n";
+ if (UseRandom::rnd()<wgta) break;
+ }
+ // while(UseRandom::rnd()>wgta && pTa>pTmin_);
+ while(pTa>pTmin_);
+
+ if(pTa<pTmin_) pTa=-GeV;
+
+ // for the initial state singularity with parton_b:
+ rhomx = (1.0 -x_[1])/(2.0*sqrt(x_[1]));
+ rho = rhomx;
+ pTb = rho*systemMass_;
+ rsub = systemMass_;
+ do {
+ // generate pT
+ //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+ //pTb = rsub*pow(pow(double(pTb/rsub),1.-power_)-log(UseRandom::rnd())/c,1./(1.-power_));
+ pTb *= pow(UseRandom::rnd(),1./c);
+ // generate rapidity of the jet
+ //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+ minyj = -8.0;
+ maxyj = 8.0;
+ rho = pTb/systemMass_;
+ /*
+ exymin= (rhomx/rho - sqrt(sqr(rhomx/rho)-1.0))*sqrt(x_[1]);
+ myjpr = log(exymin*sqrt(x_[0]/x_[1]));
+ if (myjpr>minyj) minyj = myjpr;
+ exymax= (rhomx/rho + sqrt(sqr(rhomx/rho)-1.0))*sqrt(x_[1]);
+ if (exymax>(1.0/rho)) exymax = 1.0/rho;
+ myjpr = log(exymax*sqrt(x_[0]/x_[1]));
+ if (myjpr<maxyj) maxyj = myjpr;
+ */
+ yj = UseRandom::rnd()*(maxyj-minyj)+ minyj;
+ // generate phi
+ phi = 2.0*Pi*UseRandom::rnd();
+ // transform to CS variables:
+ //rho = pTb/systemMass_;
+ vi = rho *exp(yj) *sqrt(x_[1]/x_[0]);
+ xiab = vi*(1.0-vi)/(sqr(rho)+vi);
+
+ //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+ if (xiab>1.|| xiab<x_[0]) continue;
+ if (vi<0. || vi>(1.-xiab)) continue;
+
+ //generator()->log() <<" the rapidity of gluon_b: y="<<yj<<" exymin="<<exymin<<" 1/rho="<<1.0/rho<<" exymax="<<exymax<<" myjpr="<<myjpr<<" pTb="<<pTb/GeV<<"\n";
+ /*
+ // pT of the W/Z
+ pTV = sqrt(sqr(photonpT_*sin(photonAzimuth_)+pT*sin(phi))+
+ sqr(photonpT_*cos(photonAzimuth_)+pT*cos(phi)));
+ mTV = sqrt(sqr(pTV)+sqr(bosonMass_));
+ // azimuth of W/Z
+ phiV = Constants::pi+atan2(photonpT_*sin(photonAzimuth_)+pT*sin(phi),
+ photonpT_*cos(photonAzimuth_)+pT*cos(phi));
+ // calculate x_1 and x_2
+ x1 = 0.5/rs_*(photonpT_*exp( photonRapidity_)+mTV*exp( bosonRapidity_)+pT*exp( yj)); //why there is a 0.5 factor here?
+ x2 = 0.5/rs_*(photonpT_*exp(-photonRapidity_)+mTV*exp(-bosonRapidity_)+pT*exp(-yj));
+ */
+ // calculate x_1 and x_2
+ x1 = x_[0];
+ x2 = x_[1]/xiab;
+ // sHat
+ sHat = sqr(systemMass_)/xiab; //sHat = x1*x2*s_;
+ rsHat = sqrt(sHat);
+
+ if(!quarkplus_) yj *= -1.;
+ // real radiation phase space:
+ k_glu_b= Lorentz5Momentum (pTb *cos(phi ),pTb *sin(phi ),
+ pTb *sinh( yj ),
+ pTb *cosh( yj ),ZERO);
+ // Suppose we have construct the pT and C-S variables, and then we can generate the n+1 events according to the R/B ratios
+ // of the two singular regions using the highest-kT bid technique:
+ k_a_b = _p_partona;
+ k_b_b = _p_partonb/xiab;
+ k_ga_b = InvLortr(_p_partona, _p_partonb, xiab, k_glu_b, _p_photon, 1);
+ k_V_b = InvLortr(_p_partona, _p_partonb, xiab, k_glu_b, _p_boson, 1);
+
+ if(abs(xiab-(1.-k_glu_b.dot(k_a_b+k_b_b)/k_a_b.dot(k_b_b)))>0.0001 || abs(vi-(k_glu_b.dot(k_b_b)/k_a_b.dot(k_b_b)))>0.0001) {
+ generator()->log() <<" At gluon_b singular region CS-mapping is wrong: "<<" xiab="<<1.-k_glu_b.dot(k_a_b+k_b_b)/k_a_b.dot(k_b_b)<<" ?= "<<xiab<<" vi="<<k_glu_b.dot(k_b_b)/k_a_b.dot(k_b_b)<<" ?= "<<vi
+ <<" xlim="<<x_[1]<<" vlim="<<1.-xiab<<" quarkplus="<<quarkplus_<<"\n";
+ continue;}
+
+ kadotg = k_a_b.dot(k_glu_b);
+ // kadotg = vi*k_a_a.dot(k_b_a);
+ kbdotg = k_b_b.dot(k_glu_b);
+
+ kbarp_ga = Lortr(k_a_b, k_b_b, xiab, k_glu_b, k_ga_b, 0);
+ kbarp_V = Lortr(k_a_b, k_b_b, xiab, k_glu_b, k_V_b, 0);
+
+ scale = sqr(systemMass_)+ sqr(pTb);
+ partdipole = Dipole(_p_partona, _p_partonb, _p_photon, _p_boson, charge0, charge1, MV2, kbdotg, alphaS_->value(scale), xiab);
+ sumdipole = partdipole +Dipole(xiab*k_a_b, k_b_b, kbarp_ga, kbarp_V, charge0, charge1, MV2, kadotg, alphaS_->value(scale), xiab);
+
+ //jacobfact = sHat/(16.0*sqr(Pi)*xiab)/(1.0-vi)*sqr(xiab)/sqr(systemMass_);
+ //jacobfact = sHat/(16.0*sqr(Pi))/(1.0-vi)*sqr(xiab)/systemMass_;
+ //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+ jacobfact = xiab/(16.0*sqr(Pi))/(1.0-vi);
+ //estimatefact = alphaS_->overestimateValue()/(4.0*Pi)*
+ // qqgFactor_/sqr(pTb/GeV)*pow(rsub/pTb,(power_-1.0))*(2.*8./(maxyj-minyj));
+ estimatefact = _alphas/alphaS_->ratio(scale)/(4.0*Pi)*qqgFactor_/sqr(pTb/GeV);
+ pdffact = PDFratio(x2, x_[1], scale, 1, 0, beams_[0], beams_[1]);
+ // now for the weight
+ // first kinematical factors
+ //wgt = 0.5*pow<4,1>(systemMass_)/sqr(sHat);
+ // pdf bit
+ //Energy2 scale = sqr(systemMass_)+sqr(pT);
+ pdf[2]=beams_[0]->pdf()->xfx(beams_[0],partons_[0],scale,x1);
+ pdf[3]=beams_[1]->pdf()->xfx(beams_[1],partons_[1],scale,x2);
+ if(pdf[0]<=0.||pdf[1]<=0.||pdf[2]<=0.||pdf[3]<=0.) {
+ wgtb=0.;
+ continue;
+ }
+ //throw InitException() <<" about to QQbarGratio() at gluon_b singular region\n"
+ // << Exception::abortnow;
+ //generator()->log() <<" about to QQbarGratio() at gluon_b singular region";
+ // final bit
+ wgtb = QQbarGratio(k_a_b, k_b_b, k_ga_b, k_V_b, k_glu_b, scale)*partdipole/sumdipole*pdffact/estimatefact*jacobfact;
+ // correct the y's Jacobian:
+ //wgtb *= 2.*8.0/(maxyj-minyj)*1000000.;
+ //generator()->log() <<" QQbarG weight at gluon_b singular region: "<< wgtb<<"\n";
+ if(wgtb>1.) generator()->log() << "Weight greater than one for gluon_b emission, Weight = " << wgtb << "\n";
+
+ if (UseRandom::rnd()<wgtb) break;
+ }
+ // while(UseRandom::rnd()>wgtb && pTb>pTmin_);
+ while(pTb>pTmin_);
+
+ if(pTb<pTmin_) pTb=-GeV;
+ //generator()->log() << " gluon radiation with Highest-pT-bid method: wgta="<<wgta<<" pTa="<<pTa/GeV<<" wgtb="<<wgtb<<" pTb="<<pTb/GeV<<
+ //" sbar="<<systemMass_/GeV<<"\n";
+
+ // select the real radiation event with Highest-pT-bid method
+ if(pTa > pTb){
+ pTqqbar_ = pTa;
+ pGammaqqbar_ = k_ga_a;
+ pVqqbar_ = k_V_a;
+ pGqqbar_ = k_glu_a;
+ pQqqbar_ = k_a_a;
+ pQbarqqbar_ = k_b_a;
+ emitflag = 0;
+ generator()->log() <<" QQbarG weight at gluon_a singular region: "<<wgta<<"\n";
+ //generator()->log() <<" QQbarG weight at gluon_a singular region: "<<wgta<<" xiab="<<1.-k_glu_a.dot(k_a_a+k_b_a)/k_a_a.dot(k_b_a)<<" vi="<<k_glu_a.dot(k_a_a)/k_a_a.dot(k_b_a)<<" xlim="<<x_[0]
+ // <<" vlim="<<k_glu_a.dot(k_a_a+k_b_a)/k_a_a.dot(k_b_a)<<" quarkplus="<<quarkplus_<<"\n";
+ }
+ else{
+ pTqqbar_ = pTb;
+ pGammaqqbar_ = k_ga_b;
+ pVqqbar_ = k_V_b;
+ pGqqbar_ = k_glu_b;
+ pQqqbar_ = k_a_b;
+ pQbarqqbar_ = k_b_b;
+ emitflag = 1;
+ generator()->log() <<" QQbarG weight at gluon_b singular region: "<<wgtb<<"\n";
+ //generator()->log() <<" QQbarG weight at gluon_b singular region: "<<wgtb<<" xiab="<<1.-k_glu_b.dot(k_a_b+k_b_b)/k_a_b.dot(k_b_b)<<" ?= "<<xiab<<" vi="<<k_glu_b.dot(k_b_b)/k_a_b.dot(k_b_b)<<" ?= "<<vi
+ // <<" xlim="<<x_[1]<<" vlim="<<1.-xiab<<" quarkplus="<<quarkplus_<<"\n";
+ }
+
+ /*
+ if(!quarkplus_) {
+ LorentzRotation trans;
+ trans.rotateX(Constants::pi);
+ pGammaqqbar_.transform(trans);
+ pVqqbar_ .transform(trans);
+ pGqqbar_ .transform(trans);
+ pQqqbar_ .transform(trans);
+ pQbarqqbar_ .transform(trans);
+ }
+ */
+
+ generator()->log() << " q qbar -> g V Gamma: testing new \n"
+ << "Photon = " << pGammaqqbar_/GeV << "\n"
+ << "Boson = " << pVqqbar_/GeV << "\n"
+ << "Gluon = " << pGqqbar_/GeV << "\n"
+ << "Quark = " << pQqqbar_/GeV << "\n"
+ << "Antiquark = " << pQbarqqbar_/GeV << "\n"
+ << "sum "
+ << (pGammaqqbar_+pVqqbar_+pGqqbar_-pQqqbar_-pQbarqqbar_)/GeV << "\n";
+
+ //ssHat_ = sHat;
+ //maTV_ = mTV;
+ pTparton_ = pTqqbar_;
+ //phiparton_ = phi;
+ //yparton_ = yj;
+ //generator()->log() <<" emitflag"<<emitflag<<"\n";
+}
+
+ // merge from VGammaHardGenerator
+double MEPP2VGammaPowheg::QQbarGratio(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga, Lorentz5Momentum k_V,
+ Lorentz5Momentum k_glu, Energy2 scale) {
+ double mreal, mborn, ratio;
+ //Gluon radiation Real Matrix Element:
+ mreal = MatrRealGluon(k_a, k_b, k_ga, k_V, k_glu, scale);
+ //Born Matrix Element:
+ mborn = MatrBorn(_p_partona, _p_partonb, _p_photon, _p_boson, charge0, charge1, MV2);
+
+ ratio= mreal/mborn;
+
+ return ratio;
+}
+
+
+
+
+
+
+ // generate qg to q Vgamma events (qgflag=1) and gq_bar to q_bar Vgamma events (qgflag=2)
+ // merge from VGammaHardGenerator
+void MEPP2VGammaPowheg::generateQGQ(int qgflag) {
+ Energy2 sHat, scale, kgdotq, kpdotq;
+ Energy rsHat, rsubg;
+ // storage of pt and rapidity of the q/qbar radiation
+ Energy pTg, pTp, pTV, mTV;
+ double yj,x1,x2,wgtg, wgtp, rho, rhomx, estimatefact, pdffact, jacobfact, partdipole, sumdipole;
+ // radiation phase space variables:
+ double phi, xiabqr, viqr, zq, uq, zi, xi, Nfactorg, Nfactorp, cg, cp, labbeta;
+ Lorentz5Momentum k_a_g, k_b_g, k_ga_g, k_V_g, k_quk_g, k_a_p, k_b_p, k_ga_p, k_V_p, k_quk_p, kbarp_ga, kbarp_V, k_glu, kpgt, testk, kvgt;
+ // the charge of radiated q/qbar
+ int idq, fi;
+ if (qgflag==1) {
+ fi = 1;
+ _quark = partons_[0];
+ _quarkpi = partons_[1]->CC();
+ Nfactorg = qgFactor_g;
+ Nfactorp = qgFactor_p;}
+ else {
+ fi = 0;
+ _quark = partons_[1];
+ _quarkpi = partons_[0]->CC();
+ Nfactorg = gqbarFactor_g;
+ Nfactorp = gqbarFactor_p;}
+ idq = _quarkpi->id();
+ chargeqr= _quarkpi->iCharge()/3.*idq/abs(idq);
+ labbeta = (x_[0]-x_[1])/(x_[0]+x_[1]);
+ if(!quarkplus_) labbeta *= -1.;
+ // limits on the rapidity of the jet
+ double minyj = -8.0,maxyj = 8.0, myjpr, exymin, exymax;
+ // PDFs for the Born cross section
+ double pdf[4];
+ pdf[0]=beams_[0]->pdf()->xfx(beams_[0],partons_[0],_muF2,x_[0]);
+ pdf[1]=beams_[1]->pdf()->xfx(beams_[1],partons_[1],_muF2,x_[1]);
+
+ // in the singular region that quark radiation collinear with initial state gluon (Dgq):
+ rhomx = (1.0 -x_[fi])/(2.0*sqrt(x_[fi]));
+ rho = rhomx;
+ pTg = rho*systemMass_;
+ rsubg = systemMass_;
+ // prefactor for veto algorithm
+ //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+ //cg = alphaS_->overestimateValue()/Constants::twopi*
+ //Nfactorg*(maxyj-minyj)/(power_-1.);
+ cg = alphaS_->overestimateValue()/Constants::twopi*Nfactorg*(maxyj-minyj);
+ do {
+ UseRandom::rnd();
+ // generate pT
+ //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+ //pTg = rsubg*pow(pow(double(pTg/rsubg),1.-power_)-log(UseRandom::rnd())/cg,1./(1.-power_));
+ pTg *= pow(UseRandom::rnd(),1./cg);
+ // generate rapidity of the jet
+ //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+ minyj = -8.0;
+ maxyj = 8.0;
+ rho = pTg/systemMass_;
+ /*
+ exymin= (rhomx/rho - sqrt(sqr(rhomx/rho)-1.0));
+ exymax= (rhomx/rho + sqrt(sqr(rhomx/rho)-1.0));
+ if (fi==0 && exymin<rho*sqrt(x_[fi])) exymin = rho*sqrt(x_[fi]);
+ if (fi==1 && exymax>1.0/(rho*sqrt(x_[fi]))) exymax = 1.0/(rho*sqrt(x_[fi]));
+ myjpr = log(exymin) + (double(fi)-0.5)*log(x_[1-fi]);
+ if (myjpr>minyj) minyj = myjpr;
+ myjpr = log(exymax) + (double(fi)-0.5)*log(x_[1-fi]);
+ if (myjpr<maxyj) maxyj = myjpr;
+ */
+ yj = UseRandom::rnd()*(maxyj-minyj)+ minyj;
+ // generate phi
+ phi = UseRandom::rnd()*2.0*Pi;
+ // transform to CS variables:
+ rho = pTg/systemMass_;
+ if (qgflag==2) {
+ viqr = rho *exp(-yj) *sqrt(x_[0]/x_[1]);}
+ else {
+ viqr = rho *exp( yj) *sqrt(x_[1]/x_[0]);}
+ xiabqr = viqr*(1.0-viqr)/(sqr(rho)+viqr);
+
+ //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+ if (xiabqr>1.|| xiabqr<x_[fi]) continue;
+ if (viqr<0. || viqr>(1.-xiabqr)) continue;
+
+ if (qgflag==2) {
+ x1 = x_[0]/xiabqr;
+ x2 = x_[1];}
+ else {
+ x1 = x_[0];
+ x2 = x_[1]/xiabqr;
+ }
+ // sHat
+ sHat = sqr(systemMass_)/xiabqr; //sHat = x1*x2*s_;
+ rsHat = sqrt(sHat);
+
+ if(!quarkplus_) yj *= -1.;
+ // real radiation phase space:
+ k_quk_g= Lorentz5Momentum (pTg *cos(phi ),pTg *sin(phi ),
+ pTg *sinh( yj ),
+ pTg *cosh( yj ),ZERO);
+ // Suppose we have construct the pT and C-S variables, and then we can generate the n+1 events according to the R/B ratios
+ // of the two singular regions using the highest-kT bid technique:
+ scale = sqr(systemMass_)+ sqr(pTg);
+ if (qgflag==2){
+ k_a_g = _p_partona/xiabqr;
+ k_b_g = _p_partonb;
+ k_glu = k_a_g;
+ pdffact = PDFratio(x1, x_[0], scale, 4, fi, beams_[0], beams_[1]);}
+ else {
+ k_a_g = _p_partona;
+ k_b_g = _p_partonb/xiabqr;
+ k_glu = k_b_g;
+ pdffact = PDFratio(x2, x_[1], scale, 4, fi, beams_[0], beams_[1]);}
+
+ k_ga_g = InvLortr(_p_partona, _p_partonb, xiabqr, k_quk_g, _p_photon, fi);
+ k_V_g = InvLortr(_p_partona, _p_partonb, xiabqr, k_quk_g, _p_boson, fi);
+ zi = 1.0/(1.0 + k_quk_g.dot(k_V_g)/k_ga_g.dot(k_quk_g+k_V_g));
+ kgdotq = k_glu.dot(k_quk_g);
+ kpdotq = k_ga_g.dot(k_quk_g);
+
+ //Born phase space for Dpq:
+ kbarp_ga = k_ga_g/zi;
+ kbarp_V = k_V_g + k_quk_g -(1.0-zi)*kbarp_ga;
+ //kbarp_V.rescaleMass();
+ kbarp_V.setMass(sqrt(MV2));
+ kbarp_V.rescaleEnergy();
+ //generator()->log() <<"fi="<<fi<<" x2="<<x2<< " x1="<< x1<<" viqr="<<viqr<<" xiabqr="<<xiabqr<<" pTg="<<pTg/GeV<<" k_quk_g.e="<<k_quk_g.e()/GeV
+ // <<" conserve?="<<k_quk_g.isNear(k_a_g+k_b_g-k_ga_g-k_V_g, 0.000001)<<"\n";
+ partdipole = Dipolegluqr(_p_partona, _p_partonb, _p_photon, _p_boson, charge0, charge1, MV2, kgdotq, alphaS_->value(scale), xiabqr);
+ sumdipole = partdipole +Dipolepqr(k_a_g, k_b_g, kbarp_ga, kbarp_V, chargeqr, MV2, kpdotq, zi, alphaS_->value(scale), fi);
+
+ // generator()->log() <<" xiabqr="<<xiabqr<<" correct?="<<xiabqr-(1.0-k_quk_g.dot(k_a_g+k_b_g)/k_a_g.dot(k_b_g))<<" viqr="<<viqr<<" correct?="
+ // <<viqr-kgdotq/k_a_g.dot(k_b_g)<<" zi="<<zi<<" kgdotq="<<kgdotq/sqr(GeV)<<" kpdotq= "<<kpdotq/sqr(GeV)<<
+ // " underlyingBorn="<<MatrQV(k_a_g, k_b_g, kbarp_ga, kbarp_V, chargeqr, MV2, alphaS_->value(scale), fi)<<"\n";
+
+
+ //jacobfact = sHat/(16.0*sqr(Pi)*xiabqr)/(1.0-viqr)*sqr(xiabqr)/sqr(systemMass_);
+ //jacobfact = sHat/(16.0*sqr(Pi))/(1.0-viqr)*sqr(xiabqr)/systemMass_;
+ //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+ jacobfact = xiabqr/(16.0*sqr(Pi))/(1.0-viqr);
+ //estimatefact = alphaS_->overestimateValue()/(4.0*Pi)*
+ // Nfactorg/sqr(pTg/GeV)*pow(rsubg/pTg,(power_-1.0))*(2.*8./(maxyj-minyj));
+ estimatefact = _alphas/alphaS_->ratio(scale)/(4.0*Pi)*Nfactorg/sqr(pTg/GeV);
+
+ // now for the weight
+ // pdf bit
+ if(pdffact<=0.) {
+ wgtg=0.;
+ continue;
+ }
+
+ // final bit
+ wgtg = QGQratio(k_a_g, k_b_g, k_ga_g, k_V_g, k_quk_g, scale, qgflag)*partdipole/sumdipole*pdffact/estimatefact*jacobfact;
+ //generator()->log() <<"pTg ="<<pTg/GeV<<" partdipole ="<<partdipole<<" sumdipole ="<<sumdipole<<" estimatefact ="<<estimatefact<<" jacobfact ="<<jacobfact<<" pdffact ="<<pdffact<<" Weight= "<<wgtg<<"\n";
+ //wgtg = QGQratio(k_a_g, k_b_g, k_ga_g, k_V_g, k_quk_g, scale, qgflag)*pdffact/estimatefact*jacobfact;
+ if(wgtg>1.) generator()->log() << "Weight greater than one for quark emission from "<<qgflag <<"gluon, Weight = " << wgtg << "\n";
+ //wgtg = 1.1;
+ if (UseRandom::rnd()<wgtg) break;
+ }
+ // while(UseRandom::rnd()>wgtg && pTg>pTmin_);
+ while(pTg>pTmin_);
+
+ if(pTg<pTmin_) pTg=-GeV;
+
+
+ //pTg=-GeV;
+
+
+ // in the singular region that quark radiation collinear with final state photon (Dpq):
+ Energy2 smm2, mm1, kt2, s2, pkypzu, mm3, mm4, mm5, mm6, tepT;
+ Energy4 testi;
+ s2 = sqr(systemMass_);
+ smm2 = s2 - MV2;
+ Energy smm, pT1, ephoton, pTmax, pTte;
+ smm = sqrt(smm2);
+ double chy, shy, mm2, emyjpq, ymaxpq, uqlim, tech, tesh, mm2te;
+ //generator()->log()<<"Here begin to generate quark radiation collinear with final state photon (Dpq):\n";
+ int noy;
+ double Iuz;
+ pTmax = (systemMass_-sqrt(MV2))/2.0;
+ pT1 = smm2/(2.0*systemMass_);
+ pTp = pTmax;
+ // prefactor for veto algorithm
+ minyj = -8.0;
+ maxyj = 8.0;
+ cp = alphaS_->overestimateValue()/(2.*Pi)*Nfactorp*(maxyj-minyj)/(power_photon-1.);
+ do {
+ // do {
+ // generate pT
+ pTp = smm*pow(pow(double(pTp/smm),1.-power_photon)-log(UseRandom::rnd())/cp,1./(1.-power_photon));
+ pTte = pTp;
+ // generate rapidity of the jet
+ noy = 0;
+ Iuz = 1.0;
+ //minyj = -8.0;
+ //maxyj = 8.0;
+ emyjpq = pT1/pTp - sqrt(MV2)/systemMass_;
+ //if (emyjpq>1.0) {
+ ymaxpq = log(sqrt(sqr(emyjpq)-1.0)+emyjpq )- 1.0e-7;
+ // if (ymaxpq<maxyj){
+ maxyj = ymaxpq;
+ minyj = -ymaxpq;
+ yj = UseRandom::rnd()*(maxyj-minyj)+ minyj;
+ // generate phi
+ phi = UseRandom::rnd()*2.*Pi;
+ // transform to CS variables:
+ kt2 = sqr(pTp);
+ chy = (exp(yj)+exp(-yj))/2.;
+ shy = (exp(yj)-exp(-yj))/2.;
+ mm1 = sqrt(sqr(smm2 - 2.0*pTp*systemMass_*chy)-4.0*kt2*MV2);
+ zq = systemMass_* ((smm2 -2.0*pTp*systemMass_*chy +2.0*kt2)*(systemMass_ -pTp*chy)
+ - Iuz*pTp*shy*mm1)/(smm2*(s2+kt2-2.0*pTp*systemMass_*chy));
+ uq = 1.0 -(1.0 -2.0*pTp*systemMass_*chy/smm2)/zq;
+ testi = (smm2*(1.0+zq*uq) -2.0*uq*s2)*(smm2*(1.0-uq)*(1.0-zq*uq) -2.0*uq*MV2);
+ if (testi/sqr(sqr(GeV))<0.0) {
+ Iuz = -1.0;
+ yj = -yj;
+ shy = -shy;
+ zq = systemMass_* ((smm2 -2.0*pTp*systemMass_*chy +2.0*kt2)*(systemMass_ -pTp*chy)
+ - Iuz*pTp*shy*mm1)/(smm2*(s2+kt2-2.0*pTp*systemMass_*chy));
+ uq = 1.0 -(1.0 -2.0*pTp*systemMass_*chy/smm2)/zq;
+ }
+ uqlim = (1.0-zq)*smm2/((1.0-zq)*smm2 + MV2);
+ //}
+ //else noy = 1;
+ //}
+ // if (noy==1 || zq<=0.0 || zq>=1.0 || uq>=(1.0-zq)*smm2/((1.0-zq)*smm2+MV2) || uq<=0.0)
+ // generator()->log()<<"!!!!!!!!z and u are outside the phyiscal range!!!!!!!!! \n";
+
+ // calculate x_1 and x_2
+ x1 = x_[0];
+ x2 = x_[1];
+
+ tepT = smm2*uq*zq*zq*(smm2*(1.0-uq)*(1.0-zq) -uq*MV2)/(smm2*sqr(1.0-zq*uq) -4.0*zq*uq*MV2);
+ tech = (1.0-zq*(1.0-uq))*smm2/(2.0*sqrt(tepT*s2));
+ tesh = (2.0*tepT*s2-zq*((s2+MV2)*uq-smm2*(1.0-uq)*(1.0-zq))*smm2/2.0)/(sqrt(tepT*s2)*sqrt(zq*zq*sqr(smm2)-4.0*s2*tepT));
+ //if (abs((tepT-kt2)/kt2)>0.0001)
+ //generator()->log()<<"!!!!!!!!test the C-S variables: kt2="<<kt2/sqr(GeV)<<" tepT2="<<tepT/sqr(GeV)<<" chy="<<chy<<" techy="<<tech<<" shy="<<shy<<" teshy="<<tesh<<" shy not identical?="
+ // <<(abs(shy-tesh)<0.0000001)<<" Iuz= "<<Iuz<<" testi= "<<testi/sqr(sqr(GeV))<<"\n";
+ //generator()->log()<<"@@@@@@check the frame: Born conserve?= "<<_p_photon.isNear(_p_partona+_p_partonb-_p_boson, 0.000000000001)<<" (_p_partona+_p_partonb).z= "<<(_p_partona.z()+_p_partonb.z())/GeV<<"\n";
+
+ if(pTp/(pT1*zq)>(1.0-1.0e-6) || uq/uqlim>(1.0-1.0e-6)) {
+ wgtp=0.;
+ continue;
+ }
+
+ // real radiation phase space:
+ k_quk_p= Lorentz5Momentum (pTp *cos(phi ),pTp *sin(phi ),
+ pTp *sinh( yj ),
+ pTp *cosh( yj ),ZERO);
+ ephoton = smm2/(2.0*systemMass_);
+ kpgt = Lorentz5Momentum (-pTp*cos(phi)/zq, -pTp*sin(phi)/zq,
+ sqrt(sqr(ephoton)-kt2/(zq*zq)), ephoton, ZERO);
+ k_quk_p.rotateZ(-kpgt.phi());
+ k_quk_p.rotateY(-kpgt.theta());
+ k_quk_p.rotateZ(kpgt.phi());
+ kpgt = _p_photon;
+ kpgt.boost(0.,0.,-labbeta);
+ testk = Lorentz5Momentum (ZERO, ZERO, ephoton, ephoton, ZERO);
+ k_quk_p.rotateY(kpgt.theta());
+ k_quk_p.rotateZ(kpgt.phi());
+ k_quk_p.boost(0.,0.,labbeta);
+ testk.rotateY(kpgt.theta());
+ testk.rotateZ(kpgt.phi());
+ kvgt = _p_boson;
+ kvgt.boost(0.,0.,-labbeta);
+ //generator()->log()<<"~~~~~~ test rotation in CM frame: photon.z= "<<kpgt.z()/GeV<<" boson.z="<<kvgt.z()/GeV<<" photon.e="<<kpgt.e()/GeV<<" smm2/(2.0*systemMass_="
+ // <<smm2/(2.0*systemMass_)/GeV<<" px? "<<(kpgt.x()+kvgt.x())/GeV
+ // <<" near? "<<testk.isNear(kpgt, 0.0001)<<" boson.e= "<<(s2+MV2)/(2.0*systemMass_)/GeV<<" or? = "<<kvgt.e()/GeV<<"\n";
+ testk.boost(0.,0.,labbeta);
+
+ // Suppose we have construct the pT and C-S variables, and then we can generate the n+1 events according to the R/B ratios
+ // of the two singular regions using the highest-kT bid technique:
+ k_a_p = _p_partona;
+ k_b_p = _p_partonb;
+ k_ga_p = _p_photon*zq;
+ k_V_p = _p_boson -k_quk_p +(1.0-zq)*_p_photon;
+ //k_V_p.rescaleMass();
+ k_V_p.setMass(sqrt(MV2));
+ k_V_p.rescaleEnergy();
+ kpdotq = k_ga_p.dot(k_quk_p);
+ //generator()->log()<<"##########check the rotation: uq=k_ga.k_quk/(k_quk+k_V).k_ga? "<<uq-kpdotq/k_ga_p.dot(k_quk_p+k_V_p)<<" zq=z_qVga? "<<zq-1.0/(1.0+k_quk_p.dot(k_V_p)/k_ga_p.dot(k_quk_p+k_V_p))<<
+ // " the momentum of photon correct? ="<<_p_photon.isNear(testk, 0.00000001)<<"\n";
+ //generator()->log() <<" x2="<<x2<< " x1="<< x1<<" uq="<<uq<<" zq="<<zq<<" pTp="<<pTp/GeV<<" k_quk_p.e="<<k_quk_p.e()/GeV
+ // <<" Is photon soft? photon.e= "<<k_ga_p.e()/GeV<<" conserve?="<<k_quk_p.isNear(k_a_p+k_b_p-k_ga_p-k_V_p, 0.000000001)<<"\n";
+
+ xi = 1.0- k_quk_p.dot(_p_partona+ _p_partonb)/_p_partona.dot(_p_partonb);
+ if (qgflag==2){
+ kgdotq = k_a_g.dot(k_quk_p);}
+ else {
+ kgdotq = k_b_g.dot(k_quk_p);}
+
+ kbarp_ga = Lortr(k_a_p, k_b_p, xi, k_quk_p, k_ga_p, fi);
+ kbarp_V = Lortr(k_a_p, k_b_p, xi, k_quk_p, k_V_p, fi);
+
+ scale = sqr(systemMass_)+ sqr(pTp);
+ partdipole = Dipolepqr(_p_partona, _p_partonb, _p_photon, _p_boson, chargeqr, MV2, kpdotq, zq, alphaS_->value(scale), fi);
+ if (qgflag==2){
+ sumdipole = partdipole +Dipolegluqr(xi*k_a_p, k_b_p, kbarp_ga, kbarp_V, charge0, charge1, MV2, kgdotq, alphaS_->value(scale), xi);}
+ else {
+ sumdipole = partdipole +Dipolegluqr(k_a_p, xi*k_b_p, kbarp_ga, kbarp_V, charge0, charge1, MV2, kgdotq, alphaS_->value(scale), xi);}
+
+ //mm2 = 4.0*s2*uq*(smm2*(1.0-uq)*(1.0-zq) -uq*MV2)/(smm2*(smm2*sqr(1.0-zq*uq) -4.0*uq*zq*MV2));
+ // modify:
+ //mm2 = 4.0*s2*uq*(smm2*(1.0-uq)*(1.0-zq) -uq*MV2)/(smm2*(s2*sqr(1.0-zq*uq) - MV2*sqr(1.0+zq*uq)));
+ //if ((1.0-mm2)<0.0 || abs(4.0*s2*kt2/(sqr(zq)*sqr(smm2)) - mm2)>0.01) {
+ // generator()->log()<<" Jacobian is nan: zq="<<zq<<" uq="<<uq<<" ulim="<<(1.0-zq)*smm2/((1.0-zq)*smm2 + MV2)<<" Iuz="<<Iuz<<" z^2...="<<1.0-4.0*s2*kt2/(sqr(zq)*sqr(smm2))
+ // <<" kT/kT1="<<2.0*pTp*systemMass_/smm2/zq<<" pT="<<pTp/GeV<<" yj="<<yj<<" chy="<<chy<<" shy="<<shy<<" 1.0-mm2="<<1.0-mm2<<"\n";
+ //mm2 = 0.0;
+ //}
+ //if (abs(4.0*s2*kt2/(sqr(zq)*sqr(smm2)) - mm2)>0.01)
+ mm2 = 4.0*s2*kt2/(sqr(zq)*sqr(smm2));
+ //" chy="<<chy<<" techy="<<tech<<" shy="<<shy<<" teshy="<<tesh
+ mm4 = smm2*(1.0+zq*uq)-2.0*uq*s2;
+ mm5 = smm2*sqr(1.0+zq*uq)-4.0*uq*zq*s2;
+ mm6 = smm2*(1.0-uq)*(1.0-zq*uq)-2.0*uq*MV2;
+ mm3 = mm4*mm5/mm6;
+ jacobfact = 2.0*_p_photon.dot(_p_boson)*zq/(16.0*sqr(Pi)) *abs(1.0/(sqr(smm2)*zq*zq*sqrt(1.0 -mm2))*mm3);
+ mm2te = 4.0*s2*uq*(smm2*(1.0-uq)*(1.0-zq) -uq*MV2)/(smm2*(smm2*sqr(1.0-zq*uq) -4.0*uq*zq*MV2));
+
+ /*
+ if (qgflag==2)
+ generator()->log() <<" uq="<<uq<<" zq="<<zq<<" xi="<<xi<<" kpdotq="<<kpdotq/sqr(GeV)<<" kgdotq= "<<kgdotq/sqr(GeV)<<" underlyingBorn="<<
+ MatrBorn(xi*k_a_p, k_b_p, kbarp_ga, kbarp_V, charge0, charge1,MV2)<<" conserve?="
+ <<kbarp_ga.isNear(xi*k_a_p+k_b_p-kbarp_V, 0.0000000001)<<" mm2="<<mm2<<" mm3="<<mm3/sqr(GeV)<<" Iuz="<<Iuz<<"\n";
+ else
+ generator()->log() <<" uq="<<uq<<" zq="<<zq<<" xi="<<xi<<" kpdotq="<<kpdotq/sqr(GeV)<<" kgdotq= "<<kgdotq/sqr(GeV)<<" underlyingBorn="<<
+ MatrBorn(k_a_p, xi*k_b_p, kbarp_ga, kbarp_V, charge0, charge1,MV2)<<" conserve?="
+ <<kbarp_ga.isNear(k_a_p+xi*k_b_p-kbarp_V, 0.0000000001)<<" mm2="<<mm2<<" mm3="<<mm3/sqr(GeV)<<" Iuz="<<Iuz<<"\n";
+ */
+
+ estimatefact = alphaS_->overestimateValue()/(4.0*Pi)*
+ Nfactorp/sqr(pTp/GeV)*pow(smm/pTp,(power_photon-1.0))*(2.*8./(maxyj-minyj));
+ pdffact = PDFratio(x1, x2, scale, 3, fi, beams_[0], beams_[1]);
+
+ if(pdffact<=0.) {
+ wgtp=0.;
+ continue;
+ }
+
+ // final bit
+ pTp =abs(k_quk_p.perp((k_ga_p+k_quk_p).vect())/GeV)*GeV;
+ //if (k_quk_p.isNear(k_a_p+k_b_p-k_ga_p-k_V_p, 0.000000000001)==1) {
+ wgtp = QGQratio(k_a_p, k_b_p, k_ga_p, k_V_p, k_quk_p, scale, qgflag)*partdipole/sumdipole*pdffact/estimatefact*jacobfact;
+
+ if(wgtp>1.) generator()->log() << "Weight greater than one for quark emission from photon, Weight = " << wgtp << "\n";
+ //generator()->log() <<"pTp ="<<pTp/GeV<<" or?="<<abs(k_quk_p.perp((k_ga_p+k_quk_p).vect())/GeV)<<" partdipole ="<<partdipole<<" sumdipole ="<<sumdipole<<" estimatefact ="<<estimatefact<<" jacobfact ="<<jacobfact<<" pdffact ="<<pdffact<<" Weight= "<<wgtp<<"\n";
+ //}
+ //pTp =abs(k_quk_p.perp((k_ga_p+k_quk_p).vect())/GeV)*GeV;
+ //wgtp = wgtp*10000.0;
+ //if(wgtp>1.) generator()->log() << "Weight greater than one for quark emission from photon, Weight = " << wgtp << "\n";
+ //wgtp = 1.1;
+ if (UseRandom::rnd()<wgtp) break;
+ }
+ //while(UseRandom::rnd()>wgtp && pTp>pTmin_);
+ while(pTp>pTmin_);
+
+
+ if(pTp<pTmin_) pTp=-GeV;
+
+ //generator()->log() << " quark radiation with Highest-pT-bid method: wgtg="<<wgtg<<" pTg="<<pTg/GeV<<" wgtp="<<wgtp<<" pTp="<<pTp/GeV<<
+ // " sbar="<<systemMass_/GeV<<"\n";
+ //pTp=-GeV;
+
+ // select the real radiation event with Highest-pT-bid method
+ if(pTg > pTp){
+ if (qgflag==1) {
+ QGQISR_qg = 1;
+ pTqg_ = pTg;
+ pGammaqg_ = k_ga_g;
+ pVqg_ = k_V_g;
+ pQoutqg_ = k_quk_g;
+ pQinqg_ = k_a_g;
+ pGqg_ = k_b_g;
+ if (std::isnan(wgtg)) {
+ generator()->log() <<"NaNWeight wgtg_a : pV="<<pVqg_/GeV<<" pT="<<pTqg_/GeV<<" real="<<QGQratio(k_a_g,k_b_g,k_ga_g,k_V_g,k_quk_g,sqr(systemMass_)+sqr(pTg),qgflag)
+ <<" jacobfact="<<sHat/(16.0*sqr(Pi)*xiabqr)/(1.0-viqr)*sqr(xiabqr)/sqr(systemMass_)<<" estimatefact="<<alphaS_->overestimateValue()/(4.0*Pi)*
+ Nfactorg/sqr(pTg/GeV)*pow(rsubg/pTg,(power_-1.0))<<"\n";
+ }
+ generator()->log() <<" QGQ weight at gluon collinear singular region: "<<wgtg<<"\n";
+ }
+ else if (qgflag==2) {
+ QGQISR_gqbar = 1;
+ pTgqbar_ = pTg;
+ pGammagqbar_ = k_ga_g;
+ pVgqbar_ = k_V_g;
+ pQoutgqbar_ = k_quk_g;
+ pGgqbar_ = k_a_g;
+ pQingqbar_ = k_b_g;
+ if (std::isnan(wgtg)) {
+ generator()->log() <<"NaNWeight wgtg_b : pV="<<pVgqbar_/GeV<<" pT="<<pTgqbar_/GeV<<" real="<<QGQratio(k_a_g,k_b_g,k_ga_g,k_V_g,k_quk_g,sqr(systemMass_)
+ +sqr(pTg),qgflag)<<" jacobfact="<<sHat/(16.0*sqr(Pi)*xiabqr)/(1.0-viqr)*sqr(xiabqr)/sqr(systemMass_)<<" estimatefact="<<alphaS_->overestimateValue()/(4.0*Pi)*
+ Nfactorg/sqr(pTg/GeV)*pow(rsubg/pTg,(power_-1.0))<<"\n";
+ }
+ generator()->log() <<" GQarQar weight at gluon collinear singular region: "<<wgtg<<"\n";
+ }
+ }
+ else{
+ if (qgflag==1) {
+ QGQISR_qg = 0;
+ pTqg_ = pTp;
+ pGammaqg_ = k_ga_p;
+ pVqg_ = k_V_p;
+ pQoutqg_ = k_quk_p;
+ pQinqg_ = k_a_p;
+ pGqg_ = k_b_p;
+ if (std::isnan(wgtp)) {
+ generator()->log() <<"NaNWeight wgtp_a : pV="<<k_V_p/GeV<<" pT="<<pTp/GeV<<" pTte="<<pTte/GeV<<" real="<<QGQratio(k_a_p,k_b_p,k_ga_p,k_V_p,k_quk_p,sqr(systemMass_)+sqr(pTp),qgflag)
+ <<" jacobfact="<<2.0*_p_photon.dot(_p_boson)*zq/(16.0*sqr(Pi)) *abs(1.0/(sqr(smm2)*zq*zq*sqrt(1.0 -mm2))*mm3)<<" 1-mm2="<<1.0-mm2<<" 1-mm2te="<<1.0-mm2te<<" estimatefact="
+ <<alphaS_->overestimateValue()/(4.0*Pi)*Nfactorp/sqr(pTp/GeV)*pow(smm/pTp,(power_photon-1.0))<<" smm2="<<smm2/sqr(GeV)<<"\n"<<" zq="<<zq<<" uq="<<uq<<" ulim="<<(1.0-zq)*smm2/((1.0-zq)*smm2 + MV2)<<" Iuz="<<Iuz<<" z^2...="<<1.0-4.0*s2*kt2/(sqr(zq)*sqr(smm2))<<" kT/kT1="
+ <<2.0*pTte*systemMass_/smm2/zq<<" yj="<<yj<<" chy="<<chy<<" shy="<<shy<<" beta="<<labbeta<<" pV="<<kvgt.perp()/GeV<<"\n";
+ }
+ generator()->log() <<" QGQ weight at photon collinear singular region: "<<wgtp<<"\n";
+ }
+ else if (qgflag==2) {
+ QGQISR_gqbar = 0;
+ pTgqbar_ = pTp;
+ pGammagqbar_ = k_ga_p;
+ pVgqbar_ = k_V_p;
+ pQoutgqbar_ = k_quk_p;
+ pGgqbar_ = k_a_p;
+ pQingqbar_ = k_b_p;
+ if (std::isnan(wgtp)) {
+ generator()->log() <<"NaNWeight wgtp_b : pV="<<k_V_p/GeV<<" pT="<<pTp/GeV<<" pTte="<<pTte/GeV<<" real="<<QGQratio(k_a_p,k_b_p,k_ga_p,k_V_p,k_quk_p,sqr(systemMass_)+sqr(pTp),qgflag)
+ <<" jacobfact="<<2.0*_p_photon.dot(_p_boson)*zq/(16.0*sqr(Pi)) *abs(1.0/(sqr(smm2)*zq*zq*sqrt(1.0 -mm2))*mm3)<<" 1-mm2="<<1.0-mm2<<" 1-mm2te="<<1.0-mm2te<<" estimatefact="
+ <<alphaS_->overestimateValue()/(4.0*Pi)*Nfactorp/sqr(pTp/GeV)*pow(smm/pTp,(power_photon-1.0))<<" smm2="<<smm2/sqr(GeV)<<"\n"<<" zq="<<zq<<" uq="<<uq<<" ulim="<<(1.0-zq)*smm2/((1.0-zq)*smm2 + MV2)<<" Iuz="<<Iuz<<" z^2...="<<1.0-4.0*s2*kt2/(sqr(zq)*sqr(smm2))<<" kT/kT1="
+ <<2.0*pTte*systemMass_/smm2/zq<<" yj="<<yj<<" chy="<<chy<<" shy="<<shy<<" beta="<<labbeta<<" pV="<<kvgt.perp()/GeV<<"\n";
+ }
+ generator()->log() <<" GQarQar weight at photon collinear singular region: "<<wgtp<<"\n";
+ }
+ }
+
+
+ /*
+ if(!quarkplus_) {
+ LorentzRotation trans;
+ trans.rotateX(Pi);
+ if (qgflag==1) {
+ pGammaqg_.transform(trans);
+ pVqg_ .transform(trans);
+ pQoutqg_ .transform(trans);
+ pQinqg_ .transform(trans);
+ pGqg_ .transform(trans);
+ }
+ else if (qgflag==2) {
+ pGammagqbar_.transform(trans);
+ pVgqbar_ .transform(trans);
+ pQoutgqbar_ .transform(trans);
+ pQingqbar_ .transform(trans);
+ pGgqbar_ .transform(trans);
+ }
+ }
+ */
+ if (qgflag==1) {
+ generator()->log() << " q g -> q V Gamma: testing new \n"
+ << "Photon = " << pGammaqg_/GeV << "\n"
+ << "Boson = " << pVqg_/GeV << "\n"
+ << "Gluon = " << pGqg_/GeV << "\n"
+ << "IncomgQuark/Antiquark = " << pQinqg_/GeV << "\n"
+ << "OutgoingQuark/Antiquark = " << pQoutqg_/GeV << "\n"
+ << "sum "
+ << (pGammaqg_+pVqg_+pQoutqg_-pGqg_-pQinqg_)/GeV << "\n";
+ pTparton_ = pTqg_;
+ }
+ else if (qgflag==2) {
+ generator()->log() << " g qbar -> qbar V Gamma: testing new \n"
+ << "Photon = " << pGammagqbar_/GeV << "\n"
+ << "Boson = " << pVgqbar_/GeV << "\n"
+ << "Gluon = " << pGgqbar_/GeV << "\n"
+ << "IncomgQuark/Antiquark = " << pQingqbar_/GeV << "\n"
+ << "OutgoingQuark/Antiquark = " << pQoutgqbar_/GeV << "\n"
+ << "sum "
+ << (pGammagqbar_+pVgqbar_+pQoutgqbar_-pGgqbar_-pQingqbar_)/GeV << "\n";
+ pTparton_ = pTgqbar_;
+ }
+ //ssHat_ = s2;
+ //maTV_ = mTV;
+
+ //phiparton_ = phi;
+ //yparton_ = yj;
+}
+
+ // merge from VGammaHardGenerator
+double MEPP2VGammaPowheg::QGQratio(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga, Lorentz5Momentum k_V,
+ Lorentz5Momentum k_q, Energy2 scale, int flavorflag) {
+ double mreal,mborn,ratio;
+ //Quark radiation Real Matrix Element:
+ mreal = MatrRealQuark(k_a, k_b, k_ga, k_V, k_q, scale, flavorflag);
+
+ //Born Matrix Element:
+ mborn = MatrBorn(_p_partona, _p_partonb, _p_photon, _p_boson, charge0, charge1, MV2);
+
+ ratio= mreal/mborn;
+
+ return ratio;
+}
diff --git a/MatrixElement/Powheg/MEPP2VGammaPowheg.h b/MatrixElement/Powheg/MEPP2VGammaPowheg.h
--- a/MatrixElement/Powheg/MEPP2VGammaPowheg.h
+++ b/MatrixElement/Powheg/MEPP2VGammaPowheg.h
@@ -1,379 +1,755 @@
// -*- C++ -*-
#ifndef HERWIG_MEPP2VGammaPowheg_H
#define HERWIG_MEPP2VGammaPowheg_H
//
// This is the declaration of the MEPP2VGammaPowheg class.
//
#include "Herwig++/MatrixElement/Hadron/MEPP2VGamma.h"
#include "ThePEG/PDF/BeamParticleData.h"
+#include "Herwig++/Utilities/GSLIntegrator.h"
+#include "Herwig++/Shower/Couplings/ShowerAlpha.h" //from VGammaHardGenerator
+#include "Herwig++/Shower/Base/ShowerProgenitor.h" //from VGammaHardGenerator
namespace Herwig {
using namespace ThePEG;
class MEPP2VGammaPowheg;
ThePEG_DECLARE_POINTERS(MEPP2VGammaPowheg,VGamPowhegPtr);
/**
* The MEPP2VGammaPowheg class implements the next-to-leading
* order matrix elements for $q\bar q \to W^\pm/Z^0\gamma\f$
* in the Powheg scheme.
*
* @see \ref MEPP2VGammaPowhegInterfaces "The interfaces"
* defined for MEPP2VGammaPowheg.
*/
class MEPP2VGammaPowheg: public MEPP2VGamma {
+ /**
+ * Typedef for the BeamParticleData object from VGammaHardGenerator
+ */
+ typedef Ptr<BeamParticleData>::transient_const_pointer tcBeamPtr;
+
+ /*
+public:
+ friend class KP1Integrand;
+ friend class KP2Integrand;
+ friend class KP3Integrand;
+
+ */
public:
/**
* The default constructor.
*/
MEPP2VGammaPowheg();
+ /** @name Member functions for the generation of hard QCD radiation */
+ //@{
+ /**
+ * Has a POWHEG style correction
+ */
+ virtual bool hasPOWHEGCorrection() {return true;}
+
+ /**
+ * Member to generate the Powheg hardest emission from VGammaHardGenerator
+ */
+ virtual HardTreePtr generateHardest(ShowerTreePtr,vector<ShowerInteraction::Type>);
+
+
+ /** @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;
+
+
/** @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 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;
//@}
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();
//parton distribution function of beam partID
- double PDFab(double z, int partID) const;
+ double PDFab(double z, int partID, Energy2 scale, tcBeamPtr hadron_A, tcBeamPtr hadron_B) const;
// parton distribution function ratio
- double PDFratio(double z, double x, int partID) const;
+ double PDFratio(double z, double x, Energy2 scale, int partID, int fi, tcBeamPtr hadron_A, tcBeamPtr hadron_B) 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();
//@}
// functionals of PDFs and energy fractions in the collinear remnants:
double KP1(double zz, Energy2 shat, Energy2 muF2, int partID) const;
double KP2(double zz, Energy2 shat, Energy2 muF2) const;
double KP3(double zz, int partID) const;
+ double KPpr(double xx, Energy2 shat, Energy2 muF2) const;
// definitions of H, F^V:
double Hfunc(Energy2 t, Energy2 s, Energy2 m2) const;
double FWfunc(Energy2 t, Energy2 u, Energy2 s, Energy2 m2) const;
double FZfunc(Energy2 t, Energy2 u, Energy2 s, Energy2 m2) const;
double FVfunc(Energy2 t, Energy2 u, Energy2 s, Energy2 m2) const;
+ /**
+ * Generate a \f$q \bar q \to V \gamma \f$ configuration
+ */
+ void generateQQbarG();
+
+ /**
+ * The ratio of leading to NLO matrix elements for qqbar to gluon V gamma
+ */
+ double QQbarGratio(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga, Lorentz5Momentum k_V,
+ Lorentz5Momentum k_glu, Energy2 scale);
+
+ /**
+ * generate qg to q Vgamma events (qgflag=1) and gq_bar to q_bar Vgamma events (qgflag=2)
+ */
+ void generateQGQ(int qgflag);
+
+ /**
+ * The ratio of leading to NLO matrix elements for gq_bar to q_bar Vgamma
+ */
+ double QGQratio(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga, Lorentz5Momentum k_V,
+ Lorentz5Momentum k_q, Energy2 scale, int flavorflag);
+
+
// Transformation from Born+rad phase space configuration to m+1 phase space of final states
Lorentz5Momentum InvLortr(Lorentz5Momentum kbar_a, Lorentz5Momentum kbar_b, double xi,
Lorentz5Momentum k_i, Lorentz5Momentum kbar_j, int fi) const;
//Transformation from m+1 phase space to Born phase space configuration of final states
Lorentz5Momentum Lortr(Lorentz5Momentum k_a, Lorentz5Momentum k_b, double xi,
Lorentz5Momentum k_i, Lorentz5Momentum k_j, int fi) const;
// momentum of radiated parton transformed from Born phase space
Lorentz5Momentum radk(Lorentz5Momentum kbar_a, Lorentz5Momentum kbar_b, double xi,
double vi, double phi, int fi) const;
// momentum of radiated quark transformed from gq->qV Born phase space
- Lorentz5Momentum radkqr(Lorentz5Momentum kbar_ga, Lorentz5Momentum kbar_V, Energy2 MV2,
- double zi, double ui, double phi) const;
+ Lorentz5Momentum radkqr(Lorentz5Momentum kbar_ga, Lorentz5Momentum kbar_V, Energy2 MassV2,
+ double zi, double ui, double phi, double zcut) const;
// Born matrix element
double MatrBorn(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga,
- Lorentz5Momentum k_V, double char0, double char1, Energy2 MV2) const;
+ Lorentz5Momentum k_V, double char0, double char1, Energy2 MassV2) const;
// Tree level matrix element for gq->qV
double MatrQV(Lorentz5Momentum p_a, Lorentz5Momentum p_b, Lorentz5Momentum k_q,
- Lorentz5Momentum k_V, Energy2 MV2) const;
- // Gluon Real radiation matrix element
- InvEnergy2 MatrRealGluon(Lorentz5Momentum k_a, Lorentz5Momentum k_b,
- Lorentz5Momentum k_ga,
- Lorentz5Momentum k_V, Lorentz5Momentum k_glu) const;
-
+ Lorentz5Momentum k_V, double charqr, Energy2 MassV2, double alphas, int fi) const;
+// Gluon Real radiation matrix element
+ double MatrRealGluon(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga,
+ Lorentz5Momentum k_V, Lorentz5Momentum k_glu, Energy2 scale) const;
+
// Quark Real radiation matrix element
double MatrRealQuark(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga,
- Lorentz5Momentum k_V, Lorentz5Momentum k_q) const;
+ Lorentz5Momentum k_V, Lorentz5Momentum k_q, Energy2 scale, int flavorflag) const;
// dipole of gluon radiation
- InvEnergy2 Dipole(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga,
- Lorentz5Momentum k_V, double char0,double char1,Energy2 MV2,Energy2 kig,double xi) const;
+ double Dipole(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga,
+ Lorentz5Momentum k_V,double char0,double char1,Energy2 MassV2,Energy2 kig, double alphas,double xi) const;
- double test2to3(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga,
- Lorentz5Momentum k_1, Lorentz5Momentum k_2) const;
- double test2to3am(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga,
- Lorentz5Momentum k_1, Lorentz5Momentum k_2, Energy2 MV2) const;
+// dipole of quark radiation in the singular region collinear with final state photon
+ double Dipolepqr(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga,
+ Lorentz5Momentum k_V, double chargr, Energy2 MassV2, Energy2 kig, double zi, double alphas, int fi) const;
+
+
+
+// dipole of quark radiation in the singular region collinear with initial state gluon
+ double Dipolegluqr(Lorentz5Momentum k_a, Lorentz5Momentum k_b, Lorentz5Momentum k_ga,
+ Lorentz5Momentum k_V, double char0, double char1, Energy2 MassV2, Energy2 kig, double alphas, double xi) const;
+
+// Born matrix element for V quark procduction
+ double qgME(Lorentz5Momentum p_a, Lorentz5Momentum p_b, Lorentz5Momentum k_q,
+ Lorentz5Momentum k_V, Energy2 MassV2, bool calc) const;
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:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<MEPP2VGammaPowheg> initMEPP2VGammaPowheg;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MEPP2VGammaPowheg & operator=(const MEPP2VGammaPowheg &);
protected:
/**
* Calculate the correction weight with which leading-order
* configurations are re-weighted.
*/
double NLOweight() const;
private:
/**
+ * Pointer to the object calculating the strong coupling
+ */
+ ShowerAlphaPtr alphaS_;
+
+ mutable double alphaQCD_;
+
+ /**
+ * The transverse momentum of the jet
+ */
+ Energy pTmin_;
+
+
+ /**
* The \f$T_R\f$ colour factor
*/
- mutable double TR_;
+ mutable double _TR;
/**
* The \f$C_F\f$ colour factor
*/
- mutable double CF_;
-
+ mutable double _CF;
+
+ mutable double Pi;
+
+ mutable double gamnum;
//Factorization scale
mutable Energy2 _muF2;
//kinematics: s~hat:_ss, t~hat:_tt, u~hat:_uu
mutable Energy2 _ss;
mutable Energy2 _tt;
mutable Energy2 _uu;
//types of initial states:
mutable tcPDPtr _partona;
mutable tcPDPtr _partonb;
//types of final states:
mutable tcPDPtr _gluon;
mutable tcPDPtr _photon;
mutable tcPDPtr _quark;
mutable tcPDPtr _quarkpi;
mutable tcPDPtr _boson;
+ mutable int _idboson;
mutable int _iflagcq;
//momenta of final states:
mutable Lorentz5Momentum _p_photon;
mutable Lorentz5Momentum _p_parton;
mutable Lorentz5Momentum _p_boson;
//momenta of initial states:
mutable Lorentz5Momentum _p_partona;
mutable Lorentz5Momentum _p_partonb;
//CKM matrix square
- mutable double ckm_;
-
+ mutable double ckm;
+ // the third componet of isospin of the quark when vector boson is Z0
+ mutable double I3quark;
/**
* The BeamParticleData object for the plus direction hadron
*/
- mutable Ptr<BeamParticleData>::transient_const_pointer _hadron_A;
+ mutable tcBeamPtr _hadron_A;
/**
* The BeamParticleData object for the minus direction hadron
*/
- mutable Ptr<BeamParticleData>::transient_const_pointer _hadron_B;
+ mutable tcBeamPtr _hadron_B;
//momenta fractions _xa, _xb
mutable double _xa;
mutable double _xb;
//
//alpha_S:
mutable double _alphas;
//sin(thete_W)^2
mutable double sin2w;
//electroweak alpha
mutable double alphae;
//integrated variable _xtil
mutable double _xtil;
//Real radiation integrated variables
mutable double _y1;
mutable double _y2;
mutable double _y3;
// For Real radiation part
mutable double _phi;
/**
* Parameters for the NLO weight
*/
//@{
/**
* Whether to generate the positive, negative or leading order contribution
*/
unsigned int _contrib;
//@}
/**
* Choice of the scale
*/
//@{
/**
* Type of scale
*/
unsigned int _scaleopt;
/**
* Fixed scale if used
*/
Energy _fixedScale;
/**
* Prefactor if variable scale used
*/
double _scaleFact;
+
+ //photon fraction cut:
+ mutable double fraccut;
//@}
/**
+ * integrator
+ */
+ GSLIntegrator _integrator;
+
+ /**
* Vertices
*/
//@{
/**
* FFPVertex
*/
AbstractFFVVertexPtr FFPvertex_;
/**
* FFWVertex
*/
AbstractFFVVertexPtr FFWvertex_;
/**
* FFZVertex
*/
AbstractFFVVertexPtr FFZvertex_;
/**
* WWW Vertex
*/
AbstractVVVVertexPtr WWWvertex_;
/**
* FFG Vertex
*/
AbstractFFVVertexPtr FFGvertex_;
//@}
+ /**
+ * Properties of the incoming particles
+ */
+ //@{
+ /**
+ * Pointers to the BeamParticleData objects
+ */
+ vector<tcBeamPtr> beams_;
+
+ /**
+ * Pointers to the ParticleDataObjects for the partons
+ */
+ vector<tcPDPtr> partons_;
+ //@}
+
+ /**
+ * Whether the quark is in the + or - z direction
+ */
+ bool quarkplus_;
+
+ /**
+ * Prefactor for the overestimate for \f$q\bar q\to V \gamma\f$
+ */
+ double qqgFactor_;
+
+ /**
+ * Prefactor for the overestimate for q g to V gamma q
+ */
+ double qgFactor_g;
+ double qgFactor_p;
+
+ /**
+ * Prefactor for the overestimate for qbar g to V gamma qbar
+ */
+ double gqbarFactor_g;
+ double gqbarFactor_p;
+
+ /**
+ * The power, \f$n\f$, for the sampling of initial state partons singular regions
+ */
+ double power_;
+
+ /**
+ * The power, \f$n\f$, for the sampling of final state photon singular region
+ */
+ double power_photon;
+
+ /**
+ * Born variables
+ */
+ //@{
+ /**
+ * Rapidity of the photon
+ */
+ double photonRapidity_;
+
+ /**
+ * Rapidity of the gauge boson
+ */
+ double bosonRapidity_;
+
+ /**
+ * \f$p_T\f$ of the photon
+ */
+ Energy photonpT_;
+
+ /**
+ * Azimuth of the photon
+ */
+ double photonAzimuth_;
+
+ /**
+ * gauge boson mass square
+ */
+ mutable Energy2 MV2;
+
+ /**
+ * Mass of the boson/photon system
+ */
+ Energy systemMass_;
+
+ /**
+ * Momentum fractions for the LO process
+ */
+ double x_[2];
+
+
+ // The charges of the initial state quarks
+ mutable double charge0;
+ mutable double charge1;
+ // The charges of the radiated quarks
+ mutable double chargeqr;
+ //@}
+
+ /**
+ * Momenta etc for the \f$q\bar q \to V \gamma g \f$ process
+ */
+ //@{
+ /**
+ * Momentum of the vector boson
+ */
+ Lorentz5Momentum pVqqbar_;
+
+ /**
+ * Momentum of the photon
+ */
+ Lorentz5Momentum pGammaqqbar_;
+
+ /**
+ * Momentum of the gluon
+ */
+ Lorentz5Momentum pGqqbar_;
+
+ /**
+ * Momentum of the incoming quark
+ */
+ Lorentz5Momentum pQqqbar_;
+
+ /**
+ * Momentum of the incoming antiquark
+ */
+ Lorentz5Momentum pQbarqqbar_;
+
+ /**
+ * The transverse momentum
+ */
+ Energy pTqqbar_;
+ //@}
+
+ /**
+ * Momenta etc for the \f$qg \to V \gamma q \f$ process
+ */
+ //@{
+ /**
+ * Momentum of the vector boson
+ */
+ Lorentz5Momentum pVqg_;
+
+ /**
+ * Momentum of the photon
+ */
+ Lorentz5Momentum pGammaqg_;
+
+ /**
+ * Momentum of the gluon
+ */
+ Lorentz5Momentum pGqg_;
+
+ /**
+ * Momentum of the incoming quark
+ */
+ Lorentz5Momentum pQinqg_;
+
+ /**
+ * Momentum of the incoming antiquark
+ */
+ Lorentz5Momentum pQoutqg_;
+
+ /**
+ * The transverse momentum
+ */
+ Energy pTqg_;
+ //@}
+
+ /**
+ * Momenta etc for the \f$g\bar q \to V \gamma \bar q \f$ process
+ */
+ //@{
+ /**
+ * Momentum of the vector boson
+ */
+ Lorentz5Momentum pVgqbar_;
+
+ /**
+ * Momentum of the photon
+ */
+ Lorentz5Momentum pGammagqbar_;
+
+ /**
+ * Momentum of the gluon
+ */
+ Lorentz5Momentum pGgqbar_;
+
+ /**
+ * Momentum of the incoming quark
+ */
+ Lorentz5Momentum pQingqbar_;
+
+ /**
+ * Momentum of the incoming antiquark
+ */
+ Lorentz5Momentum pQoutgqbar_;
+
+ /**
+ * The transverse momentum
+ */
+ Energy pTgqbar_;
+
+ //** the variables that are passed to the function QQbarGratio :
+ Energy2 ssHat_;
+ Energy maTV_;
+ Energy pTparton_;
+ double phiparton_;
+ double yparton_;
+
+ // ISR flag for QGQ generation
+ int QGQISR;
+ int QGQISR_gqbar;
+ int QGQISR_qg;
+
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of MEPP2VGammaPowheg. */
template <>
struct BaseClassTrait<Herwig::MEPP2VGammaPowheg,1> {
/** Typedef of the first base class of MEPP2VGammaPowheg. */
typedef Herwig::MEPP2VGamma NthBase;
};
/** This template specialization informs ThePEG about the name of
* the MEPP2VGammaPowheg class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::MEPP2VGammaPowheg>
: public ClassTraitsBase<Herwig::MEPP2VGammaPowheg> {
/** Return a platform-independent class name */
static string className() { return "Herwig::MEPP2VGammaPowheg"; }
/**
* The name of a file containing the dynamic library where the class
* MEPP2VGammaPowheg is implemented. It may also include several, space-separated,
* libraries if the class MEPP2VGammaPowheg 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 "HwMEHadron.so HwPowhegMEHadron.so"; }
};
/** @endcond */
}
+/*
+namespace Herwig {
+ // friend class MEPP2VGammaPowheg;
+ // using Herwig::MEPP2VGammaPowheg::PDFab;
+ struct KP1Integrand {
+ KP1Integrand(tcVGamPowhegPtr MEclass, double zz, Energy2 shat, Energy2 muF2, int partID, tcBeamPtr hadron_A, tcBeamPtr hadron_B)
+ : _meclass(MEclass), _zz(zz), _shat(shat), _muF2(muF2), _pID(partID), _hadron_A(hadron_A), _hadron_B(hadron_B) {}
+
+ double operator ()(double x) const {
+ double pdfzx, pdfz;
+
+ pdfzx= _meclass->PDFab(_zz/x, _pID, _muF2, _hadron_A, _hadron_B);
+ pdfz= _meclass->PDFab(_zz, _pID, _muF2, _hadron_A, _hadron_B);
+ return log(sqr(1.0-x)*_shat/(x*_muF2))*
+ (2.0/(1.0-x) -(1.0+sqr(x))/(1.0-x)*pdfzx/pdfz/x) +2.0/(1.0-x)*log(x);
+ }
+ typedef double ArgType;
+ typedef double ValType;
+
+ tcVGamPowhegPtr _meclass;
+ double _zz;
+ Energy2 _shat;
+ Energy2 _muF2;
+ int _pID;
+
+ };
+
+ struct KP2Integrand {
+ KP2Integrand(Energy2 shat, Energy2 muF2)
+ : _shat(shat), _muF2(muF2) {}
+
+ double operator ()(double x) const {
+ return log(sqr(1.0-x)*_shat/_muF2)*(2.0/(1.0-x));
+ }
+ typedef double ArgType;
+ typedef double ValType;
+
+ Energy2 _shat;
+ Energy2 _muF2;
+ };
+
+ struct KP3Integrand {
+ KP3Integrand(tcVGamPowhegPtr MEclass, double zz, int partID, Energy2 muF2, tcBeamPtr hadron_A, tcBeamPtr hadron_B)
+ : _meclass(MEclass), _zz(zz), _pID(partID), _muF2(muF2), _hadron_A(hadron_A), _hadron_B(hadron_B) {}
+
+ double operator ()(double x) const {
+ double pdfzx, pdfz;
+ MEPP2VGammaPowheg VGamPow;
+ pdfzx= _meclass->PDFab(_zz/x, _pID, _muF2, _hadron_A, _hadron_B);
+ pdfz= _meclass->PDFab(_zz, _pID, _muF2, _hadron_A, _hadron_B);
+
+ return (1.0-x)*pdfzx/pdfz/x;
+ }
+ typedef double ArgType;
+ typedef double ValType;
+
+ tcVGamPowhegPtr _meclass;
+ double _zz;
+ int _pID;
+ };
+}
+*/
+
+
#endif /* HERWIG_MEPP2VGammaPowheg_H */
diff --git a/MatrixElement/Powheg/MEqq2gZ2ffPowhegQED.cc b/MatrixElement/Powheg/MEqq2gZ2ffPowhegQED.cc
--- a/MatrixElement/Powheg/MEqq2gZ2ffPowhegQED.cc
+++ b/MatrixElement/Powheg/MEqq2gZ2ffPowhegQED.cc
@@ -1,2573 +1,2583 @@
// -*- C++ -*-
// This is the implementation of the non-inlined, non-templated member
// functions of the MEqq2gZ2ffPowhegQED class.
//
#include "MEqq2gZ2ffPowhegQED.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "Herwig++/Models/StandardModel/StandardModel.h"
#include "ThePEG/PDF/BeamParticleData.h"
#include "Herwig++/Utilities/Maths.h"
#include "Herwig++/MatrixElement/HardVertex.h"
#include "ThePEG/Helicity/Vertex/Vector/FFVVertex.h"
#include <numeric>
using namespace Herwig;
/**
* Typedef for BeamParticleData
*/
typedef Ptr<BeamParticleData>::transient_const_pointer tcBeamPtr;
MEqq2gZ2ffPowhegQED::MEqq2gZ2ffPowhegQED()
: corrections_(1), QEDContributions_(0), incomingPhotons_(true),
contrib_(1), power_(0.6), zPow_(0.5), yPow_(0.9),
alphaS_(0.118), alphaEM_(1./137.), fixedCouplings_(false),
supressionFunction_(0),
lambda2_(10000.*GeV2),
preqqbarqQCD_(10.), preqqbarqbarQCD_(10.),
preqgQCD_(10.),pregqbarQCD_(10.),
preqqbarqQED_(50.), preqqbarqbarQED_(50.),
preqgQED_(10.),pregqbarQED_(10.), preFFQED_(6.),
minpTQCD_(2.*GeV),minpTQED_(2.*GeV),
process_(2), maxFlavour_(5) {
vector<unsigned int> mopt(2,1);
massOption(mopt);
}
unsigned int MEqq2gZ2ffPowhegQED::orderInAlphaS() const {
return 0;
}
unsigned int MEqq2gZ2ffPowhegQED::orderInAlphaEW() const {
return 2;
}
IBPtr MEqq2gZ2ffPowhegQED::clone() const {
return new_ptr(*this);
}
IBPtr MEqq2gZ2ffPowhegQED::fullclone() const {
return new_ptr(*this);
}
Energy2 MEqq2gZ2ffPowhegQED::scale() const {
return sHat();
}
int MEqq2gZ2ffPowhegQED::nDim() const {
return HwMEBase::nDim() + ( contrib_>=1 && contrib_<=3 ? 3 : 0 );
}
bool MEqq2gZ2ffPowhegQED::generateKinematics(const double * r) {
if(contrib_>=1&&contrib_<=3) {
zTilde_ = r[nDim()-1];
vTilde_ = r[nDim()-2];
phi_ = Constants::twopi*r[nDim()-3];
}
jacobian(1.0);
return HwMEBase::generateKinematics(r);
}
CrossSection MEqq2gZ2ffPowhegQED::dSigHatDR() const {
// old technique
CrossSection preFactor =
jacobian()/(16.0*sqr(Constants::pi)*sHat())*sqr(hbarc);
loME_ = me2();
if(contrib_<4) return NLOWeight()*preFactor;
// folding technique to ensure positive
double wgt(0.);
unsigned int ntry(0);
do {
// radiative variables
zTilde_ = UseRandom::rnd();
vTilde_ = UseRandom::rnd();
phi_ = Constants::twopi*UseRandom::rnd();
wgt += NLOWeight();
++ntry;
}
while (wgt<0.&&ntry<100);
if(wgt<0.) return ZERO;
return wgt*preFactor/double(ntry);
}
double MEqq2gZ2ffPowhegQED::loME(const cPDVector & particles,
const vector<Lorentz5Momentum> & momenta,
bool first) const {
vector<SpinorWaveFunction> fin,aout;
vector<SpinorBarWaveFunction> ain,fout;
SpinorWaveFunction q(momenta[0],particles[0],incoming);
SpinorBarWaveFunction qbar(momenta[1],particles[1],incoming);
SpinorBarWaveFunction f(momenta[2],particles[2],outgoing);
SpinorWaveFunction fbar(momenta[3],particles[3],outgoing);
for(unsigned int ix=0;ix<2;++ix) {
q.reset(ix) ; fin.push_back(q);
qbar.reset(ix); ain.push_back(qbar);
f.reset(ix) ;fout.push_back(f);
fbar.reset(ix);aout.push_back(fbar);
}
return qqbarME(fin,ain,fout,aout,first);
}
double MEqq2gZ2ffPowhegQED::qqbarME(vector<SpinorWaveFunction> & fin ,
vector<SpinorBarWaveFunction> & ain ,
vector<SpinorBarWaveFunction> & fout,
vector<SpinorWaveFunction> & aout,
bool first) const {
// scale for the process
const Energy2 q2(scale());
ProductionMatrixElement menew(PDT::Spin1Half,PDT::Spin1Half,
PDT::Spin1Half,PDT::Spin1Half);
VectorWaveFunction inter[2];
double me[3]={0.,0.,0.};
// sum over helicities to get the matrix element
for(unsigned int ihel1=0;ihel1<2;++ihel1) {
for(unsigned int ihel2=0;ihel2<2;++ihel2) {
// intermediate for Z
inter[0]=FFZVertex_->evaluate(q2,1,Z0_ ,fin[ihel1],ain[ihel2]);
// intermediate for photon
inter[1]=FFPVertex_->evaluate(q2,1,gamma_,fin[ihel1],ain[ihel2]);
for(unsigned int ohel1=0;ohel1<2;++ohel1) {
for(unsigned int ohel2=0;ohel2<2;++ohel2) {
// first the Z exchange diagram
Complex diag1 = FFZVertex_->
evaluate(q2,aout[ohel2],fout[ohel1],inter[0]);
// first the photon exchange diagram
Complex diag2 = FFPVertex_->
evaluate(q2,aout[ohel2],fout[ohel1],inter[1]);
// add up squares of individual terms
me[1] += norm(diag1);
me[2] += norm(diag2);
// the full thing including interference
diag1 += diag2;
me[0] += norm(diag1);
menew(ihel1,ihel2,ohel1,ohel2) = diag1;
}
}
}
}
// spin and colour factor
double colspin=1./12.;
if(abs(fout[0].id())<=6) colspin*=3.;
for(int ix=0;ix<3;++ix)
me[ix]*=colspin;
if(first) {
DVector save;
save.push_back(me[1]);
save.push_back(me[2]);
meInfo(save);
me_.reset(menew);
}
return me[0];
}
Selector<const ColourLines *>
MEqq2gZ2ffPowhegQED::colourGeometries(tcDiagPtr) const {
static const ColourLines c1("1 -2");
Selector<const ColourLines *> sel;
sel.insert(1.0, &c1);
return sel;
}
void MEqq2gZ2ffPowhegQED::getDiagrams() const {
// loop over the processes we need
for ( int ix=11; ix<17; ++ix ) {
// is it a valid lepton process
bool lepton=
( process_==2 || (process_==3 && ix%2==1) ||
(process_==4 && ix%2==0) || (ix%2==0 && (ix-10)/2==process_-7) ||
(ix%2==1 && (ix-9)/2 ==process_-4));
// if not a valid process continue
if(!lepton) continue;
tcPDPtr lm = getParticleData(ix);
tcPDPtr lp = lm->CC();
for(int i = 1; i <= maxFlavour_; ++i) {
tcPDPtr q = getParticleData(i);
tcPDPtr qb = q->CC();
add(new_ptr((Tree2toNDiagram(2), q, qb, 1, Z0_ , 3, lm, 3, lp, -1)));
add(new_ptr((Tree2toNDiagram(2), q, qb, 1, gamma_, 3, lm, 3, lp, -2)));
}
}
}
Selector<MEBase::DiagramIndex>
MEqq2gZ2ffPowhegQED::diagrams(const DiagramVector & diags) const {
Selector<DiagramIndex> sel;
for ( DiagramIndex i = 0; i < diags.size(); ++i ) {
if ( diags[i]->id() == -1 ) sel.insert(meInfo()[0], i);
else if ( diags[i]->id() == -2 ) sel.insert(meInfo()[1], i);
}
return sel;
}
double MEqq2gZ2ffPowhegQED::me2() const {
// cast the vertices
tcFFVVertexPtr Zvertex = dynamic_ptr_cast<tcFFVVertexPtr>(FFZVertex_);
tcFFVVertexPtr Pvertex = dynamic_ptr_cast<tcFFVVertexPtr>(FFPVertex_);
// compute the spinors
vector<SpinorWaveFunction> fin,aout;
vector<SpinorBarWaveFunction> ain,fout;
SpinorWaveFunction q(meMomenta()[0],mePartonData()[0],incoming);
SpinorBarWaveFunction qbar(meMomenta()[1],mePartonData()[1],incoming);
SpinorBarWaveFunction f(meMomenta()[2],mePartonData()[2],outgoing);
SpinorWaveFunction fbar(meMomenta()[3],mePartonData()[3],outgoing);
for(unsigned int ix=0;ix<2;++ix) {
q.reset(ix) ;
fin .push_back(q);
qbar.reset(ix);
ain .push_back(qbar);
f .reset(ix);
fout.push_back(f);
fbar.reset(ix);
aout.push_back(fbar);
}
// scale for the process
const Energy2 q2(scale());
ProductionMatrixElement menew(PDT::Spin1Half,PDT::Spin1Half,
PDT::Spin1Half,PDT::Spin1Half);
// wavefunctions for the intermediate particles
VectorWaveFunction interZ,interP;
// momentum difference for genuine NLO structure
LorentzPolarizationVector momDiff =
(rescaledMomenta()[2]-rescaledMomenta()[3])/2./
(rescaledMomenta()[2].mass()+rescaledMomenta()[3].mass());
// sum over helicities to get the matrix element
double total[4]={0.,0.,0.,0.};
// incoming helicities
for(unsigned int ihel1=0;ihel1<2;++ihel1) {
for(unsigned int ihel2=0;ihel2<2;++ihel2) {
// intermediate for Z
interZ = FFZVertex_->evaluate(q2,1,Z0_ ,fin[ihel1],ain[ihel2]);
// intermediate for photon
interP = FFPVertex_->evaluate(q2,1,gamma_,fin[ihel1],ain[ihel2]);
// scalars
Complex scalar1 = interZ.wave().dot(momDiff);
Complex scalar2 = interP.wave().dot(momDiff);
// outgoing helicities
for(unsigned int ohel1=0;ohel1<2;++ohel1) {
for(unsigned int ohel2=0;ohel2<2;++ohel2) {
// first the Z exchange diagram
Complex diag1 = FFZVertex_->
evaluate(q2,aout[ohel2],fout[ohel1],interZ);
// first the photon exchange diagram
Complex diag2 = FFPVertex_->
evaluate(q2,aout[ohel2],fout[ohel1],interP);
// extra stuff for NLO
LorentzPolarizationVector left =
aout[ohel2].wave(). leftCurrent(fout[ohel1].wave());
LorentzPolarizationVector right =
aout[ohel2].wave().rightCurrent(fout[ohel1].wave());
Complex scalar =
aout[ohel2].wave().scalar(fout[ohel1].wave());
// nlo specific pieces
Complex diag3 =
Complex(0.,1.)*Zvertex->norm()*
(Zvertex->right()*( left.dot(interZ.wave())) +
Zvertex-> left()*(right.dot(interZ.wave())) -
( Zvertex-> left()+Zvertex->right())*scalar1*scalar);
diag3 += Complex(0.,1.)*Pvertex->norm()*
(Pvertex->right()*( left.dot(interP.wave())) +
Pvertex-> left()*(right.dot(interP.wave())) -
( Pvertex-> left()+Pvertex->right())*scalar2*scalar);
// add up squares of individual terms
total[1] += norm(diag1);
total[2] += norm(diag2);
// the full thing including interference
diag1 += diag2;
total[0] += norm(diag1);
menew(ihel1,ihel2,ohel1,ohel2) = diag1;
// nlo piece
total[3] += real(diag1*conj(diag3) + diag3*conj(diag1));
}
}
}
}
// spin and colour average
for(int ix=0;ix<4;++ix) total[ix] *= 1./12.;
// save the stuff for diagram selection
DVector save;
save.push_back(total[1]);
save.push_back(total[2]);
f2term_ = total[3];
meInfo(save);
me_.reset(menew);
return total[0];
}
void MEqq2gZ2ffPowhegQED::persistentOutput(PersistentOStream & os) const {
os << corrections_ << incomingPhotons_ << contrib_ << power_ << gluon_
<< fixedCouplings_ << alphaS_ << alphaEM_ << yPow_ << zPow_
<< supressionFunction_ << ounit(lambda2_,GeV2)
<< preqqbarqQCD_ << preqqbarqbarQCD_ << preqgQCD_ << pregqbarQCD_
<< preqqbarqQED_ << preqqbarqbarQED_ << preqgQED_ << pregqbarQED_
<< preFFQED_ << prefactorQCD_ << prefactorQED_
<< ounit(minpTQCD_,GeV) << ounit(minpTQED_,GeV) << alphaQCD_ << alphaQED_
<< FFZVertex_ << FFPVertex_ << FFGVertex_
<< Z0_ << gamma_ << process_ << maxFlavour_ << QEDContributions_;
}
void MEqq2gZ2ffPowhegQED::persistentInput(PersistentIStream & is, int) {
is >> corrections_ >> incomingPhotons_ >> contrib_ >> power_ >> gluon_
>> fixedCouplings_ >> alphaS_ >> alphaEM_ >> yPow_ >> zPow_
>> supressionFunction_ >> iunit(lambda2_,GeV2)
>> preqqbarqQCD_ >> preqqbarqbarQCD_ >> preqgQCD_ >> pregqbarQCD_
>> preqqbarqQED_ >> preqqbarqbarQED_ >> preqgQED_ >> pregqbarQED_
>> preFFQED_ >> prefactorQCD_ >> prefactorQED_
>> iunit(minpTQCD_,GeV) >> iunit(minpTQED_,GeV) >> alphaQCD_ >> alphaQED_
>> FFZVertex_ >> FFPVertex_ >> FFGVertex_
>> Z0_ >> gamma_ >> process_ >> maxFlavour_ >> QEDContributions_;
}
void MEqq2gZ2ffPowhegQED::doinit() {
HwMEBase::doinit();
// get the ParticleData objects
Z0_ = getParticleData(ThePEG::ParticleID::Z0);
gamma_ = getParticleData(ThePEG::ParticleID::gamma);
gluon_ = getParticleData(ParticleID::g);
// prefactors for overestimate for real emission
// QCD
prefactorQCD_.push_back(preqqbarqQCD_);
prefactorQCD_.push_back(preqqbarqbarQCD_);
prefactorQCD_.push_back(preqgQCD_);
prefactorQCD_.push_back(pregqbarQCD_);
// QED
prefactorQED_.push_back(preqqbarqQED_);
prefactorQED_.push_back(preqqbarqbarQED_);
prefactorQED_.push_back(preqgQED_);
prefactorQED_.push_back(pregqbarQED_);
// cast the SM pointer to the Herwig SM pointer
tcHwSMPtr hwsm=ThePEG::dynamic_ptr_cast<tcHwSMPtr>(standardModel());
if(!hwsm)
throw InitException() << "Must be the Herwig++ SusyBase class in "
<< "MEqq2gZ2ffPowhegQED::doinit"
<< Exception::abortnow;
// extract the vertices
FFZVertex_ = hwsm->vertexFFZ();
FFPVertex_ = hwsm->vertexFFP();
FFGVertex_ = hwsm->vertexFFG();
}
ClassDescription<MEqq2gZ2ffPowhegQED> MEqq2gZ2ffPowhegQED::initMEqq2gZ2ffPowhegQED;
// Definition of the static class description member.
void MEqq2gZ2ffPowhegQED::Init() {
static ClassDocumentation<MEqq2gZ2ffPowhegQED> documentation
("The MEqq2gZ2ffPowhegQED class implements the strong and QED corrections"
" to the Drell-Yan process");
static Switch<MEqq2gZ2ffPowhegQED,unsigned int> interfaceCorrections
("Corrections",
"Which corrections to include",
&MEqq2gZ2ffPowhegQED::corrections_, 1, false, false);
static SwitchOption interfaceCorrectionsQCD
(interfaceCorrections,
"QCD",
"Only include the QCD corrections",
1);
static SwitchOption interfaceCorrectionsQED
(interfaceCorrections,
"QED",
"Only include the QED corrections",
2);
static SwitchOption interfaceCorrectionsQCDandQED
(interfaceCorrections,
"QCDandQED",
"Include both QED and QCD corrections",
3);
static Switch<MEqq2gZ2ffPowhegQED,bool> interfaceIncomingPhotons
("IncomingPhotons",
"Whether or not to include incoming photons",
&MEqq2gZ2ffPowhegQED::incomingPhotons_, true, false, false);
static SwitchOption interfaceIncomingPhotonsYes
(interfaceIncomingPhotons,
"Yes",
"Include them",
true);
static SwitchOption interfaceIncomingPhotonsNo
(interfaceIncomingPhotons,
"No",
"Don't include them",
false);
static Switch<MEqq2gZ2ffPowhegQED,unsigned int> interfaceContribution
("Contribution",
"Which contributions to the cross section to include",
&MEqq2gZ2ffPowhegQED::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 SwitchOption interfaceContributionReal
(interfaceContribution,
"Real",
"Generate the high pT real emission only",
3);
static SwitchOption interfaceContributionTotalNLO
(interfaceContribution,
"TotalNLO",
"Generate the full NLO cross section using folding",
4);
static Parameter<MEqq2gZ2ffPowhegQED,double> interfaceSamplingPower
("SamplingPower",
"Power for the sampling of xp",
&MEqq2gZ2ffPowhegQED::power_, 0.6, 0.0, 1.,
false, false, Interface::limited);
static Switch<MEqq2gZ2ffPowhegQED,bool> interfaceFixedAlphaS
("FixedAlpha",
"Use a fixed value of alpha_S and alpha_EM",
&MEqq2gZ2ffPowhegQED::fixedCouplings_, false, false, false);
static SwitchOption interfaceFixedAlphaSYes
(interfaceFixedAlphaS,
"Yes",
"Use fixed alpha_S and alpha_EM",
true);
static SwitchOption interfaceFixedAlphaSNo
(interfaceFixedAlphaS,
"No",
"Use running alpha_S and alpha_EM",
false);
static Parameter<MEqq2gZ2ffPowhegQED,double> interfaceAlphaS
("AlphaS",
"The fixed value of alpha_S to use",
&MEqq2gZ2ffPowhegQED::alphaS_, 0., 0., 1.,
false, false, Interface::limited);
static Parameter<MEqq2gZ2ffPowhegQED,double> interfaceAlphaEM
("AlphaEM",
"The fixed value of alpha_EM to use",
&MEqq2gZ2ffPowhegQED::alphaS_, 1./137., 0., 1.,
false, false, Interface::limited);
static Switch<MEqq2gZ2ffPowhegQED,unsigned int> interfaceSupressionFunction
("SupressionFunction",
"Choice of the supression function",
&MEqq2gZ2ffPowhegQED::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<MEqq2gZ2ffPowhegQED,Energy2> interfaceSupressionScale
("SupressionScale",
"The square of the scale for the supression function",
&MEqq2gZ2ffPowhegQED::lambda2_, GeV2, 10000.0*GeV2, 0.0*GeV2, 0*GeV2,
false, false, Interface::lowerlim);
static Parameter<MEqq2gZ2ffPowhegQED,double> interfaceQQbarQPreFactorQCD
("QQbarQPreFactorQCD",
"Prefactor for the sampling on qqbar -> X g with radiation from q",
&MEqq2gZ2ffPowhegQED::preqqbarqQCD_, 20.0, 0.0, 1000.0,
false, false, Interface::limited);
static Parameter<MEqq2gZ2ffPowhegQED,double> interfaceQQbarQbarPreFactorQCD
("QQbarQbarPreFactorQCD",
"Prefactor for the sampling on qqbar -> X g with radiation from qbar",
&MEqq2gZ2ffPowhegQED::preqqbarqbarQCD_, 20.0, 0.0, 1000.0,
false, false, Interface::limited);
static Parameter<MEqq2gZ2ffPowhegQED,double> interfaceQGPreFactorQCD
("QGPreFactorQCD",
"The prefactor for the qg->Xq channel",
&MEqq2gZ2ffPowhegQED::preqgQCD_, 20.0, 0.0, 1000.0,
false, false, Interface::limited);
static Parameter<MEqq2gZ2ffPowhegQED,double> interfaceQbarGPreFactorQCD
("QbarGPreFactorQCD",
"The prefactor for the qbarg->Xqbar channel",
&MEqq2gZ2ffPowhegQED::pregqbarQCD_, 20.0, 0.0, 1000.0,
false, false, Interface::limited);
static Parameter<MEqq2gZ2ffPowhegQED,double> interfaceQQbarQPreFactorQED
("QQbarQPreFactorQED",
"Prefactor for the sampling on qqbar -> X g with radiation from q",
&MEqq2gZ2ffPowhegQED::preqqbarqQED_, 20.0, 0.0, 1000.0,
false, false, Interface::limited);
static Parameter<MEqq2gZ2ffPowhegQED,double> interfaceQQbarQbarPreFactorQED
("QQbarQbarPreFactorQED",
"Prefactor for the sampling on qqbar -> X g with radiation from qbar",
&MEqq2gZ2ffPowhegQED::preqqbarqbarQED_, 20.0, 0.0, 1000.0,
false, false, Interface::limited);
static Parameter<MEqq2gZ2ffPowhegQED,double> interfaceQGPreFactorQED
("QGPreFactorQED",
"The prefactor for the qg->Xq channel",
&MEqq2gZ2ffPowhegQED::preqgQED_, 20.0, 0.0, 1000.0,
false, false, Interface::limited);
static Parameter<MEqq2gZ2ffPowhegQED,double> interfaceQbarGPreFactorQED
("QbarGPreFactorQED",
"The prefactor for the qbarg->Xqbar channel",
&MEqq2gZ2ffPowhegQED::pregqbarQED_, 20.0, 0.0, 1000.0,
false, false, Interface::limited);
static Parameter<MEqq2gZ2ffPowhegQED,double> interfaceFinalStatePreFactorQED
("FinalStatePreFactorQED",
"The prefactor for final-state QED radiation",
&MEqq2gZ2ffPowhegQED::preFFQED_, 6.0, 0.0, 100.0,
false, false, Interface::limited);
static Parameter<MEqq2gZ2ffPowhegQED,Energy> interfaceMinimumpTQCD
("MinimumpTQCD",
"The minimum pT for the hard QCD emission",
&MEqq2gZ2ffPowhegQED::minpTQCD_, GeV, 1.0*GeV, 0.0*GeV, 10.0*GeV,
false, false, Interface::limited);
static Parameter<MEqq2gZ2ffPowhegQED,Energy> interfaceMinimumpTQED
("MinimumpTQED",
"The minimum pT for the hard QED emission",
&MEqq2gZ2ffPowhegQED::minpTQED_, GeV, 1.0*GeV, 0.0*GeV, 10.0*GeV,
false, false, Interface::limited);
static Reference<MEqq2gZ2ffPowhegQED,ShowerAlpha> interfaceAlphaQCD
("AlphaQCD",
"The object for the calculation of the strong coupling"
" for the hardest emission",
&MEqq2gZ2ffPowhegQED::alphaQCD_, false, false, true, false, false);
static Reference<MEqq2gZ2ffPowhegQED,ShowerAlpha> interfaceAlphaQED
("AlphaQED",
"The object for the calculation of the electromagnetic coupling"
" for the hardest emission",
&MEqq2gZ2ffPowhegQED::alphaQED_, false, false, true, false, false);
static Switch<MEqq2gZ2ffPowhegQED,int> interfaceProcess
("Process",
"Which process to included",
&MEqq2gZ2ffPowhegQED::process_, 2, false, false);
static SwitchOption interfaceProcessLeptons
(interfaceProcess,
"Leptons",
"Only include the leptons as outgoing particles",
2);
static SwitchOption interfaceProcessChargedLeptons
(interfaceProcess,
"ChargedLeptons",
"Only include the charged leptons as outgoing particles",
3);
static SwitchOption interfaceProcessNeutrinos
(interfaceProcess,
"Neutrinos",
"Only include the neutrinos as outgoing particles",
4);
static SwitchOption interfaceProcessElectron
(interfaceProcess,
"Electron",
"Only include e+e- as outgoing particles",
5);
static SwitchOption interfaceProcessMuon
(interfaceProcess,
"Muon",
"Only include mu+mu- as outgoing particles",
6);
static SwitchOption interfaceProcessTau
(interfaceProcess,
"Tau",
"Only include tau+tau- as outgoing particles",
7);
static SwitchOption interfaceProcessNu_e
(interfaceProcess,
"Nu_e",
"Only include nu_e ne_ebar as outgoing particles",
8);
static SwitchOption interfaceProcessnu_mu
(interfaceProcess,
"Nu_mu",
"Only include nu_mu nu_mubar as outgoing particles",
9);
static SwitchOption interfaceProcessnu_tau
(interfaceProcess,
"Nu_tau",
"Only include nu_tau nu_taubar as outgoing particles",
10);
static Parameter<MEqq2gZ2ffPowhegQED,int> interfaceMaxFlavour
("MaxFlavour",
"The maximum flavour of the incoming quarks",
&MEqq2gZ2ffPowhegQED::maxFlavour_, 5, 1, 5,
false, false, Interface::limited);
static Parameter<MEqq2gZ2ffPowhegQED,double> interfacezPower
("zPower",
"The sampling power for z",
&MEqq2gZ2ffPowhegQED::zPow_, 0.5, 0.0, 1.0,
false, false, Interface::limited);
static Parameter<MEqq2gZ2ffPowhegQED,double> interfaceyPower
("yPower",
"The sampling power for y",
&MEqq2gZ2ffPowhegQED::yPow_, 0.9, 0.0, 1.0,
false, false, Interface::limited);
static Switch<MEqq2gZ2ffPowhegQED,unsigned int> interfaceQEDContributions
("QEDContributions",
"Which QED corrections to include",
&MEqq2gZ2ffPowhegQED::QEDContributions_, 0, false, false);
static SwitchOption interfaceQEDContributionsAll
(interfaceQEDContributions,
"All",
"Include all the corrections",
0);
static SwitchOption interfaceQEDContributionsISR
(interfaceQEDContributions,
"ISR",
"Only include initial-state QED radiation",
1);
static SwitchOption interfaceQEDContributionsFSR
(interfaceQEDContributions,
"FSR",
"Only include final-state QED radiation",
2);
static SwitchOption interfaceQEDContributionsISRFSR
(interfaceQEDContributions,
"ISRPlusFSR",
"Only include inital- and final-state QED radiation, no intereference",
2);
}
double MEqq2gZ2ffPowhegQED::subtractedVirtual() const {
double output(0.);
// ISR QCD correction
if(corrections_==1||corrections_==3)
output += CFfact_*2.;
// ISR QED correction
if((corrections_==2||corrections_==3) && QEDContributions_ != 2)
output += sqr(double(mePartonData()[0]->iCharge())/3.)*EMfact_*2.;
// FSR QED correction
if((corrections_==2||corrections_==3) && QEDContributions_ != 1) {
double mu2 = sqr(mePartonData()[2]->mass())/sHat();
double mu = sqrt(mu2), mu4 = sqr(mu2), lmu = log(mu);
double v = sqrt(1.-4.*mu2),v2 = sqr(v),omv = 4.*mu2/(1.+v);
double f1,f2,fNS,VNS;
double r = omv/(1.+v),lr(log(r));
// normal form
if(mu>1e-4) {
f1 =
( +1. + 3.*log(0.5*(1.+v)) - 1.5*log(0.5*(1.+v2)) + sqr(Constants::pi)/6.
- 0.5*sqr(lr) - (1.+v2)/v*(lr*log(1.+v2) + sqr(Constants::pi)/12.
-0.5*log(4.*mu2)*lr + 0.25*sqr(lr)));
fNS = -0.5*(1.+2.*v2)*lr/v + 1.5*lr - 2./3.*sqr(Constants::pi) + 0.5*sqr(lr)
+ (1.+v2)/v*(Herwig::Math::ReLi2(r) + sqr(Constants::pi)/3. -
0.25*sqr(lr) + lr*log((2.*v/ (1.+v))));
VNS = 1.5*log(0.5*(1.+v2))
+ 0.5*(1.+v2)/v*( 2.*lr*log(2.*(1.+v2)/sqr(1.+v)) + 2.*Herwig::Math::ReLi2(sqr(r))
- 2.*Herwig::Math::ReLi2(2.*v/(1.+v)) - sqr(Constants::pi)/6.)
+ log(1.-mu) - 2.*log(1.-2.*mu) - 4.*mu2/(1.+v2)*log(mu/(1.-mu)) - mu/(1.-mu)
+ 4.*(2.*mu2-mu)/(1.+v2) + 0.5*sqr(Constants::pi);
f2 = mu2*lr/v;
}
// small mass limit
else {
f1 = -1./6.*
( - 6. - 24.*lmu*mu2 - 15.*mu4 - 12.*mu4*lmu - 24.*mu4*sqr(lmu)
+ 2.*mu4*sqr(Constants::pi) - 12.*mu2*mu4 - 96.*mu2*mu4*sqr(lmu)
+ 8.*mu2*mu4*sqr(Constants::pi) - 80.*mu2*mu4*lmu);
fNS = - mu2/18.*( + 36.*lmu - 36. - 45.*mu2 + 216.*lmu*mu2 - 24.*mu2*sqr(Constants::pi)
+ 72.*mu2*sqr(lmu) - 22.*mu4 + 1032.*mu4 * lmu
- 96.*mu4*sqr(Constants::pi) + 288.*mu4*sqr(lmu));
VNS = - mu2/1260.*(-6930. + 7560.*lmu + 2520.*mu - 16695.*mu2 + 1260.*mu2*sqr(Constants::pi)
+ 12600.*lmu*mu2 + 1344.*mu*mu2 - 52780.*mu4 + 36960.*mu4*lmu
+ 5040.*mu4*sqr(Constants::pi) - 12216.*mu*mu4);
f2 = mu2*( 2.*lmu + 4.*mu2*lmu + 2.*mu2 + 12.*mu4*lmu + 7.*mu4);
}
// subtracted virtual correction
output += sqr(double(mePartonData()[2]->iCharge())/3.)*
2.*EMfact_*(f1+fNS+VNS + f2*f2term_/loME_);
}
return output;
}
double MEqq2gZ2ffPowhegQED::NLOWeight() const {
// if leading-order return 1
if(contrib_==0) {
weights_.resize(1,loME_);
return loME_;
}
// strong coupling
Energy2 mu2(scale());
if(!fixedCouplings_) {
alphaS_ = SM().alphaS (mu2);
alphaEM_ = SM().alphaEM(mu2);
}
// prefactors
CFfact_ = 4./3.*alphaS_ /Constants::twopi;
TRfact_ = 1./2.*alphaS_ /Constants::twopi;
EMfact_ = alphaEM_/Constants::twopi;
// virtual pieces
double virt = subtractedVirtual();
// extract the partons and stuff for the real emission
// and collinear counter terms
// hadrons
pair<tcBeamPtr,tcBeamPtr> hadrons=
make_pair(dynamic_ptr_cast<tcBeamPtr>(lastParticles().first->dataPtr() ),
dynamic_ptr_cast<tcBeamPtr>(lastParticles().second->dataPtr()));
// momentum fractions
pair<double,double> x = make_pair(lastX1(),lastX2());
// partons
pair<tcPDPtr,tcPDPtr> 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<double,double> z;
pair<double,double> 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<double,double> 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<double,double> 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<double,double> 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);
pair<double,double> newpPDF(make_pair(-1.,-1.));
// real/coll photon
if(incomingPhotons_) {
// if check the PDF has photons
cPDVector partons = hadrons.first ->pdf()->partons(hadrons.first);
if(find(partons.begin(),partons.end(),gamma_)!=partons.end())
newpPDF.first = hadrons.first ->pdf()->xfx(hadrons.first ,gamma_,scale(),
x.first /z.first )*z.first /x.first;
partons = hadrons.second->pdf()->partons(hadrons.second);
if(find(partons.begin(),partons.end(),gamma_)!=partons.end())
newpPDF.second = hadrons.second->pdf()->xfx(hadrons.second,gluon_,scale(),
x.second/z.second)*z.second/x.second;
}
// collinear remnants
double coll = 0.;
// common terms
// 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);
// QCD
if(corrections_==1||corrections_==3) {
// g -> q
double collGQ = collinearBoson(mu2,zJac.first ,z.first ,
oldqPDF.first ,newgPDF.first );
// g -> qbar
double collGQbar = collinearBoson(mu2,zJac.second,z.second,
oldqPDF.second,newgPDF.second);
// add to sum
coll += CFfact_*(collQQ+collQbarQbar)+TRfact_*(collGQ+collGQbar);
}
// QED
if((corrections_==2||corrections_==3) &&
QEDContributions_!=2 ) {
// gamma -> q
double collPQ = newpPDF.first < 0. ? 0. :
collinearBoson(mu2,zJac.first ,z.first ,oldqPDF.first ,newpPDF.first );
// gamma -> qbar
double collPQbar = newpPDF.second < 0. ? 0. :
collinearBoson(mu2,zJac.second,z.second,oldqPDF.second,newpPDF.second);
// add to sum
coll += sqr(double(mePartonData()[0]->iCharge())/3.)*EMfact_*
(collQQ+collQbarQbar+collPQ+collPQbar);
}
// add up the virtual and remnant terms
double wgt = loME_*( 1. + virt + coll );
// real QCD emission
vector<double> realQCD1,realQCD2;
if(corrections_==1||corrections_==3) {
realQCD1 = subtractedRealQCD(x,z. first,zJac. first,
oldqPDF. first,newqPDF. first,
newgPDF. first, II12);
realQCD2 = subtractedRealQCD(x,z.second,zJac.second,
oldqPDF.second,newqPDF.second,
newgPDF.second, II21);
wgt += realQCD1[0] + realQCD1[2] +realQCD2[0] +realQCD2[2];
}
// real QED emission
vector<double> realQED1(4,0.),realQED2(4,0.),
realQED3(2,0.),realQED4(2,0.);
if(corrections_==2||corrections_==3) {
// ISR
if(QEDContributions_!=2) {
realQED1 = subtractedRealQED(x,z. first,zJac. first,
oldqPDF. first,newqPDF. first,
newpPDF. first, II12);
realQED2 = subtractedRealQED(x,z.second,zJac.second,
oldqPDF.second,newqPDF.second,
newpPDF.second, II21);
wgt += realQED1[0] + realQED1[2] +realQED2[0] +realQED2[2];
}
// FSR
if(QEDContributions_!=1) {
realQED3 = subtractedRealQED(x,zTilde_,1.,oldqPDF. first,
oldqPDF. first,0.,FF34);
realQED4 = subtractedRealQED(x,zTilde_,1.,oldqPDF. first,
oldqPDF. first,0.,FF43);
wgt += realQED3[0] + realQED4[0];
}
// \todo need to include IF terms
}
if(isnan(wgt)||isinf(wgt)) {
generator()->log() << "testing bad weight "
<< virt << " " << coll << " "
<< realQCD1[0] << " " << realQCD1[2] << " "
<< realQCD2[0] << " " << realQCD2[2] << "\n";
generator()->log() << "testing z " << z.first << " " << z.second << "\n";
generator()->log() << "testing z " << 1.-z.first << " " << 1.-z.second << "\n";
assert(false);
}
weights_.resize(11,0.);
if(corrections_==1||corrections_==3) {
weights_[ 1] = realQCD1[1];
weights_[ 2] = realQCD1[3];
weights_[ 3] = realQCD2[1];
weights_[ 4] = realQCD2[3];
}
if(corrections_==2||corrections_==3) {
weights_[ 5] = realQED1[1];
weights_[ 6] = realQED1[3];
weights_[ 7] = realQED2[1];
weights_[ 8] = realQED2[3];
weights_[ 9] = realQED3[1];
weights_[10] = realQED4[1];
}
if( contrib_ < 3 ) {
weights_[0] = wgt;
wgt = std::accumulate(weights_.begin(),weights_.end(),0.);
return contrib_ == 1 ? max(0.,wgt) : max(0.,-wgt);
}
else if(contrib_==3) {
weights_[0] = 0.;
return std::accumulate(weights_.begin(),weights_.end(),0.);
}
else
return wgt;
}
double
MEqq2gZ2ffPowhegQED::collinearQuark(double x, Energy2 mu2,
double jac, double z,
double oldPDF, double newPDF) const {
if(1.-z < 1.e-8) return 0.;
return
// 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
MEqq2gZ2ffPowhegQED::collinearBoson(Energy2 mu2, double jac, double z,
double oldPDF, double newPDF) const {
if(1.-z < 1.e-8) return 0.;
return jac/z*newPDF/oldPDF*
((sqr(z)+sqr(1.-z))*log(sqr(1.-z)*sHat()/z/mu2)
+2.*z*(1.-z));
}
vector<double>
MEqq2gZ2ffPowhegQED::subtractedRealQCD(pair<double,double> x, double z,
double zJac, double oldqPDF,
double newqPDF, double newgPDF,
DipoleType dipole) const {
double vt = vTilde_*(1.-z);
double vJac = 1.-z;
Energy pT = sqrt(sHat()*vt*(1.-vt-z)/z);
// rapidities
double rapidity;
if(dipole==II12) {
rapidity = -log(x.second*sqrt(lastS())/pT*vt);
}
else if(dipole==II21) {
rapidity = log(x.first *sqrt(lastS())/pT*vt);
}
else {
assert(false);
}
// 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<Lorentz5Momentum> pnew(5);
if(dipole==II12) {
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 if(dipole==II21) {
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) ;
}
else {
assert(false);
}
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/sqr(z);
double phase = zJac*vJac/z;
// real emission q qbar
vector<double> output(4,0.);
if(dipole==II12) {
realEmissionQCDGluon1_ = pnew;
realEmissionQCDQuark1_ = pnew;
}
else if(dipole==II21) {
realEmissionQCDGluon2_ = pnew;
realEmissionQCDQuark2_ = pnew;
}
else {
assert(false);
}
if(!(zTilde_<1e-7 || vt<1e-7 || 1.-z-vt < 1e-7 )) {
pair<double,double> realQQ = subtractedQCDMEqqbar(pnew,dipole,true);
double fact1 = CFfact_*phase*newqPDF/oldqPDF;
pair<double,double> realGQ = subtractedQCDMEgqbar(pnew,dipole,true);
double fact2 = TRfact_*phase*newgPDF/oldqPDF;
output[0] = realQQ.first *fact1;
output[1] = realQQ.second*fact1;
output[2] = realGQ.first *fact2;
output[3] = realGQ.second*fact2;
}
// return the answer
return output;
}
pair<double,double>
MEqq2gZ2ffPowhegQED::subtractedQCDMEqqbar(const vector<Lorentz5Momentum> & p,
DipoleType dipole,bool subtract) const {
// use the inheriting class to calculate the matrix element
cPDVector particles(mePartonData());
particles.push_back(gluon_);
double me = 0.75*realQCDME(particles,p);
// compute the two dipole terms
double x = (p[0]*p[1]-p[4]*p[1]-p[4]*p[0])/(p[0]*p[1]);
Lorentz5Momentum Kt = p[0]+p[1]-p[4];
vector<Lorentz5Momentum> pa(4),pb(4);
// momenta for q -> q g emission
pa[0] = x*p[0];
pa[1] = p[1];
Lorentz5Momentum K = pa[0]+pa[1];
Lorentz5Momentum Ksum = K+Kt;
Energy2 K2 = K.m2();
Energy2 Ksum2 = Ksum.m2();
for(unsigned int ix=2;ix<4;++ix)
pa[ix] = p[ix]-2.*Ksum*(Ksum*p[ix])/Ksum2+2*K*(Kt*p[ix])/K2;
// first LO matrix element
double lo1 = loME(mePartonData(),pa,false);
// momenta for qbar -> qbar g emission
pb[0] = p[0];
pb[1] = x*p[1];
K = pb[0]+pb[1];
Ksum = K+Kt;
K2 = K.m2();
Ksum2 = Ksum.m2();
for(unsigned int ix=2;ix<4;++ix)
pb[ix] = p[ix]-2.*Ksum*(Ksum*p[ix])/Ksum2+2*K*(Kt*p[ix])/K2;
// second LO matrix element
double lo2 = loME(mePartonData(),pb,false);
// first dipole
InvEnergy2 D1 = 0.5/(p[0]*p[4])/x*(2./(1.-x)-(1.+x));
// second dipole
InvEnergy2 D2 = 0.5/(p[1]*p[4])/x*(2./(1.-x)-(1.+x));
// results
pair<double,double> supressionFactor = supressionFunction(sqr(p[4].x())+sqr(p[4].y()));
pair<double,double> output = make_pair(0.,0.);
if(lo1>0.&&lo2>0.) {
if(dipole==II12) {
me *= abs(D1)*lo1/(abs(D1)*lo1+abs(D2)*lo2);
if(subtract) {
output.first = sHat()*(UnitRemoval::InvE2*me*supressionFactor.first -D1*lo1);
}
else {
output.first = sHat()*UnitRemoval::InvE2*me*supressionFactor.first;
}
output.second = sHat()*(UnitRemoval::InvE2*me*supressionFactor.second);
}
else if(dipole==II21) {
me *= abs(D2)*lo2/(abs(D1)*lo1+abs(D2)*lo2);
if(subtract) {
output.first = sHat()*(UnitRemoval::InvE2*me*supressionFactor.first -D2*lo2);
}
else {
output.first = sHat()*UnitRemoval::InvE2*me*supressionFactor.first;
}
output.second = sHat()*(UnitRemoval::InvE2*me*supressionFactor.second);
}
else {
assert(false);
}
}
return output;
}
pair<double,double>
MEqq2gZ2ffPowhegQED::subtractedQCDMEgqbar(const vector<Lorentz5Momentum> & p,
DipoleType dipole,bool subtract) const {
// use the inheriting class to calculate the matrix element
cPDVector particles(mePartonData());
if(dipole==II12) {
particles.push_back(particles[0]->CC());
particles[0] = gluon_;
}
else if(dipole==II21) {
particles.push_back(particles[1]->CC());
particles[1] = gluon_;
}
else {
assert(false);
}
double me = 2.*realQCDME(particles,p);
// compute the two dipole terms
double x = 1.-(p[4]*p[1]+p[4]*p[0])/(p[0]*p[1]);
Lorentz5Momentum Kt = p[0]+p[1]-p[4];
vector<Lorentz5Momentum> pa(4);
// momenta for ISR
if(dipole==II12) {
pa[0] = x*p[0];
pa[1] = p[1];
}
else if(dipole==II21) {
pa[0] = p[0];
pa[1] = x*p[1];
}
else {
assert(false);
}
Lorentz5Momentum K = pa[0]+pa[1];
Lorentz5Momentum Ksum = K+Kt;
Energy2 K2 = K.m2();
Energy2 Ksum2 = Ksum.m2();
for(unsigned int ix=2;ix<4;++ix)
pa[ix] = p[ix]-2.*Ksum*(Ksum*p[ix])/Ksum2+2*K*(Kt*p[ix])/K2;
// first LO matrix element
double lo1 = loME(mePartonData(),pa,false);
// dipole
InvEnergy2 D1;
if(dipole==II12) {
D1 = 0.5/(p[0]*p[4])/x*(1.-2.*x*(1.-x));
}
else if(dipole==II21) {
D1 = 0.5/(p[1]*p[4])/x*(1.-2.*x*(1.-x));
}
else {
assert(false);
}
pair<double,double> supressionFactor =
supressionFunction(sqr(p[4].x())+sqr(p[4].y()));
if(subtract) {
return make_pair(sHat()*(UnitRemoval::InvE2*me*supressionFactor.first -D1*lo1),
sHat()*(UnitRemoval::InvE2*me*supressionFactor.second));
}
else {
return make_pair(sHat()*(UnitRemoval::InvE2*me*supressionFactor.first ),
sHat()*(UnitRemoval::InvE2*me*supressionFactor.second));
}
}
double MEqq2gZ2ffPowhegQED::realQCDME(const cPDVector & particles,
const vector<Lorentz5Momentum> & momenta) const {
vector<SpinorWaveFunction> fin(2),aout(2);
vector<SpinorBarWaveFunction> ain(2),fout(2);
vector<VectorWaveFunction> gluon(2);
// wavefunctions for the q qbar -> l+ l- g process
if(particles[0]->id()==-particles[1]->id()) {
for( unsigned int i = 0; i < 2; ++i ) {
fin[i] = SpinorWaveFunction (momenta[0],particles[0], i,incoming);
ain[i] = SpinorBarWaveFunction(momenta[1],particles[1], i,incoming);
gluon[i] = VectorWaveFunction (momenta[4],particles[4],2*i,outgoing);
}
}
else if(particles[0]->id()==ParticleID::g && particles[1]->id()<0) {
for( unsigned int i = 0; i < 2; ++i ) {
fin[i] = SpinorWaveFunction (momenta[4],particles[4], i,outgoing);
ain[i] = SpinorBarWaveFunction(momenta[1],particles[1], i,incoming);
gluon[i] = VectorWaveFunction (momenta[0],particles[0],2*i,incoming);
}
}
else if(particles[0]->id()>0 && particles[1]->id()==ParticleID::g) {
for( unsigned int i = 0; i < 2; ++i ) {
fin[i] = SpinorWaveFunction (momenta[0],particles[0], i,incoming);
ain[i] = SpinorBarWaveFunction(momenta[4],particles[4], i,outgoing);
gluon[i] = VectorWaveFunction (momenta[1],particles[1],2*i,incoming);
}
}
else {
for(unsigned int ix=0;ix<particles.size();++ix) {
generator()->log() << particles[ix]->PDGName() << " " << momenta[ix]/GeV << "\n";
}
assert(false);
}
// wavefunctions for the leptons
for(unsigned int i=0; i<2; ++i) {
fout[i] = SpinorBarWaveFunction(momenta[2],particles[2],i,outgoing);
aout[i] = SpinorWaveFunction (momenta[3],particles[3],i,outgoing);
}
double output(0.);
vector<Complex> diag(4,0.);
Energy2 q2 = scale();
for(unsigned int lhel1=0;lhel1<2;++lhel1) {
for(unsigned int lhel2=0;lhel2<2;++lhel2) {
VectorWaveFunction Zwave = FFZVertex_->evaluate(q2, 1, Z0_,
aout[lhel2],fout[lhel1]);
VectorWaveFunction Pwave = FFPVertex_->evaluate(q2, 1, gamma_,
aout[lhel2],fout[lhel1]);
for(unsigned int ihel1=0;ihel1<2;++ihel1) {
for(unsigned int ihel2=0;ihel2<2;++ihel2) {
for(unsigned int ohel1=0;ohel1<2;++ohel1) {
//////// Z diagrams //////////
// first Z diagram
SpinorWaveFunction inters = FFGVertex_->
evaluate(q2,5,fin[ihel1].particle(),fin[ihel1],gluon[ohel1]);
diag[0] = FFZVertex_->evaluate(q2, inters, ain[ihel2], Zwave);
// second Z diagram
SpinorBarWaveFunction interb = FFGVertex_->
evaluate(q2,5,ain[ihel1].particle(),ain[ihel2],gluon[ohel1]);
diag[1] = FFZVertex_->evaluate(q2, fin[ihel1], interb, Zwave);
//////// photon diagrams //////////
if(particles[2]->id()==-particles[3]->id()&&
particles[2]->charged()) {
// first photon diagram
diag[2] = FFPVertex_->evaluate(q2, inters, ain[ihel2], Pwave);
// second photon diagram
diag[3] = FFPVertex_->evaluate(q2, fin[ihel1], interb, Pwave);
}
// add them up
output += norm(std::accumulate(diag.begin(),diag.end(),Complex(0.)));
}
}
}
}
}
// colour and spin factors
if(particles[0]->id()==-particles[1]->id()) {
output *= 1./9.;
}
else {
output *= 1./24.;
}
// divided by 2 g_S^2
return 0.5*output/norm(FFGVertex_->norm());
}
vector<double>
MEqq2gZ2ffPowhegQED::subtractedRealQED(pair<double,double> x, double z,
double zJac, double oldqPDF,
double newqPDF, double newpPDF,
DipoleType dipole) const {
// ISR
if(dipole==II12||dipole==II21) {
double vt = vTilde_*(1.-z);
double vJac = 1.-z;
Energy pT = sqrt(sHat()*vt*(1.-vt-z)/z);
// rapidities
double rapidity;
if(dipole==II12) {
rapidity = -log(x.second*sqrt(lastS())/pT*vt);
}
else if(dipole==II21) {
rapidity = log(x.first *sqrt(lastS())/pT*vt);
}
else {
assert(false);
}
// 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<Lorentz5Momentum> pnew(5);
if(dipole==II12) {
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 if(dipole==II21) {
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) ;
}
else {
assert(false);
}
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;
if(dipole==II12) {
realEmissionQEDPhoton1_ = pnew;
realEmissionQEDQuark1_ = pnew;
}
else if(dipole==II21) {
realEmissionQEDPhoton2_ = pnew;
realEmissionQEDQuark2_ = pnew;
}
else {
assert(false);
}
vector<double> output(4,0.);
if(!(zTilde_<1e-7 || vt<1e-7 || 1.-z-vt < 1e-7 )) {
// real emission q qbar
pair<double,double> realQQ = subtractedQEDMEqqbar(pnew,dipole,true);
double fact1 = EMfact_*phase*newqPDF/oldqPDF;
pair<double,double> realPQ(make_pair(0.,0.));
double fact2 = 0.;
if(newpPDF>0.) {
realPQ = subtractedQEDMEpqbar(pnew,dipole,true);
fact2 = EMfact_*phase*newpPDF/oldqPDF;
}
output[0] = realQQ.first *fact1;
output[1] = realQQ.second*fact1;
output[2] = realPQ.first *fact2;
output[3] = realPQ.second*fact2;
}
// return the answer
return output;
}
// FSR
else if(dipole==FF34||dipole==FF43) {
// reduced mass
double mu2 = sqr(mePartonData()[2]->mass())/sHat();
double mu = sqrt(mu2);
// jacobian
double jac = zJac;
// generate y
double yminus = 0.;
double yplus = 1.-2.*mu*(1.-mu)/(1.-2*mu2);
double rhoymax = pow(yplus-yminus,1.-yPow_);
double rhoy = zTilde_*rhoymax;
double y = yminus+pow(rhoy,1./(1.-yPow_));
jac *= pow(y-yminus,yPow_)*rhoymax/(1.-yPow_);
// generate z
double vt = sqrt(max(sqr(2.*mu2+(1.-2.*mu2)*(1.-y))-4.*mu2,0.))/(1.-2.*mu2)/(1.-y);
double zplus = (1.+vt)*(1.-2.*mu2)*y/2./(mu2 +(1.-2.*mu2)*y);
double zminus = (1.-vt)*(1.-2.*mu2)*y/2./(mu2 +(1.-2.*mu2)*y);
double rhozmax = pow(zplus-zminus,1.-zPow_);
double rhoz = vTilde_*rhozmax;
double z = zminus+pow(rhoz,1./(1.-zPow_));
jac *= pow(z-zminus,zPow_)*rhozmax/(1.-zPow_);
// calculate x1,x2,x3 and xT
double x2 = 1. - y*(1.-2.*mu2);
double x1 = 1. - z*(x2-2.*mu2);
double x3 = 2.-x1-x2;
double xT = sqrt(max(0.,sqr(x3) -0.25*sqr(sqr(x2)+sqr(x3)-sqr(x1))/(sqr(x2)-4.*mu2)));
// calculate the momenta
Energy M = sqrt(sHat());
Lorentz5Momentum pspect(ZERO,ZERO,-0.5*M*sqrt(max(sqr(x2)-4.*mu2,0.)),0.5*M*x2,M*mu);
Lorentz5Momentum pemit (-0.5*M*xT*cos(phi_),-0.5*M*xT*sin(phi_),
0.5*M*sqrt(max(sqr(x1)-sqr(xT)-4.*mu2,0.)),0.5*M*x1,M*mu);
Lorentz5Momentum pphoton( 0.5*M*xT*cos(phi_), 0.5*M*xT*sin(phi_),
0.5*M*sqrt(max(sqr(x3)-sqr(xT),0.)),0.5*M*x3,ZERO);
if(abs(pspect.z()+pemit.z()-pphoton.z())/M<1e-6)
pphoton.setZ(-pphoton.z());
else if(abs(pspect.z()-pemit.z()+pphoton.z())/M<1e-6)
pemit .setZ(- pemit.z());
// boost and rotate momenta
LorentzRotation eventFrame( ( meMomenta()[2] + meMomenta()[3] ).findBoostToCM() );
Lorentz5Momentum spectator;
if(dipole==FF34) {
spectator = eventFrame*meMomenta()[2];
}
else {
spectator = eventFrame*meMomenta()[3];
}
eventFrame.rotateZ( -spectator.phi() );
eventFrame.rotateY( -spectator.theta() );
eventFrame.invert();
vector<Lorentz5Momentum> momenta(meMomenta());
if(dipole==FF34) {
momenta[3] = eventFrame*pspect;
momenta[2] = eventFrame*pemit ;
}
else {
momenta[2] = eventFrame*pspect;
momenta[3] = eventFrame*pemit ;
}
momenta.push_back(eventFrame*pphoton);
// phase-space factor
double realFact = EMfact_*(1.-y)*jac*sqr(1.-2.*mu2)/sqrt(1.-4.*mu2);
pair<double,double> realFF = make_pair(0.,0.);
if(1.-x1>1e-5 && 1.-x2>1e-5) {
realFF = subtractedQEDMEqqbar(momenta,dipole,true);
}
vector<double> output(2,0.);
output[0] = realFF.first *realFact;
output[1] = realFF.second*realFact;
return output;
}
else {
assert(false);
return vector<double>(4,0.);
}
}
pair<double,double>
MEqq2gZ2ffPowhegQED::subtractedQEDMEqqbar(const vector<Lorentz5Momentum> & p,
DipoleType dipole, bool subtract) const {
// calculate the matrix element
cPDVector particles(mePartonData());
particles.push_back(gamma_);
vector<double> me = realQEDME(particles,p);
/////////// compute the two II dipole terms ////////////////////////////
double x = (p[0]*p[1]-p[4]*p[1]-p[4]*p[0])/(p[0]*p[1]);
Lorentz5Momentum Kt = p[0]+p[1]-p[4];
vector<Lorentz5Momentum> pa(4),pb(4);
// momenta for q -> q g emission
pa[0] = x*p[0];
pa[1] = p[1];
Lorentz5Momentum K = pa[0]+pa[1];
Lorentz5Momentum Ksum = K+Kt;
Energy2 K2 = K.m2();
Energy2 Ksum2 = Ksum.m2();
for(unsigned int ix=2;ix<4;++ix)
pa[ix] = p[ix]-2.*Ksum*(Ksum*p[ix])/Ksum2+2*K*(Kt*p[ix])/K2;
// first LO matrix element
double lo1 = loME(mePartonData(),pa,false);
// momenta for qbar -> qbar g emission
pb[0] = p[0];
pb[1] = x*p[1];
K = pb[0]+pb[1];
Ksum = K+Kt;
K2 = K.m2();
Ksum2 = Ksum.m2();
for(unsigned int ix=2;ix<4;++ix)
pb[ix] = p[ix]-2.*Ksum*(Ksum*p[ix])/Ksum2+2*K*(Kt*p[ix])/K2;
// second LO matrix element
double lo2 = loME(mePartonData(),pb,false);
// II dipoles
InvEnergy2 DII[2] = {0.5/(p[0]*p[4])/x*(2./(1.-x)-(1.+x))*lo1,
0.5/(p[1]*p[4])/x*(2./(1.-x)-(1.+x))*lo2};
/////////// compute the two FF dipole terms ////////////////////////////
InvEnergy2 DFF[2]={ZERO,ZERO};
Lorentz5Momentum q = p[0]+p[1];
Energy2 Q2=q.m2();
Energy2 lambda = sqrt((Q2-sqr(p[2].mass()+p[3].mass()))*
(Q2-sqr(p[2].mass()-p[3].mass())));
Energy2 pT2final[2];
for(unsigned int iemit=0;iemit<2;++iemit) {
unsigned int ispect = iemit==0 ? 1 : 0;
Energy2 pipj = p[4 ] * p[2+iemit ];
Energy2 pipk = p[4 ] * p[2+ispect];
Energy2 pjpk = p[2+iemit] * p[2+ispect];
double y = pipj/(pipj+pipk+pjpk);
double z = pipk/( pipk+pjpk);
Energy mij = sqrt(2.*pipj+sqr(p[2+iemit].mass()));
Energy2 lamB = sqrt((Q2-sqr(mij+p[2+ispect].mass()))*
(Q2-sqr(mij-p[2+ispect].mass())));
Energy2 Qpk = q*p[2+ispect];
Lorentz5Momentum pkt =
lambda/lamB*(p[2+ispect]-Qpk/Q2*q)
+0.5/Q2*(Q2+sqr(p[2+ispect].mass())-sqr(p[2+ispect].mass()))*q;
Lorentz5Momentum pijt =
q-pkt;
double muj = p[2+iemit ].mass()/sqrt(Q2);
double muk = p[2+ispect].mass()/sqrt(Q2);
double vt = sqrt((1.-sqr(muj+muk))*(1.-sqr(muj-muk)))/(1.-sqr(muj)-sqr(muk));
double v = sqrt(sqr(2.*sqr(muk)+(1.-sqr(muj)-sqr(muk))*(1.-y))-4.*sqr(muk))
/(1.-y)/(1.-sqr(muj)-sqr(muk));
// transverse momentum
double x1 = 2.*p[2+iemit ]*q/Q2;
double x2 = 2.*p[2+ispect]*q/Q2;
pT2final[iemit] = 0.25*Q2/(sqr(x2)-4.*sqr(muk))*
((sqr(x1)-4.*sqr(muj))*(sqr(x2)-4.*sqr(muk)) -
sqr(2.*x1+2.*x2-2.-x1*x2-2.*sqr(muj)-2.*sqr(muk)));
// dipole term
DFF[iemit] = 0.5/pipj*(2./(1.-(1.-z)*(1.-y))
-vt/v*(2.-z+sqr(p[2+iemit].mass())/pipj));
// matrix element
vector<Lorentz5Momentum> lomom(4);
lomom[0] = p[0];
lomom[1] = p[1];
if(iemit==0) {
lomom[2] = pijt;
lomom[3] = pkt ;
}
else {
lomom[3] = pijt;
lomom[2] = pkt ;
}
// leading-order matrix element
double lo = loME(mePartonData(),lomom,false);
DFF[iemit] *= lo;
}
// supression function
Energy2 pT2sup=ZERO;
if(dipole==II12||dipole==II21) {
pT2sup = sqr(p[4].x())+sqr(p[4].y());
}
else if(dipole==FF34||dipole==FF43) {
pT2sup = dipole==FF34 ? pT2final[0] : pT2final[1];
}
else {
assert(false);
}
pair<double,double> supressionFactor = supressionFunction(pT2sup);
// charge factors
for(unsigned int ix=0;ix<2;++ix) {
DII[ix] *= sqr(double(mePartonData()[0]->iCharge())/3.);
DFF[ix] *= sqr(double(mePartonData()[2]->iCharge())/3.);
}
// numerator for dipole ratio
InvEnergy2 num;
switch (dipole) {
case II12 :
num = DII[0];
break;
case II21 :
num = DII[1];
break;
case FF34 :
num = DFF[0];
break;
case FF43 :
num = DFF[1];
break;
default:
assert(false);
};
double meout(0.);
InvEnergy2 den(ZERO);
// ISR
if(QEDContributions_==1 ||
(QEDContributions_==3 && (dipole==II12 || dipole ==II21))) {
assert(dipole==II12 || dipole ==II21);
meout = me[0];
den = abs(DII[0])+abs(DII[1]);
}
// FSR
else if(QEDContributions_==2 ||
(QEDContributions_==3 && (dipole==FF34 || dipole ==FF43))) {
assert(dipole==FF34 || dipole ==FF43);
meout = me[1];
den = abs(DFF[0])+abs(DFF[1]);
}
// full result
else if(QEDContributions_==4) {
assert(false);
// for the moment matrix element is only IFS+FSR (no interference)
meout = me[0]+me[1];
// denominator for dipole ratio
den = abs(DII[0])+abs(DII[1])+abs(DFF[0])+abs(DFF[1]);
}
else
assert(false);
// return the answer
pair<double,double> output = make_pair(0.,0.);
if(den>ZERO) {
meout *= abs(num)/den;
if(subtract) {
output.first = sHat()*(UnitRemoval::InvE2*meout*supressionFactor.first -num);
}
else {
output.first = sHat()* UnitRemoval::InvE2*meout*supressionFactor.first;
}
output.second = sHat()* UnitRemoval::InvE2*meout*supressionFactor.second;
}
return output;
}
pair<double,double>
MEqq2gZ2ffPowhegQED::subtractedQEDMEpqbar(const vector<Lorentz5Momentum> & p,
DipoleType dipole, bool subtract) const {
// use the inheriting class to calculate the matrix element
cPDVector particles(mePartonData());
if(dipole==II12) {
particles.push_back(particles[0]->CC());
particles[0] = gluon_;
}
else if(dipole==II21) {
particles.push_back(particles[1]->CC());
particles[1] = gluon_;
}
else {
assert(false);
}
vector<double> me = realQEDME(particles,p);
// compute the two dipole terms
double x = 1.-(p[4]*p[1]+p[4]*p[0])/(p[0]*p[1]);
Lorentz5Momentum Kt = p[0]+p[1]-p[4];
vector<Lorentz5Momentum> pa(4);
// momenta for ISR
if(dipole==II12) {
pa[0] = x*p[0];
pa[1] = p[1];
}
else if(dipole==II21) {
pa[0] = p[0];
pa[1] = x*p[1];
}
else {
assert(false);
}
Lorentz5Momentum K = pa[0]+pa[1];
Lorentz5Momentum Ksum = K+Kt;
Energy2 K2 = K.m2();
Energy2 Ksum2 = Ksum.m2();
for(unsigned int ix=2;ix<4;++ix)
pa[ix] = p[ix]-2.*Ksum*(Ksum*p[ix])/Ksum2+2*K*(Kt*p[ix])/K2;
// first LO matrix element
double lo1 = loME(mePartonData(),pa,false);
// dipole
InvEnergy2 D1;
if(dipole==II12) {
D1 = 0.5/(p[0]*p[4])/x*(1.-2.*x*(1.-x));
}
else if(dipole==II21) {
D1 = 0.5/(p[1]*p[4])/x*(1.-2.*x*(1.-x));
}
else {
assert(false);
}
// charges
D1 *= sqr(double(mePartonData()[2]->iCharge())/3.)*lo1;
// supression function
pair<double,double> supressionFactor =
supressionFunction(sqr(p[4].x())+sqr(p[4].y()));
if(subtract) {
return make_pair(sHat()*(UnitRemoval::InvE2*me[0]*supressionFactor.first -D1),
sHat()*(UnitRemoval::InvE2*me[0]*supressionFactor.second));
}
else {
return make_pair(sHat()*(UnitRemoval::InvE2*me[0]*supressionFactor.first ),
sHat()*(UnitRemoval::InvE2*me[0]*supressionFactor.second));
}
}
vector<double>
MEqq2gZ2ffPowhegQED::realQEDME(const cPDVector & particles,
const vector<Lorentz5Momentum> & momenta) const {
vector<SpinorWaveFunction> fin(2),aout(2);
vector<SpinorBarWaveFunction> ain(2),fout(2);
vector<VectorWaveFunction> photon(2);
// wavefunctions for the q qbar -> l+ l- gamma process
if(particles[0]->id()==-particles[1]->id()) {
for( unsigned int i = 0; i < 2; ++i ) {
fin[i] = SpinorWaveFunction (momenta[0],particles[0], i,incoming);
ain[i] = SpinorBarWaveFunction(momenta[1],particles[1], i,incoming);
photon[i] = VectorWaveFunction (momenta[4],particles[4],2*i,outgoing);
}
}
else if(particles[0]->id()==ParticleID::g && particles[1]->id()<0) {
for( unsigned int i = 0; i < 2; ++i ) {
fin[i] = SpinorWaveFunction (momenta[4],particles[4], i,outgoing);
ain[i] = SpinorBarWaveFunction(momenta[1],particles[1], i,incoming);
photon[i] = VectorWaveFunction (momenta[0],particles[0],2*i,incoming);
}
}
else if(particles[0]->id()>0 && particles[1]->id()==ParticleID::g) {
for( unsigned int i = 0; i < 2; ++i ) {
fin[i] = SpinorWaveFunction (momenta[0],particles[0], i,incoming);
ain[i] = SpinorBarWaveFunction(momenta[4],particles[4], i,outgoing);
photon[i] = VectorWaveFunction (momenta[1],particles[1],2*i,incoming);
}
}
else {
for(unsigned int ix=0;ix<particles.size();++ix) {
generator()->log() << particles[ix]->PDGName() << " " << momenta[ix]/GeV << "\n";
}
assert(false);
}
// wavefunctions for the leptons
for(unsigned int i=0; i<2; ++i) {
fout[i] = SpinorBarWaveFunction(momenta[2],particles[2],i,outgoing);
aout[i] = SpinorWaveFunction (momenta[3],particles[3],i,outgoing);
}
// off-shell vector bosons for speed
Energy2 q2 = scale();
VectorWaveFunction ZwaveIn[2][2],ZwaveOut[2][2];
VectorWaveFunction PwaveIn[2][2],PwaveOut[2][2];
for(unsigned int ihel1=0;ihel1<2;++ihel1) {
for(unsigned int ihel2=0;ihel2<2;++ihel2) {
// intermediate Z
ZwaveIn [ihel1][ihel2] =
FFZVertex_->evaluate(q2,1,Z0_ ,fin [ihel1],ain [ihel2]);
ZwaveOut[ihel1][ihel2] =
FFZVertex_->evaluate(q2,1,Z0_ ,aout[ihel2],fout[ihel1]);
// intermediate photon
PwaveIn [ihel1][ihel2] =
FFPVertex_->evaluate(q2,1,gamma_,fin [ihel1],ain [ihel2]);
PwaveOut[ihel1][ihel2] =
FFPVertex_->evaluate(q2,1,gamma_,aout[ihel2],fout[ihel1]);
}
}
vector<double> output(3,0.);
vector<Complex> diagI(4,0.),diagF(4,0.);
for(unsigned int ihel1=0;ihel1<2;++ihel1) {
for(unsigned int ihel2=0;ihel2<2;++ihel2) {
for(unsigned int lhel1=0;lhel1<2;++lhel1) {
for(unsigned int lhel2=0;lhel2<2;++lhel2) {
for(unsigned int ohel1=0;ohel1<2;++ohel1) {
// ISR diagrams
// first Z diagram
SpinorWaveFunction inters = FFPVertex_->
evaluate(q2,5,fin[ihel1].particle(),fin[ihel1],photon[ohel1]);
diagI[0] = FFZVertex_->
evaluate(q2, inters, ain[ihel2], ZwaveOut[lhel1][lhel2]);
// second Z diagram
SpinorBarWaveFunction interb = FFPVertex_->
evaluate(q2,5,ain[ihel2].particle(),ain[ihel2],photon[ohel1]);
diagI[1] = FFZVertex_->
evaluate(q2, fin[ihel1], interb, ZwaveOut[lhel1][lhel2]);
if(particles[2]->charged()) {
// first photon diagram
diagI[2] = FFPVertex_->
evaluate(q2, inters, ain[ihel2], PwaveOut[lhel1][lhel2]);
// second photon diagram
diagI[3] = FFPVertex_->
evaluate(q2, fin[ihel1], interb, PwaveOut[lhel1][lhel2]);
}
// FSR diagrams
if(particles[2]->charged()) {
SpinorBarWaveFunction off1 = FFPVertex_->
evaluate(q2,3,fout[lhel1].particle(),fout[lhel1],photon[ohel1]);
diagF[0] = FFZVertex_->
evaluate(q2,aout[lhel2],off1,ZwaveIn[ihel1][ihel2]);
diagF[1] = FFPVertex_->
evaluate(q2,aout[lhel2],off1,PwaveIn[ihel1][ihel2]);
SpinorWaveFunction off2 = FFPVertex_->
evaluate(q2,3,aout[lhel2].particle(),aout[lhel2],photon[ohel1]);
diagF[2] = FFZVertex_->
evaluate(q2,off2,fout[lhel1],ZwaveIn[ihel1][ihel2]);
diagF[3] = FFPVertex_->
evaluate(q2,off2,fout[lhel1],PwaveIn[ihel1][ihel2]);
}
// totals
Complex ISR = std::accumulate(diagI.begin(),diagI.end(),Complex(0.));
Complex FSR = std::accumulate(diagF.begin(),diagF.end(),Complex(0.));
output[0] += norm(ISR);
output[1] += norm(FSR);
output[2] += real(ISR*conj(FSR)+FSR*conj(ISR));
}
}
}
}
}
// colour and spin factors
if(particles[0]->id()==-particles[1]->id()) {
for(unsigned int ix=0;ix<output.size();++ix)
output[ix] *= 1./12.;
}
else {
for(unsigned int ix=0;ix<output.size();++ix)
output[ix] *= 0.25;
}
// divided by 2 e^2
for(unsigned int ix=0;ix<output.size();++ix)
output[ix] *= 0.5/norm(FFPVertex_->norm());
return output;
}
void MEqq2gZ2ffPowhegQED::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]);
hard.push_back(sub->outgoing()[1]);
// order of particles
if( hard[0]->id() != mePartonData()[0]->id() ) swap(hard[0], hard[1]);
if( hard[2]->id() != mePartonData()[2]->id() ) swap(hard[2], hard[3]);
// wavefunctions
vector<SpinorWaveFunction> fin,aout;
vector<SpinorBarWaveFunction> ain,fout;
SpinorWaveFunction( fin ,hard[0],incoming,false,true);
SpinorBarWaveFunction(ain ,hard[1],incoming,false,true);
SpinorBarWaveFunction(fout,hard[2],outgoing,true ,true);
SpinorWaveFunction( aout,hard[3],outgoing,true ,true);
qqbarME(fin,ain,fout,aout,true);
// get the spin info objects
SpinPtr spin[4];
for(unsigned int ix=0;ix<4;++ix) spin[ix]=hard[ix]->spinInfo();
// 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 ix=0;ix<4;++ix)
spin[ix]->productionVertex(hardvertex);
}
void MEqq2gZ2ffPowhegQED::hardQCDEmission(vector<ShowerProgenitorPtr> &
particlesToShower, int & emission_type,
Energy & pTmax) {
emission_type = -1;
Energy rootS = sqrt(lastS());
// limits on the rapidity of the jet
double minyj = -10.0,maxyj = 10.0;
pair<double,double> x = make_pair(particlesToShower[0]->progenitor()->x(),
particlesToShower[1]->progenitor()->x());
// loop over the possible emissions
vector<Energy> pT;
for(unsigned int ix=0;ix<4;++ix) {
pT.push_back(0.5*generator()->maximumCMEnergy());
// particles for the hard process
cPDVector particles;
for(unsigned int iy=0;iy<particlesToShower.size();++iy) {
particles.push_back(particlesToShower[iy]->progenitor()->dataPtr());
}
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<Lorentz5Momentum> momenta(5);
double a = alphaQCD_->overestimateValue()/Constants::twopi*
prefactorQCD_[ix]*(maxyj-minyj);
pTmax = -GeV;
do {
pT[ix] *= pow(UseRandom::rnd(),1./a);
if(pT[ix]<=minpTQCD_) break;
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.||z<x.first) continue;
}
else {
vt = pT[ix]*exp( y)/rootS/x.first ;
z = (1.-pT[ix]*exp( y)/rootS/x.first )/(1.+pT[ix]*exp(-y)/rootS/x.second );
if(z>1.||z<x.second) continue;
}
if(vt>1.-z || vt<0.) continue;
if(ix%2==0) {
momenta[0] = particlesToShower[0]->progenitor()->momentum()/z;
momenta[1] = particlesToShower[1]->progenitor()->momentum();
}
else {
momenta[0] = particlesToShower[0]->progenitor()->momentum();
momenta[1] = particlesToShower[1]->progenitor()->momentum()/z;
}
double phi = Constants::twopi*UseRandom::rnd();
momenta[2] = particlesToShower[2]->progenitor()->momentum();
momenta[3] = particlesToShower[3]->progenitor()->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();
+ Energy2 K2 = Kt.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;
+ +2.*K*(Kt*momenta [iy])/K2;
}
// matrix element piece
double wgt = alphaQCD_->ratio(sqr(pT[ix]))*z/(1.-vt)/prefactorQCD_[ix]/loME_;
// compute me piece here
if(ix==0)
- wgt *= 4./3.*2.*sqr(pT[ix])/sHat()*subtractedQCDMEqqbar(momenta,II12,false).first;
+ wgt *= 8./3.*sqr(pT[ix])/sHat()*subtractedQCDMEqqbar(momenta,II12,false).first;
else if(ix==1)
- wgt *= 4./3.*2.*sqr(pT[ix])/sHat()*subtractedQCDMEqqbar(momenta,II21,false).first;
+ wgt *= 8./3.*sqr(pT[ix])/sHat()*subtractedQCDMEqqbar(momenta,II21,false).first;
else if(ix==2)
- wgt *= sqr(pT[ix])/sHat()*subtractedQCDMEgqbar(momenta,II12,false).first;
+ wgt *= sqr(pT[ix])/sHat()*subtractedQCDMEgqbar(momenta,II12,false).first;
else if(ix==3)
- wgt *= sqr(pT[ix])/sHat()*subtractedQCDMEgqbar(momenta,II21,false).first;
+ wgt *= sqr(pT[ix])/sHat()*subtractedQCDMEgqbar(momenta,II21,false).first;
// pdf piece
- double pdf[2];
+ double pdf[4];
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;
+ pdf[2] = _beams[1]->pdf()->xfx(_beams[1],_partons [1],
+ scale() ,x.second ) /x.second;
+ pdf[3] = _beams[1]->pdf()->xfx(_beams[1],particles[1],
+ scale()+sqr(pT[ix]),x.second ) /x.second;
}
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;
+ pdf[2] = _beams[0]->pdf()->xfx(_beams[0],_partons [0],
+ scale(), x.first ) /x.first;
+ pdf[3] = _beams[0]->pdf()->xfx(_beams[0],particles[0],
+ scale()+sqr(pT[ix]),x.first ) /x.first;
}
if(pdf[0]<=0.||pdf[1]<=0.) continue;
+ if(pdf[2]<=0.||pdf[3]<=0.) continue;
wgt *= pdf[1]/pdf[0];
+ wgt *= pdf[3]/pdf[2];
// check weight less than one
if(wgt>1.) {
generator()->log() << "Weight greater than one for emission type " << ix
<< "in MEqq2gZ2ffPowhegQED::generateHardest()"
<< " weight = " << wgt << "\n";
}
// break if select emission
if(UseRandom::rnd()<wgt) break;
}
while(pT[ix]>minpTQCD_);
if(pT[ix]>minpTQCD_ && pT[ix]>pTmax) {
pTmax = pT[ix];
if(ix==0) {
realEmissionQCDGluon1_=momenta;
emission_type=1;
}
else if(ix==1) {
realEmissionQCDGluon2_=momenta;
emission_type=3;
}
else if(ix==2) {
realEmissionQCDQuark1_=momenta;
emission_type=2;
}
else if(ix==3) {
realEmissionQCDQuark2_=momenta;
emission_type=4;
}
}
}
}
/**
* Generate a hard QED emission
*/
void MEqq2gZ2ffPowhegQED::hardQEDEmission(vector<ShowerProgenitorPtr> & particlesToShower,
int & emission_type, Energy & pTmax) {
emission_type = -1;
pTmax = -GeV;
Energy pT_II(-GeV),pT_IF(-GeV),pT_FF(-GeV);
int type_II(-1),type_IF(-1),type_FF(-1);
// initial-initial radiation
hardQEDIIEmission(particlesToShower,type_II,pT_II);
// final-final radiation
hardQEDFFEmission(particlesToShower,type_FF,pT_FF);
// initial-final radiation
hardQEDIFEmission(particlesToShower,type_IF,pT_IF);
if(type_II<0&&type_FF<0&&type_IF<0) return;
// select the maximum pT emission
if( pT_II>pT_FF && pT_II>pT_IF) {
pTmax = pT_II;
emission_type = type_II;
}
else if (pT_FF>pT_II && pT_FF>pT_IF) {
pTmax = pT_FF;
emission_type = type_FF;
}
else if (pT_IF>pT_FF && pT_IF>pT_II) {
pTmax = pT_IF;
emission_type = type_IF;
}
}
void MEqq2gZ2ffPowhegQED::hardQEDIIEmission(vector<ShowerProgenitorPtr> & particlesToShower,
int & emission_type, Energy & pTmax) {
emission_type = -1;
pTmax = -GeV;
if(QEDContributions_==2) return;
Energy rootS = sqrt(lastS());
// limits on the rapidity of the jet
double minyj = -10.0,maxyj = 10.0;
pair<double,double> x = make_pair(particlesToShower[0]->progenitor()->x(),
particlesToShower[1]->progenitor()->x());
// loop over the possible emissions
vector<Energy> pT;
double charge = sqr(double(particlesToShower[0]->progenitor()->dataPtr()->iCharge())/3.);
pTmax = -GeV;
for(unsigned int ix=0;ix<4;++ix) {
// skip incoming photons if not required
if(!incomingPhotons_&&(ix==2||ix==3)) continue;
pT.push_back(0.5*generator()->maximumCMEnergy());
// particles for the hard process
cPDVector particles;
for(unsigned int iy=0;iy<particlesToShower.size();++iy) {
particles.push_back(particlesToShower[iy]->progenitor()->dataPtr());
}
if(ix<2) particles.push_back(gamma_);
else if(ix==2) {
particles.push_back(particles[0]->CC());
particles[0] = gamma_;
}
else {
particles.push_back(particles[1]->CC());
particles[1] = gamma_;
}
vector<Lorentz5Momentum> momenta(5);
double a = alphaQED_->overestimateValue()/Constants::twopi*
prefactorQED_[ix]*(maxyj-minyj)*charge;
do {
pT[ix] *= pow(UseRandom::rnd(),1./a);
if(pT[ix]<=minpTQED_) break;
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.||z<x.first) continue;
}
else {
vt = pT[ix]*exp( y)/rootS/x.first ;
z = (1.-pT[ix]*exp( y)/rootS/x.first )/(1.+pT[ix]*exp(-y)/rootS/x.second );
if(z>1.||z<x.second) continue;
}
if(vt>1.-z || vt<0.) continue;
if(ix%2==0) {
momenta[0] = particlesToShower[0]->progenitor()->momentum()/z;
momenta[1] = particlesToShower[1]->progenitor()->momentum();
}
else {
momenta[0] = particlesToShower[0]->progenitor()->momentum();
momenta[1] = particlesToShower[1]->progenitor()->momentum()/z;
}
double phi = Constants::twopi*UseRandom::rnd();
momenta[2] = particlesToShower[2]->progenitor()->momentum();
momenta[3] = particlesToShower[3]->progenitor()->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 = alphaQED_->ratio(sqr(pT[ix]))*z/(1.-vt)/prefactorQED_[ix]/loME_/charge;
// compute me piece here
if(ix==0)
wgt *= 2.*sqr(pT[ix])/sHat()*subtractedQEDMEqqbar(momenta,II12,false).first;
else if(ix==1)
wgt *= 2.*sqr(pT[ix])/sHat()*subtractedQEDMEqqbar(momenta,II21,false).first;
else if(ix==2)
wgt *= 2.*sqr(pT[ix])/sHat()*subtractedQEDMEpqbar(momenta,II12,false).first;
else if(ix==3)
wgt *= 2.*sqr(pT[ix])/sHat()*subtractedQEDMEpqbar(momenta,II21,false).first;
// 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];
// check weight less than one
if(wgt>1.) {
generator()->log() << "Weight greater than one for emission type " << ix
<< "in MEqq2gZ2ffPowhegQED::hardQEDIIEmission()"
<< " weight = " << wgt << "\n";
}
// break if select emission
if(UseRandom::rnd()<wgt) break;
}
while(pT[ix]>minpTQED_);
if(pT[ix]>minpTQED_ && pT[ix]>pTmax) {
pTmax = pT[ix];
if(ix==0) {
realEmissionQEDPhoton1_ = momenta;
emission_type=5;
}
else if(ix==1) {
realEmissionQEDPhoton2_ = momenta;
emission_type=7;
}
else if(ix==2) {
realEmissionQEDQuark1_ = momenta;
emission_type=6;
}
else if(ix==3) {
realEmissionQEDQuark2_ = momenta;
emission_type=8;
}
}
}
}
void MEqq2gZ2ffPowhegQED::hardQEDIFEmission(vector<ShowerProgenitorPtr> & particlesToShower,
int & emission_type, Energy & pTmax) {
emission_type = -1;
pTmax = -GeV;
if(QEDContributions_!=0) return;
}
void MEqq2gZ2ffPowhegQED::
hardQEDFFEmission(vector<ShowerProgenitorPtr> & particlesToShower,
int & emission_type, Energy & pTmax) {
if(QEDContributions_==1) return;
emission_type = -1;
pTmax = -GeV;
// extract the particles
cPDVector particles;
for(unsigned int iy=0;iy<particlesToShower.size();++iy) {
particles.push_back(particlesToShower[iy]->progenitor()->dataPtr());
}
particles.push_back(gamma_);
// boost from lab to CMS frame with outgoing particles
// along the z axis
Lorentz5Momentum pcms = particlesToShower[2]->progenitor()->momentum() +
particlesToShower[3]->progenitor()->momentum();
LorentzRotation eventFrame( pcms.findBoostToCM() );
Lorentz5Momentum spectator = eventFrame*particlesToShower[2]->progenitor()->momentum();
eventFrame.rotateZ( -spectator.phi() );
eventFrame.rotateY( -spectator.theta() );
eventFrame.invert();
// mass of the final-state system
Energy2 M2 = pcms.m2();
Energy M = sqrt(M2);
double mu1 = particlesToShower[2]->progenitor()->momentum().mass()/M;
double mu2 = particlesToShower[2]->progenitor()->momentum().mass()/M;
double mu12 = sqr(mu1), mu22 = sqr(mu2);
double lambda = sqrt(1.+sqr(mu12)+sqr(mu22)-2.*mu12-2.*mu22-2.*mu12*mu22);
// max pT
pTmax = 0.5*sqrt(M2)*(1.-sqr(mu1+mu2));
// max y
double ymax = acosh(pTmax/minpTQED_);
if(!particlesToShower[2]->progenitor()->dataPtr()->charged())
return;
double charge = sqr(double(particlesToShower[2]->
progenitor()->dataPtr()->iCharge())/3.);
double a = alphaQED_->overestimateValue()/Constants::twopi*2.*ymax*preFFQED_*charge;
// variables for the emission
Energy pT[2];
double y[2],phi[2],x3[2],x1[2][2],x2[2][2];
double contrib[2][2];
// storage of the real emission momenta
vector<Lorentz5Momentum> realMomenta[2][2]=
{{vector<Lorentz5Momentum>(5),vector<Lorentz5Momentum>(5)},
{vector<Lorentz5Momentum>(5),vector<Lorentz5Momentum>(5)}};
for(unsigned int ix=0;ix<2;++ix)
for(unsigned int iy=0;iy<2;++iy)
for(unsigned int iz=0;iz<2;++iz)
realMomenta[ix][iy][iz] = particlesToShower[iz]->progenitor()->momentum();
// generate the emission
for(unsigned int ix=0;ix<2;++ix) {
if(ix==1) {
swap(mu1 ,mu2 );
swap(mu12,mu22);
}
pT[ix] = pTmax;
y [ix] = 0.;
bool reject = true;
do {
// generate pT
pT[ix] *= pow(UseRandom::rnd(),1./a);
if(pT[ix]<minpTQED_) {
pT[ix] = -GeV;
break;
}
// generate y
y[ix] = -ymax+2.*UseRandom::rnd()*ymax;
// generate phi
phi[ix] = UseRandom::rnd()*Constants::twopi;
// calculate x3 and check in allowed region
x3[ix] = 2.*pT[ix]*cosh(y[ix])/M;
if(x3[ix] < 0. || x3[ix] > 1. -sqr( mu1 + mu2 ) ) continue;
// find the possible solutions for x1
double xT2 = sqr(2./M*pT[ix]);
double root = (-sqr(x3[ix])+xT2)*
(xT2*mu22+2.*x3[ix]-sqr(mu12)+2.*mu22+2.*mu12-sqr(x3[ix])-1.
+2.*mu12*mu22-sqr(mu22)-2.*mu22*x3[ix]-2.*mu12*x3[ix]);
double c1=2.*sqr(x3[ix])-4.*mu22-6.*x3[ix]+4.*mu12-xT2*x3[ix]
+2.*xT2-2.*mu12*x3[ix]+2.*mu22*x3[ix]+4.;
if(root<0.) continue;
x1[ix][0] = 1./(4.-4.*x3[ix]+xT2)*(c1-2.*sqrt(root));
x1[ix][1] = 1./(4.-4.*x3[ix]+xT2)*(c1+2.*sqrt(root));
// change sign of y if 2nd particle emits
if(ix==1) y[ix] *=-1.;
// loop over the solutions
for(unsigned int iy=0;iy<2;++iy) {
contrib[ix][iy]=0.;
// check x1 value allowed
if(x1[ix][iy]<2.*mu1||x1[ix][iy]>1.+mu12-mu22) continue;
// calculate x2 value and check allowed
x2[ix][iy] = 2.-x3[ix]-x1[ix][iy];
double root = max(0.,sqr(x1[ix][iy])-4.*mu12);
root = sqrt(root);
double x2min = 1.+mu22-mu12
-0.5*(1.-x1[ix][iy]+mu12-mu22)/(1.-x1[ix][iy]+mu12)*(x1[ix][iy]-2.*mu12+root);
double x2max = 1.+mu22-mu12
-0.5*(1.-x1[ix][iy]+mu12-mu22)/(1.-x1[ix][iy]+mu12)*(x1[ix][iy]-2.*mu12-root);
if(x2[ix][iy]<x2min||x2[ix][iy]>x2max) continue;
// check the z components
double z1 = sqrt(sqr(x1[ix][iy])-4.*mu12-xT2);
double z2 = -sqrt(sqr(x2[ix][iy])-4.*mu22);
double z3 = pT[ix]*sinh(y[ix])*2./M;
if(ix==1) z3 *=-1.;
if(abs(-z1+z2+z3)<1e-9) z1 *= -1.;
if(abs(z1+z2+z3)>1e-5) continue;
// construct the momenta
realMomenta[ix][iy][4] =
Lorentz5Momentum(pT[ix]*cos(phi[ix]),pT[ix]*sin(phi[ix]),
pT[ix]*sinh(y[ix]) ,pT[ix]*cosh(y[ix]),ZERO);
if(ix==0) {
realMomenta[ix][iy][2] =
Lorentz5Momentum(-pT[ix]*cos(phi[ix]),-pT[ix]*sin(phi[ix]),
z1*0.5*M,x1[ix][iy]*0.5*M,M*mu1);
realMomenta[ix][iy][3] =
Lorentz5Momentum(ZERO,ZERO, z2*0.5*M,x2[ix][iy]*0.5*M,M*mu2);
}
else {
realMomenta[ix][iy][2] =
Lorentz5Momentum(ZERO,ZERO,-z2*0.5*M,x2[ix][iy]*0.5*M,M*mu2);
realMomenta[ix][iy][3] =
Lorentz5Momentum(-pT[ix]*cos(phi[ix]),-pT[ix]*sin(phi[ix]),
-z1*0.5*M,x1[ix][iy]*0.5*M,M*mu1);
}
// boost the momenta back to the lab
for(unsigned int iz=2;iz<5;++iz)
realMomenta[ix][iy][iz] *= eventFrame;
// jacobian and prefactors for the weight
Energy J = M/sqrt(xT2)*abs(-x1[ix][iy]*x2[ix][iy]+2.*mu22*x1[ix][iy]
+x2[ix][iy]+x2[ix][iy]*mu12+mu22*x2[ix][iy]
-sqr(x2[ix][iy]))
/pow(sqr(x2[ix][iy])-4.*mu22,1.5);
// prefactors etc
contrib[ix][iy] = 0.5*pT[ix]/J/preFFQED_/lambda;
// matrix element piece
double me;
if(ix==0) me = subtractedQEDMEqqbar(realMomenta[ix][iy],
FF34,false).first/charge/loME_;
else me = subtractedQEDMEqqbar(realMomenta[ix][iy],
FF43,false).first/charge/loME_;
contrib[ix][iy] *= 2.*me;
// coupling piece
contrib[ix][iy] *= alphaQED_->ratio(sqr(pT[ix]));
}
if(contrib[ix][0]+contrib[ix][1]>1.) {
ostringstream s;
s << "MEee2gZ2qq::generateHardest weight for channel " << ix
<< "is " << contrib[ix][0]+contrib[ix][1]
<< " which is greater than 1";
generator()->logWarning( Exception(s.str(), Exception::warning) );
}
reject = UseRandom::rnd() > contrib[ix][0] + contrib[ix][1];
}
while (reject);
if(pT[ix]<minpTQED_)
pT[ix] = -GeV;
}
emission_type = -1;
pTmax = -GeV;
if(pT[0]<ZERO&&pT[1]<ZERO) return;
// now pick the emmision with highest pT
if(pT[0]>pT[1]) {
emission_type=9;
pTmax = pT[0];
if(UseRandom::rnd()<contrib[0][0]/(contrib[0][0]+contrib[0][1]))
realEmissionQEDFFLepton3_ = realMomenta[0][0];
else
realEmissionQEDFFLepton3_ = realMomenta[0][1];
}
else {
emission_type=10;
pTmax = pT[1];
if(UseRandom::rnd()<contrib[1][0]/(contrib[1][0]+contrib[1][1]))
realEmissionQEDFFLepton4_ = realMomenta[1][0];
else
realEmissionQEDFFLepton4_ = realMomenta[1][1];
}
}
HardTreePtr MEqq2gZ2ffPowhegQED::generateHardest(ShowerTreePtr tree,
vector<ShowerInteraction::Type> inter) {
// get the particles to be showered
_beams.clear();
_partons.clear();
// find the incoming particles
ShowerParticleVector incoming;
map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator cit;
_quarkplus = true;
vector<ShowerProgenitorPtr> particlesToShower;
//progenitor particles are produced in z direction.
for( cit = tree->incomingLines().begin(); cit != tree->incomingLines().end(); ++cit ) {
incoming.push_back( cit->first->progenitor() );
_beams.push_back( cit->first->beam() );
_partons.push_back( cit->first->progenitor()->dataPtr() );
// check that quark is along +ve z direction
if(cit->first->progenitor()->id() > 0 &&
cit->first->progenitor()->momentum().z() < ZERO )
_quarkplus = false;
particlesToShower.push_back( cit->first );
}
// we are assuming quark first, swap order to ensure this
// if antiquark first
if(_partons[0]->id()<_partons[1]->id()) {
swap(_partons[0],_partons[1]);
swap(_beams[0],_beams[1]);
swap(incoming[0],incoming[1]);
swap(particlesToShower[0],particlesToShower[1]);
}
// outgoing particles
for( map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator
cjt= tree->outgoingLines().begin();
cjt != tree->outgoingLines().end();++cjt ) {
particlesToShower.push_back( cjt->first );
}
if(particlesToShower[2]->id()<0)
swap(particlesToShower[2],particlesToShower[3]);
// genuine hard emission in matrix element
double wgtb = std::accumulate(++weights_.begin(),weights_.end(),0.);
int emission_type(-1);
bool hardEmission=false;
if(wgtb>UseRandom::rnd()*(weights_[0]+wgtb)) {
wgtb *= UseRandom::rnd();
unsigned int itype=1;
for(;itype<weights_.size();++itype) {
if(weights_[itype]>=wgtb) break;
wgtb-=weights_[itype];
}
emission_type = itype;
hardEmission = true;
}
// generate a hard emission from the sudakov
else {
int qcd_type(-1),qed_type(-1);
Energy qcd_pT(-GeV),qed_pT(-GeV);
for(unsigned int ix=0;ix<inter.size();++ix) {
if(inter[ix]==ShowerInteraction::QCD)
hardQCDEmission(particlesToShower,qcd_type,qcd_pT);
else if(inter[ix]==ShowerInteraction::QED)
hardQEDEmission(particlesToShower,qed_type,qed_pT);
}
if(qcd_type<0&&qed_type<0) {
return HardTreePtr();
}
else if(qcd_type>0&&qed_type>0) {
if(qcd_pT>=qed_pT) {
emission_type = qcd_type;
}
else {
emission_type = qed_type;
}
}
else if(qcd_type>0) {
emission_type = qcd_type;
}
else {
emission_type = qed_type;
}
}
// construct the HardTree object needed to perform the showers
ShowerParticleVector newparticles;
// make the particles for the HardTree
// create the partons
// q qbar -> g X
vector<Lorentz5Momentum> pnew;
if(emission_type==1||emission_type==3) {
newparticles.push_back(new_ptr(ShowerParticle(_partons[0] ,false)));
newparticles.push_back(new_ptr(ShowerParticle(_partons[1] ,false)));
newparticles.push_back(new_ptr(ShowerParticle(gluon_ , true)));
if(emission_type ==1) pnew = realEmissionQCDGluon1_;
else pnew = realEmissionQCDGluon2_;
}
// q g -> q X
else if(emission_type==4) {
newparticles.push_back(new_ptr(ShowerParticle(_partons[0] ,false)));
newparticles.push_back(new_ptr(ShowerParticle(gluon_ ,false)));
newparticles.push_back(new_ptr(ShowerParticle(_partons[1]->CC(), true)));
pnew = realEmissionQCDQuark2_;
}
// g qbar -> qbar X
else if(emission_type==2) {
newparticles.push_back(new_ptr(ShowerParticle(gluon_ ,false)));
newparticles.push_back(new_ptr(ShowerParticle(_partons[1] ,false)));
newparticles.push_back(new_ptr(ShowerParticle(_partons[0]->CC(), true)));
pnew = realEmissionQCDQuark1_;
}
else if(emission_type==5||emission_type==7) {
newparticles.push_back(new_ptr(ShowerParticle(_partons[0] ,false)));
newparticles.push_back(new_ptr(ShowerParticle(_partons[1] ,false)));
newparticles.push_back(new_ptr(ShowerParticle(gamma_ , true)));
if(emission_type ==5) pnew = realEmissionQEDPhoton1_;
else pnew = realEmissionQEDPhoton2_;
}
else if(emission_type==8) {
newparticles.push_back(new_ptr(ShowerParticle(_partons[0] ,false)));
newparticles.push_back(new_ptr(ShowerParticle(gamma_ ,false)));
newparticles.push_back(new_ptr(ShowerParticle(_partons[1]->CC(), true)));
pnew = realEmissionQEDQuark2_;
}
else if(emission_type==6) {
newparticles.push_back(new_ptr(ShowerParticle(gamma_ ,false)));
newparticles.push_back(new_ptr(ShowerParticle(_partons[1] ,false)));
newparticles.push_back(new_ptr(ShowerParticle(_partons[0]->CC(), true)));
pnew = realEmissionQEDQuark1_;
}
else if(emission_type==9 || emission_type==10) {
newparticles.push_back(new_ptr(ShowerParticle(_partons[0] ,false)));
newparticles.push_back(new_ptr(ShowerParticle(_partons[1] ,false)));
newparticles.push_back(new_ptr(ShowerParticle(gamma_ , true)));
if(emission_type ==9) pnew = realEmissionQEDFFLepton3_;
else pnew = realEmissionQEDFFLepton4_;
}
else {
assert(false);
}
// transform to get directions right if hard emission
LorentzRotation R;
if(!_quarkplus&&hardEmission) {
PPair partons = make_pair(particlesToShower[0]->progenitor(),
particlesToShower[1]->progenitor());
if(partons.first->id()<0) swap(partons.first,partons.second);
Boost bv = (partons.first->momentum()+
partons.second->momentum()).boostVector();
R = LorentzRotation(-bv);
R.rotateY(-partons.first->momentum().theta());
R.boost(bv);
for(unsigned int ix=0;ix<pnew.size();++ix)
pnew[ix].transform(R);
}
// work out which particle emits
int iemit(-1),ispect(-1);
if(emission_type==1 || emission_type==2 ||
emission_type==5 || emission_type==6) {
iemit = 0;
ispect = 1;
}
else if(emission_type==3 || emission_type==4 ||
emission_type==7 || emission_type==8) {
iemit = 1;
ispect = 0;
}
else if(emission_type==9) {
iemit = 3;
ispect = 4;
}
else if(emission_type==10) {
iemit = 4;
ispect = 3;
}
assert(iemit>=0&&ispect>=0);
// work out which interaction
ShowerInteraction::Type interaction =
emission_type<=4 ? ShowerInteraction::QCD : ShowerInteraction::QED;
// set the momenta
for(unsigned int ix=0;ix<2;++ix) newparticles[ix]->set5Momentum(pnew[ix]);
newparticles[2]->set5Momentum(pnew[4]);
// ISR
if(iemit<2) {
// create the off-shell particle
Lorentz5Momentum poff=pnew[iemit]-pnew[4];
poff.rescaleMass();
newparticles.push_back(new_ptr(ShowerParticle(_partons[iemit],false)));
newparticles.back()->set5Momentum(poff);
}
// FSR
else {
// create the off-shell particle
Lorentz5Momentum poff=pnew[iemit-1]+pnew[4];
poff.rescaleMass();
newparticles.push_back(new_ptr(ShowerParticle(mePartonData()[iemit-1],true)));
newparticles.back()->set5Momentum(poff);
}
// outgoing particles
for(unsigned int ix=2;ix<4;++ix) {
newparticles.push_back(new_ptr(ShowerParticle(particlesToShower[ix]
->progenitor()->dataPtr(),
true)));
}
newparticles[4]->set5Momentum(pnew[2]);
newparticles[5]->set5Momentum(pnew[3]);
vector<HardBranchingPtr> inBranch,hardBranch;
// create the branchings for the incoming particles
inBranch.push_back(new_ptr(HardBranching(newparticles[0],SudakovPtr(),
HardBranchingPtr(),HardBranching::Incoming)));
inBranch.push_back(new_ptr(HardBranching(newparticles[1],SudakovPtr(),
HardBranchingPtr(),HardBranching::Incoming)));
// ISR
if(iemit<2) {
// intermediate IS particle
hardBranch.push_back(new_ptr(HardBranching(newparticles[3],SudakovPtr(),
inBranch[iemit],HardBranching::Incoming)));
inBranch[iemit]->addChild(hardBranch.back());
// create the branching for the emitted jet
inBranch[iemit]->addChild(new_ptr(HardBranching(newparticles[2],SudakovPtr(),
inBranch[iemit],
HardBranching::Outgoing)));
// add other particle
hardBranch.push_back(inBranch[ispect]);
// outgoing particles
for(unsigned int ix=4;ix<newparticles.size();++ix) {
hardBranch.push_back(new_ptr(HardBranching(newparticles[ix],SudakovPtr(),
HardBranchingPtr(),
HardBranching::Outgoing)));
}
}
// FSR
else {
hardBranch.push_back(inBranch[0]);
hardBranch.push_back(inBranch[1]);
if(iemit==3) {
hardBranch.push_back(new_ptr(HardBranching(newparticles[3],SudakovPtr(),
HardBranchingPtr(),
HardBranching::Outgoing)));
hardBranch.back()->addChild(new_ptr(HardBranching(newparticles[4],SudakovPtr(),
hardBranch.back(),
HardBranching::Outgoing)));
hardBranch.back()->addChild(new_ptr(HardBranching(newparticles[2],SudakovPtr(),
hardBranch.back(),
HardBranching::Outgoing)));
hardBranch.push_back(new_ptr(HardBranching(newparticles[5],SudakovPtr(),
HardBranchingPtr(),
HardBranching::Outgoing)));
}
else {
hardBranch.push_back(new_ptr(HardBranching(newparticles[4],SudakovPtr(),
HardBranchingPtr(),
HardBranching::Outgoing)));
hardBranch.push_back(new_ptr(HardBranching(newparticles[3],SudakovPtr(),
HardBranchingPtr(),
HardBranching::Outgoing)));
hardBranch.back()->addChild(new_ptr(HardBranching(newparticles[5],SudakovPtr(),
hardBranch.back(),
HardBranching::Outgoing)));
hardBranch.back()->addChild(new_ptr(HardBranching(newparticles[2],SudakovPtr(),
hardBranch.back(),
HardBranching::Outgoing)));
}
}
// set the evolution partners
if(emission_type<=4) {
hardBranch[0]->colourPartner(hardBranch[1]);
hardBranch[1]->colourPartner(hardBranch[0]);
}
else if(emission_type<=10) {
hardBranch[2]->colourPartner(hardBranch[3]);
hardBranch[3]->colourPartner(hardBranch[2]);
hardBranch[2]->colourPartner(hardBranch[3]);
hardBranch[3]->colourPartner(hardBranch[2]);
}
// make the tree
HardTreePtr hardtree=new_ptr(HardTree(hardBranch,inBranch,interaction));
// connect the ShowerParticles with the branchings
// and set the maximum pt for the radiation
Energy pt = pnew[4].perp();
set<HardBranchingPtr> hard=hardtree->branchings();
for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
particlesToShower[ix]->maximumpT(max(pt,minpTQCD_),ShowerInteraction::QCD);
particlesToShower[ix]->maximumpT(max(pt,minpTQED_),ShowerInteraction::QED);
for(set<HardBranchingPtr>::const_iterator mit=hard.begin();
mit!=hard.end();++mit) {
if(particlesToShower[ix]->progenitor()->id()==(*mit)->branchingParticle()->id()&&
(( particlesToShower[ix]->progenitor()->isFinalState()&&
(**mit).status()==HardBranching::Outgoing)||
(!particlesToShower[ix]->progenitor()->isFinalState()&&
(**mit).status()==HardBranching::Incoming))) {
hardtree->connect(particlesToShower[ix]->progenitor(),*mit);
if((**mit).status()==HardBranching::Incoming) {
(*mit)->beam(particlesToShower[ix]->original()->parents()[0]);
HardBranchingPtr parent=(*mit)->parent();
while(parent) {
parent->beam(particlesToShower[ix]->original()->parents()[0]);
parent=parent->parent();
};
}
}
}
}
ColinePtr newline=new_ptr(ColourLine());
for(set<HardBranchingPtr>::const_iterator cit=hardtree->branchings().begin();
cit!=hardtree->branchings().end();++cit) {
if((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour3)
newline->addColoured((**cit).branchingParticle());
else if((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour3bar)
newline->addAntiColoured((**cit).branchingParticle());
}
// return the tree
// generator()->log() << "Had hard radiation " << iemit << "\n";
// generator()->log() << *hardtree << "\n";
// cerr << "Had hard radiation " << iemit << "\n";
// cerr << *hardtree << "\n";
return hardtree;
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, May 14, 10:02 AM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5067054
Default Alt Text
(252 KB)

Event Timeline