Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F8308817
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
137 KB
Subscribers
None
View Options
diff --git a/include/RHEJ/MatrixElement.hh b/include/RHEJ/MatrixElement.hh
index bd8b92b..4099267 100644
--- a/include/RHEJ/MatrixElement.hh
+++ b/include/RHEJ/MatrixElement.hh
@@ -1,254 +1,260 @@
/** \file
* \brief Contains the MatrixElement Class
*/
#pragma once
#include <functional>
#include "RHEJ/config.hh"
#include "RHEJ/utility.hh"
#include "RHEJ/HiggsCouplingSettings.hh"
#include "CLHEP/Vector/LorentzVector.h"
namespace RHEJ{
//! Class to calculate the squares of matrix elements
class MatrixElement{
public:
/** \brief MatrixElement Constructor
* @param alpha_s Function taking the renormalisation scale
* and returning the strong coupling constant
* @param conf General matrix element settings
*/
MatrixElement(
std::function<double (double)> alpha_s,
MatrixElementConfig conf
);
/**
* \brief regulated HEJ matrix element
* @param mur Value of the renormalisation scale
* @param incoming Incoming particles
* @param outgoing Outgoing particles
* @param check_momenta Special treatment for partons inside extremal jets
* @returns The HEJ matrix element including virtual corrections
*
* cf. eq. (22) in \cite Andersen:2011hs
* Incoming particles should be ordered by ascending z momentum.
* Outgoing particles should be ordered by ascending rapidity.
*
* \internal Relation to standard HEJ Met2: MatrixElement = Met2*shat^2/(pdfta*pdftb)
*/
double operator()(
double mur,
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
std::unordered_map<int, std::vector<Particle>> const & decays,
bool check_momenta
) const;
//! HEJ tree-level matrix element
/**
* @param mur Value of the renormalisation scale
* @param incoming Incoming particles
* @param outgoing Outgoing particles
* @param check_momenta Special treatment for partons inside extremal jets
* @returns The HEJ matrix element without virtual corrections
*
* cf. eq. (22) in \cite Andersen:2011hs
* Incoming particles should be ordered by ascending z momentum.
* Outgoing particles should be ordered by ascending rapidity.
*/
double tree(
double mur,
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
std::unordered_map<int, std::vector<Particle>> const & decays,
bool check_momenta
) const;
//! HEJ tree-level matrix element - parametric part
/**
* @param mur Value of the renormalisation scale
* @param incoming Incoming particles
* @param outgoing Outgoing particles
* @returns The parametric part of the tree matrix element
*
* cf. eq. (22) in \cite Andersen:2011hs
*
* The tree level matrix element factorises into a parametric part
* which depends on the theory parameters (alpha_s and scale)
* and a kinematic part comprising the dependence on the particle momenta
* and colour factors. This function returns the former.
*/
double tree_param(
double mur,
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing
) const;
//! HEJ tree-level matrix element - kinematic part
/**
* @param incoming Incoming particles
* @param outgoing Outgoing particles
* @param check_momenta Special treatment for partons inside extremal jets
* @returns The kinematic part of the tree matrix element
*
* cf. eq. (22) in \cite Andersen:2011hs
* Incoming particles should be ordered by ascending z momentum.
* Outgoing particles should be ordered by ascending rapidity.
*
* The tree level matrix element factorises into a parametric part
* which depends on the theory parameters (alpha_s and scale)
* and a kinematic part comprising the dependence on the particle momenta
* and colour factors. This function returns the latter.
*/
double tree_kin(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
std::unordered_map<int, std::vector<Particle>> const & decays,
bool check_momenta
) const;
/**
* \brief Calculates the Virtual Corrections
* @param mur Value of the renormalisation scale
* @param in Incoming particles
* @param out Outgoing particles
* @returns The Virtual Corrections of the Matrix Element
*
* Incoming particles should be ordered by ascending z momentum.
* Outgoing particles should be ordered by ascending rapidity.
*
* The all order virtual corrections to LL in the MRK limit is
* given by replacing 1/t in the scattering amplitude according to the
* lipatov ansatz.
*
* cf. second-to-last line of eq. (22) in \cite Andersen:2011hs
* note that indices are off by one, i.e. out[0].p corresponds to p_1
*/
double virtual_corrections(
double mur,
std::array<Particle, 2> const & in,
std::vector<Particle> const & out
) const;
private:
//! \internal cf. last line of eq. (22) in \cite Andersen:2011hs
double omega0(
double alpha_s, double mur,
fastjet::PseudoJet const & q_j, double lambda
) const;
double tree_kin_jets(
std::array<Particle, 2> const & incoming,
std::vector<Particle> partons,
bool check_momenta
) const;
double tree_kin_W(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
std::unordered_map<int, std::vector<Particle>> const & decays,
bool WPlus,
bool check_momenta
) const;
double tree_kin_W_FKL(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
std::unordered_map<int, std::vector<Particle>> const & decays,
bool WPlus,
bool check_momenta
) const;
double tree_kin_W_unob(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
std::unordered_map<int, std::vector<Particle>> const & decays,
bool WPlus,
bool check_momenta
) const;
double tree_kin_W_unof(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
std::unordered_map<int, std::vector<Particle>> const & decays,
bool WPlus,
bool check_momenta
) const;
double tree_kin_W_qqxb(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
std::unordered_map<int, std::vector<Particle>> const & decays,
bool WPlus,
bool check_momenta
) const;
double tree_kin_W_qqxf(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
std::unordered_map<int, std::vector<Particle>> const & decays,
bool WPlus,
bool check_momenta
) const;
-
+ double tree_kin_W_qqxmid(
+ std::array<Particle, 2> const & incoming,
+ std::vector<Particle> const & outgoing,
+ std::unordered_map<int, std::vector<Particle>> const & decays,
+ bool WPlus,
+ bool check_momenta
+ ) const;
double tree_kin_Higgs(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
bool check_momenta
) const;
double tree_kin_Higgs_first(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
bool check_momenta
) const;
double tree_kin_Higgs_last(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
bool check_momenta
) const;
/**
* \internal
* \brief Higgs inbetween extremal partons.
*
* Note that in the case of unordered emission, the Higgs is *always*
* treated as if in between the extremal (FKL) partons, even if its
* rapidity is outside the extremal parton rapidities
*/
double tree_kin_Higgs_between(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
bool check_momenta
) const;
double tree_param_partons(
double alpha_s, double mur,
std::vector<Particle> const & partons
) const;
std::vector<int> in_extremal_jet_indices(
std::vector<fastjet::PseudoJet> const & partons
) const;
std::vector<Particle> tag_extremal_jet_partons(
std::array<Particle, 2> const & incoming,
std::vector<Particle> out_partons, bool check_momenta
) const;
double MH2_forwardH(
CLHEP::HepLorentzVector p1out, CLHEP::HepLorentzVector p1in,
pid::ParticleID type2,
CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in,
CLHEP::HepLorentzVector pH,
double t1, double t2
) const;
std::function<double (double)> alpha_s_;
MatrixElementConfig param_;
};
}
diff --git a/src/MatrixElement.cc b/src/MatrixElement.cc
index 593de0a..e89dc9b 100644
--- a/src/MatrixElement.cc
+++ b/src/MatrixElement.cc
@@ -1,1542 +1,1748 @@
#include "RHEJ/MatrixElement.hh"
#include <CLHEP/Random/Randomize.h>
#include <CLHEP/Random/RanluxEngine.h>
#include "RHEJ/Constants.hh"
#include "RHEJ/currents.hh"
#include "RHEJ/PDG_codes.hh"
#include "RHEJ/uno.hh"
#include "RHEJ/qqx.hh"
#include "RHEJ/utility.hh"
namespace RHEJ{
//cf. last line of eq. (22) in \ref Andersen:2011hs
double MatrixElement::omega0(
double alpha_s, double mur,
fastjet::PseudoJet const & q_j, double lambda
) const {
const double result = - alpha_s*N_C/M_PI*log(q_j.perp2()/(lambda*lambda));
if(! param_.log_correction) return result;
// use alpha_s(sqrt(q_j*lambda)), evolved to mur
return (
1. + alpha_s/(4.*M_PI)*beta0*log(mur*mur/(q_j.perp()*lambda))
)*result;
}
double MatrixElement::virtual_corrections(
double mur,
std::array<Particle, 2> const & in,
std::vector<Particle> const & out
) const{
fastjet::PseudoJet const & pa = in.front().p;
#ifndef NDEBUG
fastjet::PseudoJet const & pb = in.back().p;
double const norm = (in.front().p + in.back().p).E();
#endif
assert(std::is_sorted(out.begin(), out.end(), rapidity_less{}));
assert(out.size() >= 2);
assert(pa.pz() < pb.pz());
fastjet::PseudoJet q = pa - out[0].p;
size_t first_idx = 0;
size_t last_idx = out.size() - 1;
// if there is a Higgs or unordered gluon outside the extremal partons
// then it is not part of the FKL ladder and does not contribute
// to the virtual corrections
if(out.front().type == pid::Higgs || has_unob_gluon(in, out)){
q -= out[1].p;
++first_idx;
}
if(out.back().type == pid::Higgs || has_unof_gluon(in, out)){
--last_idx;
}
double exponent = 0;
const double alpha_s = alpha_s_(mur);
for(size_t j = first_idx; j < last_idx; ++j){
exponent += omega0(alpha_s, mur, q, CLAMBDA)*(
out[j+1].rapidity() - out[j].rapidity()
);
q -= out[j+1].p;
}
assert(
nearby(q, -1*pb, norm)
|| out.back().type == pid::Higgs
|| has_unof_gluon(in, out)
);
return exp(exponent);
}
} // namespace RHEJ
namespace {
//! Lipatov vertex for partons emitted into extremal jets
double C2Lipatov(CLHEP::HepLorentzVector qav, CLHEP::HepLorentzVector qbv,
CLHEP::HepLorentzVector p1, CLHEP::HepLorentzVector p2)
{
CLHEP::HepLorentzVector temptrans=-(qav+qbv);
CLHEP::HepLorentzVector p5=qav-qbv;
CLHEP::HepLorentzVector CL=temptrans
+ p1*(qav.m2()/p5.dot(p1) + 2.*p5.dot(p2)/p1.dot(p2))
- p2*(qbv.m2()/p5.dot(p2) + 2.*p5.dot(p1)/p1.dot(p2));
// cout << "#Fadin qa : "<<qav<<endl;
// cout << "#Fadin qb : "<<qbv<<endl;
// cout << "#Fadin p1 : "<<p1<<endl;
// cout << "#Fadin p2 : "<<p2<<endl;
// cout << "#Fadin p5 : "<<p5<<endl;
// cout << "#Fadin Gauge Check : "<< CL.dot(p5)<<endl;
// cout << "#Fadin C2L : "<< -CL.dot(CL)<<" "<<-CL.dot(CL)/(qav.m2()*qbv.m2())/(4./p5.perp2())<<endl;
// TODO can this dead test go?
// if (-CL.dot(CL)<0.)
// if (fabs(CL.dot(p5))>fabs(CL.dot(CL))) // not sufficient!
// return 0.;
// else
return -CL.dot(CL);
}
//! Lipatov vertex with soft subtraction for partons emitted into extremal jets
double C2Lipatovots(CLHEP::HepLorentzVector qav, CLHEP::HepLorentzVector qbv,
CLHEP::HepLorentzVector p1, CLHEP::HepLorentzVector p2)
{
double kperp=(qav-qbv).perp();
if (kperp>RHEJ::CLAMBDA)
return C2Lipatov(qav, qbv, p1, p2)/(qav.m2()*qbv.m2());
else {
double Cls=(C2Lipatov(qav, qbv, p1, p2)/(qav.m2()*qbv.m2()));
return Cls-4./(kperp*kperp);
}
}
//! Lipatov vertex
double C2Lipatov(CLHEP::HepLorentzVector qav, CLHEP::HepLorentzVector qbv,
CLHEP::HepLorentzVector pim, CLHEP::HepLorentzVector pip,
CLHEP::HepLorentzVector pom, CLHEP::HepLorentzVector pop) // B
{
CLHEP::HepLorentzVector temptrans=-(qav+qbv);
CLHEP::HepLorentzVector p5=qav-qbv;
CLHEP::HepLorentzVector CL=temptrans
+ qav.m2()*(1./p5.dot(pip)*pip + 1./p5.dot(pop)*pop)/2.
- qbv.m2()*(1./p5.dot(pim)*pim + 1./p5.dot(pom)*pom)/2.
+ ( pip*(p5.dot(pim)/pip.dot(pim) + p5.dot(pom)/pip.dot(pom))
+ pop*(p5.dot(pim)/pop.dot(pim) + p5.dot(pom)/pop.dot(pom))
- pim*(p5.dot(pip)/pip.dot(pim) + p5.dot(pop)/pop.dot(pim))
- pom*(p5.dot(pip)/pip.dot(pom) + p5.dot(pop)/pop.dot(pom)) )/2.;
return -CL.dot(CL);
}
//! Lipatov vertex with soft subtraction
double C2Lipatovots(CLHEP::HepLorentzVector qav, CLHEP::HepLorentzVector qbv,
CLHEP::HepLorentzVector pa, CLHEP::HepLorentzVector pb,
CLHEP::HepLorentzVector p1, CLHEP::HepLorentzVector p2)
{
double kperp=(qav-qbv).perp();
if (kperp>RHEJ::CLAMBDA)
return C2Lipatov(qav, qbv, pa, pb, p1, p2)/(qav.m2()*qbv.m2());
else {
double Cls=(C2Lipatov(qav, qbv, pa, pb, p1, p2)/(qav.m2()*qbv.m2()));
double temp=Cls-4./(kperp*kperp);
return temp;
}
}
/** Matrix element squared for tree-level current-current scattering
* @param aptype Particle a PDG ID
* @param bptype Particle b PDG ID
* @param pn Particle n Momentum
* @param pb Particle b Momentum
* @param p1 Particle 1 Momentum
* @param pa Particle a Momentum
* @returns ME Squared for Tree-Level Current-Current Scattering
*/
double ME_current(
int aptype, int bptype,
CLHEP::HepLorentzVector const & pn,
CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & p1,
CLHEP::HepLorentzVector const & pa
){
if (aptype==21&&bptype==21) {
return jM2gg(pn,pb,p1,pa);
} else if (aptype==21&&bptype!=21) {
if (bptype > 0)
return jM2qg(pn,pb,p1,pa);
else
return jM2qbarg(pn,pb,p1,pa);
}
else if (bptype==21&&aptype!=21) { // ----- || -----
if (aptype > 0)
return jM2qg(p1,pa,pn,pb);
else
return jM2qbarg(p1,pa,pn,pb);
}
else { // they are both quark
if (bptype>0) {
if (aptype>0)
return jM2qQ(pn,pb,p1,pa);
else
return jM2qQbar(pn,pb,p1,pa);
}
else {
if (aptype>0)
return jM2qQbar(p1,pa,pn,pb);
else
return jM2qbarQbar(pn,pb,p1,pa);
}
}
throw std::logic_error("unknown particle types");
}
/** Matrix element squared for tree-level current-current scattering With W+Jets
* @param aptype Particle a PDG ID
* @param bptype Particle b PDG ID
* @param pn Particle n Momentum
* @param pb Particle b Momentum
* @param p1 Particle 1 Momentum
* @param pa Particle a Momentum
* @returns ME Squared for Tree-Level Current-Current Scattering
*/
double ME_W_current(
int aptype, int bptype,
CLHEP::HepLorentzVector const & pn,
CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & p1,
CLHEP::HepLorentzVector const & pa,
CLHEP::HepLorentzVector const & plbar,
CLHEP::HepLorentzVector const & pl,
bool const wc
){
// We know it cannot be gg incoming.
if (aptype==21&&bptype!=21) {
if (bptype > 0)
return jMWqg(pn,pl,plbar,pb,p1,pa);
else
return jMWqbarg(pn,pl,plbar,pb,p1,pa);
}
else if (bptype==21&&aptype!=21) { // ----- || -----
if (aptype > 0)
return jMWqg(p1,pl,plbar,pa,pn,pb);
else
return jMWqbarg(p1,pl,plbar,pa,pn,pb);
}
else { // they are both quark
if (wc==true){ // emission off b, (first argument pbout)
if (bptype>0) {
if (aptype>0)
return jMWqQ(pn,pl,plbar,pb,p1,pa);
else
return jMWqQbar(pn,pl,plbar,pb,p1,pa);
}
else {
if (aptype>0)
return jMWqbarQ(pn,pl,plbar,pb,p1,pa);
else
return jMWqbarQbar(pn,pl,plbar,pb,p1,pa);
}
}
else{ // emission off a, (first argument paout)
if (aptype > 0) {
if (bptype > 0)
return jMWqQ(p1,plbar,pl,pa,pn,pb);
else
return jMWqQbar(p1,plbar,pl,pa,pn,pb);
}
else { // a is anti-quark
if (bptype > 0)
return jMWqbarQ(p1,plbar,pl,pa,pn,pb);
else
return jMWqbarQbar(p1,plbar,pl,pa,pn,pb);
}
}
}
throw std::logic_error("unknown particle types");
}
/** Matrix element squared for backwards uno tree-level current-current scattering With W+Jets
* @param aptype Particle a PDG ID
* @param bptype Particle b PDG ID
* @param pn Particle n Momentum
* @param pb Particle b Momentum
* @param p1 Particle 1 Momentum
* @param pa Particle a Momentum
* @param pg Unordered gluon momentum
* @returns ME Squared for unob Tree-Level Current-Current Scattering
*/
double ME_W_unob_current(
int aptype, int bptype,
CLHEP::HepLorentzVector const & pn,
CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & p1,
CLHEP::HepLorentzVector const & pa,
CLHEP::HepLorentzVector const & pg,
CLHEP::HepLorentzVector const & plbar,
CLHEP::HepLorentzVector const & pl,
bool const wc
){
// we know they are not both gluons
if (bptype == 21 && aptype != 21) { // b gluon => W emission off a
if (aptype > 0)
return jM2Wunogqg(pg,p1,plbar,pl,pa,pn,pb);
else
return jM2Wunogqbarg(pg,p1,plbar,pl,pa,pn,pb);
}
else { // they are both quark
if (wc==true) {// emission off b, i.e. b is first current
if (bptype>0){
if (aptype>0)
return junobMWqQg(pn,plbar,pl,pb,p1,pa,pg);
else
return junobMWqQbarg(pn,plbar,pl,pb,p1,pa,pg);
}
else{
if (aptype>0)
return junobMWqbarQg(pn,plbar,pl,pb,p1,pa,pg);
else
return junobMWqbarQbarg(pn,plbar,pl,pb,p1,pa,pg);
}
}
else {// wc == false, emission off a, i.e. a is first current
if (aptype > 0) {
if (bptype > 0) //qq
return jM2WunogqQ(pg,p1,plbar,pl,pa,pn,pb);
else //qqbar
return jM2WunogqQbar(pg,p1,plbar,pl,pa,pn,pb);
}
else { // a is anti-quark
if (bptype > 0) //qbarq
return jM2WunogqbarQ(pg,p1,plbar,pl,pa,pn,pb);
else //qbarqbar
return jM2WunogqbarQbar(pg,p1,plbar,pl,pa,pn,pb);
}
}
}
}
/** Matrix element squared for uno forward tree-level current-current scattering With W+Jets
* @param aptype Particle a PDG ID
* @param bptype Particle b PDG ID
* @param pn Particle n Momentum
* @param pb Particle b Momentum
* @param p1 Particle 1 Momentum
* @param pa Particle a Momentum
* @param pg Unordered gluon momentum
* @returns ME Squared for unof Tree-Level Current-Current Scattering
*/
double ME_W_unof_current(
int aptype, int bptype,
CLHEP::HepLorentzVector const & pn,
CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & p1,
CLHEP::HepLorentzVector const & pa,
CLHEP::HepLorentzVector const & pg,
CLHEP::HepLorentzVector const & plbar,
CLHEP::HepLorentzVector const & pl,
bool const wc
){
// we know they are not both gluons
if (aptype==21 && bptype!=21) {//a gluon => W emission off b
if (bptype > 0)
return jM2Wunogqg(pg, pn,plbar, pl, pb, p1, pa);
else
return jM2Wunogqbarg(pg, pn,plbar, pl, pb, p1, pa);
}
else { // they are both quark
if (wc==true) {// emission off b, i.e. b is first current
if (bptype>0){
if (aptype>0)
return jM2WunogqQ(pg,pn,plbar,pl,pb,p1,pa);
else
return jM2WunogqQbar(pg,pn,plbar,pl,pb,p1,pa);
}
else{
if (aptype>0)
return jM2WunogqbarQ(pg,pn,plbar,pl,pb,p1,pa);
else
return jM2WunogqbarQbar(pg,pn,plbar,pl,pb,p1,pa);
}
}
else {// wc == false, emission off a, i.e. a is first current
if (aptype > 0) {
if (bptype > 0) //qq
return junofMWgqQ(pg,pn,pb,p1,plbar,pl,pa);
else //qqbar
return junofMWgqQbar(pg,pn,pb,p1,plbar,pl,pa);
}
else { // a is anti-quark
if (bptype > 0) //qbarq
return junofMWgqbarQ(pg,pn,pb,p1,plbar,pl,pa);
else //qbarqbar
return junofMWgqbarQbar(pg,pn,pb,p1,plbar,pl,pa);
}
}
}
}
/** \brief Matrix element squared for backward qqx tree-level current-current scattering With W+Jets
* @param aptype Particle a PDG ID
* @param bptype Particle b PDG ID
* @param pa Initial state a Momentum
* @param pb Initial state b Momentum
* @param pq Final state q Momentum
* @param pqbar Final state qbar Momentum
* @param pn Final state n Momentum
* @param plbar Final state anti-lepton momentum
* @param pl Final state lepton momentum
* @returns ME Squared for qqxb Tree-Level Current-Current Scattering
*/
double ME_W_qqxb_current(
int aptype, int bptype,
CLHEP::HepLorentzVector const & pa,
CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & pq,
CLHEP::HepLorentzVector const & pqbar,
CLHEP::HepLorentzVector const & pn,
CLHEP::HepLorentzVector const & plbar,
CLHEP::HepLorentzVector const & pl,
bool const wc
){
// CAM factors for the qqx amps, and qqbar ordering (default, qbar extremal)
bool swapQuarkAntiquark=false;
double CFbackward;
if (pqbar.rapidity() > pq.rapidity()){
swapQuarkAntiquark=true;
CFbackward = (0.5*(3.-1./3.)*(pa.minus()/(pq.minus())+(pq.minus())/pa.minus())+1./3.)*3./4.;
}
else{
CFbackward = (0.5*(3.-1./3.)*(pa.minus()/(pqbar.minus())+(pqbar.minus())/pa.minus())+1./3.)*3./4.;
}
// With qqbar we could have 2 incoming gluons and W Emission
if (aptype==21&&bptype==21) {//a gluon, b gluon gg->qqbarWg
// This will be a wqqx emission as there is no other possible W Emission Site.
if (swapQuarkAntiquark){
return jM2Wggtoqqbarg(pa, pqbar, plbar, pl, pq, pn,pb)*CFbackward;}
else {
return jM2Wggtoqbarqg(pa, pq, plbar, pl, pqbar, pn,pb)*CFbackward;}
}
else if (aptype!=21&&bptype==21 ) {//b gluon => W emission off a leg or qqx
if (wc!=1){ // W Emitted from backwards qqx
if (swapQuarkAntiquark){
return jM2WgQtoqqbarQ(pa, pq, plbar, pl, pqbar, pn, pb)*CFbackward;}
else{
return jM2WgQtoqbarqQ(pa, pq, plbar, pl, pqbar, pn, pb)*CFbackward;}
}
else { // W Must be emitted from forwards leg.
if (swapQuarkAntiquark){
return jM2WgqtoQQqW(pb, pa, pn, pqbar, pq, plbar, pl)*CFbackward;}
else{
return jM2WgqtoQQqW(pb, pa, pn, pq, pqbar, plbar, pl)*CFbackward;}
}
}
}
/* \brief Matrix element squared for forward qqx tree-level current-current scattering With W+Jets
* @param aptype Particle a PDG ID
* @param bptype Particle b PDG ID
* @param pa Initial state a Momentum
* @param pb Initial state b Momentum
* @param pq Final state q Momentum
* @param pqbar Final state qbar Momentum
* @param p1 Final state 1 Momentum
* @param plbar Final state anti-lepton momentum
* @param pl Final state lepton momentum
* @returns ME Squared for qqxf Tree-Level Current-Current Scattering
*/
double ME_W_qqxf_current(
int aptype, int bptype,
CLHEP::HepLorentzVector const & pa,
CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & pq,
CLHEP::HepLorentzVector const & pqbar,
CLHEP::HepLorentzVector const & p1,
CLHEP::HepLorentzVector const & plbar,
CLHEP::HepLorentzVector const & pl,
bool const wc
){
// CAM factors for the qqx amps, and qqbar ordering (default, qbar extremal)
bool swapQuarkAntiquark=false;
double CFforward;
if (pqbar.rapidity() < pq.rapidity()){
swapQuarkAntiquark=true;
CFforward = (0.5*(3.-1./3.)*(pb.plus()/(pq.plus())+(pq.plus())/pb.plus())+1./3.)*3./4.;
}
else{
CFforward = (0.5*(3.-1./3.)*(pb.plus()/(pqbar.plus())+(pqbar.plus())/pb.plus())+1./3.)*3./4.;
}
// With qqbar we could have 2 incoming gluons and W Emission
if (aptype==21&&bptype==21) {//a gluon, b gluon gg->qqbarWg
// This will be a wqqx emission as there is no other possible W Emission Site.
if (swapQuarkAntiquark){
return jM2Wggtoqqbarg(pb, pqbar, plbar, pl, pq, p1,pa)*CFforward;}
else {
return jM2Wggtoqbarqg(pb, pq, plbar, pl, pqbar, p1,pa)*CFforward;}
}
else if (bptype!=21&&aptype==21) {// a gluon => W emission off b or qqx
if (wc==1){ // W Emitted from forwards qqx
if (swapQuarkAntiquark){
return jM2WgQtoqbarqQ(pb, pq, plbar,pl, pqbar, p1, pa)*CFforward;}
else {
return jM2WgQtoqqbarQ(pb, pq, plbar,pl, pqbar, p1, pa)*CFforward;}
}
// W Must be emitted from backwards leg.
if (swapQuarkAntiquark){
return jM2WgqtoQQqW(pa,pb, p1, pqbar, pq, plbar, pl)*CFforward;}
else{
return jM2WgqtoQQqW(pa,pb, p1, pq, pqbar, plbar, pl)*CFforward;}
}
}
+ /* \brief Matrix element squared for central qqx tree-level current-current scattering With W+Jets
+ * @param aptype Particle a PDG ID
+ * @param bptype Particle b PDG ID
+ * @param nabove Number of gluons emitted before central qqxpair
+ * @param nbelow Number of gluons emitted after central qqxpair
+ * @param pa Initial state a Momentum
+ * @param pb Initial state b Momentum\
+ * @param pq Final state qbar Momentum
+ * @param pqbar Final state q Momentum
+ * @param partons Vector of all outgoing partons
+ * @param plbar Final state anti-lepton momentum
+ * @param pl Final state lepton momentum
+ * @param wqq Boolean. True siginfies W boson is emitted from Central qqx
+ * @param wc Boolean. wc=true signifies w boson emitted from leg b; if wqq=false.
+ * @returns ME Squared for qqxmid Tree-Level Current-Current Scattering
+ */
+ double ME_W_qqxmid_current(
+ int aptype, int bptype,
+ int nabove, int nbelow,
+ CLHEP::HepLorentzVector const & pa,
+ CLHEP::HepLorentzVector const & pb,
+ CLHEP::HepLorentzVector const & pq,
+ CLHEP::HepLorentzVector const & pqbar,
+ std::vector<HLV> partons,
+ CLHEP::HepLorentzVector const & plbar,
+ CLHEP::HepLorentzVector const & pl,
+ bool const wqq, bool const wc
+ ){
+ // CAM factors for the qqx amps, and qqbar ordering (default, pq backwards)
+ bool swapQuarkAntiquark=false;
+ if (pqbar.rapidity() < pq.rapidity()){
+ swapQuarkAntiquark=true;
+ }
+ double CFforward = (0.5*(3.-1./3.)*(pb.plus()/(partons[partons.size()-1].plus())+(partons[partons.size()-1].plus())/pb.plus())+1./3.)*3./4.;
+ double CFbackward = (0.5*(3.-1./3.)*(pa.minus()/(partons[0].minus())+(partons[0].minus())/pa.minus())+1./3.)*3./4.;
+ double wt=1.;
+
+ if (aptype==21) wt*=CFbackward;
+ if (bptype==21) wt*=CFforward;
+
+ if (aptype <=0 && bptype <=0){ // Both External AntiQuark
+ if (wqq==1){//emission from central qqbar
+ return wt*jM2WqqtoqQQq(pa, pb, pl,plbar, partons,true,true, swapQuarkAntiquark, nabove, nbelow);
+ }
+ else if (wc==1){//emission from b leg
+ return wt*jM2WqqtoqQQqW(pa, pb, pl,plbar, partons, true,true, swapQuarkAntiquark, nabove, nbelow, true);
+ }
+ else { // emission from a leg
+ return wt*jM2WqqtoqQQqW(pa, pb, pl,plbar, partons, true,true, swapQuarkAntiquark, nabove, nbelow, false);
+ }
+ } // end both antiquark
+ else if (aptype<=0){ // a is antiquark
+ if (wqq==1){//emission from central qqbar
+ return wt*jM2WqqtoqQQq(pa, pb, pl,plbar, partons, false, true, swapQuarkAntiquark, nabove, nbelow);
+ }
+ else if (wc==1){//emission from b leg
+ return wt*jM2WqqtoqQQqW(pa, pb, pl,plbar, partons,false,true, swapQuarkAntiquark, nabove, nbelow, true);
+ }
+ else { // emission from a leg
+ return wt*jM2WqqtoqQQqW(pa, pb, pl,plbar, partons, false, true, swapQuarkAntiquark, nabove, nbelow, false);
+ }
+
+ } // end a is antiquark
+
+ else if (bptype<=0){ // b is antiquark
+ if (wqq==1){//emission from central qqbar
+ return wt*jM2WqqtoqQQq(pa, pb, pl,plbar, partons, true, false, swapQuarkAntiquark, nabove, nbelow);
+ }
+ else if (wc==1){//emission from b leg
+ return wt*jM2WqqtoqQQqW(pa, pb, pl,plbar, partons, true, false, swapQuarkAntiquark, nabove, nbelow, true);
+ }
+ else { // emission from a leg
+ return wt*jM2WqqtoqQQqW(pa, pb, pl,plbar, partons, true, false, swapQuarkAntiquark, nabove, nbelow, false);
+ }
+
+ } //end b is antiquark
+ else{ //Both Quark or gluon
+ if (wqq==1){//emission from central qqbar
+ return wt*jM2WqqtoqQQq(pa, pb, pl, plbar, partons, false, false, swapQuarkAntiquark, nabove, nbelow);}
+ else if (wc==1){//emission from b leg
+ return wt*jM2WqqtoqQQqW(pa, pb, pl,plbar, partons, false, false, swapQuarkAntiquark, nabove, nbelow, true);
+ }
+ else { // emission from a leg
+ return wt*jM2WqqtoqQQqW(pa, pb, pl,plbar, partons, false, false, swapQuarkAntiquark, nabove, nbelow, false);
+ }
+
+ }
+ }
+
+
+
/** \brief Matrix element squared for tree-level current-current scattering with Higgs
* @param aptype Particle a PDG ID
* @param bptype Particle b PDG ID
* @param pn Particle n Momentum
* @param pb Particle b Momentum
* @param p1 Particle 1 Momentum
* @param pa Particle a Momentum
* @param qH t-channel momentum before Higgs
* @param qHp1 t-channel momentum after Higgs
* @returns ME Squared for Tree-Level Current-Current Scattering with Higgs
*/
double ME_Higgs_current(
int aptype, int bptype,
CLHEP::HepLorentzVector const & pn,
CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & p1,
CLHEP::HepLorentzVector const & pa,
CLHEP::HepLorentzVector const & qH, // t-channel momentum before Higgs
CLHEP::HepLorentzVector const & qHp1, // t-channel momentum after Higgs
double mt, bool include_bottom, double mb
){
if (aptype==21&&bptype==21) // gg initial state
return MH2gg(pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
else if (aptype==21&&bptype!=21) {
if (bptype > 0)
return MH2qg(pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb)*4./9.;
else
return MH2qbarg(pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb)*4./9.;
}
else if (bptype==21&&aptype!=21) {
if (aptype > 0)
return MH2qg(p1,pa,pn,pb,-qH,-qHp1,mt,include_bottom,mb)*4./9.;
else
return MH2qbarg(p1,pa,pn,pb,-qH,-qHp1,mt,include_bottom,mb)*4./9.;
}
else { // they are both quark
if (bptype>0) {
if (aptype>0)
return MH2qQ(pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb)*4.*4./(9.*9.);
else
return MH2qQbar(pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb)*4.*4./(9.*9.);
}
else {
if (aptype>0)
return MH2qQbar(p1,pa,pn,pb,-qH,-qHp1,mt,include_bottom,mb)*4.*4./(9.*9.);
else
return MH2qbarQbar(pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb)*4.*4./(9.*9.);
}
}
throw std::logic_error("unknown particle types");
}
/** \brief Current matrix element squared with Higgs and unordered forward emission
* @param aptype Particle A PDG ID
* @param bptype Particle B PDG ID
* @param punof Unordered Particle Momentum
* @param pn Particle n Momentum
* @param pb Particle b Momentum
* @param p1 Particle 1 Momentum
* @param pa Particle a Momentum
* @param qH t-channel momentum before Higgs
* @param qHp1 t-channel momentum after Higgs
* @returns ME Squared with Higgs and unordered forward emission
*/
double ME_Higgs_current_unof(
int aptype, int bptype,
CLHEP::HepLorentzVector const & punof,
CLHEP::HepLorentzVector const & pn,
CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & p1,
CLHEP::HepLorentzVector const & pa,
CLHEP::HepLorentzVector const & qH, // t-channel momentum before Higgs
CLHEP::HepLorentzVector const & qHp1, // t-channel momentum after Higgs
double mt, bool include_bottom, double mb
){
if (aptype==21&&bptype!=21) {
if (bptype > 0)
return jM2unogqHg(punof,pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
else
return jM2unogqbarHg(punof,pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
}
else { // they are both quark
if (bptype>0) {
if (aptype>0)
return jM2unogqHQ(punof,pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
else
return jM2unogqHQbar(punof,pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
}
else {
if (aptype>0)
return jM2unogqbarHQ(punof,pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
else
return jM2unogqbarHQbar(punof,pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
}
}
throw std::logic_error("unknown particle types");
}
/** \brief Current matrix element squared with Higgs and unordered backward emission
* @param aptype Particle A PDG ID
* @param bptype Particle B PDG ID
* @param pn Particle n Momentum
* @param pb Particle b Momentum
* @param punob Unordered back Particle Momentum
* @param p1 Particle 1 Momentum
* @param pa Particle a Momentum
* @param qH t-channel momentum before Higgs
* @param qHp1 t-channel momentum after Higgs
* @returns ME Squared with Higgs and unordered backward emission
*/
double ME_Higgs_current_unob(
int aptype, int bptype,
CLHEP::HepLorentzVector const & pn,
CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & punob,
CLHEP::HepLorentzVector const & p1,
CLHEP::HepLorentzVector const & pa,
CLHEP::HepLorentzVector const & qH, // t-channel momentum before Higgs
CLHEP::HepLorentzVector const & qHp1, // t-channel momentum after Higgs
double mt, bool include_bottom, double mb
){
if (bptype==21&&aptype!=21) {
if (aptype > 0)
return jM2unobgHQg(pn,pb,punob,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
else
return jM2unobgHQbarg(pn,pb,punob,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
}
else { // they are both quark
if (aptype>0) {
if (bptype>0)
return jM2unobqHQg(pn,pb,punob,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
else
return jM2unobqbarHQg(pn,pb,punob,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
}
else {
if (bptype>0)
return jM2unobqHQbarg(pn,pb,punob,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
else
return jM2unobqbarHQbarg(pn,pb,punob,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
}
}
throw std::logic_error("unknown particle types");
}
CLHEP::HepLorentzVector to_HepLorentzVector(RHEJ::Particle const & particle){
return {particle.p.px(), particle.p.py(), particle.p.pz(), particle.p.E()};
}
void validate(RHEJ::MatrixElementConfig const & config) {
#ifndef RHEJ_BUILD_WITH_QCDLOOP
if(!config.Higgs_coupling.use_impact_factors) {
throw std::invalid_argument{
"Invalid Higgs coupling settings.\n"
"HEJ without QCDloop support can only use impact factors.\n"
"Set use_impact_factors to true or recompile HEJ.\n"
};
}
#endif
if(config.Higgs_coupling.use_impact_factors
&& config.Higgs_coupling.mt != std::numeric_limits<double>::infinity()) {
throw std::invalid_argument{
"Conflicting settings: "
"impact factors may only be used in the infinite top mass limit"
};
}
}
} // namespace anonymous
namespace RHEJ{
MatrixElement::MatrixElement(
std::function<double (double)> alpha_s,
MatrixElementConfig conf
):
alpha_s_{std::move(alpha_s)},
param_{std::move(conf)}
{
validate(param_);
}
double MatrixElement::operator()(
double mur,
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
std::unordered_map<int, std::vector<Particle>> const & decays,
bool check_momenta
) const {
return tree(
mur,
incoming, outgoing, decays,
check_momenta
)*virtual_corrections(
mur,
incoming, outgoing
);
}
double MatrixElement::tree_kin(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
std::unordered_map<int, std::vector<Particle>> const & decays,
bool check_momenta
) const {
assert(
std::is_sorted(
incoming.begin(), incoming.end(),
[](Particle o1, Particle o2){return o1.p.pz()<o2.p.pz();}
)
);
assert(std::is_sorted(outgoing.begin(), outgoing.end(), rapidity_less{}));
auto AWZH_boson = std::find_if(
begin(outgoing), end(outgoing),
[](Particle const & p){return is_AWZH_boson(p);}
);
if(AWZH_boson == end(outgoing)){
return tree_kin_jets(incoming, outgoing, check_momenta);
}
switch(AWZH_boson->type){
case pid::Higgs: {
return tree_kin_Higgs(incoming, outgoing, check_momenta);
}
// TODO
case pid::Wp: {
return tree_kin_W(incoming, outgoing, decays, true, check_momenta);
}
case pid::Wm: {
return tree_kin_W(incoming, outgoing, decays, false, check_momenta);
}
case pid::photon:
case pid::Z:
default:
throw std::logic_error("Emission of boson of unsupported type.");
}
}
namespace{
constexpr int extremal_jet_idx = 1;
constexpr int no_extremal_jet_idx = 0;
bool treat_as_extremal(Particle const & parton){
return parton.p.user_index() == extremal_jet_idx;
}
template<class InputIterator>
double FKL_ladder_weight(
InputIterator begin_gluon, InputIterator end_gluon,
CLHEP::HepLorentzVector const & q0,
CLHEP::HepLorentzVector const & pa, CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & p1, CLHEP::HepLorentzVector const & pn
){
double wt = 1;
auto qi = q0;
for(auto gluon_it = begin_gluon; gluon_it != end_gluon; ++gluon_it){
assert(gluon_it->type == pid::gluon);
const auto g = to_HepLorentzVector(*gluon_it);
const auto qip1 = qi - g;
if(treat_as_extremal(*gluon_it)){
wt *= C2Lipatovots(qip1, qi, pa, pb)*C_A;
} else{
wt *= C2Lipatovots(qip1, qi, pa, pb, p1, pn)*C_A;
}
qi = qip1;
}
return wt;
}
} // namespace anonymous
std::vector<Particle> MatrixElement::tag_extremal_jet_partons(
std::array<Particle, 2> const & incoming,
std::vector<Particle> out_partons, bool check_momenta
) const{
if(!check_momenta){
for(auto & parton: out_partons){
parton.p.set_user_index(no_extremal_jet_idx);
}
return out_partons;
}
fastjet::ClusterSequence cs(to_PseudoJet(out_partons), param_.jet_param.def);
const auto jets = sorted_by_rapidity(cs.inclusive_jets(param_.jet_param.min_pt));
assert(jets.size() >= 2);
auto most_backward = begin(jets);
auto most_forward = end(jets) - 1;
// skip jets caused by unordered emission
if(has_unob_gluon(incoming, out_partons)){
assert(jets.size() >= 3);
++most_backward;
}
else if(has_unof_gluon(incoming, out_partons)){
assert(jets.size() >= 3);
--most_forward;
}
const auto extremal_jet_indices = cs.particle_jet_indices(
{*most_backward, *most_forward}
);
assert(extremal_jet_indices.size() == out_partons.size());
for(size_t i = 0; i < out_partons.size(); ++i){
assert(RHEJ::is_parton(out_partons[i]));
const int idx = (extremal_jet_indices[i]>=0)?
extremal_jet_idx:
no_extremal_jet_idx;
out_partons[i].p.set_user_index(idx);
}
return out_partons;
}
double MatrixElement::tree_kin_jets(
std::array<Particle, 2> const & incoming,
std::vector<Particle> partons,
bool check_momenta
) const {
partons = tag_extremal_jet_partons(incoming, partons, check_momenta);
if(has_unob_gluon(incoming, partons) || has_unof_gluon(incoming, partons)){
throw std::logic_error("unordered emission not implemented for pure jets");
}
const auto pa = to_HepLorentzVector(incoming[0]);
const auto pb = to_HepLorentzVector(incoming[1]);
const auto p1 = to_HepLorentzVector(partons.front());
const auto pn = to_HepLorentzVector(partons.back());
return ME_current(
incoming[0].type, incoming[1].type,
pn, pb, p1, pa
)/(4*(N_C*N_C - 1))*FKL_ladder_weight(
begin(partons) + 1, end(partons) - 1,
pa - p1, pa, pb, p1, pn
);
}
double MatrixElement::tree_kin_W(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
std::unordered_map<int, std::vector<Particle>> const & decays,
bool WPlus,
bool check_momenta
) const {
if(has_unob_gluon(incoming, outgoing)){
throw std::logic_error("unordered emission not yet implemented for W+jets");
//return tree_kin_W_unob(incoming, outgoing, check_momenta);
}
else if(has_unof_gluon(incoming, outgoing)){
throw std::logic_error("unordered emission not yet implemented for W+jets");
// return tree_kin_W_unof(incoming, outgoing, check_momenta);
}
else if(has_Ex_qqx(incoming, outgoing)){
throw std::logic_error("Extremal qqx not yet implemented for W+jets");
// return tree_kin_W_Exqqx(incoming, outgoing, check_momenta);
}
else if(has_mid_qqx(outgoing)){
throw std::logic_error("Central qqx not yet implemented for W+jets");
// return tree_kin_W_qqxCentral(incoming, outgoing, check_momenta);
}
else{
return tree_kin_W_FKL(incoming, outgoing, decays, WPlus, check_momenta);
}
}
double MatrixElement::tree_kin_W_FKL(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
std::unordered_map<int, std::vector<Particle>> const & decays,
bool WPlus,
bool check_momenta
) const {
const auto the_W = std::find_if(
begin(outgoing), end(outgoing),
[](Particle const & s){ return abs(s.type) == pid::Wp; }
);
HLV plbar, pl;
for (auto& x: decays) {
if (x.second.at(0).type < 0){
plbar = to_HepLorentzVector(x.second.at(0));
pl = to_HepLorentzVector(x.second.at(1));
}
else{
pl = to_HepLorentzVector(x.second.at(0));
plbar = to_HepLorentzVector(x.second.at(1));
}
}
const auto pW = to_HepLorentzVector(*the_W);
std::vector<Particle> partons(begin(outgoing), the_W);
partons.insert(end(partons), the_W + 1, end(outgoing));
partons = tag_extremal_jet_partons(incoming, partons, check_momenta);
const auto pa = to_HepLorentzVector(incoming[0]);
const auto pb = to_HepLorentzVector(incoming[1]);
auto p1 = to_HepLorentzVector(partons[0]);
auto pn = to_HepLorentzVector(partons[partons.size() - 1]);
auto q0 = pa - p1;
auto begin_ladder = begin(partons) + 1;
auto end_ladder = end(partons) - 1;
bool wc;
if (incoming[0].type==partons[0].type) { //leg b emits w
wc = true;}
else{
wc = false;
q0 -=pl + plbar;
}
double current_factor;
if (WPlus){
current_factor = ME_W_current(
incoming[0].type, incoming[1].type,
pn, pb, p1, pa, pl, plbar, wc
);
}
else{
current_factor = ME_W_current(
incoming[0].type, incoming[1].type,
pn, pb, p1, pa, plbar, pl, wc
);
}
const double ladder_factor = FKL_ladder_weight(
begin_ladder, end_ladder,
q0, pa, pb, p1, pn
);
return current_factor*9./8.*ladder_factor;
}
double MatrixElement::tree_kin_W_unob(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
std::unordered_map<int, std::vector<Particle>> const & decays,
bool WPlus,
bool check_momenta
) const {
const auto the_W = std::find_if(
begin(outgoing), end(outgoing),
[](Particle const & s){ return abs(s.type) == pid::Wp; }
);
HLV plbar, pl;
for (auto& x: decays) {
if (x.second.at(0).type < 0){
plbar = to_HepLorentzVector(x.second.at(0));
pl = to_HepLorentzVector(x.second.at(1));
}
else{
pl = to_HepLorentzVector(x.second.at(0));
plbar = to_HepLorentzVector(x.second.at(1));
}
}
const auto pW = to_HepLorentzVector(*the_W);
std::vector<Particle> partons(begin(outgoing), the_W);
partons.insert(end(partons), the_W + 1, end(outgoing));
partons = tag_extremal_jet_partons(incoming, partons, check_momenta);
const auto pa = to_HepLorentzVector(incoming[0]);
const auto pb = to_HepLorentzVector(incoming[1]);
auto pg = to_HepLorentzVector(partons[0]);
auto p1 = to_HepLorentzVector(partons[1]);
auto pn = to_HepLorentzVector(partons[partons.size() - 1]);
auto q0 = pa - p1- pg;
auto begin_ladder = begin(partons) + 2;
auto end_ladder = end(partons) - 1;
bool wc;
if (incoming[0].type==partons[1].type) { //leg b emits w
wc = true;}
else{
wc = false;
q0 -=pl + plbar;
}
double current_factor;
if (WPlus){
current_factor = ME_W_unob_current(
incoming[0].type, incoming[1].type,
pn, pb, p1, pa, pg, pl, plbar, wc
);
}
else{
current_factor = ME_W_unob_current(
incoming[0].type, incoming[1].type,
pn, pb, p1, pa, pg, plbar, pl, wc
);
}
const double ladder_factor = FKL_ladder_weight(
begin_ladder, end_ladder,
q0, pa, pb, p1, pn
);
return current_factor*9./8.*ladder_factor;
}
double MatrixElement::tree_kin_W_unof(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
std::unordered_map<int, std::vector<Particle>> const & decays,
bool WPlus,
bool check_momenta
) const {
const auto the_W = std::find_if(
begin(outgoing), end(outgoing),
[](Particle const & s){ return abs(s.type) == pid::Wp; }
);
HLV plbar, pl;
for (auto& x: decays) {
if (x.second.at(0).type < 0){
plbar = to_HepLorentzVector(x.second.at(0));
pl = to_HepLorentzVector(x.second.at(1));
}
else{
pl = to_HepLorentzVector(x.second.at(0));
plbar = to_HepLorentzVector(x.second.at(1));
}
}
const auto pW = to_HepLorentzVector(*the_W);
std::vector<Particle> partons(begin(outgoing), the_W);
partons.insert(end(partons), the_W + 1, end(outgoing));
partons = tag_extremal_jet_partons(incoming, partons, check_momenta);
const auto pa = to_HepLorentzVector(incoming[0]);
const auto pb = to_HepLorentzVector(incoming[1]);
auto p1 = to_HepLorentzVector(partons[0]);
auto pn = to_HepLorentzVector(partons[partons.size() - 2]);
auto pg = to_HepLorentzVector(partons[partons.size() - 1]);
auto q0 = pa - p1;
auto begin_ladder = begin(partons) + 1;
auto end_ladder = end(partons) - 2;
bool wc;
if (incoming[0].type==partons[0].type) { //leg b emits w
wc = true;}
else{
wc = false;
q0 -=pl + plbar;
}
double current_factor;
if (WPlus){
current_factor = ME_W_unof_current(
incoming[0].type, incoming[1].type,
pn, pb, p1, pa, pg, pl, plbar, wc
);
}
else{
current_factor = ME_W_unof_current(
incoming[0].type, incoming[1].type,
pn, pb, p1, pa, pg, plbar, pl, wc
);
}
const double ladder_factor = FKL_ladder_weight(
begin_ladder, end_ladder,
q0, pa, pb, p1, pn
);
return current_factor*9./8.*ladder_factor;
}
double MatrixElement::tree_kin_W_qqxb(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
std::unordered_map<int, std::vector<Particle>> const & decays,
bool WPlus,
bool check_momenta
) const {
const auto the_W = std::find_if(
begin(outgoing), end(outgoing),
[](Particle const & s){ return abs(s.type) == pid::Wp; }
);
HLV plbar, pl;
for (auto& x: decays) {
if (x.second.at(0).type < 0){
plbar = to_HepLorentzVector(x.second.at(0));
pl = to_HepLorentzVector(x.second.at(1));
}
else{
pl = to_HepLorentzVector(x.second.at(0));
plbar = to_HepLorentzVector(x.second.at(1));
}
}
const auto pW = to_HepLorentzVector(*the_W);
std::vector<Particle> partons(begin(outgoing), the_W);
partons.insert(end(partons), the_W + 1, end(outgoing));
partons = tag_extremal_jet_partons(incoming, partons, check_momenta);
const auto pa = to_HepLorentzVector(incoming[0]);
const auto pb = to_HepLorentzVector(incoming[1]);
HLV pq,pqbar;
if(is_quark(partons[0])){
pq = to_HepLorentzVector(partons[0]);
pqbar = to_HepLorentzVector(partons[1]);
}
else{
pq = to_HepLorentzVector(partons[1]);
pqbar = to_HepLorentzVector(partons[0]);
}
auto p1 = to_HepLorentzVector(partons[0]);
auto pn = to_HepLorentzVector(partons[partons.size() - 1]);
auto q0 = pa - pq - pqbar;
auto begin_ladder = begin(partons) + 2;
auto end_ladder = end(partons) - 1;
bool wc;
if (partons[0].type==-partons[1].type) { //leg b emits w
wc = true;}
else{
wc = false;
q0 -=pl + plbar;
}
double current_factor;
if (WPlus){
current_factor = ME_W_qqxb_current(
incoming[0].type, incoming[1].type,
pa, pb, pq, pqbar, pn, pl, plbar, wc
);
}
else{
current_factor = ME_W_qqxb_current(
incoming[0].type, incoming[1].type,
pa, pb, pq, pqbar, pn, plbar, pl, wc
);
}
const double ladder_factor = FKL_ladder_weight(
begin_ladder, end_ladder,
q0, pa, pb, p1, pn
);
return current_factor*9./8.*ladder_factor;
}
-
double MatrixElement::tree_kin_W_qqxf(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
std::unordered_map<int, std::vector<Particle>> const & decays,
bool WPlus,
bool check_momenta
) const {
const auto the_W = std::find_if(
begin(outgoing), end(outgoing),
[](Particle const & s){ return abs(s.type) == pid::Wp; }
);
HLV plbar, pl;
for (auto& x: decays) {
if (x.second.at(0).type < 0){
plbar = to_HepLorentzVector(x.second.at(0));
pl = to_HepLorentzVector(x.second.at(1));
}
else{
pl = to_HepLorentzVector(x.second.at(0));
plbar = to_HepLorentzVector(x.second.at(1));
}
}
const auto pW = to_HepLorentzVector(*the_W);
std::vector<Particle> partons(begin(outgoing), the_W);
partons.insert(end(partons), the_W + 1, end(outgoing));
partons = tag_extremal_jet_partons(incoming, partons, check_momenta);
const auto pa = to_HepLorentzVector(incoming[0]);
const auto pb = to_HepLorentzVector(incoming[1]);
HLV pq,pqbar;
if(is_quark(partons[partons.size() - 1])){
pq = to_HepLorentzVector(partons[partons.size() - 1]);
pqbar = to_HepLorentzVector(partons[partons.size() - 2]);
}
else{
pq = to_HepLorentzVector(partons[partons.size() - 2]);
pqbar = to_HepLorentzVector(partons[partons.size() - 1]);
}
auto p1 = to_HepLorentzVector(partons[0]);
auto pn = to_HepLorentzVector(partons[partons.size() - 1]);
auto q0 = pa - p1;
auto begin_ladder = begin(partons) + 1;
auto end_ladder = end(partons) - 2;
bool wc;
if (incoming[0].type==partons[0].type) { //leg b emits w
wc = true;}
else{
wc = false;
q0 -=pl + plbar;
}
double current_factor;
if (WPlus){
current_factor = ME_W_qqxf_current(
incoming[0].type, incoming[1].type,
pa, pb, pq, pqbar, p1, pl, plbar, wc
);
}
else{
current_factor = ME_W_qqxf_current(
incoming[0].type, incoming[1].type,
pa, pb, pq, pqbar, p1, plbar, pl, wc
);
}
const double ladder_factor = FKL_ladder_weight(
begin_ladder, end_ladder,
q0, pa, pb, p1, pn
);
return current_factor*9./8.*ladder_factor;
}
+ double MatrixElement::tree_kin_W_qqxmid(
+ std::array<Particle, 2> const & incoming,
+ std::vector<Particle> const & outgoing,
+ std::unordered_map<int, std::vector<Particle>> const & decays,
+ bool WPlus,
+ bool check_momenta
+ ) const {
+
+ const auto the_W = std::find_if(
+ begin(outgoing), end(outgoing),
+ [](Particle const & s){ return abs(s.type) == pid::Wp; }
+ );
+
+ HLV plbar, pl;
+
+ for (auto& x: decays) {
+ if (x.second.at(0).type < 0){
+ plbar = to_HepLorentzVector(x.second.at(0));
+ pl = to_HepLorentzVector(x.second.at(1));
+ }
+ else{
+ pl = to_HepLorentzVector(x.second.at(0));
+ plbar = to_HepLorentzVector(x.second.at(1));
+ }
+ }
+
+ const auto pW = to_HepLorentzVector(*the_W);
+ std::vector<Particle> partons(begin(outgoing), the_W);
+ partons.insert(end(partons), the_W + 1, end(outgoing));
+ partons = tag_extremal_jet_partons(incoming, partons, check_momenta);
+
+ const auto pa = to_HepLorentzVector(incoming[0]);
+ const auto pb = to_HepLorentzVector(incoming[1]);
+
+ HLV pq,pqbar;
+ const auto backmidquark = std::find_if(
+ begin(partons)+1, end(partons)-1,
+ [](Particle const & s){ return s.type != pid::gluon; }
+ );
+
+ if (is_quark(backmidquark->type)){
+ pq = to_HepLorentzVector(*backmidquark);
+ pqbar = to_HepLorentzVector(*(backmidquark+1));
+ }
+ else {
+ pqbar = to_HepLorentzVector(*backmidquark);
+ pq = to_HepLorentzVector(*(backmidquark+1));
+ }
+
+ auto p1 = to_HepLorentzVector(partons[0]);
+ auto pn = to_HepLorentzVector(partons[partons.size() - 1]);
+
+ auto q0 = pa - p1;
+ // t-channel momentum after qqx
+ auto qqxt = q0;
+
+ bool wc, wqq;
+ if (backmidquark->type == -(backmidquark+1)->type){ // Central qqx does not emit
+ wqq=false;
+ if (incoming[0].type==partons[0].type) {
+ wc = true;
+ }
+ else{
+ wc = false;
+ q0-=pl+plbar;
+ }
+ }
+ else{
+ wqq = true;
+ wc = false;
+ qqxt-=pl+plbar;
+ }
+
+ auto begin_ladder = begin(partons) + 1;
+ auto end_ladder = end(partons) - 1;
+ auto first_after_qqx = (backmidquark+2);
+ for(auto parton_it = begin_ladder; parton_it != first_after_qqx; ++parton_it){
+ qqxt -= to_HepLorentzVector(*parton_it);
+ }
+
+ int nabove = std::distance(begin_ladder, backmidquark-1);
+ int nbelow = std::distance(first_after_qqx, end_ladder);
+
+ std::vector<HLV> partonsHLV;
+ partonsHLV.reserve(partons.size());
+ for (size_t i = 0; i != partons.size(); ++i) {
+ partonsHLV.push_back(to_HepLorentzVector(partons[i]));
+ }
+
+ double current_factor;
+ if (WPlus){
+ current_factor = ME_W_qqxmid_current(
+ incoming[0].type, incoming[1].type, nabove, nbelow,
+ pa, pb, pq, pqbar, partonsHLV, pl, plbar, wqq, wc
+ );
+ }
+ else{
+ current_factor = ME_W_qqxmid_current(
+ incoming[0].type, incoming[1].type, nabove, nbelow,
+ pa, pb, pq, pqbar, partonsHLV, plbar, pl, wqq, wc
+ );
+ }
+
+ const double ladder_factor = FKL_ladder_weight(
+ begin_ladder, backmidquark-1,
+ q0, pa, pb, p1, pn
+ )*FKL_ladder_weight(
+ first_after_qqx, end_ladder,
+ qqxt, pa, pb, p1, pn
+ );
+ return current_factor*C_A*C_A/(N_C*N_C-1.)*ladder_factor;
+ }
+
+
+
+
double MatrixElement::tree_kin_Higgs(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
bool check_momenta
) const {
if(has_uno_gluon(incoming, outgoing)){
return tree_kin_Higgs_between(incoming, outgoing, check_momenta);
}
if(outgoing.front().type == pid::Higgs){
return tree_kin_Higgs_first(incoming, outgoing, check_momenta);
}
if(outgoing.back().type == pid::Higgs){
return tree_kin_Higgs_last(incoming, outgoing, check_momenta);
}
return tree_kin_Higgs_between(incoming, outgoing, check_momenta);
}
namespace {
// Colour acceleration multipliers, for gluons see eq. (7) in arXiv:0910.5113
// TODO: code duplication with currents.cc
double K_g(double p1minus, double paminus) {
return 1./2.*(p1minus/paminus + paminus/p1minus)*(C_A - 1./C_A) + 1./C_A;
}
double K_g(
CLHEP::HepLorentzVector const & pout,
CLHEP::HepLorentzVector const & pin
) {
if(pin.z() > 0) return K_g(pout.plus(), pin.plus());
return K_g(pout.minus(), pin.minus());
}
double K(
ParticleID type,
CLHEP::HepLorentzVector const & pout,
CLHEP::HepLorentzVector const & pin
) {
if(type == ParticleID::gluon) return K_g(pout, pin);
return C_F;
}
// Colour factor in strict MRK limit
double K_MRK(ParticleID type) {
return (type == ParticleID::gluon)?C_A:C_F;
}
}
double MatrixElement::MH2_forwardH(
CLHEP::HepLorentzVector p1out, CLHEP::HepLorentzVector p1in,
ParticleID type2,
CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in,
CLHEP::HepLorentzVector pH,
double t1, double t2
) const{
ignore(p2out, p2in);
const double shat = p1in.invariantMass2(p2in);
// gluon case
#ifdef RHEJ_BUILD_WITH_QCDLOOP
if(!param_.Higgs_coupling.use_impact_factors){
return K(type2, p2out, p2in)*C_A*1./(16*M_PI*M_PI)*t1/t2*MH2gq_outsideH(
p1out, p1in, p2out, p2in, pH,
param_.Higgs_coupling.mt, param_.Higgs_coupling.include_bottom,
param_.Higgs_coupling.mb
)/(4*(N_C*N_C - 1));
}
#endif
return K_MRK(type2)/C_A*9./2.*shat*shat*(
C2gHgp(p1in,p1out,pH) + C2gHgm(p1in,p1out,pH)
)/(t1*t2);
}
double MatrixElement::tree_kin_Higgs_first(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
bool check_momenta
) const {
assert(outgoing.front().type == pid::Higgs);
if(outgoing[1].type != pid::gluon) {
assert(incoming.front().type == outgoing[1].type);
return tree_kin_Higgs_between(incoming, outgoing, check_momenta);
}
const auto pH = to_HepLorentzVector(outgoing.front());
const auto partons = tag_extremal_jet_partons(
incoming,
std::vector<Particle>(begin(outgoing) + 1, end(outgoing)),
check_momenta
);
const auto pa = to_HepLorentzVector(incoming[0]);
const auto pb = to_HepLorentzVector(incoming[1]);
const auto p1 = to_HepLorentzVector(partons.front());
const auto pn = to_HepLorentzVector(partons.back());
const auto q0 = pa - p1 - pH;
const double t1 = q0.m2();
const double t2 = (pn - pb).m2();
return MH2_forwardH(
p1, pa, incoming[1].type, pn, pb, pH,
t1, t2
)*FKL_ladder_weight(
begin(partons) + 1, end(partons) - 1,
q0, pa, pb, p1, pn
);
}
double MatrixElement::tree_kin_Higgs_last(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
bool check_momenta
) const {
assert(outgoing.back().type == pid::Higgs);
if(outgoing[outgoing.size()-2].type != pid::gluon) {
assert(incoming.back().type == outgoing[outgoing.size()-2].type);
return tree_kin_Higgs_between(incoming, outgoing, check_momenta);
}
const auto pH = to_HepLorentzVector(outgoing.back());
const auto partons = tag_extremal_jet_partons(
incoming,
std::vector<Particle>(begin(outgoing), end(outgoing) - 1),
check_momenta
);
const auto pa = to_HepLorentzVector(incoming[0]);
const auto pb = to_HepLorentzVector(incoming[1]);
auto p1 = to_HepLorentzVector(partons.front());
const auto pn = to_HepLorentzVector(partons.back());
auto q0 = pa - p1;
const double t1 = q0.m2();
const double t2 = (pn + pH - pb).m2();
return MH2_forwardH(
pn, pb, incoming[0].type, p1, pa, pH,
t2, t1
)*FKL_ladder_weight(
begin(partons) + 1, end(partons) - 1,
q0, pa, pb, p1, pn
);
}
double MatrixElement::tree_kin_Higgs_between(
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
bool check_momenta
) const {
const auto the_Higgs = std::find_if(
begin(outgoing), end(outgoing),
[](Particle const & s){ return s.type == pid::Higgs; }
);
assert(the_Higgs != end(outgoing));
const auto pH = to_HepLorentzVector(*the_Higgs);
std::vector<Particle> partons(begin(outgoing), the_Higgs);
partons.insert(end(partons), the_Higgs + 1, end(outgoing));
partons = tag_extremal_jet_partons(incoming, partons, check_momenta);
const auto pa = to_HepLorentzVector(incoming[0]);
const auto pb = to_HepLorentzVector(incoming[1]);
auto p1 = to_HepLorentzVector(
partons[has_unob_gluon(incoming, outgoing)?1:0]
);
auto pn = to_HepLorentzVector(
partons[partons.size() - (has_unof_gluon(incoming, outgoing)?2:1)]
);
auto first_after_Higgs = begin(partons) + (the_Higgs-begin(outgoing));
assert(
(first_after_Higgs == end(partons) && (
has_unob_gluon(incoming, outgoing)
|| partons.back().type != pid::gluon
))
|| first_after_Higgs->rapidity() >= the_Higgs->rapidity()
);
assert(
(first_after_Higgs == begin(partons) && (
has_unof_gluon(incoming, outgoing)
|| partons.front().type != pid::gluon
))
|| (first_after_Higgs-1)->rapidity() <= the_Higgs->rapidity()
);
// always treat the Higgs as if it were in between the extremal FKL partons
if(first_after_Higgs == begin(partons)) ++first_after_Higgs;
else if(first_after_Higgs == end(partons)) --first_after_Higgs;
// t-channel momentum before Higgs
auto qH = pa;
for(auto parton_it = begin(partons); parton_it != first_after_Higgs; ++parton_it){
qH -= to_HepLorentzVector(*parton_it);
}
auto q0 = pa - p1;
auto begin_ladder = begin(partons) + 1;
auto end_ladder = end(partons) - 1;
double current_factor;
if(has_unob_gluon(incoming, outgoing)){
current_factor = C_A*C_A/2.*ME_Higgs_current_unob( // 1/2 = "K_uno"
incoming[0].type, incoming[1].type,
pn, pb, to_HepLorentzVector(partons.front()), p1, pa, qH, qH - pH,
param_.Higgs_coupling.mt,
param_.Higgs_coupling.include_bottom, param_.Higgs_coupling.mb
);
const auto p_unob = to_HepLorentzVector(partons.front());
q0 -= p_unob;
p1 += p_unob;
++begin_ladder;
}
else if(has_unof_gluon(incoming, outgoing)){
current_factor = C_A*C_A/2.*ME_Higgs_current_unof( // 1/2 = "K_uno"
incoming[0].type, incoming[1].type,
to_HepLorentzVector(partons.back()), pn, pb, p1, pa, qH, qH - pH,
param_.Higgs_coupling.mt,
param_.Higgs_coupling.include_bottom, param_.Higgs_coupling.mb
);
pn += to_HepLorentzVector(partons.back());
--end_ladder;
}
else{
current_factor = ME_Higgs_current(
incoming[0].type, incoming[1].type,
pn, pb, p1, pa, qH, qH - pH,
param_.Higgs_coupling.mt,
param_.Higgs_coupling.include_bottom, param_.Higgs_coupling.mb
);
}
const double ladder_factor = FKL_ladder_weight(
begin_ladder, first_after_Higgs,
q0, pa, pb, p1, pn
)*FKL_ladder_weight(
first_after_Higgs, end_ladder,
qH - pH, pa, pb, p1, pn
);
return current_factor*C_A*C_A/(N_C*N_C-1.)*ladder_factor;
}
double MatrixElement::tree_param_partons(
double alpha_s, double mur,
std::vector<Particle> const & partons
) const{
const double gs2 = 4.*M_PI*alpha_s;
double wt = std::pow(gs2, partons.size());
if(param_.log_correction){
// use alpha_s(q_perp), evolved to mur
assert(partons.size() >= 2);
for(size_t i = 1; i < partons.size()-1; ++i){
wt *= 1 + alpha_s/(2*M_PI)*beta0*log(mur/partons[i].p.perp());
}
}
return wt;
}
double MatrixElement::tree_param(
double mur,
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing
) const{
const double alpha_s = alpha_s_(mur);
auto AWZH_boson = std::find_if(
begin(outgoing), end(outgoing),
[](auto const & p){return is_AWZH_boson(p);}
);
double AWZH_coupling = 1.;
if(AWZH_boson != end(outgoing)){
switch(AWZH_boson->type){
case pid::Higgs: {
AWZH_coupling = alpha_s*alpha_s;
break;
}
// TODO
case pid::Wp:{
AWZH_coupling = alpha_w*alpha_w/2;
break;
}
case pid::Wm:{
AWZH_coupling = alpha_w*alpha_w/2;
break;
}
case pid::photon:
case pid::Z:
default:
throw std::logic_error("Emission of boson of unsupported type");
}
}
if(has_unob_gluon(incoming, outgoing)){
return AWZH_coupling*4*M_PI*alpha_s*tree_param_partons(
alpha_s, mur, filter_partons({begin(outgoing) + 1, end(outgoing)})
);
}
if(has_unof_gluon(incoming, outgoing)){
return AWZH_coupling*4*M_PI*alpha_s*tree_param_partons(
alpha_s, mur, filter_partons({begin(outgoing), end(outgoing) - 1})
);
}
return AWZH_coupling*tree_param_partons(alpha_s, mur, filter_partons(outgoing));
}
double MatrixElement::tree(
double mur,
std::array<Particle, 2> const & incoming,
std::vector<Particle> const & outgoing,
std::unordered_map<int, std::vector<Particle>> const & decays,
bool check_momenta
) const {
return tree_param(mur, incoming, outgoing)*tree_kin(
incoming, outgoing, decays, check_momenta
);
}
} // namespace RHEJ
diff --git a/src/Wjets.cc b/src/Wjets.cc
index 8d75651..cd5a520 100644
--- a/src/Wjets.cc
+++ b/src/Wjets.cc
@@ -1,2019 +1,2019 @@
#include "RHEJ/currents.hh"
#include "RHEJ/utility.hh"
#include "RHEJ/Tensor.hh"
#include "RHEJ/Constants.hh"
#include <array>
#include <iostream>
namespace { // Helper Functions
// FKL W Helper Functions
void jW (CLHEP::HepLorentzVector pout, bool helout, CLHEP::HepLorentzVector pe,
bool hele, CLHEP::HepLorentzVector pnu, bool helnu, CLHEP::HepLorentzVector pin,
bool helin, current cur)
{
// NOTA BENE: Conventions for W+ --> e+ nu, so that nu is lepton(6), e is anti-lepton(5)
// Need to swap e and nu for events with W- --> e- nubar!
if (helin==helout && hele==helnu) {
CLHEP::HepLorentzVector qa=pout+pe+pnu;
CLHEP::HepLorentzVector qb=pin-pe-pnu;
double ta(qa.m2()),tb(qb.m2());
current t65,vout,vin,temp2,temp3,temp5;
joo(pnu,helnu,pe,hele,t65);
vout[0]=pout.e();
vout[1]=pout.x();
vout[2]=pout.y();
vout[3]=pout.z();
vin[0]=pin.e();
vin[1]=pin.x();
vin[2]=pin.y();
vin[3]=pin.z();
COM brac615=cdot(t65,vout);
COM brac645=cdot(t65,vin);
// prod1565 and prod6465 are zero for Ws (not Zs)!!
joo(pout,helout,pnu,helout,temp2);
COM prod1665=cdot(temp2,t65);
j(pe,helin,pin,helin,temp3);
COM prod5465=cdot(temp3,t65);
joo(pout,helout,pe,helout,temp2);
j(pnu,helnu,pin,helin,temp3);
j(pout,helout,pin,helin,temp5);
current term1,term2,term3,sum;
cmult(2.*brac615/ta+2.*brac645/tb,temp5,term1);
cmult(prod1665/ta,temp3,term2);
cmult(-prod5465/tb,temp2,term3);
cadd(term1,term2,term3,sum);
cur[0]=sum[0];
cur[1]=sum[1];
cur[2]=sum[2];
cur[3]=sum[3];
}
}
void jWbar (CLHEP::HepLorentzVector pout, bool helout, CLHEP::HepLorentzVector pe, bool hele, CLHEP::HepLorentzVector pnu, bool helnu, CLHEP::HepLorentzVector pin, bool helin, current cur)
{
// NOTA BENE: Conventions for W+ --> e+ nu, so that nu is lepton(6), e is anti-lepton(5)
// Need to swap e and nu for events with W- --> e- nubar!
if (helin==helout && hele==helnu) {
CLHEP::HepLorentzVector qa=pout+pe+pnu;
CLHEP::HepLorentzVector qb=pin-pe-pnu;
double ta(qa.m2()),tb(qb.m2());
current t65,vout,vin,temp2,temp3,temp5;
joo(pnu,helnu,pe,hele,t65);
vout[0]=pout.e();
vout[1]=pout.x();
vout[2]=pout.y();
vout[3]=pout.z();
vin[0]=pin.e();
vin[1]=pin.x();
vin[2]=pin.y();
vin[3]=pin.z();
COM brac615=cdot(t65,vout);
COM brac645=cdot(t65,vin);
// prod1565 and prod6465 are zero for Ws (not Zs)!!
joo(pe,helout,pout,helout,temp2); // temp2 is <5|alpha|1>
COM prod5165=cdot(temp2,t65);
jio(pin,helin,pnu,helin,temp3); // temp3 is <4|alpha|6>
COM prod4665=cdot(temp3,t65);
joo(pnu,helout,pout,helout,temp2); // temp2 is now <6|mu|1>
jio(pin,helin,pe,helin,temp3); // temp3 is now <4|mu|5>
jio(pin,helin,pout,helout,temp5); // temp5 is <4|mu|1>
current term1,term2,term3,sum;
cmult(-2.*brac615/ta-2.*brac645/tb,temp5,term1);
cmult(-prod5165/ta,temp3,term2);
cmult(prod4665/tb,temp2,term3);
cadd(term1,term2,term3,sum);
cur[0]=sum[0];
cur[1]=sum[1];
cur[2]=sum[2];
cur[3]=sum[3];
}
}
CCurrent jW (CLHEP::HepLorentzVector pout, bool helout, CLHEP::HepLorentzVector pe, bool hele, CLHEP::HepLorentzVector pnu, bool helnu, CLHEP::HepLorentzVector pin, bool helin)
{
COM cur[4];
cur[0]=0.;
cur[1]=0.;
cur[2]=0.;
cur[3]=0.;
CCurrent sum(0.,0.,0.,0.);
// NOTA BENE: Conventions for W+ --> e+ nu, so that nu is lepton(6), e is anti-lepton(5)
// Need to swap e and nu for events with W- --> e- nubar!
if (helin==helout && hele==helnu) {
CLHEP::HepLorentzVector qa=pout+pe+pnu;
CLHEP::HepLorentzVector qb=pin-pe-pnu;
double ta(qa.m2()),tb(qb.m2());
CCurrent temp2,temp3,temp5;
CCurrent t65 = joo(pnu,helnu,pe,hele);
CCurrent vout(pout.e(),pout.x(),pout.y(),pout.z());
CCurrent vin(pin.e(),pin.x(),pin.y(),pin.z());
COM brac615=t65.dot(vout);
COM brac645=t65.dot(vin);
// prod1565 and prod6465 are zero for Ws (not Zs)!!
temp2 = joo(pout,helout,pnu,helout);
COM prod1665=temp2.dot(t65);
temp3 = j(pe,helin,pin,helin);
COM prod5465=temp3.dot(t65);
temp2=joo(pout,helout,pe,helout);
temp3=j(pnu,helnu,pin,helin);
temp5=j(pout,helout,pin,helin);
CCurrent term1,term2,term3;
term1=(2.*brac615/ta+2.*brac645/tb)*temp5;
term2=(prod1665/ta)*temp3;
term3=(-prod5465/tb)*temp2;
sum=term1+term2+term3;
}
return sum;
}
CCurrent jWbar (CLHEP::HepLorentzVector pout, bool helout, CLHEP::HepLorentzVector pe, bool hele, CLHEP::HepLorentzVector pnu, bool helnu, CLHEP::HepLorentzVector pin, bool helin)
{
COM cur[4];
cur[0]=0.;
cur[1]=0.;
cur[2]=0.;
cur[3]=0.;
CCurrent sum(0.,0.,0.,0.);
// NOTA BENE: Conventions for W+ --> e+ nu, so that nu is lepton(6), e is anti-lepton(5)
// Need to swap e and nu for events with W- --> e- nubar!
if (helin==helout && hele==helnu) {
CLHEP::HepLorentzVector qa=pout+pe+pnu;
CLHEP::HepLorentzVector qb=pin-pe-pnu;
double ta(qa.m2()),tb(qb.m2());
CCurrent temp2,temp3,temp5;
CCurrent t65 = joo(pnu,helnu,pe,hele);
CCurrent vout(pout.e(),pout.x(),pout.y(),pout.z());
CCurrent vin(pin.e(),pin.x(),pin.y(),pin.z());
COM brac615=t65.dot(vout);
COM brac645=t65.dot(vin);
// prod1565 and prod6465 are zero for Ws (not Zs)!!
temp2 = joo(pe,helout,pout,helout); // temp2 is <5|alpha|1>
COM prod5165=temp2.dot(t65);
temp3 = jio(pin,helin,pnu,helin); // temp3 is <4|alpha|6>
COM prod4665=temp3.dot(t65);
temp2=joo(pnu,helout,pout,helout); // temp2 is now <6|mu|1>
temp3=jio(pin,helin,pe,helin); // temp3 is now <4|mu|5>
temp5=jio(pin,helin,pout,helout); // temp5 is <4|mu|1>
CCurrent term1,term2,term3;
term1 =(-2.*brac615/ta-2.*brac645/tb)*temp5;
term2 =(-prod5165/ta)*temp3;
term3 =(prod4665/tb)*temp2;
sum = term1 + term2 + term3;
}
return sum;
}
// Relevant W+Jets Unordered Contribution Helper Functions
// W+Jets Uno
double jM2Wuno(CLHEP::HepLorentzVector pg, CLHEP::HepLorentzVector p1,CLHEP::HepLorentzVector plbar, CLHEP::HepLorentzVector pl, CLHEP::HepLorentzVector pa, bool h1, CLHEP::HepLorentzVector p2, CLHEP::HepLorentzVector pb, bool h2, bool pol)
{
static bool is_sigma_index_set(false);
if(!is_sigma_index_set){
//std::cout<<"Setting sigma_index...." << std::endl;
if(init_sigma_index())
is_sigma_index_set = true;
else
return 0.;
}
CLHEP::HepLorentzVector pW = pl+plbar;
CLHEP::HepLorentzVector q1g=pa-pW-p1-pg;
CLHEP::HepLorentzVector q1 = pa-p1-pW;
CLHEP::HepLorentzVector q2 = p2-pb;
const double taW = (pa-pW).m2();
const double taW1 = (pa-pW-p1).m2();
const double tb2 = (pb-p2).m2();
const double tb2g = (pb-p2-pg).m2();
const double s1W = (p1+pW).m2();
const double s1gW = (p1+pW+pg).m2();
const double s1g = (p1+pg).m2();
const double tag = (pa-pg).m2();
const double taWg = (pa-pW-pg).m2();
const double ca = RHEJ::C_A;
const double cf = RHEJ::C_F; ///<TODO directly use RHEJ constants
//use p1 as ref vec in pol tensor
Tensor<1,4> epsg = eps(pg,p2,pol);
Tensor<1,4> epsW = TCurrent(pl,false,plbar,false);
Tensor<1,4> j2b = TCurrent(p2,h2,pb,h2);
Tensor<1,4> Tq1q2 = Construct1Tensor((q1+q2)/taW1 + (pb/pb.dot(pg)
+ p2/p2.dot(pg)) * tb2/(2*tb2g));
Tensor<1,4> Tq1g = Construct1Tensor((-pg-q1))/taW1;
Tensor<1,4> Tq2g = Construct1Tensor((pg-q2));
Tensor<1,4> TqaW = Construct1Tensor((pa-pW));//pa-pw
Tensor<1,4> Tqag = Construct1Tensor((pa-pg));
Tensor<1,4> TqaWg = Construct1Tensor((pa-pg-pW));
Tensor<1,4> Tp1g = Construct1Tensor((p1+pg));
Tensor<1,4> Tp1W = Construct1Tensor((p1+pW));//p1+pw
Tensor<1,4> Tp1gW = Construct1Tensor((p1+pg+pW));//p1+pw+pg
Tensor<2,4> g=Metric();
Tensor<3,4> J31a = T3Current(p1, h1, pa, h1);
Tensor<2,4> J2_qaW =J31a.contract(TqaW/taW, 2);
Tensor<2,4> J2_p1W =J31a.contract(Tp1W/s1W, 2);
Tensor<3,4> L1a =J2_qaW.leftprod(Tq1q2);
Tensor<3,4> L1b =J2_p1W.leftprod(Tq1q2);
Tensor<3,4> L2a = J2_qaW.leftprod(Tq1g);
Tensor<3,4> L2b = J2_p1W.leftprod(Tq1g);
Tensor<3,4> L3 = (g.rightprod(J2_qaW.contract(Tq2g,1)+J2_p1W.contract(Tq2g,2)))/taW1;
Tensor<3,4> L(0.);
Tensor<5,4> J51a = T5Current(p1, h1, pa, h1);
Tensor<4,4> J_qaW = J51a.contract(TqaW,4);
Tensor<4,4> J_qag = J51a.contract(Tqag,4);
Tensor<4,4> J_p1gW = J51a.contract(Tp1gW,4);
Tensor<3,4> U1a = J_qaW.contract(Tp1g,2);
Tensor<3,4> U1b = J_p1gW.contract(Tp1g,2);
Tensor<3,4> U1c = J_p1gW.contract(Tp1W,2);
Tensor<3,4> U1(0.);
Tensor<3,4> U2a = J_qaW.contract(TqaWg,2);
Tensor<3,4> U2b = J_qag.contract(TqaWg,2);
Tensor<3,4> U2c = J_qag.contract(Tp1W,2);
Tensor<3,4> U2(0.);
for(int nu=0; nu<4;nu++){
for(int mu=0;mu<4;mu++){
for(int rho=0;rho<4;rho++){
L.Set(nu, mu, rho, L1a.at(nu,mu,rho) + L1b.at(nu,rho,mu)
+ L2a.at(mu,nu,rho) + L2b.at(mu,rho,nu) + L3.at(mu,nu,rho));
U1.Set(nu, mu, rho, U1a.at(nu, mu, rho) / (s1g*taW)
+ U1b.at(nu,rho,mu) / (s1g*s1gW) + U1c.at(rho,nu,mu) / (s1W*s1gW));
U2.Set(nu,mu,rho,U2a.at(mu,nu,rho) / (taWg*taW)
+ U2b.at(mu,rho,nu) / (taWg*tag) + U2c.at(rho,mu,nu) / (s1W*tag));
}
}
}
COM X = ((((U1-L).contract(epsW,3)).contract(j2b,2)).contract(epsg,1)).at(0);
COM Y = ((((U2+L).contract(epsW,3)).contract(j2b,2)).contract(epsg,1)).at(0);
double amp = ca*cf*cf/2.*(norm(X)+norm(Y)) - cf/2.*(X*conj(Y)).real();
double t1 = q1g.m2();
double t2 = q2.m2();
//Divide by t-channels
amp/=(t1*t2);
//Average over initial states
amp/=(4.*ca*ca);
return amp;
}
// Relevant Wqqx Helper Functions.
//g->qxqlxl (Calculates gluon to qqx Current. See JV_\mu in WSubleading Notes)
Tensor <1,4> gtqqxW(CLHEP::HepLorentzVector pq,CLHEP::HepLorentzVector pqbar,CLHEP::HepLorentzVector pl,CLHEP::HepLorentzVector plbar){
double s2AB=(pl+plbar+pq).m2();
double s3AB=(pl+plbar+pqbar).m2();
Tensor<1,4> Tpq = Construct1Tensor(pq);
Tensor<1,4> Tpqbar = Construct1Tensor(pqbar);
Tensor<1,4> TAB = Construct1Tensor(pl+plbar);
// Define llx current.
Tensor<1,4> ABCur = TCurrent(pl, false, plbar, false);
//blank 3 Gamma Current
Tensor<3,4> JV23 = T3Current(pq,false,pqbar,false);
// Components of g->qqW before W Contraction
Tensor<2,4> JV1 = JV23.contract((Tpq + TAB),2)/(s2AB);
Tensor<2,4> JV2 = JV23.contract((Tpqbar + TAB),2)/(s3AB);
// g->qqW Current. Note Minus between terms due to momentum flow.
// Also note: (-I)^2 from W vert. (I) from Quark prop.
Tensor<1,4> JVCur = (JV1.contract(ABCur,1) - JV2.contract(ABCur,2))*COM(0.,-1.);
return JVCur;
}
// Helper Functions Calculate the Crossed Contribution
Tensor <2,4> MCrossW(CLHEP::HepLorentzVector pa,CLHEP::HepLorentzVector p1,CLHEP::HepLorentzVector pb,CLHEP::HepLorentzVector p4, CLHEP::HepLorentzVector pq,CLHEP::HepLorentzVector pqbar,CLHEP::HepLorentzVector pl,CLHEP::HepLorentzVector plbar, std::vector<HLV> partons, int nabove){
// Useful propagator factors
double s2AB=(pl+plbar+pq).m2();
double s3AB=(pl+plbar+pqbar).m2();
CLHEP::HepLorentzVector q1, q3;
q1=pa;
for(int i=0; i<nabove+1;i++){
q1=q1-partons.at(i);
}
q3 = q1 - pq - pqbar - pl - plbar;
double tcro1=(q3+pq).m2();
double tcro2=(q1-pqbar).m2();
Tensor<1,4> Tp1 = Construct1Tensor(p1);
Tensor<1,4> Tp4 = Construct1Tensor(p4);
Tensor<1,4> Tpa = Construct1Tensor(pa);
Tensor<1,4> Tpb = Construct1Tensor(pb);
Tensor<1,4> Tpq = Construct1Tensor(pq);
Tensor<1,4> Tpqbar = Construct1Tensor(pqbar);
Tensor<1,4> TAB = Construct1Tensor(pl+plbar);
Tensor<1,4> Tq1 = Construct1Tensor(q1);
Tensor<1,4> Tq3 = Construct1Tensor(q3);
Tensor<2,4> g=Metric();
// Define llx current.
Tensor<1,4> ABCur = TCurrent(pl, false, plbar,false);
//Blank 5 gamma Current
Tensor<5,4> J523 = T5Current(pq,false,pqbar,false);
// 4 gamma currents (with 1 contraction already).
Tensor<4,4> J_q3q = J523.contract((Tq3+Tpq),2);
Tensor<4,4> J_2AB = J523.contract((Tpq+TAB),2);
// Components of Crossed Vertex Contribution
Tensor<3,4> Xcro1 = J_q3q.contract((Tpqbar + TAB),3);
Tensor<3,4> Xcro2 = J_q3q.contract((Tq1-Tpqbar),3);
Tensor<3,4> Xcro3 = J_2AB.contract((Tq1-Tpqbar),3);
// Term Denominators Taken Care of at this stage
Tensor<2,4> Xcro1Cont = Xcro1.contract(ABCur,3)/(tcro1*s3AB);
Tensor<2,4> Xcro2Cont = Xcro2.contract(ABCur,2)/(tcro1*tcro2);
Tensor<2,4> Xcro3Cont = Xcro3.contract(ABCur,1)/(s2AB*tcro2);
//Initialise the Crossed Vertex Object
Tensor<2,4> Xcro(0.);
for(int mu=0; mu<4;mu++){
for(int nu=0;nu<4;nu++){
Xcro.Set(mu,nu, -(-Xcro1Cont.at(nu,mu)+Xcro2Cont.at(nu,mu)+Xcro3Cont.at(nu,mu)));
}
}
return Xcro;
}
// Helper Functions Calculate the Uncrossed Contribution
Tensor <2,4> MUncrossW(CLHEP::HepLorentzVector pa, CLHEP::HepLorentzVector p1, CLHEP::HepLorentzVector pb, CLHEP::HepLorentzVector p4, CLHEP::HepLorentzVector pq,CLHEP::HepLorentzVector pqbar,CLHEP::HepLorentzVector pl,CLHEP::HepLorentzVector plbar, std::vector<HLV> partons, int nabove){
double s2AB=(pl+plbar+pq).m2();
double s3AB=(pl+plbar+pqbar).m2();
CLHEP::HepLorentzVector q1, q3;
q1=pa;
for(int i=0; i<nabove+1;i++){
q1=q1-partons.at(i);
}
q3 = q1 - pl - plbar - pq - pqbar;
double tunc1 = (q1-pq).m2();
double tunc2 = (q3+pqbar).m2();
Tensor<1,4> Tp1 = Construct1Tensor(p1);
Tensor<1,4> Tp4 = Construct1Tensor(p4);
Tensor<1,4> Tpa = Construct1Tensor(pa);
Tensor<1,4> Tpb = Construct1Tensor(pb);
Tensor<1,4> Tpq = Construct1Tensor(pq);
Tensor<1,4> Tpqbar = Construct1Tensor(pqbar);
Tensor<1,4> TAB = Construct1Tensor(pl+plbar);
Tensor<1,4> Tq1 = Construct1Tensor(q1);
Tensor<1,4> Tq3 = Construct1Tensor(q3);
Tensor<2,4> g=Metric();
// Define llx current.
Tensor<1,4> ABCur = TCurrent(pl, false, plbar, false);
//Blank 5 gamma Current
Tensor<5,4> J523 = T5Current(pq,false,pqbar,false);
// 4 gamma currents (with 1 contraction already).
Tensor<4,4> J_2AB = J523.contract((Tpq+TAB),2);
Tensor<4,4> J_q1q = J523.contract((Tq1-Tpq),2);
// 2 Contractions taken care of.
Tensor<3,4> Xunc1 = J_2AB.contract((Tq3+Tpqbar),3);
Tensor<3,4> Xunc2 = J_q1q.contract((Tq3+Tpqbar),3);
Tensor<3,4> Xunc3 = J_q1q.contract((Tpqbar+TAB),3);
// Term Denominators Taken Care of at this stage
Tensor<2,4> Xunc1Cont = Xunc1.contract(ABCur,1)/(s2AB*tunc2);
Tensor<2,4> Xunc2Cont = Xunc2.contract(ABCur,2)/(tunc1*tunc2);
Tensor<2,4> Xunc3Cont = Xunc3.contract(ABCur,3)/(tunc1*s3AB);
//Initialise the Uncrossed Vertex Object
Tensor<2,4> Xunc(0.);
for(int mu=0; mu<4;mu++){
for(int nu=0;nu<4;nu++){
Xunc.Set(mu,nu,-(- Xunc1Cont.at(mu,nu)+Xunc2Cont.at(mu,nu) +Xunc3Cont.at(mu,nu)));
}
}
return Xunc;
}
// Helper Functions Calculate the g->qqxW (Eikonal) Contributions
Tensor <2,4> MSymW(CLHEP::HepLorentzVector pa,CLHEP::HepLorentzVector p1,CLHEP::HepLorentzVector pb,CLHEP::HepLorentzVector p4, CLHEP::HepLorentzVector pq,CLHEP::HepLorentzVector pqbar,CLHEP::HepLorentzVector pl,CLHEP::HepLorentzVector plbar, std::vector<HLV> partons, int nabove){
double sa2=(pa+pq).m2();
double s12=(p1+pq).m2();
double sa3=(pa+pqbar).m2();
double s13=(p1+pqbar).m2();
double saA=(pa+pl).m2();
double s1A=(p1+pl).m2();
double saB=(pa+plbar).m2();
double s1B=(p1+plbar).m2();
double sb2=(pb+pq).m2();
double s42=(p4+pq).m2();
double sb3=(pb+pqbar).m2();
double s43=(p4+pqbar).m2();
double sbA=(pb+pl).m2();
double s4A=(p4+pl).m2();
double sbB=(pb+plbar).m2();
double s4B=(p4+plbar).m2();
double s23AB=(pl+plbar+pq+pqbar).m2();
CLHEP::HepLorentzVector q1,q3;
q1=pa;
for(int i=0;i<nabove+1;i++){
q1-=partons.at(i);
}
q3=q1-pq-pqbar-plbar-pl;
double t1 = (q1).m2();
double t3 = (q3).m2();
//Define Tensors to be used
Tensor<1,4> Tp1 = Construct1Tensor(p1);
Tensor<1,4> Tp4 = Construct1Tensor(p4);
Tensor<1,4> Tpa = Construct1Tensor(pa);
Tensor<1,4> Tpb = Construct1Tensor(pb);
Tensor<1,4> Tpq = Construct1Tensor(pq);
Tensor<1,4> Tpqbar = Construct1Tensor(pqbar);
Tensor<1,4> TAB = Construct1Tensor(pl+plbar);
Tensor<1,4> Tq1 = Construct1Tensor(q1);
Tensor<1,4> Tq3 = Construct1Tensor(q3);
Tensor<2,4> g=Metric();
// g->qqW Current (Factors of sqrt2 dealt with in this function.)
Tensor<1,4> JV = gtqqxW(pq,pqbar,pl,plbar);
// 1a gluon emisson Contribution
Tensor<3,4> X1a = g.rightprod(Tp1*(t1/(s12+s13+s1A+s1B)) + Tpa*(t1/(sa2+sa3+saA+saB)));
Tensor<2,4> X1aCont = X1a.contract(JV,3);
//4b gluon emission Contribution
Tensor<3,4> X4b = g.rightprod(Tp4*(t3/(s42+s43+s4A+s4B)) + Tpb*(t3/(sb2+sb3+sbA+sbB)));
Tensor<2,4> X4bCont = X4b.contract(JV,3);
//Set up each term of 3G diagram.
Tensor<3,4> X3g1 = g.leftprod(Tq1+Tpq+Tpqbar+TAB);
Tensor<3,4> X3g2 = g.leftprod(Tq3-Tpq-Tpqbar-TAB);
Tensor<3,4> X3g3 = g.leftprod((Tq1+Tq3));
// Note the contraction of indices changes term by term
Tensor<2,4> X3g1Cont = X3g1.contract(JV,3);
Tensor<2,4> X3g2Cont = X3g2.contract(JV,2);
Tensor<2,4> X3g3Cont = X3g3.contract(JV,1);
// XSym is an amalgamation of x1a, X4b and X3g. Makes sense from a colour factor point of view.
Tensor<2,4>Xsym(0.);
for(int mu=0; mu<4;mu++){
for(int nu=0;nu<4;nu++){
Xsym.Set(mu,nu, (X3g1Cont.at(nu,mu) + X3g2Cont.at(mu,nu) - X3g3Cont.at(nu,mu))
+ (X1aCont.at(mu,nu) - X4bCont.at(mu,nu)) );
}
}
return Xsym/s23AB;
}
Tensor <2,4> MCross(CLHEP::HepLorentzVector pa, CLHEP::HepLorentzVector pq,CLHEP::HepLorentzVector pqbar, std::vector<HLV> partons, bool hq, int nabove){
CLHEP::HepLorentzVector q1;
q1=pa;
for(int i=0;i<nabove+1;i++){
q1-=partons.at(i);
}
double t2=(q1-pqbar).m2();
Tensor<1,4> Tq1 = Construct1Tensor(q1-pqbar);
//Blank 3 gamma Current
Tensor<3,4> J323 = T3Current(pq,hq,pqbar,hq);
// 2 gamma current (with 1 contraction already).
Tensor<2,4> XCroCont = J323.contract((Tq1),2)/(t2);
//Initialise the Crossed Vertex
Tensor<2,4> Xcro(0.);
for(int mu=0; mu<4;mu++){
for(int nu=0;nu<4;nu++){
Xcro.Set(mu,nu, (XCroCont.at(nu,mu)));
}
}
return Xcro;
}
// Helper Functions Calculate the Uncrossed Contribution
Tensor <2,4> MUncross(CLHEP::HepLorentzVector pa, CLHEP::HepLorentzVector pq,CLHEP::HepLorentzVector pqbar, std::vector<HLV> partons, bool hq, int nabove){
CLHEP::HepLorentzVector q1;
q1=pa;
for(int i=0;i<nabove+1;i++){
q1-=partons.at(i);
}
double t2 = (q1-pq).m2();
Tensor<1,4> Tq1 = Construct1Tensor(q1-pq);
//Blank 3 gamma Current
Tensor<3,4> J323 = T3Current(pq,hq,pqbar,hq);
// 2 gamma currents (with 1 contraction already).
Tensor<2,4> XUncCont = J323.contract((Tq1),2)/t2;
//Initialise the Uncrossed Vertex
Tensor<2,4> Xunc(0.);
for(int mu=0; mu<4;mu++){
for(int nu=0;nu<4;nu++){
Xunc.Set(mu,nu,-(XUncCont.at(mu,nu)));
}
}
return Xunc;
}
// Helper Functions Calculate the Eikonal Contributions
Tensor <2,4> MSym(CLHEP::HepLorentzVector pa,CLHEP::HepLorentzVector p1,CLHEP::HepLorentzVector pb,CLHEP::HepLorentzVector p4, CLHEP::HepLorentzVector pq,CLHEP::HepLorentzVector pqbar, std::vector<HLV> partons, bool hq, int nabove){
CLHEP::HepLorentzVector q1, q3;
q1=pa;
for(int i=0;i<nabove+1;i++){
q1-=partons.at(i);
}
q3 = q1-pq-pqbar;
double t1 = (q1).m2();
double t3 = (q3).m2();
double s23 = (pq+pqbar).m2();
double sa2 = (pa+pq).m2();
double sa3 = (pa+pqbar).m2();
double s12 = (p1+pq).m2();
double s13 = (p1+pqbar).m2();
double sb2 = (pb+pq).m2();
double sb3 = (pb+pqbar).m2();
double s42 = (p4+pq).m2();
double s43 = (p4+pqbar).m2();
//Define Tensors to be used
Tensor<1,4> Tp1 = Construct1Tensor(p1);
Tensor<1,4> Tp4 = Construct1Tensor(p4);
Tensor<1,4> Tpa = Construct1Tensor(pa);
Tensor<1,4> Tpb = Construct1Tensor(pb);
Tensor<1,4> Tpq = Construct1Tensor(pq);
Tensor<1,4> Tpqbar = Construct1Tensor(pqbar);
Tensor<1,4> Tq1 = Construct1Tensor(q1);
Tensor<1,4> Tq3 = Construct1Tensor(q3);
Tensor<2,4> g=Metric();
Tensor<1,4> qqxCur = TCurrent(pq, hq, pqbar, hq);
// // 1a gluon emisson Contribution
Tensor<3,4> X1a = g.rightprod(Tp1*(t1/(s12+s13))+Tpa*(t1/(sa2+sa3)));
Tensor<2,4> X1aCont = X1a.contract(qqxCur,3);
// //4b gluon emission Contribution
Tensor<3,4> X4b = g.rightprod(Tp4*(t3/(s42+s43)) + Tpb*(t3/(sb2+sb3)));
Tensor<2,4> X4bCont = X4b.contract(qqxCur,3);
// New Formulation Corresponding to New Analytics
Tensor<3,4> X3g1 = g.leftprod(Tq1+Tpq+Tpqbar);
Tensor<3,4> X3g2 = g.leftprod(Tq3-Tpq-Tpqbar);
Tensor<3,4> X3g3 = g.leftprod((Tq1+Tq3));
// Note the contraction of indices changes term by term
Tensor<2,4> X3g1Cont = X3g1.contract(qqxCur,3);
Tensor<2,4> X3g2Cont = X3g2.contract(qqxCur,2);
Tensor<2,4> X3g3Cont = X3g3.contract(qqxCur,1);
Tensor<2,4>Xsym(0.);
for(int mu=0; mu<4;mu++){
for(int nu=0;nu<4;nu++){
Xsym.Set(mu, nu, COM(0,1) * ( (X3g1Cont.at(nu,mu) + X3g2Cont.at(mu,nu)
- X3g3Cont.at(nu,mu)) + (X1aCont.at(mu,nu) - X4bCont.at(mu,nu)) ) );
}
}
return Xsym/s23;
}
Tensor <1,4> jW4bEmit(HLV pb, HLV p4, HLV pl, HLV plbar, bool aqlinepb){
// Build the external quark line W Emmision
Tensor<1,4> ABCurr = TCurrent(pl, false, plbar, false)/2;
Tensor<1,4> Tp4W = Construct1Tensor((p4+pl+plbar));//p4+pw
Tensor<1,4> TpbW = Construct1Tensor((pb-pl-plbar));//pb-pw
Tensor<3,4> J4bBlank;
if (aqlinepb){
J4bBlank = T3Current(pb,false,p4,false);
}
else{
J4bBlank = T3Current(p4,false,pb,false);
}
double t4AB = (p4+pl+plbar).m2();
double tbAB = (pb-pl-plbar).m2();
Tensor<2,4> J4b1 = (J4bBlank.contract(Tp4W,2))/t4AB;
Tensor<2,4> J4b2 = (J4bBlank.contract(TpbW,2))/tbAB;
Tensor<2,4> T4bmMom(0.);
if (aqlinepb){
for(int mu=0; mu<4;mu++){
for(int nu=0;nu<4;nu++){
T4bmMom.Set(mu,nu, (J4b1.at(nu,mu) + J4b2.at(mu,nu))*(COM(-1,0)));
}
}
}
else{
for(int mu=0; mu<4;mu++){
for(int nu=0;nu<4;nu++){
T4bmMom.Set(nu,mu, (J4b1.at(nu,mu) + J4b2.at(mu,nu)));
}
}
}
Tensor<1,4> T4bm = T4bmMom.contract(ABCurr,1);
return T4bm;
}
} // Anonymous Namespace helper functions
//Functions which can be called elsewhere (declarations in currents.hh).
// W+Jets Unordered Contributions
//qQ->qQWg_unob
double junobMWqQg (CLHEP::HepLorentzVector p1out, CLHEP::HepLorentzVector pe, CLHEP::HepLorentzVector pnu,CLHEP::HepLorentzVector p1in, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in, CLHEP::HepLorentzVector pg)
// Calculates the square of the current contractions for qQ->qenuQ scattering
// p1: quark (with W emittance)
// p2: Quark
{
CCurrent mj1m,mj2p,mj2m;
CLHEP::HepLorentzVector q1=p1in-p1out-pe-pnu;
CLHEP::HepLorentzVector q2=-(p2in-p2out-pg);
CLHEP::HepLorentzVector q3=-(p2in-p2out);
mj1m=jW(p1out,false,pe,false,pnu,false,p1in,false);
mj2p=j(p2out,true,p2in,true);
mj2m=j(p2out,false,p2in,false);
// Dot products of these which occur again and again
COM MWmp=mj1m.dot(mj2p); // And now for the Higgs ones
COM MWmm=mj1m.dot(mj2m);
CCurrent jgbm,jgbp,j2gm,j2gp;
j2gp=joo(p2out,true,pg,true);
j2gm=joo(p2out,false,pg,false);
jgbp=j(pg,true,p2in,true);
jgbm=j(pg,false,p2in,false);
CCurrent qsum(q2+q3);
CCurrent Lmp,Lmm,Lpp,Lpm,U1mp,U1mm,U1pp,U1pm,U2mp,U2mm,U2pp,U2pm,p1o(p1out),p1i(p1in);
CCurrent p2o(p2out);
CCurrent p2i(p2in);
Lmm=((-1.)*qsum*(MWmm) + (-2.*mj1m.dot(pg))*mj2m+2.*mj2m.dot(pg)*mj1m+(p1o/pg.dot(p1out) + p1i/pg.dot(p1in))*(q2.m2()*MWmm/2.))/q3.m2();
Lmp=((-1.)*qsum*(MWmp) + (-2.*mj1m.dot(pg))*mj2p+2.*mj2p.dot(pg)*mj1m+(p1o/pg.dot(p1out) + p1i/pg.dot(p1in))*(q2.m2()*MWmp/2.))/q3.m2();
U1mm=(jgbm.dot(mj1m)*j2gm+2.*p2o*MWmm)/(p2out+pg).m2();
U1mp=(jgbp.dot(mj1m)*j2gp+2.*p2o*MWmp)/(p2out+pg).m2();
U2mm=((-1.)*j2gm.dot(mj1m)*jgbm+2.*p2i*MWmm)/(p2in-pg).m2();
U2mp=((-1.)*j2gp.dot(mj1m)*jgbp+2.*p2i*MWmp)/(p2in-pg).m2();
const double cf=RHEJ::C_F;
double amm,amp;
amm=cf*(2.*vre(Lmm-U1mm,Lmm+U2mm))+2.*cf*cf/3.*vabs2(U1mm+U2mm);
amp=cf*(2.*vre(Lmp-U1mp,Lmp+U2mp))+2.*cf*cf/3.*vabs2(U1mp+U2mp);
double ampsq=-(amm+amp);
// Now add the t-channels
double th=q2.m2()*q1.m2();
ampsq/=th;
ampsq/=16.;
return ampsq;
}
//qQbar->qQbarWg_unob
double junobMWqQbarg (CLHEP::HepLorentzVector p1out, CLHEP::HepLorentzVector pe, CLHEP::HepLorentzVector pnu,CLHEP::HepLorentzVector p1in, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in, CLHEP::HepLorentzVector pg)
// Calculates the square of the current contractions for qQ->qenuQ scattering
// p1: quark (with W emittance)
// p2: Quark
{
CCurrent mj1m,mj2p,mj2m;
CLHEP::HepLorentzVector q1=p1in-p1out-pe-pnu;
CLHEP::HepLorentzVector q2=-(p2in-p2out-pg);
CLHEP::HepLorentzVector q3=-(p2in-p2out);
mj1m=jW(p1out,false,pe,false,pnu,false,p1in,false);
mj2p=jio(p2in,true,p2out,true);
mj2m=jio(p2in,false,p2out,false);
// Dot products of these which occur again and again
COM MWmp=mj1m.dot(mj2p); // And now for the Higgs ones
COM MWmm=mj1m.dot(mj2m);
CCurrent jgbm,jgbp,j2gm,j2gp;
j2gp=joo(pg,true,p2out,true);
j2gm=joo(pg,false,p2out,false);
jgbp=jio(p2in,true,pg,true);
jgbm=jio(p2in,false,pg,false);
CCurrent qsum(q2+q3);
CCurrent Lmp,Lmm,Lpp,Lpm,U1mp,U1mm,U1pp,U1pm,U2mp,U2mm,U2pp,U2pm,p1o(p1out),p1i(p1in);
CCurrent p2o(p2out);
CCurrent p2i(p2in);
Lmm=((-1.)*qsum*(MWmm) + (-2.*mj1m.dot(pg))*mj2m+2.*mj2m.dot(pg)*mj1m+(p1o/pg.dot(p1out) + p1i/pg.dot(p1in))*(q2.m2()*MWmm/2.))/q3.m2();
Lmp=((-1.)*qsum*(MWmp) + (-2.*mj1m.dot(pg))*mj2p+2.*mj2p.dot(pg)*mj1m+(p1o/pg.dot(p1out) + p1i/pg.dot(p1in))*(q2.m2()*MWmp/2.))/q3.m2();
U1mm=(jgbm.dot(mj1m)*j2gm+2.*p2o*MWmm)/(p2out+pg).m2();
U1mp=(jgbp.dot(mj1m)*j2gp+2.*p2o*MWmp)/(p2out+pg).m2();
U2mm=((-1.)*j2gm.dot(mj1m)*jgbm+2.*p2i*MWmm)/(p2in-pg).m2();
U2mp=((-1.)*j2gp.dot(mj1m)*jgbp+2.*p2i*MWmp)/(p2in-pg).m2();
const double cf=RHEJ::C_F;
double amm,amp;
amm=cf*(2.*vre(Lmm-U1mm,Lmm+U2mm))+2.*cf*cf/3.*vabs2(U1mm+U2mm);
amp=cf*(2.*vre(Lmp-U1mp,Lmp+U2mp))+2.*cf*cf/3.*vabs2(U1mp+U2mp);
double ampsq=-(amm+amp);
// Now add the t-channels
double th=q2.m2()*q1.m2();
ampsq/=th;
ampsq/=16.;
return ampsq;
}
//qbarQ->qbarQWg_unob
double junobMWqbarQg (CLHEP::HepLorentzVector p1out, CLHEP::HepLorentzVector pe, CLHEP::HepLorentzVector pnu,CLHEP::HepLorentzVector p1in, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in, CLHEP::HepLorentzVector pg)
// Calculates the square of the current contractions for qQ->qenuQ scattering
// p1: quark (with W emittance)
// p2: Quark
{
CCurrent mj1m,mj2p,mj2m;
CLHEP::HepLorentzVector q1=p1in-p1out-pe-pnu;
CLHEP::HepLorentzVector q2=-(p2in-p2out-pg);
CLHEP::HepLorentzVector q3=-(p2in-p2out);
mj1m=jWbar(p1out,false,pe,false,pnu,false,p1in,false);
mj2p=j(p2out,true,p2in,true);
mj2m=j(p2out,false,p2in,false);
// Dot products of these which occur again and again
COM MWmp=mj1m.dot(mj2p); // And now for the Higgs ones
COM MWmm=mj1m.dot(mj2m);
CCurrent jgbm,jgbp,j2gm,j2gp;
j2gp=joo(p2out,true,pg,true);
j2gm=joo(p2out,false,pg,false);
jgbp=j(pg,true,p2in,true);
jgbm=j(pg,false,p2in,false);
CCurrent qsum(q2+q3);
CCurrent Lmp,Lmm,Lpp,Lpm,U1mp,U1mm,U1pp,U1pm,U2mp,U2mm,U2pp,U2pm,p1o(p1out),p1i(p1in);
CCurrent p2o(p2out);
CCurrent p2i(p2in);
Lmm=((-1.)*qsum*(MWmm) + (-2.*mj1m.dot(pg))*mj2m+2.*mj2m.dot(pg)*mj1m+(p1o/pg.dot(p1out) + p1i/pg.dot(p1in))*(q2.m2()*MWmm/2.))/q3.m2();
Lmp=((-1.)*qsum*(MWmp) + (-2.*mj1m.dot(pg))*mj2p+2.*mj2p.dot(pg)*mj1m+(p1o/pg.dot(p1out) + p1i/pg.dot(p1in))*(q2.m2()*MWmp/2.))/q3.m2();
U1mm=(jgbm.dot(mj1m)*j2gm+2.*p2o*MWmm)/(p2out+pg).m2();
U1mp=(jgbp.dot(mj1m)*j2gp+2.*p2o*MWmp)/(p2out+pg).m2();
U2mm=((-1.)*j2gm.dot(mj1m)*jgbm+2.*p2i*MWmm)/(p2in-pg).m2();
U2mp=((-1.)*j2gp.dot(mj1m)*jgbp+2.*p2i*MWmp)/(p2in-pg).m2();
const double cf=RHEJ::C_F;
double amm,amp;
amm=cf*(2.*vre(Lmm-U1mm,Lmm+U2mm))+2.*cf*cf/3.*vabs2(U1mm+U2mm);
amp=cf*(2.*vre(Lmp-U1mp,Lmp+U2mp))+2.*cf*cf/3.*vabs2(U1mp+U2mp);
double ampsq=-(amm+amp);
// Now add the t-channels
double th=q2.m2()*q1.m2();
ampsq/=th;
ampsq/=16.;
return ampsq;
}
//qbarQbar->qbarQbarWg_unob
double junobMWqbarQbarg (CLHEP::HepLorentzVector p1out, CLHEP::HepLorentzVector pe, CLHEP::HepLorentzVector pnu,CLHEP::HepLorentzVector p1in, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in, CLHEP::HepLorentzVector pg)
// Calculates the square of the current contractions for qQ->qenuQ scattering
// p1: quark (with W emittance)
// p2: Quark
{
CCurrent mj1m,mj2p,mj2m;
CLHEP::HepLorentzVector q1=p1in-p1out-pe-pnu;
CLHEP::HepLorentzVector q2=-(p2in-p2out-pg);
CLHEP::HepLorentzVector q3=-(p2in-p2out);
mj1m=jWbar(p1out,false,pe,false,pnu,false,p1in,false);
mj2p=jio(p2in,true,p2out,true);
mj2m=jio(p2in,false,p2out,false);
// Dot products of these which occur again and again
COM MWmp=mj1m.dot(mj2p); // And now for the Higgs ones
COM MWmm=mj1m.dot(mj2m);
CCurrent jgbm,jgbp,j2gm,j2gp;
j2gp=joo(pg,true,p2out,true);
j2gm=joo(pg,false,p2out,false);
jgbp=jio(p2in,true,pg,true);
jgbm=jio(p2in,false,pg,false);
CCurrent qsum(q2+q3);
CCurrent Lmp,Lmm,Lpp,Lpm,U1mp,U1mm,U1pp,U1pm,U2mp,U2mm,U2pp,U2pm,p1o(p1out),p1i(p1in);
CCurrent p2o(p2out);
CCurrent p2i(p2in);
Lmm=((-1.)*qsum*(MWmm) + (-2.*mj1m.dot(pg))*mj2m+2.*mj2m.dot(pg)*mj1m+(p1o/pg.dot(p1out) + p1i/pg.dot(p1in))*(q2.m2()*MWmm/2.))/q3.m2();
Lmp=((-1.)*qsum*(MWmp) + (-2.*mj1m.dot(pg))*mj2p+2.*mj2p.dot(pg)*mj1m+(p1o/pg.dot(p1out) + p1i/pg.dot(p1in))*(q2.m2()*MWmp/2.))/q3.m2();
U1mm=(jgbm.dot(mj1m)*j2gm+2.*p2o*MWmm)/(p2out+pg).m2();
U1mp=(jgbp.dot(mj1m)*j2gp+2.*p2o*MWmp)/(p2out+pg).m2();
U2mm=((-1.)*j2gm.dot(mj1m)*jgbm+2.*p2i*MWmm)/(p2in-pg).m2();
U2mp=((-1.)*j2gp.dot(mj1m)*jgbp+2.*p2i*MWmp)/(p2in-pg).m2();
const double cf=RHEJ::C_F;
double amm,amp;
amm=cf*(2.*vre(Lmm-U1mm,Lmm+U2mm))+2.*cf*cf/3.*vabs2(U1mm+U2mm);
amp=cf*(2.*vre(Lmp-U1mp,Lmp+U2mp))+2.*cf*cf/3.*vabs2(U1mp+U2mp);
double ampsq=-(amm+amp);
// Now add the t-channels
double th=q2.m2()*q1.m2();
ampsq/=th;
ampsq/=16.;
return ampsq;
}
////////////////////////////////////////////////////////////////////
//qQ->qQWg_unof
double junofMWgqQ (CLHEP::HepLorentzVector pg,CLHEP::HepLorentzVector p1out,CLHEP::HepLorentzVector p1in, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector pe, CLHEP::HepLorentzVector pnu, CLHEP::HepLorentzVector p2in)
// Calculates the square of the current contractions for qQ->qenuQ scattering
// p1: quark (with W emittance)
// p2: Quark
{
CCurrent mj2m,mj1p,mj1m;
CLHEP::HepLorentzVector q1=p1in-p1out;
CLHEP::HepLorentzVector qg=p1in-p1out-pg;
CLHEP::HepLorentzVector q2=-(p2in-p2out-pe-pnu);
mj2m=jW(p2out,false,pe,false,pnu,false,p2in,false);
mj1p=j(p1out,true,p1in,true);
mj1m=j(p1out,false,p1in,false);
// Dot products of these which occur again and again
COM MWpm=mj1p.dot(mj2m); // And now for the Higgs ones
COM MWmm=mj1m.dot(mj2m);
CCurrent jgam,jgap,j2gm,j2gp;
j2gp=joo(p1out,true,pg,true);
j2gm=joo(p1out,false,pg,false);
jgap=j(pg,true,p1in,true);
jgam=j(pg,false,p1in,false);
CCurrent qsum(q1+qg);
CCurrent Lmp,Lmm,Lpp,Lpm,U1mp,U1mm,U1pp,U1pm,U2mp,U2mm,U2pp,U2pm,p2o(p2out),p2i(p2in);
CCurrent p1o(p1out);
CCurrent p1i(p1in);
Lmm=(qsum*(MWmm) + (-2.*mj2m.dot(pg))*mj1m+2.*mj1m.dot(pg)*mj2m+(p2o/pg.dot(p2out) + p2i/pg.dot(p2in))*(qg.m2()*MWmm/2.))/q1.m2();
Lpm=(qsum*(MWpm) + (-2.*mj2m.dot(pg))*mj1p+2.*mj1p.dot(pg)*mj2m+(p2o/pg.dot(p2out) + p2i/pg.dot(p2in))*(qg.m2()*MWpm/2.))/q1.m2();
U1mm=(jgam.dot(mj2m)*j2gm+2.*p1o*MWmm)/(p1out+pg).m2();
U1pm=(jgap.dot(mj2m)*j2gp+2.*p1o*MWpm)/(p1out+pg).m2();
U2mm=((-1.)*j2gm.dot(mj2m)*jgam+2.*p1i*MWmm)/(p1in-pg).m2();
U2pm=((-1.)*j2gp.dot(mj2m)*jgap+2.*p1i*MWpm)/(p1in-pg).m2();
const double cf=RHEJ::C_F;
double amm,apm;
amm=cf*(2.*vre(Lmm-U1mm,Lmm+U2mm))+2.*cf*cf/3.*vabs2(U1mm+U2mm);
apm=cf*(2.*vre(Lpm-U1pm,Lpm+U2pm))+2.*cf*cf/3.*vabs2(U1pm+U2pm);
double ampsq=-(apm+amm);
// Now add the t-channels
double th=q2.m2()*qg.m2();
ampsq/=th;
ampsq/=16.;
return ampsq;
}
//qQbar->qQbarWg_unof
double junofMWgqQbar (CLHEP::HepLorentzVector pg,CLHEP::HepLorentzVector p1out,CLHEP::HepLorentzVector p1in, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector pe, CLHEP::HepLorentzVector pnu, CLHEP::HepLorentzVector p2in)
// Calculates the square of the current contractions for qQ->qenuQ scattering
// p1: quark (with W emittance)
// p2: Quark
{
CCurrent mj2m,mj1p,mj1m;
CLHEP::HepLorentzVector q1=p1in-p1out;
CLHEP::HepLorentzVector qg=p1in-p1out-pg;
CLHEP::HepLorentzVector q2=-(p2in-p2out-pe-pnu);
mj2m=jWbar(p2out,false,pe,false,pnu,false,p2in,false);
mj1p=j(p1out,true,p1in,true);
mj1m=j(p1out,false,p1in,false);
// Dot products of these which occur again and again
COM MWpm=mj1p.dot(mj2m); // And now for the Higgs ones
COM MWmm=mj1m.dot(mj2m);
CCurrent jgam,jgap,j2gm,j2gp;
j2gp=joo(p1out,true,pg,true);
j2gm=joo(p1out,false,pg,false);
jgap=j(pg,true,p1in,true);
jgam=j(pg,false,p1in,false);
CCurrent qsum(q1+qg);
CCurrent Lmp,Lmm,Lpp,Lpm,U1mp,U1mm,U1pp,U1pm,U2mp,U2mm,U2pp,U2pm,p2o(p2out),p2i(p2in);
CCurrent p1o(p1out);
CCurrent p1i(p1in);
Lmm=(qsum*(MWmm) + (-2.*mj2m.dot(pg))*mj1m+2.*mj1m.dot(pg)*mj2m+(p2o/pg.dot(p2out) + p2i/pg.dot(p2in))*(qg.m2()*MWmm/2.))/q1.m2();
Lpm=(qsum*(MWpm) + (-2.*mj2m.dot(pg))*mj1p+2.*mj1p.dot(pg)*mj2m+(p2o/pg.dot(p2out) + p2i/pg.dot(p2in))*(qg.m2()*MWpm/2.))/q1.m2();
U1mm=(jgam.dot(mj2m)*j2gm+2.*p1o*MWmm)/(p1out+pg).m2();
U1pm=(jgap.dot(mj2m)*j2gp+2.*p1o*MWpm)/(p1out+pg).m2();
U2mm=((-1.)*j2gm.dot(mj2m)*jgam+2.*p1i*MWmm)/(p1in-pg).m2();
U2pm=((-1.)*j2gp.dot(mj2m)*jgap+2.*p1i*MWpm)/(p1in-pg).m2();
const double cf=RHEJ::C_F;
double amm,apm;
amm=cf*(2.*vre(Lmm-U1mm,Lmm+U2mm))+2.*cf*cf/3.*vabs2(U1mm+U2mm);
apm=cf*(2.*vre(Lpm-U1pm,Lpm+U2pm))+2.*cf*cf/3.*vabs2(U1pm+U2pm);
double ampsq=-(apm+amm);
// Now add the t-channels
double th=q2.m2()*qg.m2();
ampsq/=th;
ampsq/=16.;
return ampsq;
}
//qbarQ->qbarQWg_unof
double junofMWgqbarQ (CLHEP::HepLorentzVector pg,CLHEP::HepLorentzVector p1out,CLHEP::HepLorentzVector p1in, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector pe, CLHEP::HepLorentzVector pnu, CLHEP::HepLorentzVector p2in)
// Calculates the square of the current contractions for qQ->qenuQ scattering
// p1: quark (with W emittance)
// p2: Quark
{
CCurrent mj2m,mj1p,mj1m;
CLHEP::HepLorentzVector q1=p1in-p1out;
CLHEP::HepLorentzVector qg=p1in-p1out-pg;
CLHEP::HepLorentzVector q2=-(p2in-p2out-pe-pnu);
mj2m=jW(p2out,false,pe,false,pnu,false,p2in,false);
mj1p=jio(p1in,true,p1out,true);
mj1m=jio(p1in,false,p1out,false);
// Dot products of these which occur again and again
COM MWpm=mj1p.dot(mj2m); // And now for the Higgs ones
COM MWmm=mj1m.dot(mj2m);
CCurrent jgam,jgap,j2gm,j2gp;
j2gp=joo(pg,true,p1out,true);
j2gm=joo(pg,false,p1out,false);
jgap=jio(p1in,true,pg,true);
jgam=jio(p1in,false,pg,false);
CCurrent qsum(q1+qg);
CCurrent Lmp,Lmm,Lpp,Lpm,U1mp,U1mm,U1pp,U1pm,U2mp,U2mm,U2pp,U2pm,p2o(p2out),p2i(p2in);
CCurrent p1o(p1out);
CCurrent p1i(p1in);
Lmm=(qsum*(MWmm) + (-2.*mj2m.dot(pg))*mj1m+2.*mj1m.dot(pg)*mj2m+(p2o/pg.dot(p2out) + p2i/pg.dot(p2in))*(qg.m2()*MWmm/2.))/q1.m2();
Lpm=(qsum*(MWpm) + (-2.*mj2m.dot(pg))*mj1p+2.*mj1p.dot(pg)*mj2m+(p2o/pg.dot(p2out) + p2i/pg.dot(p2in))*(qg.m2()*MWpm/2.))/q1.m2();
U1mm=(jgam.dot(mj2m)*j2gm+2.*p1o*MWmm)/(p1out+pg).m2();
U1pm=(jgap.dot(mj2m)*j2gp+2.*p1o*MWpm)/(p1out+pg).m2();
U2mm=((-1.)*j2gm.dot(mj2m)*jgam+2.*p1i*MWmm)/(p1in-pg).m2();
U2pm=((-1.)*j2gp.dot(mj2m)*jgap+2.*p1i*MWpm)/(p1in-pg).m2();
const double cf=RHEJ::C_F;
double amm,apm;
amm=cf*(2.*vre(Lmm-U1mm,Lmm+U2mm))+2.*cf*cf/3.*vabs2(U1mm+U2mm);
apm=cf*(2.*vre(Lpm-U1pm,Lpm+U2pm))+2.*cf*cf/3.*vabs2(U1pm+U2pm);
double ampsq=-(apm+amm);
// Now add the t-channels
double th=q2.m2()*qg.m2();
ampsq/=th;
ampsq/=16.;
return ampsq;
}
//qbarQbar->qbarQbarWg_unof
double junofMWgqbarQbar (CLHEP::HepLorentzVector pg,CLHEP::HepLorentzVector p1out,CLHEP::HepLorentzVector p1in, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector pe, CLHEP::HepLorentzVector pnu, CLHEP::HepLorentzVector p2in)
// Calculates the square of the current contractions for qQ->qenuQ scattering
// p1: quark (with W emittance)
// p2: Quark
{
CCurrent mj2m,mj1p,mj1m;
CLHEP::HepLorentzVector q1=p1in-p1out;
CLHEP::HepLorentzVector qg=p1in-p1out-pg;
CLHEP::HepLorentzVector q2=-(p2in-p2out-pe-pnu);
mj2m=jWbar(p2out,false,pe,false,pnu,false,p2in,false);
mj1p=jio(p1in,true,p1out,true);
mj1m=jio(p1in,false,p1out,false);
// Dot products of these which occur again and again
COM MWpm=mj1p.dot(mj2m); // And now for the Higgs ones
COM MWmm=mj1m.dot(mj2m);
CCurrent jgam,jgap,j2gm,j2gp;
j2gp=joo(pg,true,p1out,true);
j2gm=joo(pg,false,p1out,false);
jgap=jio(p1in,true,pg,true);
jgam=jio(p1in,false,pg,false);
CCurrent qsum(q1+qg);
CCurrent Lmp,Lmm,Lpp,Lpm,U1mp,U1mm,U1pp,U1pm,U2mp,U2mm,U2pp,U2pm,p2o(p2out),p2i(p2in);
CCurrent p1o(p1out);
CCurrent p1i(p1in);
Lmm=(qsum*(MWmm) + (-2.*mj2m.dot(pg))*mj1m+2.*mj1m.dot(pg)*mj2m+(p2o/pg.dot(p2out) + p2i/pg.dot(p2in))*(qg.m2()*MWmm/2.))/q1.m2();
Lpm=(qsum*(MWpm) + (-2.*mj2m.dot(pg))*mj1p+2.*mj1p.dot(pg)*mj2m+(p2o/pg.dot(p2out) + p2i/pg.dot(p2in))*(qg.m2()*MWpm/2.))/q1.m2();
U1mm=(jgam.dot(mj2m)*j2gm+2.*p1o*MWmm)/(p1out+pg).m2();
U1pm=(jgap.dot(mj2m)*j2gp+2.*p1o*MWpm)/(p1out+pg).m2();
U2mm=((-1.)*j2gm.dot(mj2m)*jgam+2.*p1i*MWmm)/(p1in-pg).m2();
U2pm=((-1.)*j2gp.dot(mj2m)*jgap+2.*p1i*MWpm)/(p1in-pg).m2();
const double cf=RHEJ::C_F;
double amm,apm;
amm=cf*(2.*vre(Lmm-U1mm,Lmm+U2mm))+2.*cf*cf/3.*vabs2(U1mm+U2mm);
apm=cf*(2.*vre(Lpm-U1pm,Lpm+U2pm))+2.*cf*cf/3.*vabs2(U1pm+U2pm);
double ampsq=-(apm+amm);
// Now add the t-channels
double th=q2.m2()*qg.m2();
ampsq/=th;
ampsq/=16.;
return ampsq;
}
///TODO make this comment more visible
/// Naming scheme jM2-Wuno-g-({q/qbar}{Q/Qbar/g})
///TODO Spit naming for more complicated functions?
/// e.g. jM2WqqtoqQQq -> jM2_Wqq_to_qQQq
double jM2WunogqQ(CLHEP::HepLorentzVector pg, CLHEP::HepLorentzVector p1out,CLHEP::HepLorentzVector plbar,CLHEP::HepLorentzVector pl, CLHEP::HepLorentzVector p1in, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in)
{
//COM temp;
double ME2mpp=0.;
double ME2mpm=0.;
double ME2mmp=0.;
double ME2mmm=0.;
double ME2;
ME2mpp = jM2Wuno(pg, p1out,plbar,pl,p1in,false,p2out,p2in,true,true);
ME2mpm = jM2Wuno(pg, p1out,plbar,pl,p1in,false,p2out,p2in,true,false);
ME2mmp = jM2Wuno(pg, p1out,plbar,pl,p1in,false,p2out,p2in,false,true);
ME2mmm = jM2Wuno(pg, p1out,plbar,pl,p1in,false,p2out,p2in,false,false);
//Helicity sum
ME2 = ME2mpp + ME2mpm + ME2mmp + ME2mmm;
return ME2;
}
//same as function above but actually obtaining the antiquark line by crossing symmetry, where p1out and p1in are expected to be negative.
//should give same result as jM2WunogqbarQ below (verified)
double jM2WunogqQ_crossqQ(CLHEP::HepLorentzVector pg, CLHEP::HepLorentzVector p1out,CLHEP::HepLorentzVector plbar,CLHEP::HepLorentzVector pl, CLHEP::HepLorentzVector p1in, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in)
{
//COM temp;
double ME2mpp=0.;
double ME2mpm=0.;
double ME2mmp=0.;
double ME2mmm=0.;
double ME2;
ME2mpp = jM2Wuno(pg, p1out,plbar,pl,p1in,false,p2out,p2in,true,true);
ME2mpm = jM2Wuno(pg, p1out,plbar,pl,p1in,false,p2out,p2in,true,false);
ME2mmp = jM2Wuno(pg, p1out,plbar,pl,p1in,false,p2out,p2in,false,true);
ME2mmm = jM2Wuno(pg, p1out,plbar,pl,p1in,false,p2out,p2in,false,false);
//Helicity sum
ME2 = ME2mpp + ME2mpm + ME2mmp + ME2mmm;
return ME2;
}
double jM2WunogqQbar(CLHEP::HepLorentzVector pg, CLHEP::HepLorentzVector p1out,CLHEP::HepLorentzVector plbar,CLHEP::HepLorentzVector pl, CLHEP::HepLorentzVector p1in, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in)
{
//COM temp;
double ME2mpp=0.;
double ME2mpm=0.;
double ME2mmp=0.;
double ME2mmm=0.;
double ME2;
ME2mpp = jM2Wuno(pg, p1out,plbar,pl,p1in,false,p2out,p2in,true,true);
ME2mpm = jM2Wuno(pg, p1out,plbar,pl,p1in,false,p2out,p2in,true,false);
ME2mmp = jM2Wuno(pg, p1out,plbar,pl,p1in,false,p2out,p2in,false,true);
ME2mmm = jM2Wuno(pg, p1out,plbar,pl,p1in,false,p2out,p2in,false,false);
//Helicity sum
ME2 = ME2mpp + ME2mpm + ME2mmp + ME2mmm;
return ME2;
}
double jM2Wunogqg(CLHEP::HepLorentzVector pg, CLHEP::HepLorentzVector p1out,CLHEP::HepLorentzVector plbar,CLHEP::HepLorentzVector pl, CLHEP::HepLorentzVector p1in, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in)
{
//COM temp;
double ME2mpp=0.;
double ME2mpm=0.;
double ME2mmp=0.;
double ME2mmm=0.;
double ME2;
ME2mpp = jM2Wuno(pg, p1out,plbar,pl,p1in,false,p2out,p2in,true,true);
ME2mpm = jM2Wuno(pg, p1out,plbar,pl,p1in,false,p2out,p2in,true,false);
ME2mmp = jM2Wuno(pg, p1out,plbar,pl,p1in,false,p2out,p2in,false,true);
ME2mmm = jM2Wuno(pg, p1out,plbar,pl,p1in,false,p2out,p2in,false,false);
//Helicity sum
ME2 = ME2mpp + ME2mpm + ME2mmp + ME2mmm;
const double ca = RHEJ::C_A;
const double cf = RHEJ::C_F; ///<TODO directly use RHEJ constants
double ratio; // p2-/pb- in the notes
if (p2in.pz()>0.) // if the gluon is the positive
ratio=p2out.plus()/p2in.plus();
else // the gluon is the negative
ratio=p2out.minus()/p2in.minus();
double cam = ( (ca - 1/ca)*(ratio + 1./ratio)/2. + 1/ca)/cf;
ME2*=cam;
return ME2;
}
double jM2WunogqbarQ(CLHEP::HepLorentzVector pg, CLHEP::HepLorentzVector p1out,CLHEP::HepLorentzVector plbar,CLHEP::HepLorentzVector pl, CLHEP::HepLorentzVector p1in, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in)
{
//COM temp;
double ME2mpp=0.;
double ME2mpm=0.;
double ME2mmp=0.;
double ME2mmm=0.;
double ME2;
ME2mpp = jM2Wuno(pg, p1out,plbar,pl,p1in,true,p2out,p2in,true,true);
ME2mpm = jM2Wuno(pg, p1out,plbar,pl,p1in,true,p2out,p2in,true,false);
ME2mmp = jM2Wuno(pg, p1out,plbar,pl,p1in,true,p2out,p2in,false,true);
ME2mmm = jM2Wuno(pg, p1out,plbar,pl,p1in,true,p2out,p2in,false,false);
//Helicity sum
ME2 = ME2mpp + ME2mpm + ME2mmp + ME2mmm;
return ME2;
}
double jM2WunogqbarQbar(CLHEP::HepLorentzVector pg, CLHEP::HepLorentzVector p1out,CLHEP::HepLorentzVector plbar,CLHEP::HepLorentzVector pl, CLHEP::HepLorentzVector p1in, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in)
{
//COM temp;
double ME2mpp=0.;
double ME2mpm=0.;
double ME2mmp=0.;
double ME2mmm=0.;
double ME2;
ME2mpp = jM2Wuno(pg, p1out,plbar,pl,p1in,true,p2out,p2in,true,true);
ME2mpm = jM2Wuno(pg, p1out,plbar,pl,p1in,true,p2out,p2in,true,false);
ME2mmp = jM2Wuno(pg, p1out,plbar,pl,p1in,true,p2out,p2in,false,true);
ME2mmm = jM2Wuno(pg, p1out,plbar,pl,p1in,true,p2out,p2in,false,false);
//Helicity sum
ME2 = ME2mpp + ME2mpm + ME2mmp + ME2mmm;
return ME2;
}
double jM2Wunogqbarg(CLHEP::HepLorentzVector pg, CLHEP::HepLorentzVector p1out,CLHEP::HepLorentzVector plbar,CLHEP::HepLorentzVector pl, CLHEP::HepLorentzVector p1in, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in)
{
//COM temp;
double ME2mpp=0.;
double ME2mpm=0.;
double ME2mmp=0.;
double ME2mmm=0.;
double ME2;
ME2mpp = jM2Wuno(pg, p1out,plbar,pl,p1in,true,p2out,p2in,true,true);
ME2mpm = jM2Wuno(pg, p1out,plbar,pl,p1in,true,p2out,p2in,true,false);
ME2mmp = jM2Wuno(pg, p1out,plbar,pl,p1in,true,p2out,p2in,false,true);
ME2mmm = jM2Wuno(pg, p1out,plbar,pl,p1in,true,p2out,p2in,false,false);
//Helicity sum
ME2 = ME2mpp + ME2mpm + ME2mmp + ME2mmm;
const double ca = RHEJ::C_A;
const double cf = RHEJ::C_F; ///<TODO directly use RHEJ constants
double ratio; // p2-/pb- in the notes
if (p2in.pz()>0.) // if the gluon is the positive
ratio=p2out.plus()/p2in.plus();
else // the gluon is the negative
ratio=p2out.minus()/p2in.minus();
double cam = ( (ca - 1/ca)*(ratio + 1./ratio)/2. + 1/ca)/cf;
ME2*=cam;
return ME2;
}
// W+Jets qqxExtremal
// W+Jets qqxExtremal Currents - wqq emission
double jM2WgQtoqbarqQ(CLHEP::HepLorentzVector pgin, CLHEP::HepLorentzVector pqout,CLHEP::HepLorentzVector plbar,CLHEP::HepLorentzVector pl, CLHEP::HepLorentzVector pqbarout, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in)
{
//COM temp;
double ME2mpp=0.;
double ME2mpm=0.;
double ME2mmp=0.;
double ME2mmm=0.;
double ME2;
ME2mpp = jM2Wuno(-pgin, pqout,plbar,pl,-pqbarout,false,p2out,p2in,true,true);
ME2mpm = jM2Wuno(-pgin, pqout,plbar,pl,-pqbarout,false,p2out,p2in,true,false);
ME2mmp = jM2Wuno(-pgin, pqout,plbar,pl,-pqbarout,false,p2out,p2in,false,true);
ME2mmm = jM2Wuno(-pgin, pqout,plbar,pl,-pqbarout,false,p2out,p2in,false,false);
//Helicity sum
ME2 = ME2mpp + ME2mpm + ME2mmp + ME2mmm;
//Correct colour averaging
ME2*=(3.0/8.0);
return ME2;
}
double jM2WgQtoqqbarQ(CLHEP::HepLorentzVector pgin, CLHEP::HepLorentzVector pqbarout,CLHEP::HepLorentzVector plbar,CLHEP::HepLorentzVector pl, CLHEP::HepLorentzVector pqout, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in){
//COM temp;
double ME2mpp=0.;
double ME2mpm=0.;
double ME2mmp=0.;
double ME2mmm=0.;
double ME2;
ME2mpp = jM2Wuno(-pgin, pqbarout,plbar,pl,-pqout,true,p2out,p2in,true,true);
ME2mpm = jM2Wuno(-pgin, pqbarout,plbar,pl,-pqout,true,p2out,p2in,true,false);
ME2mmp = jM2Wuno(-pgin, pqbarout,plbar,pl,-pqout,true,p2out,p2in,false,true);
ME2mmm = jM2Wuno(-pgin, pqbarout,plbar,pl,-pqout,true,p2out,p2in,false,false);
//Helicity sum
ME2 = ME2mpp + ME2mpm + ME2mmp + ME2mmm;
//Correct colour averaging
ME2*=(3.0/8.0);
return ME2;
}
double jM2Wggtoqbarqg(CLHEP::HepLorentzVector pgin, CLHEP::HepLorentzVector pqout,CLHEP::HepLorentzVector plbar,CLHEP::HepLorentzVector pl, CLHEP::HepLorentzVector pqbarout, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in)
{
//COM temp;
double ME2mpp=0.;
double ME2mpm=0.;
double ME2mmp=0.;
double ME2mmm=0.;
double ME2;
ME2mpp = jM2Wuno(-pgin, pqout,plbar,pl,-pqbarout,false,p2out,p2in,true,true);
ME2mpm = jM2Wuno(-pgin, pqout,plbar,pl,-pqbarout,false,p2out,p2in,true,false);
ME2mmp = jM2Wuno(-pgin, pqout,plbar,pl,-pqbarout,false,p2out,p2in,false,true);
ME2mmm = jM2Wuno(-pgin, pqout,plbar,pl,-pqbarout,false,p2out,p2in,false,false);
//Helicity sum
ME2 = ME2mpp + ME2mpm + ME2mmp + ME2mmm;
const double ca = RHEJ::C_A;
const double cf = RHEJ::C_F; ///<TODO directly use RHEJ constants
double ratio; // p2-/pb- in the notes
if (p2in.pz()>0.) // if the gluon is the positive
ratio=p2out.plus()/p2in.plus();
else // the gluon is the negative
ratio=p2out.minus()/p2in.minus();
double cam = ( (ca - 1/ca)*(ratio + 1./ratio)/2. + 1/ca)/cf;
ME2*=cam;
//Correct colour averaging
ME2*=(3.0/8.0);
return ME2;
}
double jM2Wggtoqqbarg(CLHEP::HepLorentzVector pgin, CLHEP::HepLorentzVector pqbarout,CLHEP::HepLorentzVector plbar,CLHEP::HepLorentzVector pl, CLHEP::HepLorentzVector pqout, CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in){
//COM temp;
double ME2mpp=0.;
double ME2mpm=0.;
double ME2mmp=0.;
double ME2mmm=0.;
double ME2;
ME2mpp = jM2Wuno(-pgin, pqbarout,plbar,pl,-pqout,true,p2out,p2in,true,true);
ME2mpm = jM2Wuno(-pgin, pqbarout,plbar,pl,-pqout,true,p2out,p2in,true,false);
ME2mmp = jM2Wuno(-pgin, pqbarout,plbar,pl,-pqout,true,p2out,p2in,false,true);
ME2mmm = jM2Wuno(-pgin, pqbarout,plbar,pl,-pqout,true,p2out,p2in,false,false);
//Helicity sum
ME2 = ME2mpp + ME2mpm + ME2mmp + ME2mmm;
const double ca = RHEJ::C_A;
const double cf = RHEJ::C_F; ///<TODO directly use RHEJ constants
double ratio; // p2-/pb- in the notes
if (p2in.pz()>0.) // if the gluon is the positive
ratio=p2out.plus()/p2in.plus();
else // the gluon is the negative
ratio=p2out.minus()/p2in.minus();
double cam = ( (ca - 1/ca)*(ratio + 1./ratio)/2. + 1/ca)/cf;
ME2*=cam;
//Correct colour averaging
ME2*=(3.0/8.0);
return ME2;
}
namespace {
//First, a function for generating polarisation tensors. Output as 'current'.
void eps(CLHEP::HepLorentzVector refmom, CLHEP::HepLorentzVector kb, bool hel, current &ep){
current curm,curp;
//Recall - positive helicity eps has negative helicity choices for spinors and vice versa
j(refmom,true,kb,true,curm);
j(refmom,false,kb,false,curp);
double norm=1.;
if(kb.z()<0.)
norm *= sqrt(2.*refmom.plus()*kb.minus());
if(kb.z()>0.)
norm = sqrt(2.*refmom.minus()*kb.plus());
if(hel==false){
ep[0] = curm[0]/norm;
ep[1] = curm[1]/norm;
ep[2] = curm[2]/norm;
ep[3] = curm[3]/norm;
}
if(hel==true){
ep[0] = curp[0]/norm;
ep[1] = curp[1]/norm;
ep[2] = curp[2]/norm;
ep[3] = curp[3]/norm;
}
}
//Now build up each part of the squared amplitude
COM qWggm1(CLHEP::HepLorentzVector pa, CLHEP::HepLorentzVector pb, CLHEP::HepLorentzVector p1, CLHEP::HepLorentzVector p2, CLHEP::HepLorentzVector p3, CLHEP::HepLorentzVector pl, CLHEP::HepLorentzVector plbar, bool helchain, bool heltop, bool helb,CLHEP::HepLorentzVector refmom){
current cur33, cur23, curb3, cur2b, ep;
joo(p3, helchain, p3, helchain,cur33);
joo(p2,helchain,p3,helchain,cur23);
jio(pb,helchain,p3,helchain,curb3);
joi(p2,helchain,pb,helchain,cur2b);
// Build the external quark line W Emmision
Tensor<1,4> ABCurr = TCurrent(pl, false, plbar, false);
Tensor<1,4> Tp1W = Construct1Tensor((p1+pl+plbar));//p1+pw
Tensor<1,4> TqaW = Construct1Tensor((pa-pl-plbar));//pa-pw
Tensor<3,4> J1aBlank = T3Current(p1,false,pa,false);
double t1AB = (p1+pl+plbar).m2();
double taAB = (pa-pl-plbar).m2();
Tensor<2,4> J1a1 = (J1aBlank.contract(Tp1W,2))/t1AB;
Tensor<2,4> J1a2 = (J1aBlank.contract(TqaW,2))/taAB;
Tensor<1,4> cur1a = J1a1.contract(ABCurr,1) + J1a2.contract(ABCurr,2);
double t2 = (p3-pb)*(p3-pb);
//Create vertex
COM v1[4][4];
for(int u=0; u<4;u++)
{
for(int v=0; v<4; v++)
{
v1[u][v]=(cur23[u]*cur33[v]-cur2b[u]*curb3[v])/t2*(-1.);
}
}
//Dot in current and eps
//Metric tensor
double eta[4][4]={};
eta[0][0]=1.;
eta[1][1]=-1.;
eta[2][2]=-1.;
eta[3][3]=-1.;
//eps
eps(refmom,pb,helb, ep);
COM M1=0.;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
for(int k=0; k<4; k++){
for(int l=0; l<4;l++){
M1+= eta[i][k]*cur1a.at(k)*(v1[i][j])*ep[l]*eta[l][j];
}
}
}
}
return M1;
}
COM qWggm2(CLHEP::HepLorentzVector pa, CLHEP::HepLorentzVector pb, CLHEP::HepLorentzVector p1, CLHEP::HepLorentzVector p2, CLHEP::HepLorentzVector p3, CLHEP::HepLorentzVector pl, CLHEP::HepLorentzVector plbar, bool helchain, bool heltop, bool helb,CLHEP::HepLorentzVector refmom){
current cur22, cur23, curb3, cur2b, ep;
joo(p2, helchain, p2, helchain,cur22);
joo(p2,helchain,p3,helchain,cur23);
jio(pb,helchain,p3,helchain,curb3);
joi(p2,helchain,pb,helchain,cur2b);
// Build the external quark line W Emmision
Tensor<1,4> ABCurr = TCurrent(pl, false, plbar, false);
Tensor<1,4> Tp1W = Construct1Tensor((p1+pl+plbar));//p1+pw
Tensor<1,4> TqaW = Construct1Tensor((pa-pl-plbar));//pa-pw
Tensor<3,4> J1aBlank = T3Current(p1,false,pa,false);
double t1AB = (p1+pl+plbar).m2();
double taAB = (pa-pl-plbar).m2();
Tensor<2,4> J1a1 = (J1aBlank.contract(Tp1W,2))/t1AB;
Tensor<2,4> J1a2 = (J1aBlank.contract(TqaW,2))/taAB;
Tensor<1,4> cur1a = J1a1.contract(ABCurr,1) + J1a2.contract(ABCurr,2);
double t2t = (p2-pb)*(p2-pb);
//Create vertex
COM v2[4][4]={};
for(int u=0; u<4;u++)
{
for(int v=0; v<4; v++)
{
v2[u][v]=(cur22[v]*cur23[u]-cur2b[v]*curb3[u])/t2t;
}
}
//Dot in current and eps
//Metric tensor
double eta[4][4]={};
eta[0][0]=1.;
eta[1][1]=-1.;
eta[2][2]=-1.;
eta[3][3]=-1.;
//eps
eps(refmom,pb,helb, ep);
COM M2=0.;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
for(int k=0; k<4; k++){
for(int l=0; l<4;l++){
M2+= eta[i][k]*cur1a.at(k)*(v2[i][j])*ep[l]*eta[l][j];
}
}
}
}
return M2;
}
COM qWggm3(CLHEP::HepLorentzVector pa, CLHEP::HepLorentzVector pb, CLHEP::HepLorentzVector p1, CLHEP::HepLorentzVector p2, CLHEP::HepLorentzVector p3, CLHEP::HepLorentzVector pl, CLHEP::HepLorentzVector plbar, bool helchain, bool heltop, bool helb,CLHEP::HepLorentzVector refmom){
//3 gluon vertex bit
double eta[4][4]={};
eta[0][0]=1.;
eta[1][1]=-1.;
eta[2][2]=-1.;
eta[3][3]=-1.;
current spincur,ep;
double s23 = (p2+p3)*(p2+p3);
joo(p2,helchain,p3,helchain,spincur);
// Build the external quark line W Emmision
Tensor<1,4> ABCurr = TCurrent(pl, false, plbar, false);
Tensor<1,4> Tp1W = Construct1Tensor((p1+pl+plbar));//p1+pw
Tensor<1,4> TqaW = Construct1Tensor((pa-pl-plbar));//pa-pw
Tensor<3,4> J1aBlank = T3Current(p1,false,pa,false);
double t1AB = (p1+pl+plbar).m2();
double taAB = (pa-pl-plbar).m2();
Tensor<2,4> J1a1 = (J1aBlank.contract(Tp1W,2))/t1AB;
Tensor<2,4> J1a2 = (J1aBlank.contract(TqaW,2))/taAB;
Tensor<1,4> cur1a = J1a1.contract(ABCurr,1) + J1a2.contract(ABCurr,2);
//Redefine relevant momenta as currents - for ease of calling correct part of vector
current ka,k2,k3,kb;
kb[0]=pb.e();
kb[1]=pb.x();
kb[2]=pb.y();
kb[3]=pb.z();
k2[0]=p2.e();
k2[1]=p2.x();
k2[2]=p2.y();
k2[3]=p2.z();
k3[0]=p3.e();
k3[1]=p3.x();
k3[2]=p3.y();
k3[3]=p3.z();
ka[0]=pa.e();
ka[1]=pa.x();
ka[2]=pa.y();
ka[3]=pa.z();
COM V3g[4][4]={};
for(int u=0;u<4;u++){
for(int v=0;v<4;v++){
for(int p=0;p<4;p++){
for(int r=0; r<4;r++){
V3g[u][v] += COM(0.,1.)*(((2.*k2[v]+2.*k3[v])*eta[u][p] - (2.*kb[u])*eta[p][v]+2.*kb[p]*eta[u][v])*spincur[r]*eta[r][p])/s23;
}
}
}
}
COM diffextrabit[4][4]={};
for(int u=0;u<4;u++) {
for(int v=0;v<4;v++) {
diffextrabit[u][v] = 0.;
}
}
//Dot in current and eps
//eps
eps(refmom,pb,helb, ep);
COM M3=0.;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
for(int k=0; k<4; k++){
for(int l=0; l<4;l++){
M3+= eta[i][k]*cur1a.at(k)*(V3g[i][j]+diffextrabit[i][j])*ep[l]*eta[l][j];
}
}
}
}
return M3;
}
}
// no wqq emission
double jM2WgqtoQQqW(CLHEP::HepLorentzVector pa, CLHEP::HepLorentzVector pb, CLHEP::HepLorentzVector p1, CLHEP::HepLorentzVector p2, CLHEP::HepLorentzVector p3,CLHEP::HepLorentzVector plbar,CLHEP::HepLorentzVector pl){
// 4 indepedent helicity choices (complex conjugation related).
//Need to evalute each independent hel configuration and store that result somewhere
COM Mmmm1 = qWggm1(pa,pb,p1,p2,p3,pl,plbar,false,false,false, pa);
COM Mmmm2 = qWggm2(pa,pb,p1,p2,p3,pl,plbar,false,false,false, pa);
COM Mmmm3 = qWggm3(pa,pb,p1,p2,p3,pl,plbar,false,false,false, pa);
COM Mmmp1 = qWggm1(pa,pb,p1,p2,p3,pl,plbar,false,true,false, pa);
COM Mmmp2 = qWggm2(pa,pb,p1,p2,p3,pl,plbar,false,true,false, pa);
COM Mmmp3 = qWggm3(pa,pb,p1,p2,p3,pl,plbar,false,true,false, pa);
COM Mpmm1 = qWggm1(pa,pb,p1,p2,p3,pl,plbar,false,false,true, pa);
COM Mpmm2 = qWggm2(pa,pb,p1,p2,p3,pl,plbar,false,false,true, pa);
COM Mpmm3 = qWggm3(pa,pb,p1,p2,p3,pl,plbar,false,false,true, pa);
COM Mpmp1 = qWggm1(pa,pb,p1,p2,p3,pl,plbar,false,true,true, pa);
COM Mpmp2 = qWggm2(pa,pb,p1,p2,p3,pl,plbar,false,true,true, pa);
COM Mpmp3 = qWggm3(pa,pb,p1,p2,p3,pl,plbar,false,true,true, pa);
//Colour factors:
COM cm1m1,cm2m2,cm3m3,cm1m2,cm1m3,cm2m3;
cm1m1=8./3.;
cm2m2=8./3.;
cm3m3=6.;
cm1m2 =-1./3.;
cm1m3 = -3.*COM(0.,1.);
cm2m3 = 3.*COM(0.,1.);
//Sqaure and sum for each helicity config:
double Mmmm,Mmmp,Mpmm,Mpmp;
Mmmm = real(cm1m1*pow(abs(Mmmm1),2)+cm2m2*pow(abs(Mmmm2),2)+cm3m3*pow(abs(Mmmm3),2)+2.*real(cm1m2*Mmmm1*conj(Mmmm2))+2.*real(cm1m3*Mmmm1*conj(Mmmm3))+2.*real(cm2m3*Mmmm2*conj(Mmmm3)));
Mmmp = real(cm1m1*pow(abs(Mmmp1),2)+cm2m2*pow(abs(Mmmp2),2)+cm3m3*pow(abs(Mmmp3),2)+2.*real(cm1m2*Mmmp1*conj(Mmmp2))+2.*real(cm1m3*Mmmp1*conj(Mmmp3))+2.*real(cm2m3*Mmmp2*conj(Mmmp3)));
Mpmm = real(cm1m1*pow(abs(Mpmm1),2)+cm2m2*pow(abs(Mpmm2),2)+cm3m3*pow(abs(Mpmm3),2)+2.*real(cm1m2*Mpmm1*conj(Mpmm2))+2.*real(cm1m3*Mpmm1*conj(Mpmm3))+2.*real(cm2m3*Mpmm2*conj(Mpmm3)));
Mpmp = real(cm1m1*pow(abs(Mpmp1),2)+cm2m2*pow(abs(Mpmp2),2)+cm3m3*pow(abs(Mpmp3),2)+2.*real(cm1m2*Mpmp1*conj(Mpmp2))+2.*real(cm1m3*Mpmp1*conj(Mpmp3))+2.*real(cm2m3*Mpmp2*conj(Mpmp3)));
return ((Mmmm+Mmmp+Mpmm+Mpmp)/24./4.)/(pa-p1).m2()/(p2+p3-pb).m2();
}
// W+Jets qqxCentral
-double jM2WqqtoqQQq(CLHEP::HepLorentzVector pa, CLHEP::HepLorentzVector pb,CLHEP::HepLorentzVector pl, CLHEP::HepLorentzVector plbar, std::vector<HLV> partons, bool aqlinepa, bool aqlinepb, bool qqxmarker, int nabove)
+double jM2WqqtoqQQq(CLHEP::HepLorentzVector pa, CLHEP::HepLorentzVector pb,CLHEP::HepLorentzVector pl, CLHEP::HepLorentzVector plbar, std::vector<HLV> partons, bool aqlinepa, bool aqlinepb, bool qqxmarker, int nabove, int nbelow)
{
static bool is_sigma_index_set(false);
if(!is_sigma_index_set){
if(init_sigma_index())
is_sigma_index_set = true;
else
return 0.;}
HLV pq, pqbar, p1, p4;
if (qqxmarker){
pqbar = partons[nabove+1];
pq = partons[nabove+2];}
else{
pq = partons[nabove+1];
pqbar = partons[nabove+2];}
p1 = partons.front();
p4 = partons.back();
Tensor<1,4> T1am, T4bm, T1ap, T4bp;
if(!(aqlinepa)){
T1ap = TCurrent(p1, true, pa, true);
T1am = TCurrent(p1, false, pa, false);}
else if(aqlinepa){
T1ap = TCurrent(pa, true, p1, true);
T1am = TCurrent(pa, false, p1, false);}
if(!(aqlinepb)){
T4bp = TCurrent(p4, true, pb, true);
T4bm = TCurrent(p4, false, pb, false);}
else if(aqlinepb){
T4bp = TCurrent(pb, true, p4, true);
T4bm = TCurrent(pb, false, p4, false);}
// Calculate the 3 separate contributions to the effective vertex
Tensor<2,4> Xunc = MUncrossW(pa, p1, pb, p4, pq, pqbar, pl, plbar, partons, nabove);
Tensor<2,4> Xcro = MCrossW( pa, p1, pb, p4, pq, pqbar, pl, plbar, partons, nabove);
Tensor<2,4> Xsym = MSymW( pa, p1, pb, p4, pq, pqbar, pl, plbar, partons, nabove);
// 4 Different Helicity Choices (Differs from Pure Jet Case, where there is also the choice in qqbar helicity.
// (- - hel choice)
COM M_mmUnc = (((Xunc).contract(T1am,1)).contract(T4bm,1)).at(0);
COM M_mmCro = (((Xcro).contract(T1am,1)).contract(T4bm,1)).at(0);
COM M_mmSym = (((Xsym).contract(T1am,1)).contract(T4bm,1)).at(0);
// (- + hel choice)
COM M_mpUnc = (((Xunc).contract(T1am,1)).contract(T4bp,1)).at(0);
COM M_mpCro = (((Xcro).contract(T1am,1)).contract(T4bp,1)).at(0);
COM M_mpSym = (((Xsym).contract(T1am,1)).contract(T4bp,1)).at(0);
// (+ - hel choice)
COM M_pmUnc = (((Xunc).contract(T1ap,1)).contract(T4bm,1)).at(0);
COM M_pmCro = (((Xcro).contract(T1ap,1)).contract(T4bm,1)).at(0);
COM M_pmSym = (((Xsym).contract(T1ap,1)).contract(T4bm,1)).at(0);
// (+ + hel choice)
COM M_ppUnc = (((Xunc).contract(T1ap,1)).contract(T4bp,1)).at(0);
COM M_ppCro = (((Xcro).contract(T1ap,1)).contract(T4bp,1)).at(0);
COM M_ppSym = (((Xsym).contract(T1ap,1)).contract(T4bp,1)).at(0);
//Colour factors:
COM cmsms,cmumu,cmcmc,cmsmu,cmsmc,cmumc;
cmsms=3.;
cmumu=4./3.;
cmcmc=4./3.;
cmsmu =3./2.*COM(0.,1.);
cmsmc = -3./2.*COM(0.,1.);
cmumc = -1./6.;
// Work Out Interference in each case of helicity:
double amp_mm = real(cmsms*pow(abs(M_mmSym),2)
+cmumu*pow(abs(M_mmUnc),2)
+cmcmc*pow(abs(M_mmCro),2)
+2.*real(cmsmu*M_mmSym*conj(M_mmUnc))
+2.*real(cmsmc*M_mmSym*conj(M_mmCro))
+2.*real(cmumc*M_mmUnc*conj(M_mmCro)));
double amp_mp = real(cmsms*pow(abs(M_mpSym),2)
+cmumu*pow(abs(M_mpUnc),2)
+cmcmc*pow(abs(M_mpCro),2)
+2.*real(cmsmu*M_mpSym*conj(M_mpUnc))
+2.*real(cmsmc*M_mpSym*conj(M_mpCro))
+2.*real(cmumc*M_mpUnc*conj(M_mpCro)));
double amp_pm = real(cmsms*pow(abs(M_pmSym),2)
+cmumu*pow(abs(M_pmUnc),2)
+cmcmc*pow(abs(M_pmCro),2)
+2.*real(cmsmu*M_pmSym*conj(M_pmUnc))
+2.*real(cmsmc*M_pmSym*conj(M_pmCro))
+2.*real(cmumc*M_pmUnc*conj(M_pmCro)));
double amp_pp = real(cmsms*pow(abs(M_ppSym),2)
+cmumu*pow(abs(M_ppUnc),2)
+cmcmc*pow(abs(M_ppCro),2)
+2.*real(cmsmu*M_ppSym*conj(M_ppUnc))
+2.*real(cmsmc*M_ppSym*conj(M_ppCro))
+2.*real(cmumc*M_ppUnc*conj(M_ppCro)));
double amp=((amp_mm+amp_mp+amp_pm+amp_pp)/(9.*4.));
CLHEP::HepLorentzVector q1,q3;
q1=pa;
for(int i=0;i<nabove+1;i++){
q1-=partons.at(i);
}
q3 = q1 - pq - pqbar - pl - plbar;
double t1 = (q1).m2();
double t3 = (q3).m2();
//Divide by t-channels
amp/=(t1*t1*t3*t3);
return amp;
}
// no wqq emission
double jM2WqqtoqQQqW(CLHEP::HepLorentzVector pa, CLHEP::HepLorentzVector pb,CLHEP::HepLorentzVector pl,CLHEP::HepLorentzVector plbar, std::vector<CLHEP::HepLorentzVector> partons, bool aqlinepa, bool aqlinepb, bool qqxmarker, int nabove, int nbelow, bool forwards){
static bool is_sigma_index_set(false);
if(!is_sigma_index_set){
if(init_sigma_index())
is_sigma_index_set = true;
else
return 0.;
}
if (!forwards){ //If Emission from Leg a instead, flip process.
HLV dummymom = pa;
bool dummybool= aqlinepa;
int dummyint = nabove;
pa = pb;
pb = dummymom;
std::reverse(partons.begin(),partons.end());
qqxmarker = !(qqxmarker);
aqlinepa = aqlinepb;
aqlinepb = dummybool;
nabove = nbelow;
nbelow = dummyint;
}
HLV pq, pqbar, p1,p4;
if (qqxmarker){
pqbar = partons[nabove+1];
pq = partons[nabove+2];}
else{
pq = partons[nabove+1];
pqbar = partons[nabove+2];}
p1 = partons.front();
p4 = partons.back();
Tensor<1,4> T1am(0.), T1ap(0.);
if(!(aqlinepa)){
T1ap = TCurrent(p1, true, pa, true);
T1am = TCurrent(p1, false, pa, false);}
else if(aqlinepa){
T1ap = TCurrent(pa, true, p1, true);
T1am = TCurrent(pa, false, p1, false);}
Tensor <1,4> T4bm = jW4bEmit(pb, p4, pl, plbar, aqlinepb);
// Calculate the 3 separate contributions to the effective vertex
Tensor<2,4> Xunc_m = MUncross(pa, pq, pqbar,partons, false, nabove);
Tensor<2,4> Xcro_m = MCross( pa, pq, pqbar,partons, false, nabove);
Tensor<2,4> Xsym_m = MSym( pa, p1, pb, p4, pq, pqbar, partons, false, nabove);
Tensor<2,4> Xunc_p = MUncross(pa, pq, pqbar,partons, true, nabove);
Tensor<2,4> Xcro_p = MCross( pa, pq, pqbar,partons, true, nabove);
Tensor<2,4> Xsym_p = MSym( pa, p1, pb, p4, pq, pqbar, partons, true, nabove);
// (- - hel choice)
COM M_mmUnc = (((Xunc_m).contract(T1am,1)).contract(T4bm,1)).at(0);
COM M_mmCro = (((Xcro_m).contract(T1am,1)).contract(T4bm,1)).at(0);
COM M_mmSym = (((Xsym_m).contract(T1am,1)).contract(T4bm,1)).at(0);
// (- + hel choice)
COM M_mpUnc = (((Xunc_p).contract(T1am,1)).contract(T4bm,1)).at(0);
COM M_mpCro = (((Xcro_p).contract(T1am,1)).contract(T4bm,1)).at(0);
COM M_mpSym = (((Xsym_p).contract(T1am,1)).contract(T4bm,1)).at(0);
// (+ - hel choice)
COM M_pmUnc = (((Xunc_m).contract(T1ap,1)).contract(T4bm,1)).at(0);
COM M_pmCro = (((Xcro_m).contract(T1ap,1)).contract(T4bm,1)).at(0);
COM M_pmSym = (((Xsym_m).contract(T1ap,1)).contract(T4bm,1)).at(0);
// (+ + hel choice)
COM M_ppUnc = (((Xunc_p).contract(T1ap,1)).contract(T4bm,1)).at(0);
COM M_ppCro = (((Xcro_p).contract(T1ap,1)).contract(T4bm,1)).at(0);
COM M_ppSym = (((Xsym_p).contract(T1ap,1)).contract(T4bm,1)).at(0);
//Colour factors:
COM cmsms,cmumu,cmcmc,cmsmu,cmsmc,cmumc;
cmsms=3.;
cmumu=4./3.;
cmcmc=4./3.;
cmsmu =3./2.*COM(0.,1.);
cmsmc = -3./2.*COM(0.,1.);
cmumc = -1./6.;
// Work Out Interference in each case of helicity:
double amp_mm = real(cmsms*pow(abs(M_mmSym),2)
+cmumu*pow(abs(M_mmUnc),2)
+cmcmc*pow(abs(M_mmCro),2)
+2.*real(cmsmu*M_mmSym*conj(M_mmUnc))
+2.*real(cmsmc*M_mmSym*conj(M_mmCro))
+2.*real(cmumc*M_mmUnc*conj(M_mmCro)));
double amp_mp = real(cmsms*pow(abs(M_mpSym),2)
+cmumu*pow(abs(M_mpUnc),2)
+cmcmc*pow(abs(M_mpCro),2)
+2.*real(cmsmu*M_mpSym*conj(M_mpUnc))
+2.*real(cmsmc*M_mpSym*conj(M_mpCro))
+2.*real(cmumc*M_mpUnc*conj(M_mpCro)));
double amp_pm = real(cmsms*pow(abs(M_pmSym),2)
+cmumu*pow(abs(M_pmUnc),2)
+cmcmc*pow(abs(M_pmCro),2)
+2.*real(cmsmu*M_pmSym*conj(M_pmUnc))
+2.*real(cmsmc*M_pmSym*conj(M_pmCro))
+2.*real(cmumc*M_pmUnc*conj(M_pmCro)));
double amp_pp = real(cmsms*pow(abs(M_ppSym),2)
+cmumu*pow(abs(M_ppUnc),2)
+cmcmc*pow(abs(M_ppCro),2)
+2.*real(cmsmu*M_ppSym*conj(M_ppUnc))
+2.*real(cmsmc*M_ppSym*conj(M_ppCro))
+2.*real(cmumc*M_ppUnc*conj(M_ppCro)));
double amp=((amp_mm+amp_mp+amp_pm+amp_pp)/(9.*4.));
CLHEP::HepLorentzVector q1,q3;
q1=pa;
for(int i=0;i<nabove+1;i++){
q1-=partons.at(i);
}
q3 = q1 - pq - pqbar;
double t1 = (q1).m2();
double t3 = (q3).m2();
//Divide by t-channels
amp/=(t1*t1*t3*t3);
return amp;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Dec 21, 1:14 PM (1 d, 1 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4022915
Default Alt Text
(137 KB)
Attached To
rHEJ HEJ
Event Timeline
Log In to Comment