Page MenuHomeHEPForge

No OneTemporary

diff --git a/include/HEJ/Zjets.hh b/include/HEJ/Zjets.hh
index 5c15606..f3e6cf9 100644
--- a/include/HEJ/Zjets.hh
+++ b/include/HEJ/Zjets.hh
@@ -1,115 +1,123 @@
/**
* \authors The HEJ collaboration (see AUTHORS for details)
* \date 2020
* \copyright GPLv2 or later
*/
/** \file
* \brief Functions computing the square of current contractions in Z+Jets.
*/
#pragma once
#include <vector>
#include "CLHEP/Vector/LorentzVector.h"
#include "HEJ/PDG_codes.hh"
typedef CLHEP::HepLorentzVector HLV;
namespace HEJ {
class ParticleProperties;
}
//! Square of qQ->qQe+e- Z+Jets Scattering Current
/**
* @param pa Momentum of initial state quark
* @param pb Momentum of initial state quark
* @param p1 Momentum of final state quark
* @param p2 Momentum of final state quark
* @param pep Momentum of final state positron
* @param pem Momentum of final state electron
* @param aptype Initial particle 1 type
* @param bptype Initial particle 2 type
* @param zprop Mass and width of the Z boson
* @param stw2 Value of sin(theta_w)^2
* @param ctw Value of cos(theta_w)
* @returns Square of the current contractions for qQ->qQe+e- Scattering
*
* This returns the square of the current contractions in qQ->qQ scattering
* with an emission of a Z Boson.
*/
-std::vector <double> ME_Z_qQ(HLV pa, HLV pb, HLV p1, HLV p2, HLV pep, HLV pem,
- HEJ::ParticleID aptype, HEJ::ParticleID bptype,
+std::vector <double> ME_Z_qQ(const HLV & pa, const HLV & pb,
+ const HLV & p1, const HLV & p2,
+ const HLV & pep, const HLV & pem,
+ const HEJ::ParticleID aptype, const HEJ::ParticleID bptype,
HEJ::ParticleProperties const & zprop,
- double stw2, double ctw);
+ const double stw2, const double ctw);
//! Square of qg->qge+e- Z+Jets Scattering Current
/**
* @param pa Momentum of initial state quark
* @param pb Momentum of initial state gluon
* @param p1 Momentum of final state quark
* @param p2 Momentum of final state gluon
* @param pep Momentum of final state positron
* @param pem Momentum of final state electron
* @param aptype Initial particle 1 type
* @param bptype Initial particle 2 type
* @param zprop Mass and width of the Z boson
* @param stw2 Value of sin(theta_w)^2
* @param ctw Value of cos(theta_w)
* @returns Square of the current contractions for qg->qge+e- Scattering
*
* This returns the square of the current contractions in qg->qg scattering
* with an emission of a Z Boson.
*/
-double ME_Z_qg(HLV pa, HLV pb, HLV p1, HLV p2, HLV pep, HLV pem,
- HEJ::ParticleID aptype, HEJ::ParticleID bptype,
+double ME_Z_qg(const HLV & pa, const HLV & pb,
+ const HLV & p1, const HLV & p2,
+ const HLV & pep, const HLV & pem,
+ const HEJ::ParticleID aptype, const HEJ::ParticleID bptype,
HEJ::ParticleProperties const & zprop,
- double stw2, double ctw);
+ const double stw2, const double ctw);
//! Square of qQ->gqQe+e- Z+Jets Unordered Current
/**
* @param pa Momentum of initial state quark a
* @param pb Momentum of initial state quark b
* @param pg Momentum of final state unordered gluon
* @param p1 Momentum of final state quark a
* @param p2 Momentum of final state quark b
* @param pep Momentum of final state positron
* @param pem Momentum of final state electron
* @param aptype Initial particle 1 type
* @param bptype Initial particle 2 type
* @param zprop Mass and width of the Z boson
* @param stw2 Value of sin(theta_w)^2
* @param ctw Value of cos(theta_w)
* @returns Square of the current contractions for qQ->gqQe+e- Scattering
*
* This returns the square of the current contractions in qQ->gqQ scattering
* with an emission of a Z Boson.
*/
-std::vector <double> ME_Zuno_qQ(HLV pa, HLV pb, HLV pg, HLV p1, HLV p2, HLV pep, HLV pem,
- HEJ::ParticleID aptype, HEJ::ParticleID bptype,
+std::vector <double> ME_Zuno_qQ(const HLV & pa, const HLV & pb,
+ const HLV & pg, const HLV & p1, const HLV & p2,
+ const HLV & pep, const HLV & pem,
+ const HEJ::ParticleID aptype, const HEJ::ParticleID bptype,
HEJ::ParticleProperties const & zprop,
- double stw2, double ctw);
+ const double stw2, const double ctw);
//! Square of qg->gqge+e- Z+Jets Unordered Current
/**
* @param pa Momentum of initial state quark
* @param pb Momentum of initial state gluon
* @param pg Momentum of final state unordered gluon
* @param p1 Momentum of final state quark
* @param p2 Momentum of final state gluon
* @param pep Momentum of final state positron
* @param pem Momentum of final state electron
* @param aptype Initial particle 1 type
* @param bptype Initial particle 2 type
* @param zprop Mass and width of the Z boson
* @param stw2 Value of sin(theta_w)^2
* @param ctw Value of cos(theta_w)
* @returns Square of the current contractions for qg->gqge+e- Scattering
*
* This returns the square of the current contractions in qg->gqg scattering
* with an emission of a Z Boson.
*/
-double ME_Zuno_qg(HLV pa, HLV pb, HLV pg, HLV p1, HLV p2, HLV pep, HLV pem,
- HEJ::ParticleID aptype, HEJ::ParticleID bptype,
+double ME_Zuno_qg(const HLV & pa, const HLV & pb,
+ const HLV & pg, const HLV & p1, const HLV & p2,
+ const HLV & pep, const HLV & pem,
+ const HEJ::ParticleID aptype, const HEJ::ParticleID bptype,
HEJ::ParticleProperties const & zprop,
- double stw2, double ctw);
\ No newline at end of file
+ const double stw2, const double ctw);
\ No newline at end of file
diff --git a/src/MatrixElement.cc b/src/MatrixElement.cc
index ed6acf7..e4be323 100644
--- a/src/MatrixElement.cc
+++ b/src/MatrixElement.cc
@@ -1,2203 +1,2204 @@
/**
* \authors The HEJ collaboration (see AUTHORS for details)
* \date 2019-2020
* \copyright GPLv2 or later
*/
#include "HEJ/MatrixElement.hh"
#include <algorithm>
#include <assert.h>
#include <limits>
#include <math.h>
#include <stddef.h>
#include <unordered_map>
#include <utility>
#include "CLHEP/Vector/LorentzVector.h"
#include "HEJ/Constants.hh"
#include "HEJ/Event.hh"
#include "HEJ/event_types.hh"
#include "HEJ/exceptions.hh"
#include "HEJ/ConfigFlags.hh"
#include "HEJ/Hjets.hh"
#include "HEJ/jets.hh"
#include "HEJ/Particle.hh"
#include "HEJ/PDG_codes.hh"
#include "HEJ/utility.hh"
#include "HEJ/Wjets.hh"
#include "HEJ/Zjets.hh"
namespace HEJ{
double MatrixElement::omega0(
double alpha_s, double mur,
fastjet::PseudoJet const & q_j
) const {
const double lambda = param_.regulator_lambda;
const double result = - alpha_s*N_C/M_PI*log(q_j.perp2()/(lambda*lambda));
if(! param_.log_correction) return result;
return (
1. + alpha_s/(4.*M_PI)*beta0*log(mur*mur/(q_j.perp()*lambda))
)*result;
}
Weights MatrixElement::operator()(Event const & event) const {
std::vector <double> tree_kin_part=tree_kin(event);
std::vector <Weights> virtual_part=virtual_corrections(event);
if(tree_kin_part.size() != virtual_part.size()) {
throw std::logic_error("tree and virtuals have different sizes");
}
Weights sum = Weights{0., std::vector<double>(event.variations().size(), 0.)};
for(size_t i=0; i<tree_kin_part.size(); ++i) {
sum += tree_kin_part.at(i)*virtual_part.at(i);
}
return tree_param(event)*sum;
}
Weights MatrixElement::tree(Event const & event) const {
std::vector <double> tree_kin_part=tree_kin(event);
double sum = 0.;
for(size_t i=0; i<tree_kin_part.size(); ++i) {
sum += tree_kin_part.at(i);
}
return tree_param(event)*sum;
}
Weights MatrixElement::tree_param(Event const & event) const {
if(! is_resummable(event.type())) {
return Weights{0., std::vector<double>(event.variations().size(), 0.)};
}
Weights result;
// only compute once for each renormalisation scale
std::unordered_map<double, double> known;
result.central = tree_param(event, event.central().mur);
known.emplace(event.central().mur, result.central);
for(auto const & var: event.variations()) {
const auto ME_it = known.find(var.mur);
if(ME_it == end(known)) {
const double wt = tree_param(event, var.mur);
result.variations.emplace_back(wt);
known.emplace(var.mur, wt);
}
else {
result.variations.emplace_back(ME_it->second);
}
}
return result;
}
std::vector<Weights> MatrixElement::virtual_corrections(Event const & event) const {
if(! is_resummable(event.type())) {
return {Weights{0., std::vector<double>(event.variations().size(), 0.)}};
}
// only compute once for each renormalisation scale
std::unordered_map<double, std::vector<double> > known_vec;
std::vector<double> central_vec=virtual_corrections(event, event.central().mur);
known_vec.emplace(event.central().mur, central_vec);
for(auto const & var: event.variations()) {
const auto ME_it = known_vec.find(var.mur);
if(ME_it == end(known_vec)) {
known_vec.emplace(var.mur, virtual_corrections(event, var.mur));
}
}
// At this stage known_vec contains one vector of virtual corrections for each mur value
// Now put this into a vector of Weights
std::vector<Weights> result_vec;
for(size_t i=0; i<central_vec.size(); ++i) {
Weights result;
result.central = central_vec.at(i);
for(auto const & var: event.variations()) {
const auto ME_it = known_vec.find(var.mur);
result.variations.emplace_back(ME_it->second.at(i));
}
result_vec.emplace_back(result);
}
return result_vec;
}
double MatrixElement::virtual_corrections_W(
Event const & event,
const double mur,
Particle const & WBoson
) const{
auto const & in = event.incoming();
const auto partons = filter_partons(event.outgoing());
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(partons.begin(), partons.end(), rapidity_less{}));
assert(partons.size() >= 2);
assert(pa.pz() < pb.pz());
fastjet::PseudoJet q = pa - partons[0].p;
size_t first_idx = 0;
size_t last_idx = partons.size() - 1;
#ifndef NDEBUG
bool wc = true;
#endif
bool wqq = false;
// With extremal qqx or unordered gluon outside the extremal
// partons then it is not part of the FKL ladder and does not
// contribute to the virtual corrections. W emitted from the
// most backward leg must be taken into account in t-channel
if (event.type() == event_type::unob) {
q -= partons[1].p;
++first_idx;
if (in[0].type != partons[1].type ){
q -= WBoson.p;
#ifndef NDEBUG
wc=false;
#endif
}
}
else if (event.type() == event_type::qqxexb) {
q -= partons[1].p;
++first_idx;
if (abs(partons[0].type) != abs(partons[1].type)){
q -= WBoson.p;
#ifndef NDEBUG
wc=false;
#endif
}
}
else {
if(event.type() == event_type::unof
|| event.type() == event_type::qqxexf){
--last_idx;
}
if (in[0].type != partons[0].type ){
q -= WBoson.p;
#ifndef NDEBUG
wc=false;
#endif
}
}
size_t first_idx_qqx = last_idx;
size_t last_idx_qqx = last_idx;
//if qqxMid event, virtual correction do not occur between
//qqx pair.
if(event.type() == event_type::qqxmid){
const auto backquark = std::find_if(
begin(partons) + 1, end(partons) - 1 ,
[](Particle const & s){ return (s.type != pid::gluon); }
);
if(backquark == end(partons) || (backquark+1)->type==pid::gluon) return 0;
if(abs(backquark->type) != abs((backquark+1)->type)) {
wqq=true;
#ifndef NDEBUG
wc=false;
#endif
}
last_idx = std::distance(begin(partons), backquark);
first_idx_qqx = last_idx+1;
}
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)*(
partons[j+1].rapidity() - partons[j].rapidity()
);
q -=partons[j+1].p;
} // End Loop one
if (last_idx != first_idx_qqx) q -= partons[last_idx+1].p;
if (wqq) q -= WBoson.p;
for(size_t j = first_idx_qqx; j < last_idx_qqx; ++j){
exponent += omega0(alpha_s, mur, q)*(
partons[j+1].rapidity() - partons[j].rapidity()
);
q -= partons[j+1].p;
}
#ifndef NDEBUG
if (wc) q -= WBoson.p;
assert(
nearby(q, -1*pb, norm)
|| is_AWZH_boson(partons.back().type)
|| event.type() == event_type::unof
|| event.type() == event_type::qqxexf
);
#endif
return exp(exponent);
}
std::vector <double> MatrixElement::virtual_corrections_Z_qq(
Event const & event,
- double mur,
+ const double mur,
Particle const & ZBoson
) const{
auto const & in = event.incoming();
const auto partons = filter_partons(event.outgoing());
fastjet::PseudoJet const & pa = in.front().p;
#ifndef NDEBUG
fastjet::PseudoJet const & pb = in.back().p;
#endif
assert(std::is_sorted(partons.begin(), partons.end(), rapidity_less{}));
assert(partons.size() >= 2);
assert(pa.pz() < pb.pz());
fastjet::PseudoJet q_t = pa - partons[0].p - ZBoson.p;
fastjet::PseudoJet q_b = pa - partons[0].p;
size_t first_idx = 0;
size_t last_idx = partons.size() - 1;
// Unordered gluon does not contribute to the virtual corrections
if (event.type() == event_type::unob) {
// Gluon is partons[0] and is already subtracted
// partons[1] is the backward quark
q_t -= partons[1].p;
q_b -= partons[1].p;
++first_idx;
} else if (event.type() == event_type::unof) {
// End sum at forward quark
--last_idx;
}
double sum_top=0., sum_bot=0., sum_mix=0.;
const double alpha_s = alpha_s_(mur);
for(size_t j = first_idx; j < last_idx; ++j){
- double dy = partons[j+1].rapidity() - partons[j].rapidity();
- double tmp_top = omega0(alpha_s, mur, q_t)*dy;
- double tmp_bot = omega0(alpha_s, mur, q_b)*dy;
+ const double dy = partons[j+1].rapidity() - partons[j].rapidity();
+ const double tmp_top = omega0(alpha_s, mur, q_t)*dy;
+ const double tmp_bot = omega0(alpha_s, mur, q_b)*dy;
sum_top += tmp_top;
sum_bot += tmp_bot;
sum_mix += (tmp_top + tmp_bot) / 2.;
q_t -= partons[j+1].p;
q_b -= partons[j+1].p;
}
return {exp(sum_top), exp(sum_bot), exp(sum_mix)};
}
double MatrixElement::virtual_corrections_Z_qg(
Event const & event,
- double mur,
+ const double mur,
Particle const & ZBoson,
- bool is_gq_event
+ const bool is_gq_event
) const{
auto const & in = event.incoming();
const auto partons = filter_partons(event.outgoing());
fastjet::PseudoJet const & pa = in.front().p;
#ifndef NDEBUG
fastjet::PseudoJet const & pb = in.back().p;
#endif
assert(std::is_sorted(partons.begin(), partons.end(), rapidity_less{}));
assert(partons.size() >= 2);
assert(pa.pz() < pb.pz());
// If this is a gq event, don't subtract the Z momentum from first q
fastjet::PseudoJet q = (is_gq_event ? pa - partons[0].p : pa - partons[0].p - ZBoson.p);
size_t first_idx = 0;
size_t last_idx = partons.size() - 1;
// Unordered gluon does not contribute to the virtual corrections
if (event.type() == event_type::unob) {
// Gluon is partons[0] and is already subtracted
// partons[1] is the backward quark
q -= partons[1].p;
++first_idx;
} else if (event.type() == event_type::unof) {
// End sum at forward quark
--last_idx;
}
double sum=0.;
const double alpha_s = alpha_s_(mur);
for(size_t j = first_idx; j < last_idx; ++j){
sum += omega0(alpha_s, mur, q)*(partons[j+1].rapidity()
- partons[j].rapidity());
q -= partons[j+1].p;
}
return exp(sum);
}
std::vector<double> MatrixElement::virtual_corrections(
Event const & event,
const double mur
) const{
auto const & in = event.incoming();
auto const & out = event.outgoing();
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
const auto AWZH_boson = std::find_if(
begin(out), end(out),
[](Particle const & p){ return is_AWZH_boson(p); }
);
if(AWZH_boson != end(out) && abs(AWZH_boson->type) == pid::Wp){
return {virtual_corrections_W(event, mur, *AWZH_boson)};
}
if(AWZH_boson != end(out) && AWZH_boson->type == pid::Z_photon_mix){
if(is_gluon(in.back().type)){
// This is a qg event
return {virtual_corrections_Z_qg(event, mur, *AWZH_boson, false)};
}else if(is_gluon(in.front().type)){
// This is a gq event
return {virtual_corrections_Z_qg(event, mur, *AWZH_boson, true)};
}else{
// This is a qq event
return virtual_corrections_Z_qq(event, mur, *AWZH_boson);
}
}
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 boson, extremal qqx 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)
|| event.type() == event_type::unob
|| event.type() == event_type::qqxexb){
q -= out[1].p;
++first_idx;
}
if((out.back().type == pid::Higgs)
|| event.type() == event_type::unof
|| event.type() == event_type::qqxexf){
--last_idx;
}
size_t first_idx_qqx = last_idx;
size_t last_idx_qqx = last_idx;
//if qqxMid event, virtual correction do not occur between
//qqx pair.
if(event.type() == event_type::qqxmid){
const auto backquark = std::find_if(
begin(out) + 1, end(out) - 1 ,
[](Particle const & s){ return (s.type != pid::gluon && is_parton(s.type)); }
);
if(backquark == end(out) || (backquark+1)->type==pid::gluon) return {0.};
last_idx = std::distance(begin(out), backquark);
first_idx_qqx = last_idx+1;
}
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)*(
out[j+1].rapidity() - out[j].rapidity()
);
q -= out[j+1].p;
}
if (last_idx != first_idx_qqx) q -= out[last_idx+1].p;
for(size_t j = first_idx_qqx; j < last_idx_qqx; ++j){
exponent += omega0(alpha_s, mur, q)*(
out[j+1].rapidity() - out[j].rapidity()
);
q -= out[j+1].p;
}
assert(
nearby(q, -1*pb, norm)
|| out.back().type == pid::Higgs
|| event.type() == event_type::unof
|| event.type() == event_type::qqxexf
);
return {exp(exponent)};
}
namespace {
//! Lipatov vertex for partons emitted into extremal jets
double C2Lipatov(
CLHEP::HepLorentzVector const & qav,
CLHEP::HepLorentzVector const & qbv,
CLHEP::HepLorentzVector const & p1,
CLHEP::HepLorentzVector const & p2
){
const CLHEP::HepLorentzVector temptrans=-(qav+qbv);
const CLHEP::HepLorentzVector p5=qav-qbv;
const 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));
return -CL.dot(CL);
}
//! Lipatov vertex with soft subtraction for partons emitted into extremal jets
double C2Lipatovots(
CLHEP::HepLorentzVector const & qav,
CLHEP::HepLorentzVector const & qbv,
CLHEP::HepLorentzVector const & p1,
CLHEP::HepLorentzVector const & p2,
const double lambda
) {
const double Cls=(C2Lipatov(qav, qbv, p1, p2)/(qav.m2()*qbv.m2()));
const double kperp=(qav-qbv).perp();
if (kperp>lambda)
return Cls;
return Cls-4./(kperp*kperp);
}
//! Lipatov vertex
double C2Lipatov( // B
CLHEP::HepLorentzVector const & qav,
CLHEP::HepLorentzVector const & qbv,
CLHEP::HepLorentzVector const & pim,
CLHEP::HepLorentzVector const & pip,
CLHEP::HepLorentzVector const & pom,
CLHEP::HepLorentzVector const & pop
){
const CLHEP::HepLorentzVector temptrans=-(qav+qbv);
const CLHEP::HepLorentzVector p5=qav-qbv;
const 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 const & qav,
CLHEP::HepLorentzVector const & qbv,
CLHEP::HepLorentzVector const & pa,
CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & p1,
CLHEP::HepLorentzVector const & p2,
const double lambda
) {
const double Cls=(C2Lipatov(qav, qbv, pa, pb, p1, p2)/(qav.m2()*qbv.m2()));
const double kperp=(qav-qbv).perp();
if (kperp>lambda)
return Cls;
return Cls-4./(kperp*kperp);
}
double C2Lipatov_Mix(
CLHEP::HepLorentzVector const & qav_b, CLHEP::HepLorentzVector const & qbv_b,
CLHEP::HepLorentzVector const & qav_t, CLHEP::HepLorentzVector const & qbv_t,
CLHEP::HepLorentzVector const & p1, CLHEP::HepLorentzVector const & p2
) {
- HLV temptrans_b = -(qav_b + qbv_b);
- HLV temptrans_t = -(qav_t + qbv_t);
+ const HLV temptrans_b = -(qav_b + qbv_b);
+ const HLV temptrans_t = -(qav_t + qbv_t);
- HLV p5_b = qav_b - qbv_b;
- HLV p5_t = qav_t - qbv_t;
+ const HLV p5_b = qav_b - qbv_b;
+ const HLV p5_t = qav_t - qbv_t;
- HLV CL_b = -(qav_b + qbv_b)
- + (qav_b.m2() / p5_b.dot(p1) + 2.0 * p5_b.dot(p2) / p1.dot(p2)) * p1
- - p2 * (qbv_b.m2() / p5_b.dot(p2) + 2.0 * p5_b.dot(p1) / p1.dot(p2));
- HLV CL_t = -(qav_t + qbv_t)
- + (qav_t.m2() / p5_t.dot(p1) + 2.0 * p5_t.dot(p2) / p1.dot(p2)) * p1
- - p2 * (qbv_t.m2() / p5_t.dot(p2) + 2.0 * p5_t.dot(p1) / p1.dot(p2));
+ const HLV CL_b = -(qav_b + qbv_b)
+ + (qav_b.m2() / p5_b.dot(p1) + 2.0 * p5_b.dot(p2) / p1.dot(p2)) * p1
+ - p2 * (qbv_b.m2() / p5_b.dot(p2) + 2.0 * p5_b.dot(p1) / p1.dot(p2));
+ const HLV CL_t = -(qav_t + qbv_t)
+ + (qav_t.m2() / p5_t.dot(p1) + 2.0 * p5_t.dot(p2) / p1.dot(p2)) * p1
+ - p2 * (qbv_t.m2() / p5_t.dot(p2) + 2.0 * p5_t.dot(p1) / p1.dot(p2));
return -CL_b.dot(CL_t);
}
double C2Lipatovots_Mix(
CLHEP::HepLorentzVector const & qav_b, CLHEP::HepLorentzVector const & qbv_b,
CLHEP::HepLorentzVector const & qav_t, CLHEP::HepLorentzVector const & qbv_t,
CLHEP::HepLorentzVector const & p1, CLHEP::HepLorentzVector const & p2,
- double lambda
+ const double lambda
) {
- double kperp = (qav_b - qbv_b).perp();
+ const double kperp = (qav_b - qbv_b).perp();
if (kperp > lambda) {
return C2Lipatov_Mix(qav_b, qbv_b, qav_t, qbv_t, p1, p2)
/ sqrt(qav_b.m2() * qbv_b.m2() * qav_t.m2() * qbv_t.m2());
} else {
- double Cls = C2Lipatov_Mix(qav_b, qbv_b, qav_t, qbv_t, p1, p2)
- / sqrt(qav_b.m2() * qbv_b.m2() * qav_t.m2() * qbv_t.m2());
+ const double Cls = C2Lipatov_Mix(qav_b, qbv_b, qav_t, qbv_t, p1, p2)
+ / sqrt(qav_b.m2() * qbv_b.m2() * qav_t.m2() * qbv_t.m2());
return Cls - 4.0 / (kperp * kperp);
}
}
double C2Lipatov_Mix(
CLHEP::HepLorentzVector const & qav_b, CLHEP::HepLorentzVector const & qbv_b,
CLHEP::HepLorentzVector const & qav_t, CLHEP::HepLorentzVector const & qbv_t,
CLHEP::HepLorentzVector const & pim, CLHEP::HepLorentzVector const & pip,
CLHEP::HepLorentzVector const & pom, CLHEP::HepLorentzVector const & pop
) {
- HLV temptrans_b = -(qav_b + qbv_b);
- HLV temptrans_t = -(qav_t + qbv_t);
-
- HLV p5_b = qav_b - qbv_b;
- HLV p5_t = qav_t - qbv_t;
-
- HLV CL_b = temptrans_b
- + qav_b.m2()*(1./p5_b.dot(pip)*pip+1./p5_b.dot(pop)*pop)/2.
- - qbv_b.m2()*(1./p5_b.dot(pim)*pim+1./p5_b.dot(pom)*pom)/2.
- + (pip*(p5_b.dot(pim)/pip.dot(pim)+p5_b.dot(pom)/pip.dot(pom))
- +pop*(p5_b.dot(pim)/pop.dot(pim)+p5_b.dot(pom)/pop.dot(pom))
- -pim*(p5_b.dot(pip)/pip.dot(pim) + p5_b.dot(pop)/pop.dot(pim))
- -pom*(p5_b.dot(pip)/pip.dot(pom) + p5_b.dot(pop)/pop.dot(pom)))/2.;
-
- HLV CL_t = temptrans_t
- + qav_t.m2()*(1./p5_t.dot(pip)*pip+1./p5_t.dot(pop)*pop)/2.
- - qbv_t.m2()*(1./p5_t.dot(pim)*pim+1./p5_t.dot(pom)*pom)/2.
- + (pip*(p5_t.dot(pim)/pip.dot(pim)+p5_t.dot(pom)/pip.dot(pom))
- +pop*(p5_t.dot(pim)/pop.dot(pim)+p5_t.dot(pom)/pop.dot(pom))
- -pim*(p5_t.dot(pip)/pip.dot(pim) + p5_t.dot(pop)/pop.dot(pim))
- -pom*(p5_t.dot(pip)/pip.dot(pom) + p5_t.dot(pop)/pop.dot(pom)))/2.;
+ const HLV temptrans_b = -(qav_b + qbv_b);
+ const HLV temptrans_t = -(qav_t + qbv_t);
+
+ const HLV p5_b = qav_b - qbv_b;
+ const HLV p5_t = qav_t - qbv_t;
+
+ const HLV CL_b = temptrans_b
+ + qav_b.m2()*(1./p5_b.dot(pip)*pip+1./p5_b.dot(pop)*pop)/2.
+ - qbv_b.m2()*(1./p5_b.dot(pim)*pim+1./p5_b.dot(pom)*pom)/2.
+ + (pip*(p5_b.dot(pim)/pip.dot(pim)+p5_b.dot(pom)/pip.dot(pom))
+ +pop*(p5_b.dot(pim)/pop.dot(pim)+p5_b.dot(pom)/pop.dot(pom))
+ -pim*(p5_b.dot(pip)/pip.dot(pim) + p5_b.dot(pop)/pop.dot(pim))
+ -pom*(p5_b.dot(pip)/pip.dot(pom) + p5_b.dot(pop)/pop.dot(pom)))/2.;
+
+ const HLV CL_t = temptrans_t
+ + qav_t.m2()*(1./p5_t.dot(pip)*pip+1./p5_t.dot(pop)*pop)/2.
+ - qbv_t.m2()*(1./p5_t.dot(pim)*pim+1./p5_t.dot(pom)*pom)/2.
+ + (pip*(p5_t.dot(pim)/pip.dot(pim)+p5_t.dot(pom)/pip.dot(pom))
+ +pop*(p5_t.dot(pim)/pop.dot(pim)+p5_t.dot(pom)/pop.dot(pom))
+ -pim*(p5_t.dot(pip)/pip.dot(pim) + p5_t.dot(pop)/pop.dot(pim))
+ -pom*(p5_t.dot(pip)/pip.dot(pom) + p5_t.dot(pop)/pop.dot(pom)))/2.;
return -CL_b.dot(CL_t);
}
double C2Lipatovots_Mix(
CLHEP::HepLorentzVector const & qav_b, CLHEP::HepLorentzVector const & qbv_b,
CLHEP::HepLorentzVector const & qav_t, CLHEP::HepLorentzVector const & qbv_t,
CLHEP::HepLorentzVector const & pa, CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & p1, CLHEP::HepLorentzVector const & p2,
- double lambda
+ const double lambda
) {
- double kperp = (qav_b - qbv_b).perp();
+ const double kperp = (qav_b - qbv_b).perp();
if (kperp > lambda) {
return C2Lipatov_Mix(qav_b, qbv_b, qav_t, qbv_t, pa, pb, p1, p2)
/ sqrt(qav_b.m2() * qbv_b.m2() * qav_t.m2() * qbv_t.m2());
} else {
- double Cls = C2Lipatov_Mix(qav_b, qbv_b, qav_t, qbv_t, pa, pb, p1, p2)
- / sqrt(qav_b.m2() * qbv_b.m2() * qav_t.m2() * qbv_t.m2());
- double temp = Cls - 4.0 / (kperp * kperp);
+ const double Cls = C2Lipatov_Mix(qav_b, qbv_b, qav_t, qbv_t, pa, pb, p1, p2)
+ / sqrt(qav_b.m2() * qbv_b.m2() * qav_t.m2() * qbv_t.m2());
+ const double temp = Cls - 4.0 / (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 pg Unordered gluon momentum
* @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
*
* @note The unof contribution can be calculated by reversing the argument ordering.
*/
double ME_uno_current(
ParticleID aptype, ParticleID bptype,
CLHEP::HepLorentzVector const & pg,
CLHEP::HepLorentzVector const & pn,
CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & p1,
CLHEP::HepLorentzVector const & pa
){
assert(aptype!=pid::gluon); // aptype cannot be gluon
if (bptype==pid::gluon) {
if (is_quark(aptype))
return ME_unob_qg(pg,p1,pa,pn,pb);
else
return ME_unob_qbarg(pg,p1,pa,pn,pb);
}
else if (is_antiquark(bptype)) {
if (is_quark(aptype))
return ME_unob_qQbar(pg,p1,pa,pn,pb);
else
return ME_unob_qbarQbar(pg,p1,pa,pn,pb);
}
else { //bptype == quark
if (is_quark(aptype))
return ME_unob_qQ(pg,p1,pa,pn,pb);
else
return ME_unob_qbarQ(pg,p1,pa,pn,pb);
}
throw std::logic_error("unreachable");
}
/** Matrix element squared for tree-level current-current scattering
* @param bptype Particle b PDG ID
* @param pgin Incoming gluon momentum
* @param pq Quark from splitting Momentum
* @param pqbar Anti-quark from splitting Momentum
* @param pn Particle n Momentum
* @param pb Particle b Momentum
* @param swap_q_qx Boolean. Ordering of qqbar pair. False: pqbar extremal.
* @returns ME Squared for Tree-Level Current-Current Scattering
*
* @note The qqxf contribution can be calculated by reversing the argument ordering.
*/
double ME_qqx_current(
ParticleID bptype,
CLHEP::HepLorentzVector const & pgin,
CLHEP::HepLorentzVector const & pq,
CLHEP::HepLorentzVector const & pqbar,
CLHEP::HepLorentzVector const & pn,
CLHEP::HepLorentzVector const & pb,
bool const swap_q_qx
){
if (bptype==pid::gluon) {
if (swap_q_qx) // pq extremal
return ME_Exqqx_qqbarg(pgin,pq,pqbar,pn,pb);
else // pqbar extremal
return ME_Exqqx_qbarqg(pgin,pq,pqbar,pn,pb);
}
else { // b leg quark line
if (swap_q_qx) //extremal pq
return ME_Exqqx_qqbarQ(pgin,pq,pqbar,pn,pb);
else
return ME_Exqqx_qbarqQ(pgin,pq,pqbar,pn,pb);
}
throw std::logic_error("unreachable");
}
/* \brief Matrix element squared for central qqx tree-level current-current
* scattering
*
* @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
* @returns ME Squared for qqxmid Tree-Level Current-Current Scattering
*/
double ME_qqxmid_current(
ParticleID aptype, ParticleID bptype, int nabove,
CLHEP::HepLorentzVector const & pa,
CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & pq,
CLHEP::HepLorentzVector const & pqbar,
std::vector<HLV> const & partons){
// CAM factors for the qqx amps, and qqbar ordering (default, pq backwards)
const bool swap_q_qx=pqbar.rapidity() < pq.rapidity();
double wt=1.;
if (aptype==pid::gluon) wt*=K_g(partons.front(),pa)/HEJ::C_F;
if (bptype==pid::gluon) wt*=K_g(partons.back(),pb)/HEJ::C_F;
return wt*ME_Cenqqx_qq(pa, pb, partons,is_antiquark(bptype),is_antiquark(aptype), swap_q_qx, nabove);
}
/** 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(
ParticleID aptype, ParticleID bptype,
CLHEP::HepLorentzVector const & pn,
CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & p1,
CLHEP::HepLorentzVector const & pa
){
if (aptype==pid::gluon && bptype==pid::gluon) {
return ME_gg(pn,pb,p1,pa);
} else if (aptype==pid::gluon && bptype!=pid::gluon) {
if (is_quark(bptype))
return ME_qg(pn,pb,p1,pa);
else
return ME_qbarg(pn,pb,p1,pa);
}
else if (bptype==pid::gluon && aptype!=pid::gluon) {
if (is_quark(aptype))
return ME_qg(p1,pa,pn,pb);
else
return ME_qbarg(p1,pa,pn,pb);
}
else { // they are both quark
if (is_quark(bptype)) {
if (is_quark(aptype))
return ME_qQ(pn,pb,p1,pa);
else
return ME_qQbar(pn,pb,p1,pa);
}
else {
if (is_quark(aptype))
return ME_qQbar(p1,pa,pn,pb);
else
return ME_qbarQbar(pn,pb,p1,pa);
}
}
throw std::logic_error("unreachable");
}
/** 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
* @param wc Boolean. True->W Emitted from b. Else; emitted from leg a
* @returns ME Squared for Tree-Level Current-Current Scattering
*/
double ME_W_current(
ParticleID aptype, ParticleID 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, ParticleProperties const & Wprop
){
// We know it cannot be gg incoming.
assert(!(aptype==pid::gluon && bptype==pid::gluon));
if (aptype==pid::gluon && bptype!=pid::gluon) {
if (is_quark(bptype))
return ME_W_qg(pn,plbar,pl,pb,p1,pa,Wprop);
else
return ME_W_qbarg(pn,plbar,pl,pb,p1,pa,Wprop);
}
else if (bptype==pid::gluon && aptype!=pid::gluon) {
if (is_quark(aptype))
return ME_W_qg(p1,plbar,pl,pa,pn,pb,Wprop);
else
return ME_W_qbarg(p1,plbar,pl,pa,pn,pb,Wprop);
}
else { // they are both quark
if (wc==true){ // emission off b, (first argument pbout)
if (is_quark(bptype)) {
if (is_quark(aptype))
return ME_W_qQ(pn,plbar,pl,pb,p1,pa,Wprop);
else
return ME_W_qQbar(pn,plbar,pl,pb,p1,pa,Wprop);
}
else {
if (is_quark(aptype))
return ME_W_qbarQ(pn,plbar,pl,pb,p1,pa,Wprop);
else
return ME_W_qbarQbar(pn,plbar,pl,pb,p1,pa,Wprop);
}
}
else{ // emission off a, (first argument paout)
if (is_quark(aptype)) {
if (is_quark(bptype))
return ME_W_qQ(p1,plbar,pl,pa,pn,pb,Wprop);
else
return ME_W_qQbar(p1,plbar,pl,pa,pn,pb,Wprop);
}
else { // a is anti-quark
if (is_quark(bptype))
return ME_W_qbarQ(p1,plbar,pl,pa,pn,pb,Wprop);
else
return ME_W_qbarQbar(p1,plbar,pl,pa,pn,pb,Wprop);
}
}
}
throw std::logic_error("unreachable");
}
/** 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
* @param wc Boolean. True->W Emitted from b. Else; emitted from leg a
* @returns ME Squared for unob Tree-Level Current-Current Scattering
*
* @note The unof contribution can be calculated by reversing the argument ordering.
*/
double ME_W_uno_current(
ParticleID aptype, ParticleID 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, ParticleProperties const & Wprop
){
// we know they are not both gluons
assert(bptype != pid::gluon || aptype != pid::gluon);
if (bptype == pid::gluon && aptype != pid::gluon) {
// b gluon => W emission off a
if (is_quark(aptype))
return ME_Wuno_qg(p1,pa,pn,pb,pg,plbar,pl,Wprop);
else
return ME_Wuno_qbarg(p1,pa,pn,pb,pg,plbar,pl,Wprop);
}
else { // they are both quark
if (wc) {// emission off b, i.e. b is first current
if (is_quark(bptype)){
if (is_quark(aptype))
return ME_W_unob_qQ(p1,pa,pn,pb,pg,plbar,pl,Wprop);
else
return ME_W_unob_qQbar(p1,pa,pn,pb,pg,plbar,pl,Wprop);
}
else{
if (is_quark(aptype))
return ME_W_unob_qbarQ(p1,pa,pn,pb,pg,plbar,pl,Wprop);
else
return ME_W_unob_qbarQbar(p1,pa,pn,pb,pg,plbar,pl,Wprop);
}
}
else {// wc == false, emission off a, i.e. a is first current
if (is_quark(aptype)) {
if (is_quark(bptype)) //qq
return ME_Wuno_qQ(p1,pa,pn,pb,pg,plbar,pl,Wprop);
else //qqbar
return ME_Wuno_qQbar(p1,pa,pn,pb,pg,plbar,pl,Wprop);
}
else { // a is anti-quark
if (is_quark(bptype)) //qbarq
return ME_Wuno_qbarQ(p1,pa,pn,pb,pg,plbar,pl,Wprop);
else //qbarqbar
return ME_Wuno_qbarQbar(p1,pa,pn,pb,pg,plbar,pl,Wprop);
}
}
}
throw std::logic_error("unreachable");
}
/** \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
* @param swap_q_qx Boolean. Ordering of qqbar pair. False: pqbar extremal.
* @param wc Boolean. True->W Emitted from b. Else; emitted from leg a
* @returns ME Squared for qqxb Tree-Level Current-Current Scattering
*
* @note calculate forwards qqx contribution by reversing argument ordering.
*/
double ME_W_qqx_current(
ParticleID aptype, ParticleID 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 swap_q_qx, bool const wc,
ParticleProperties const & Wprop
){
// CAM factors for the qqx amps, and qqbar ordering (default, qbar extremal)
const double CFbackward = K_g( (swap_q_qx)?pq:pqbar ,pa)/HEJ::C_F;
// With qqbar we could have 2 incoming gluons and W Emission
if (aptype==pid::gluon && bptype==pid::gluon) {
//a gluon, b gluon gg->qqbarWg
// This will be a wqqx emission as there is no other possible W Emission
// Site.
if (swap_q_qx)
return ME_WExqqx_qqbarg(pa, pqbar, plbar, pl, pq, pn, pb, Wprop)*CFbackward;
else
return ME_WExqqx_qbarqg(pa, pq, plbar, pl, pqbar, pn, pb, Wprop)*CFbackward;
}
else {
assert(aptype==pid::gluon && bptype!=pid::gluon );
//a gluon => W emission off b leg or qqx
if (!wc){ // W Emitted from backwards qqx
if (swap_q_qx)
return ME_WExqqx_qqbarQ(pa, pqbar, plbar, pl, pq, pn, pb, Wprop)*CFbackward;
else
return ME_WExqqx_qbarqQ(pa, pq, plbar, pl, pqbar, pn, pb, Wprop)*CFbackward;
}
else { // W Must be emitted from forwards leg.
if (swap_q_qx)
return ME_W_Exqqx_QQq(pb, pa, pn, pqbar, pq, plbar, pl, is_antiquark(bptype), Wprop)*CFbackward;
else
return ME_W_Exqqx_QQq(pb, pa, pn, pq, pqbar, plbar, pl, is_antiquark(bptype), Wprop)*CFbackward;
}
}
throw std::logic_error("unreachable");
}
/* \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(
ParticleID aptype, ParticleID bptype,
int nabove, int nbelow,
CLHEP::HepLorentzVector const & pa,
CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & pq,
CLHEP::HepLorentzVector const & pqbar,
std::vector<HLV> const & partons,
CLHEP::HepLorentzVector const & plbar,
CLHEP::HepLorentzVector const & pl,
bool const wqq, bool const wc,
ParticleProperties const & Wprop
){
// CAM factors for the qqx amps, and qqbar ordering (default, pq backwards)
const bool swap_q_qx=pqbar.rapidity() < pq.rapidity();
double wt=1.;
if (aptype==pid::gluon) wt*=K_g(partons.front(),pa)/HEJ::C_F;
if (bptype==pid::gluon) wt*=K_g(partons.back(),pb)/HEJ::C_F;
if(wqq)
return wt*ME_WCenqqx_qq(pa, pb, pl, plbar, partons,(is_antiquark(bptype)),(is_antiquark(aptype)),
swap_q_qx, nabove, Wprop);
return wt*ME_W_Cenqqx_qq(pa, pb, pl, plbar, partons, (is_antiquark(bptype)), (is_antiquark(aptype)),
swap_q_qx, nabove, nbelow, wc, Wprop);
}
/** Matrix element squared for tree-level current-current scattering With Z+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 plbar Final state positron momentum
* @param pl Final state electron momentum
* @param Zprop Z properties
* @param stw2 Value of sin(theta_w)^2
* @param ctw Value of cos(theta_w)
* @returns ME Squared for Tree-Level Current-Current Scattering
*/
std::vector<double> ME_Z_current(
- ParticleID aptype, ParticleID bptype,
+ const ParticleID aptype, const ParticleID 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,
ParticleProperties const & Zprop,
- double stw2, double ctw
+ const double stw2, const double ctw
){
// we know they are not both gluons
assert(!is_gluon(aptype) || !is_gluon(bptype));
if(is_anyquark(aptype) && is_gluon(bptype)){
// This is a qg event
- double current_factor=ME_Z_qg(pa,pb,p1,pn,plbar,pl,aptype,bptype,Zprop,stw2,ctw);
+ const double current_factor=ME_Z_qg(pa,pb,p1,pn,plbar,pl,aptype,bptype,Zprop,stw2,ctw);
return { current_factor };
}else if(is_gluon(aptype) && is_anyquark(bptype)){
// This is a gq event
- double current_factor=ME_Z_qg(pb,pa,pn,p1,plbar,pl,bptype,aptype,Zprop,stw2,ctw);
+ const double current_factor=ME_Z_qg(pb,pa,pn,p1,plbar,pl,bptype,aptype,Zprop,stw2,ctw);
return { current_factor };
}else if(is_anyquark(aptype) && is_anyquark(bptype)){
// This is a qq event
return ME_Z_qQ(pa,pb,p1,pn,plbar,pl,aptype,bptype,Zprop,stw2,ctw);
}else{
// It cannot be gg incoming
throw std::logic_error("Bad particle types");
}
}
/** Matrix element squared for backwards uno tree-level current-current
* scattering With Z+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
* @param plbar Final state positron momentum
* @param pl Final state electron momentum
* @param Zprop Z properties
* @param stw2 Value of sin(theta_w)^2
* @param ctw Value of cos(theta_w)
* @returns ME Squared for unob Tree-Level Current-Current Scattering
*
* @note The unof contribution can be calculated by reversing the argument ordering.
*/
std::vector<double> ME_Z_uno_current(
- ParticleID aptype, ParticleID bptype,
+ const ParticleID aptype, const ParticleID 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,
ParticleProperties const & Zprop,
- double stw2, double ctw
+ const double stw2, const double ctw
){
// we know they are not both gluons
assert(!is_gluon(aptype) || !is_gluon(bptype));
if (is_anyquark(aptype) && is_gluon(bptype)) {
// This is a qg event
- double current_factor=ME_Zuno_qg(pa,pb,pg,p1,pn,plbar,pl,aptype,bptype,Zprop,stw2,ctw);
+ const double current_factor=ME_Zuno_qg(pa,pb,pg,p1,pn,plbar,pl,aptype,bptype,Zprop,stw2,ctw);
return { current_factor };
} else if (is_gluon(aptype) && is_anyquark(bptype)) {
// This is a gq event
- double current_factor=ME_Zuno_qg(pb,pa,pg,pn,p1,plbar,pl,bptype,aptype,Zprop,stw2,ctw);
+ const double current_factor=ME_Zuno_qg(pb,pa,pg,pn,p1,plbar,pl,bptype,aptype,Zprop,stw2,ctw);
return { current_factor };
} else if (is_anyquark(aptype) && is_anyquark(bptype)) {
// This is a qq event
return ME_Zuno_qQ(pa,pb,pg,p1,pn,plbar,pl,aptype,bptype,Zprop,stw2,ctw);
}
throw std::logic_error("unreachable");
}
/** \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(
ParticleID aptype, ParticleID 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, double vev
){
if (aptype==pid::gluon && bptype==pid::gluon)
// gg initial state
return ME_H_gg(pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb,vev);
else if (aptype==pid::gluon&&bptype!=pid::gluon) {
if (is_quark(bptype))
return ME_H_qg(pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb,vev)*4./9.;
else
return ME_H_qbarg(pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb,vev)*4./9.;
}
else if (bptype==pid::gluon && aptype!=pid::gluon) {
if (is_quark(aptype))
return ME_H_qg(p1,pa,pn,pb,-qH,-qHp1,mt,include_bottom,mb,vev)*4./9.;
else
return ME_H_qbarg(p1,pa,pn,pb,-qH,-qHp1,mt,include_bottom,mb,vev)*4./9.;
}
else { // they are both quark
if (is_quark(bptype)) {
if (is_quark(aptype))
return ME_H_qQ(pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb,vev)*4.*4./(9.*9.);
else
return ME_H_qQbar(pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb,vev)*4.*4./(9.*9.);
}
else {
if (is_quark(aptype))
return ME_H_qQbar(p1,pa,pn,pb,-qH,-qHp1,mt,include_bottom,mb,vev)*4.*4./(9.*9.);
else
return ME_H_qbarQbar(pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb,vev)*4.*4./(9.*9.);
}
}
throw std::logic_error("unreachable");
}
/** \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 pg 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
*
* @note This function assumes unordered gluon backwards from pa-p1 current.
* For unof, reverse call order
*/
double ME_Higgs_current_uno(
ParticleID aptype, ParticleID bptype,
CLHEP::HepLorentzVector const & pg,
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, double vev
){
if (bptype==pid::gluon && aptype!=pid::gluon) {
if (is_quark(aptype))
return ME_H_unob_gQ(pg,p1,pa,pn,pb,-qH,-qHp1,mt,include_bottom,mb,vev);
else
return ME_H_unob_gQbar(pg,p1,pa,pn,pb,-qH,-qHp1,mt,include_bottom,mb,vev);
}
else { // they are both quark
if (is_quark(aptype)) {
if (is_quark(bptype))
return ME_H_unob_qQ(pg,p1,pa,pn,pb,-qH,-qHp1,mt,include_bottom,mb,vev);
else
return ME_H_unob_qbarQ(pg,p1,pa,pn,pb,-qH,-qHp1,mt,include_bottom,mb,vev);
}
else {
if (is_quark(bptype))
return ME_H_unob_qQbar(pg,p1,pa,pn,pb,-qH,-qHp1,mt,include_bottom,mb,vev);
else
return ME_H_unob_qbarQbar(pg,p1,pa,pn,pb,-qH,-qHp1,mt,include_bottom,mb,vev);
}
}
throw std::logic_error("unreachable");
}
CLHEP::HepLorentzVector to_HepLorentzVector(HEJ::Particle const & particle){
return {particle.p.px(), particle.p.py(), particle.p.pz(), particle.p.E()};
}
void validate(HEJ::MatrixElementConfig const & config) {
#ifndef HEJ_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
MatrixElement::MatrixElement(
std::function<double (double)> alpha_s,
MatrixElementConfig conf
):
alpha_s_{std::move(alpha_s)},
param_{std::move(conf)}
{
validate(param_);
}
std::vector<double> MatrixElement::tree_kin(
Event const & ev
) const {
if(! is_resummable(ev.type())) return {0.};
auto AWZH_boson = std::find_if(
begin(ev.outgoing()), end(ev.outgoing()),
[](Particle const & p){return is_AWZH_boson(p);}
);
if(AWZH_boson == end(ev.outgoing()))
return {tree_kin_jets(ev)};
switch(AWZH_boson->type){
case pid::Higgs:
return {tree_kin_Higgs(ev)};
case pid::Wp:
case pid::Wm:
return {tree_kin_W(ev)};
case pid::Z_photon_mix:
return tree_kin_Z(ev);
// TODO
case pid::photon:
case pid::Z:
default:
throw not_implemented("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 lambda
){
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, lambda)*C_A;
} else{
wt *= C2Lipatovots(qip1, qi, pa, pb, p1, pn, lambda)*C_A;
}
qi = qip1;
}
return wt;
}
template<class InputIterator>
std::vector <double> FKL_ladder_weight_mix(
InputIterator begin_gluon, InputIterator end_gluon,
CLHEP::HepLorentzVector const & q0_t, CLHEP::HepLorentzVector const & q0_b,
CLHEP::HepLorentzVector const & pa, CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & p1, CLHEP::HepLorentzVector const & pn,
- double lambda
+ const double lambda
){
double wt_top = 1;
double wt_bot = 1;
double wt_mix = 1;
auto qi_t = q0_t;
auto qi_b = q0_b;
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_t = qi_t - g;
const auto qip1_b = qi_b - g;
if(treat_as_extremal(*gluon_it)){
wt_top *= C2Lipatovots(qip1_t, qi_t, pa, pb, lambda)*C_A;
wt_bot *= C2Lipatovots(qip1_b, qi_b, pa, pb, lambda)*C_A;
wt_mix *= C2Lipatovots_Mix(qip1_t, qi_t, qip1_b, qi_b, pa, pb, lambda)*C_A;
} else{
wt_top *= C2Lipatovots(qip1_t, qi_t, pa, pb, p1, pn, lambda)*C_A;
wt_bot *= C2Lipatovots(qip1_b, qi_b, pa, pb, p1, pn, lambda)*C_A;
wt_mix *= C2Lipatovots_Mix(qip1_t, qi_t, qip1_b, qi_b, pa, pb, p1, pn, lambda)*C_A;
}
qi_t = qip1_t;
qi_b = qip1_b;
}
return {wt_top, wt_bot, wt_mix};
}
} // namespace anonymous
std::vector<Particle> MatrixElement::tag_extremal_jet_partons(
Event const & ev
) const{
auto out_partons = filter_partons(ev.outgoing());
if(out_partons.size() == ev.jets().size()){
// no additional emissions in extremal jets, don't need to tag anything
for(auto & parton: out_partons){
parton.p.set_user_index(no_extremal_jet_idx);
}
return out_partons;
}
const auto & jets = ev.jets();
assert(jets.size() >= 2);
auto most_backward = begin(jets);
auto most_forward = end(jets) - 1;
// skip jets caused by unordered emission or qqx
if(ev.type() == event_type::unob || ev.type() == event_type::qqxexb){
assert(jets.size() >= 3);
++most_backward;
}
else if(ev.type() == event_type::unof || ev.type() == event_type::qqxexf){
assert(jets.size() >= 3);
--most_forward;
}
const auto extremal_jet_indices = ev.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(HEJ::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;
}
namespace {
double tree_kin_jets_qqxmid(
ParticleID aptype, ParticleID bptype, HLV pa, HLV pb,
std::vector<Particle> const & partons,
double lambda
){
HLV pq,pqbar;
const auto backmidquark = std::find_if(
begin(partons)+1, end(partons)-1,
[](Particle const & s){ return s.type != pid::gluon; }
);
assert(backmidquark!=end(partons)-1);
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;
const auto begin_ladder = cbegin(partons) + 1;
const auto end_ladder_1 = (backmidquark);
const auto begin_ladder_2 = (backmidquark+2);
const auto end_ladder = cend(partons) - 1;
for(auto parton_it = begin_ladder; parton_it < begin_ladder_2; ++parton_it){
qqxt -= to_HepLorentzVector(*parton_it);
}
const int nabove = std::distance(begin_ladder, backmidquark);
std::vector<HLV> partonsHLV;
partonsHLV.reserve(partons.size());
for (size_t i = 0; i != partons.size(); ++i) {
partonsHLV.push_back(to_HepLorentzVector(partons[i]));
}
const double current_factor = ME_qqxmid_current(
aptype, bptype, nabove, pa, pb,
pq, pqbar, partonsHLV
);
const double ladder_factor = FKL_ladder_weight(
begin_ladder, end_ladder_1,
q0, pa, pb, p1, pn,
lambda
)*FKL_ladder_weight(
begin_ladder_2, end_ladder,
qqxt, pa, pb, p1, pn,
lambda
);
return current_factor*ladder_factor;
}
template<class InIter, class partIter>
double tree_kin_jets_qqx(InIter BeginIn, InIter EndIn, partIter BeginPart,
partIter EndPart, double lambda){
const bool swap_q_qx = is_quark(*BeginPart);
const auto pgin = to_HepLorentzVector(*BeginIn);
const auto pb = to_HepLorentzVector(*(EndIn-1));
const auto pq = to_HepLorentzVector(*(BeginPart+(swap_q_qx?0:1)));
const auto pqbar = to_HepLorentzVector(*(BeginPart+(swap_q_qx?1:0)));
const auto p1 = to_HepLorentzVector(*(BeginPart));
const auto pn = to_HepLorentzVector(*(EndPart-1));
assert((BeginIn)->type==pid::gluon); // Incoming a must be gluon.
const double current_factor = ME_qqx_current(
(EndIn-1)->type, pgin, pq, pqbar, pn, pb, swap_q_qx
)/(4.*(N_C*N_C - 1.));
const double ladder_factor = FKL_ladder_weight(
(BeginPart+2), (EndPart-1),
pgin-pq-pqbar, pgin, pb, p1, pn, lambda
);
return current_factor*ladder_factor;
}
template<class InIter, class partIter>
double tree_kin_jets_uno(InIter BeginIn, InIter EndIn, partIter BeginPart,
partIter EndPart, double lambda){
const auto pa = to_HepLorentzVector(*BeginIn);
const auto pb = to_HepLorentzVector(*(EndIn-1));
const auto pg = to_HepLorentzVector(*BeginPart);
const auto p1 = to_HepLorentzVector(*(BeginPart+1));
const auto pn = to_HepLorentzVector(*(EndPart-1));
const double current_factor = ME_uno_current(
(BeginIn)->type, (EndIn-1)->type, pg, pn, pb, p1, pa
)/(4.*(N_C*N_C - 1.));
const double ladder_factor = FKL_ladder_weight(
(BeginPart+2), (EndPart-1),
pa-p1-pg, pa, pb, p1, pn, lambda
);
return current_factor*ladder_factor;
}
}
double MatrixElement::tree_kin_jets(Event const & ev) const {
auto const & incoming = ev.incoming();
const auto partons = tag_extremal_jet_partons(ev);
if (ev.type()==HEJ::event_type::FKL){
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,
param_.regulator_lambda
);
}
else if (ev.type()==HEJ::event_type::unordered_backward){
return tree_kin_jets_uno(incoming.begin(), incoming.end(),
partons.begin(), partons.end(),
param_.regulator_lambda);
}
else if (ev.type()==HEJ::event_type::unordered_forward){
return tree_kin_jets_uno(incoming.rbegin(), incoming.rend(),
partons.rbegin(), partons.rend(),
param_.regulator_lambda);
}
else if (ev.type()==HEJ::event_type::extremal_qqxb){
return tree_kin_jets_qqx(incoming.begin(), incoming.end(),
partons.begin(), partons.end(),
param_.regulator_lambda);
}
else if (ev.type()==HEJ::event_type::extremal_qqxf){
return tree_kin_jets_qqx(incoming.rbegin(), incoming.rend(),
partons.rbegin(), partons.rend(),
param_.regulator_lambda);
}
else if (ev.type()==HEJ::event_type::central_qqx){
return tree_kin_jets_qqxmid(incoming[0].type, incoming[1].type,
to_HepLorentzVector(incoming[0]),
to_HepLorentzVector(incoming[1]),
partons, param_.regulator_lambda);
}
else {
throw std::logic_error("Cannot reweight non-resummable processes in Pure Jets");
}
}
namespace{
double tree_kin_W_FKL(
ParticleID aptype, ParticleID bptype, HLV pa, HLV pb,
std::vector<Particle> const & partons,
HLV plbar, HLV pl,
double lambda, ParticleProperties const & Wprop
){
auto p1 = to_HepLorentzVector(partons[0]);
auto pn = to_HepLorentzVector(partons[partons.size() - 1]);
const auto begin_ladder = cbegin(partons) + 1;
const auto end_ladder = cend(partons) - 1;
bool wc = aptype==partons[0].type; //leg b emits w
auto q0 = pa - p1;
if(!wc)
q0 -= pl + plbar;
const double current_factor = ME_W_current(
aptype, bptype, pn, pb,
p1, pa, plbar, pl, wc, Wprop
);
const double ladder_factor = FKL_ladder_weight(
begin_ladder, end_ladder,
q0, pa, pb, p1, pn,
lambda
);
return current_factor*ladder_factor;
}
template<class InIter, class partIter>
double tree_kin_W_uno(InIter BeginIn, partIter BeginPart,
partIter EndPart, const HLV & plbar, const HLV & pl,
double lambda, ParticleProperties const & Wprop){
const auto pa = to_HepLorentzVector(*BeginIn);
const auto pb = to_HepLorentzVector(*(BeginIn+1));
const auto pg = to_HepLorentzVector(*BeginPart);
const auto p1 = to_HepLorentzVector(*(BeginPart+1));
const auto pn = to_HepLorentzVector(*(EndPart-1));
bool wc = (BeginIn)->type==(BeginPart+1)->type; //leg b emits w
auto q0 = pa - p1 - pg;
if(!wc)
q0 -= pl + plbar;
const double current_factor = ME_W_uno_current(
(BeginIn)->type, (BeginIn+1)->type, pn, pb,
p1, pa, pg, plbar, pl, wc, Wprop
);
const double ladder_factor = FKL_ladder_weight(
BeginPart+2, EndPart-1,
q0, pa, pb, p1, pn,
lambda
);
return current_factor*C_A*C_A/(N_C*N_C-1.)*ladder_factor;
}
template<class InIter, class partIter>
double tree_kin_W_qqx(InIter BeginIn, partIter BeginPart,
partIter EndPart, const HLV & plbar, const HLV & pl,
double lambda, ParticleProperties const & Wprop){
const bool swap_q_qx=is_quark(*BeginPart);
const auto pa = to_HepLorentzVector(*BeginIn);
const auto pb = to_HepLorentzVector(*(BeginIn+1));
const auto pq = to_HepLorentzVector(*(BeginPart+(swap_q_qx?0:1)));
const auto pqbar = to_HepLorentzVector(*(BeginPart+(swap_q_qx?1:0)));
const auto p1 = to_HepLorentzVector(*(BeginPart));
const auto pn = to_HepLorentzVector(*(EndPart-1));
const bool wc = (BeginIn+1)->type!=(EndPart-1)->type; //leg b emits w
auto q0 = pa - pq - pqbar;
if(!wc)
q0 -= pl + plbar;
const double current_factor = ME_W_qqx_current(
(BeginIn)->type, (BeginIn+1)->type, pa, pb,
pq, pqbar, pn, plbar, pl, swap_q_qx, wc, Wprop
);
const double ladder_factor = FKL_ladder_weight(
BeginPart+2, EndPart-1,
q0, pa, pb, p1, pn,
lambda
);
return current_factor*C_A*C_A/(N_C*N_C-1.)*ladder_factor;
}
double tree_kin_W_qqxmid(
ParticleID aptype, ParticleID bptype, HLV pa, HLV pb,
std::vector<Particle> const & partons,
HLV plbar, HLV pl,
double lambda, ParticleProperties const & Wprop
){
HLV pq,pqbar;
const auto backmidquark = std::find_if(
begin(partons)+1, end(partons)-1,
[](Particle const & s){ return s.type != pid::gluon; }
);
assert(backmidquark!=end(partons)-1);
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.front());
auto pn = to_HepLorentzVector(partons.back());
auto q0 = pa - p1;
// t-channel momentum after qqx
auto qqxt = q0;
bool wqq = backmidquark->type != -(backmidquark+1)->type; // qqx emit W
bool wc = !wqq & (aptype==partons.front().type); //leg b emits w
assert(!wqq || (wqq && !wc));
if(wqq){ // emission from qqx
qqxt -= pl + plbar;
} else if(!wc) { // emission from leg a
q0 -= pl + plbar;
qqxt -= pl + plbar;
}
const auto begin_ladder = cbegin(partons) + 1;
const auto end_ladder_1 = (backmidquark);
const auto begin_ladder_2 = (backmidquark+2);
const auto end_ladder = cend(partons) - 1;
for(auto parton_it = begin_ladder; parton_it < begin_ladder_2; ++parton_it){
qqxt -= to_HepLorentzVector(*parton_it);
}
const int nabove = std::distance(begin_ladder, backmidquark);
const int nbelow = std::distance(begin_ladder_2, 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]));
}
const double current_factor = ME_W_qqxmid_current(
aptype, bptype, nabove, nbelow, pa, pb,
pq, pqbar, partonsHLV, plbar, pl, wqq, wc, Wprop
);
const double ladder_factor = FKL_ladder_weight(
begin_ladder, end_ladder_1,
q0, pa, pb, p1, pn,
lambda
)*FKL_ladder_weight(
begin_ladder_2, end_ladder,
qqxt, pa, pb, p1, pn,
lambda
);
return current_factor*C_A*C_A/(N_C*N_C-1.)*ladder_factor;
}
} // namespace anonymous
double MatrixElement::tree_kin_W(Event const & ev) const {
using namespace event_type;
auto const & incoming(ev.incoming());
#ifndef NDEBUG
// assert that there is exactly one decay corresponding to the W
assert(ev.decays().size() == 1);
auto const & w_boson{
std::find_if(ev.outgoing().cbegin(), ev.outgoing().cend(),
[] (Particle const & p) -> bool {
return std::abs(p.type) == ParticleID::Wp;
}) };
assert(w_boson != ev.outgoing().cend());
assert( static_cast<long int>(ev.decays().cbegin()->first)
== std::distance(ev.outgoing().cbegin(), w_boson) );
#endif
// find decay products of W
auto const & decay{ ev.decays().cbegin()->second };
assert(decay.size() == 2);
assert( ( is_anylepton(decay.at(0)) && is_anyneutrino(decay.at(1)) )
|| ( is_anylepton(decay.at(1)) && is_anyneutrino(decay.at(0)) ) );
// get lepton & neutrino
HLV plbar, pl;
if (decay.at(0).type < 0){
plbar = to_HepLorentzVector(decay.at(0));
pl = to_HepLorentzVector(decay.at(1));
}
else{
pl = to_HepLorentzVector(decay.at(0));
plbar = to_HepLorentzVector(decay.at(1));
}
const auto pa = to_HepLorentzVector(incoming[0]);
const auto pb = to_HepLorentzVector(incoming[1]);
const auto partons = tag_extremal_jet_partons(ev);
if(ev.type() == FKL){
return tree_kin_W_FKL(incoming[0].type, incoming[1].type,
pa, pb, partons, plbar, pl,
param_.regulator_lambda,
param_.ew_parameters.Wprop());
}
if(ev.type() == unordered_backward){
return tree_kin_W_uno(cbegin(incoming), cbegin(partons),
cend(partons), plbar, pl,
param_.regulator_lambda,
param_.ew_parameters.Wprop());
}
if(ev.type() == unordered_forward){
return tree_kin_W_uno(crbegin(incoming), crbegin(partons),
crend(partons), plbar, pl,
param_.regulator_lambda,
param_.ew_parameters.Wprop());
}
if(ev.type() == extremal_qqxb){
return tree_kin_W_qqx(cbegin(incoming), cbegin(partons),
cend(partons), plbar, pl,
param_.regulator_lambda,
param_.ew_parameters.Wprop());
}
if(ev.type() == extremal_qqxf){
return tree_kin_W_qqx(crbegin(incoming), crbegin(partons),
crend(partons), plbar, pl,
param_.regulator_lambda,
param_.ew_parameters.Wprop());
}
assert(ev.type() == central_qqx);
return tree_kin_W_qqxmid(incoming[0].type, incoming[1].type,
pa, pb, partons, plbar, pl,
param_.regulator_lambda,
param_.ew_parameters.Wprop());
}
namespace{
std::vector <double> tree_kin_Z_FKL(
- ParticleID aptype, ParticleID bptype, HLV pa, HLV pb,
+ const ParticleID aptype, const ParticleID bptype,
+ HLV const & pa, HLV const & pb,
std::vector<Particle> const & partons,
- HLV plbar, HLV pl,
- double lambda, ParticleProperties const & Zprop,
- double stw2, double ctw
+ HLV const & plbar, HLV const & pl,
+ const double lambda, ParticleProperties const & Zprop,
+ const double stw2, const double ctw
){
- auto p1 = to_HepLorentzVector(partons[0]);
- auto pn = to_HepLorentzVector(partons[partons.size() - 1]);
+ const auto p1 = to_HepLorentzVector(partons[0]);
+ const auto pn = to_HepLorentzVector(partons[partons.size() - 1]);
const auto begin_ladder = cbegin(partons) + 1;
const auto end_ladder = cend(partons) - 1;
- std::vector <double> current_factor = ME_Z_current(
+ const std::vector <double> current_factor = ME_Z_current(
aptype, bptype, pn, pb, p1, pa,
plbar, pl, Zprop, stw2, ctw
);
std::vector <double> ladder_factor;
if(is_gluon(bptype)){
// This is a qg event
- auto q0 = pa-p1-plbar-pl;
+ const auto q0 = pa-p1-plbar-pl;
ladder_factor.push_back(FKL_ladder_weight(begin_ladder, end_ladder,
q0, pa, pb, p1, pn, lambda));
}else if(is_gluon(aptype)){
// This is a gq event
- auto q0 = pa-p1;
+ const auto q0 = pa-p1;
ladder_factor.push_back(FKL_ladder_weight(begin_ladder, end_ladder,
q0, pa, pb, p1, pn, lambda));
}else{
// This is a qq event
- auto q0 = pa-p1-plbar-pl;
- auto q1 = pa-p1;
+ const auto q0 = pa-p1-plbar-pl;
+ const auto q1 = pa-p1;
ladder_factor=FKL_ladder_weight_mix(begin_ladder, end_ladder,
q0, q1, pa, pb, p1, pn, lambda);
}
std::vector <double> result;
for(size_t i=0; i<current_factor.size(); i++){
result.push_back(current_factor.at(i)*ladder_factor.at(i));
}
return result;
}
template<class InIter, class partIter>
std::vector <double> tree_kin_Z_uno(InIter BeginIn, partIter BeginPart, partIter EndPart,
const HLV & plbar, const HLV & pl,
- double lambda, ParticleProperties const & Zprop,
- double stw2, double ctw){
+ const double lambda, ParticleProperties const & Zprop,
+ const double stw2, const double ctw){
const auto pa = to_HepLorentzVector(*BeginIn);
const auto pb = to_HepLorentzVector(*(BeginIn+1));
const auto pg = to_HepLorentzVector(*BeginPart);
const auto p1 = to_HepLorentzVector(*(BeginPart+1));
const auto pn = to_HepLorentzVector(*(EndPart-1));
const ParticleID aptype = (BeginIn)->type;
const ParticleID bptype = (BeginIn+1)->type;
- std::vector <double> current_factor = ME_Z_uno_current(
+ const std::vector <double> current_factor = ME_Z_uno_current(
aptype, bptype, pn, pb, p1, pa, pg,
plbar, pl, Zprop, stw2, ctw
);
std::vector <double> ladder_factor;
if(is_gluon(bptype)){
// This is a qg event
- auto q0 = pa-pg-p1-plbar-pl;
+ const auto q0 = pa-pg-p1-plbar-pl;
ladder_factor.push_back(FKL_ladder_weight(BeginPart+2, EndPart-1,
q0, pa, pb, p1, pn, lambda));
}else if(is_gluon(aptype)){
// This is a gq event
- auto q0 = pa-pg-p1;
+ const auto q0 = pa-pg-p1;
ladder_factor.push_back(FKL_ladder_weight(BeginPart+2, EndPart-1,
q0, pa, pb, p1, pn, lambda));
}else{
// This is a qq event
- auto q0 = pa-pg-p1-plbar-pl;
- auto q1 = pa-pg-p1;
+ const auto q0 = pa-pg-p1-plbar-pl;
+ const auto q1 = pa-pg-p1;
ladder_factor=FKL_ladder_weight_mix(BeginPart+2, EndPart-1,
q0, q1, pa, pb, p1, pn, lambda);
}
std::vector <double> result;
for(size_t i=0; i<current_factor.size(); i++){
result.push_back(current_factor.at(i)*ladder_factor.at(i));
}
return result;
}
} // namespace anonymous
std::vector<double> MatrixElement::tree_kin_Z(Event const & ev) const {
using namespace event_type;
auto const & incoming(ev.incoming());
// find decay products of Z
auto const & decay{ ev.decays().cbegin()->second };
assert(decay.size() == 2);
assert(is_anylepton(decay.at(0)) && !is_anyneutrino(decay.at(0))
&& decay.at(0).type==-decay.at(1).type);
// get leptons
HLV plbar, pl;
if (decay.at(0).type < 0){
plbar = to_HepLorentzVector(decay.at(0));
pl = to_HepLorentzVector(decay.at(1));
}
else{
pl = to_HepLorentzVector(decay.at(0));
plbar = to_HepLorentzVector(decay.at(1));
}
const auto pa = to_HepLorentzVector(incoming[0]);
const auto pb = to_HepLorentzVector(incoming[1]);
const auto partons = tag_extremal_jet_partons(ev);
- double stw2 = param_.ew_parameters.sin2_tw();
- double ctw = param_.ew_parameters.cos_tw();
+ const double stw2 = param_.ew_parameters.sin2_tw();
+ const double ctw = param_.ew_parameters.cos_tw();
if(ev.type() == FKL){
return tree_kin_Z_FKL(incoming[0].type, incoming[1].type,
pa, pb, partons, plbar, pl,
param_.regulator_lambda,
param_.ew_parameters.Zprop(),
stw2, ctw);
}
if(ev.type() == unordered_backward){
return tree_kin_Z_uno(cbegin(incoming), cbegin(partons),
cend(partons), plbar, pl,
param_.regulator_lambda,
param_.ew_parameters.Zprop(),
stw2, ctw);
}
if(ev.type() == unordered_forward){
return tree_kin_Z_uno(crbegin(incoming), crbegin(partons),
crend(partons), plbar, pl,
param_.regulator_lambda,
param_.ew_parameters.Zprop(),
stw2, ctw);
}
throw std::logic_error("Can only reweight FKL or uno processes in Z+Jets");
}
double MatrixElement::tree_kin_Higgs(Event const & ev) const {
if(is_uno(ev.type())){
return tree_kin_Higgs_between(ev);
}
if(ev.outgoing().front().type == pid::Higgs){
return tree_kin_Higgs_first(ev);
}
if(ev.outgoing().back().type == pid::Higgs){
return tree_kin_Higgs_last(ev);
}
return tree_kin_Higgs_between(ev);
}
namespace {
// Colour acceleration multipliers, for gluons see eq. (7) in arXiv:0910.5113
#ifdef HEJ_BUILD_WITH_QCDLOOP
// TODO: code duplication with jets.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 == pid::gluon) return K_g(pout, pin);
return C_F;
}
#endif
// Colour factor in strict MRK limit
double K_MRK(ParticleID type) {
return (type == pid::gluon)?C_A:C_F;
}
}
double MatrixElement::MH2_forwardH(
CLHEP::HepLorentzVector const & p1out,
CLHEP::HepLorentzVector const & p1in,
ParticleID type2,
CLHEP::HepLorentzVector const & p2out,
CLHEP::HepLorentzVector const & p2in,
CLHEP::HepLorentzVector const & pH,
double t1, double t2
) const{
ignore(p2out, p2in);
const double shat = p1in.invariantMass2(p2in);
const double vev = param_.ew_parameters.vev();
// gluon case
#ifdef HEJ_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*ME_Houtside_gq(
p1out, p1in, p2out, p2in, pH,
param_.Higgs_coupling.mt, param_.Higgs_coupling.include_bottom,
param_.Higgs_coupling.mb, vev
)/(4*(N_C*N_C - 1));
}
#endif
return K_MRK(type2)/C_A*9./2.*shat*shat*(
C2gHgp(p1in,p1out,pH,vev) + C2gHgm(p1in,p1out,pH,vev)
)/(t1*t2);
}
double MatrixElement::tree_kin_Higgs_first(Event const & ev) const {
auto const & incoming = ev.incoming();
auto const & outgoing = ev.outgoing();
assert(outgoing.front().type == pid::Higgs);
if(outgoing[1].type != pid::gluon) {
assert(incoming.front().type == outgoing[1].type);
return tree_kin_Higgs_between(ev);
}
const auto pH = to_HepLorentzVector(outgoing.front());
const auto partons = tag_extremal_jet_partons(
ev
);
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,
param_.regulator_lambda
);
}
double MatrixElement::tree_kin_Higgs_last(Event const & ev) const {
auto const & incoming = ev.incoming();
auto const & outgoing = ev.outgoing();
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(ev);
}
const auto pH = to_HepLorentzVector(outgoing.back());
const auto partons = tag_extremal_jet_partons(
ev
);
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,
param_.regulator_lambda
);
}
namespace {
template<class InIter, class partIter>
double tree_kin_Higgs_uno(InIter BeginIn, InIter EndIn, partIter BeginPart,
partIter EndPart, const HLV & qH, const HLV & qHp1,
double mt, bool inc_bot, double mb, double vev){
const auto pa = to_HepLorentzVector(*BeginIn);
const auto pb = to_HepLorentzVector(*(EndIn-1));
const auto pg = to_HepLorentzVector(*BeginPart);
const auto p1 = to_HepLorentzVector(*(BeginPart+1));
const auto pn = to_HepLorentzVector(*(EndPart-1));
return ME_Higgs_current_uno(
(BeginIn)->type, (EndIn-1)->type, pg, pn, pb, p1, pa,
qH, qHp1, mt, inc_bot, mb, vev
);
}
}
double MatrixElement::tree_kin_Higgs_between(Event const & ev) const {
using namespace event_type;
auto const & incoming = ev.incoming();
auto const & outgoing = ev.outgoing();
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);
const auto partons = tag_extremal_jet_partons(ev);
const auto pa = to_HepLorentzVector(incoming[0]);
const auto pb = to_HepLorentzVector(incoming[1]);
auto p1 = to_HepLorentzVector(
partons[(ev.type() == unob)?1:0]
);
auto pn = to_HepLorentzVector(
partons[partons.size() - ((ev.type() == unof)?2:1)]
);
auto first_after_Higgs = begin(partons) + (the_Higgs-begin(outgoing));
assert(
(first_after_Higgs == end(partons) && (
(ev.type() == unob)
|| partons.back().type != pid::gluon
))
|| first_after_Higgs->rapidity() >= the_Higgs->rapidity()
);
assert(
(first_after_Higgs == begin(partons) && (
(ev.type() == unof)
|| 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(ev.type() == FKL){
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,
param_.ew_parameters.vev()
);
}
else if(ev.type() == unob){
current_factor = HEJ::C_A*HEJ::C_A/2*tree_kin_Higgs_uno(
begin(incoming), end(incoming), begin(partons),
end(partons), qH, qH-pH, param_.Higgs_coupling.mt,
param_.Higgs_coupling.include_bottom, param_.Higgs_coupling.mb,
param_.ew_parameters.vev()
);
const auto p_unob = to_HepLorentzVector(partons.front());
q0 -= p_unob;
p1 += p_unob;
++begin_ladder;
}
else if(ev.type() == unof){
current_factor = HEJ::C_A*HEJ::C_A/2*tree_kin_Higgs_uno(
rbegin(incoming), rend(incoming), rbegin(partons),
rend(partons), qH-pH, qH, param_.Higgs_coupling.mt,
param_.Higgs_coupling.include_bottom, param_.Higgs_coupling.mb,
param_.ew_parameters.vev()
);
pn += to_HepLorentzVector(partons.back());
--end_ladder;
}
else{
throw std::logic_error("Can only reweight FKL or uno processes in H+Jets");
}
const double ladder_factor = FKL_ladder_weight(
begin_ladder, first_after_Higgs,
q0, pa, pb, p1, pn,
param_.regulator_lambda
)*FKL_ladder_weight(
first_after_Higgs, end_ladder,
qH - pH, pa, pb, p1, pn,
param_.regulator_lambda
);
return current_factor*C_A*C_A/(N_C*N_C-1.)*ladder_factor;
}
namespace {
double get_AWZH_coupling(Event const & ev, double alpha_s, double alpha_w) {
const auto AWZH_boson = std::find_if(
begin(ev.outgoing()), end(ev.outgoing()),
[](auto const & p){return is_AWZH_boson(p);}
);
if(AWZH_boson == end(ev.outgoing())) return 1.;
switch(AWZH_boson->type){
case pid::Higgs:
return alpha_s*alpha_s;
case pid::Wp:
case pid::Wm:
return alpha_w*alpha_w;
case pid::Z_photon_mix:
return alpha_w*alpha_w;
// TODO
case pid::photon:
case pid::Z:
default:
throw not_implemented("Emission of boson of unsupported type");
}
}
}
double MatrixElement::tree_param(Event const & ev, double mur) const {
assert(is_resummable(ev.type()));
const auto begin_partons = ev.begin_partons();
const auto end_partons = ev.end_partons();
const auto num_partons = std::distance(begin_partons, end_partons);
const double alpha_s = alpha_s_(mur);
const double gs2 = 4.*M_PI*alpha_s;
double res = std::pow(gs2, num_partons);
if(param_.log_correction){
// use alpha_s(q_perp), evolved to mur
assert(num_partons >= 2);
const auto first_emission = std::next(begin_partons);
const auto last_emission = std::prev(end_partons);
for(auto parton = first_emission; parton != last_emission; ++parton){
res *= 1. + alpha_s/(2.*M_PI)*beta0*log(mur/parton->perp());
}
}
return get_AWZH_coupling(ev, alpha_s, param_.ew_parameters.alpha_w())*res;
}
} // namespace HEJ
diff --git a/src/Zjets.cc b/src/Zjets.cc
index 42d5243..76dcc40 100644
--- a/src/Zjets.cc
+++ b/src/Zjets.cc
@@ -1,509 +1,517 @@
/**
* \authors The HEJ collaboration (see AUTHORS for details)
* \date 2020
* \copyright GPLv2 or later
*/
#include <vector>
#include "HEJ/Constants.hh"
#include "HEJ/EWConstants.hh"
#include "HEJ/PDG_codes.hh"
#include "HEJ/jets.hh"
// generated headers
#include "HEJ/currents/jZ_j.hh"
#include "HEJ/currents/jZuno_j.hh"
#include "HEJ/currents/jZ_juno.hh"
using HEJ::Helicity;
using HEJ::ParticleProperties;
using HEJ::ParticleID;
namespace helicity = HEJ::helicity;
namespace {
// Z propagator
- COM ZProp(double q, ParticleProperties const & zprop){
+ COM ZProp(const double q, ParticleProperties const & zprop){
return 1. / (q - zprop.mass*zprop.mass + COM(0.,1.)*zprop.width*zprop.mass);
}
// Photon propagator
- COM GProp(double q) {
+ COM GProp(const double q) {
return 1. / q;
}
// Weak charge
- double Zq (ParticleID PID, Helicity h, double stw2, double ctw) {
+ double Zq (const ParticleID PID, const Helicity h, const double stw2, const double ctw) {
using namespace HEJ::pid;
// Positive Spin
if (h == helicity::plus) {
// quarks
if (PID == d || PID == s || PID == b) return (+ 1.0 * stw2 / 3.0) / ctw;
if (PID == u || PID == c) return (- 2.0 * stw2 / 3.0) / ctw;
// antiquarks
if (PID == d_bar || PID == s_bar || PID == b_bar) return (+ 0.5 - 1.0 * stw2 / 3.0) / ctw;
if (PID == u_bar || PID == c_bar) return (- 0.5 + 2.0 * stw2 / 3.0) / ctw;
// electron
if (PID == electron) return stw2 / ctw;
}
// Negative Spin
else {
// quarks
if (PID == d || PID == s || PID == b) return (- 0.5 + 1.0 * stw2 / 3.0) / ctw;
if (PID == u || PID == c) return (+ 0.5 - 2.0 * stw2 / 3.0) / ctw;
// antiquarks
if (PID == d_bar || PID == s_bar || PID == b_bar) return (- 1.0 * stw2 / 3.0) / ctw;
if (PID == u_bar || PID == c_bar) return (+ 2.0 * stw2 / 3.0) / ctw;
// electron
if (PID == electron) return (-1.0 / 2.0 + stw2) / ctw;
}
throw std::logic_error("ERROR! No weak charge found");
}
// Electric charge
- double Gq (ParticleID PID) {
+ double Gq (const ParticleID PID) {
using namespace HEJ::pid;
if (PID == d || PID == s || PID == b) return -1./3.;
if (PID == u || PID == c) return +2./3.;
if (PID == d_bar || PID == s_bar || PID == b_bar) return +1./3.;
if (PID == u_bar || PID == c_bar) return -2./3.;
throw std::logic_error("ERROR! No electric charge found");
}
//! Prefactor for Z+Jets Contributions
/**
* @brief Z+Jets Contributions Prefactor
* @param aptype Incoming Particle 1 type (Z emission)
* @param PZ Z Propagator
* @param PG Photon Propagator
* @param stw2 Value of sin(theta_w)^2
* @param ctw Value of cos(theta_w)
* @param res Ouput: pref[h1][hl]
*
* Calculates prefactor for Z+Jets (includes couplings and propagators)
*/
- void Z_amp_pref(ParticleID aptype, COM PZ, COM PG, double stw2, double ctw, COM (&res)[2][2]
+ void Z_amp_pref(const ParticleID aptype, const COM PZ, const COM PG,
+ const double stw2, const double ctw, COM (&res)[2][2]
){
using helicity::plus;
using helicity::minus;
const double Zq_a_p = Zq(aptype, plus, stw2, ctw);
const double Zq_a_m = Zq(aptype, minus, stw2, ctw);
const double Ze_p = Zq(HEJ::pid::electron, plus, stw2, ctw);
const double Ze_m = Zq(HEJ::pid::electron, minus, stw2, ctw);
const double Gq_a = Gq(aptype);
res[1][1] = -2.*(Zq_a_p * Ze_p * PZ - Gq_a * PG * stw2);
res[1][0] = -2.*(Zq_a_p * Ze_m * PZ - Gq_a * PG * stw2);
res[0][0] = -2.*(Zq_a_m * Ze_m * PZ - Gq_a * PG * stw2);
res[0][1] = -2.*(Zq_a_m * Ze_p * PZ - Gq_a * PG * stw2);
}
//! Z+Jets FKL Contribution
/**
* @brief Z+Jets FKL Contribution
* @param pa Incoming Particle 1 (Z emission)
* @param pb Incoming Particle 2
* @param p1 Outgoing Particle 1 (Z emission)
* @param p2 Outgoing Particle 2
* @param pep Outgoing positron
* @param pem Outgoing electron
* @param res Ouput: jZ_j[h1][hl][h2]
*
* Calculates j_Z^\mu j_\mu.
*/
- void jZ_j(HLV pa, HLV pb, HLV p1, HLV p2, HLV pep, HLV pem, COM (&res)[2][2][2]
+ void jZ_j(const HLV & pa, const HLV & pb, const HLV & p1, const HLV & p2,
+ const HLV & pep, const HLV & pem, COM (&res)[2][2][2]
){
using helicity::plus;
using helicity::minus;
res[1][1][1] = HEJ::jZ_j<plus, plus, plus> (pa, p1, pb, p2, pem, pep);
res[1][1][0] = HEJ::jZ_j<plus, plus, minus>(pa, p1, pb, p2, pem, pep);
res[1][0][1] = HEJ::jZ_j<plus, minus, plus> (pa, p1, pb, p2, pem, pep);
res[1][0][0] = HEJ::jZ_j<plus, minus, minus>(pa, p1, pb, p2, pem, pep);
res[0][0][0] = conj(res[1][1][1]);
res[0][0][1] = conj(res[1][1][0]);
res[0][1][0] = conj(res[1][0][1]);
res[0][1][1] = conj(res[1][0][0]);
}
/**
* @brief Z+Jets Unordered Contribution, unordered on Z side
* @param pa Incoming Particle 1 (Z and Uno emission)
* @param pb Incoming Particle 2
* @param pg Unordered Gluon
* @param p1 Outgoing Particle 1 (Z and Uno emission)
* @param p2 Outgoing Particle 2
* @param pep Outgoing positron
* @param pem Outgoing electron
* @param X Ouput: (U1-L)[h1][hl][h2][hg]
* @param Y Ouput: (U2+L)[h1][hl][h2][hg]
*
* Calculates j_Z_{uno}^\mu j_\mu. Ie, unordered with Z emission same side.
*/
- void jZuno_j(HLV pa, HLV pb, HLV pg, HLV p1, HLV p2, HLV pep, HLV pem,
- COM (&X)[2][2][2][2], COM (&Y)[2][2][2][2]
+ void jZuno_j(const HLV & pa, const HLV & pb, const HLV & pg, const HLV & p1, const HLV & p2,
+ const HLV & pep, const HLV & pem, COM (&X)[2][2][2][2], COM (&Y)[2][2][2][2]
){
using helicity::plus;
using helicity::minus;
COM U1[2][2][2][2];
U1[1][1][1][1] = HEJ::U1<plus, plus, plus, plus> (p1, p2, pa, pb, pg, pem, pep);
U1[1][1][1][0] = HEJ::U1<plus, plus, plus, minus>(p1, p2, pa, pb, pg, pem, pep);
U1[1][1][0][1] = HEJ::U1<plus, plus, minus, plus> (p1, p2, pa, pb, pg, pem, pep);
U1[1][1][0][0] = HEJ::U1<plus, plus, minus, minus>(p1, p2, pa, pb, pg, pem, pep);
U1[1][0][1][1] = HEJ::U1<plus, minus, plus, plus> (p1, p2, pa, pb, pg, pem, pep);
U1[1][0][1][0] = HEJ::U1<plus, minus, plus, minus>(p1, p2, pa, pb, pg, pem, pep);
U1[1][0][0][1] = HEJ::U1<plus, minus, minus, plus> (p1, p2, pa, pb, pg, pem, pep);
U1[1][0][0][0] = HEJ::U1<plus, minus, minus, minus>(p1, p2, pa, pb, pg, pem, pep);
U1[0][1][1][1] = HEJ::U1<minus, plus, plus, plus> (p1, p2, pa, pb, pg, pem, pep);
U1[0][1][1][0] = HEJ::U1<minus, plus, plus, minus>(p1, p2, pa, pb, pg, pem, pep);
U1[0][1][0][1] = HEJ::U1<minus, plus, minus, plus> (p1, p2, pa, pb, pg, pem, pep);
U1[0][1][0][0] = HEJ::U1<minus, plus, minus, minus>(p1, p2, pa, pb, pg, pem, pep);
U1[0][0][1][1] = HEJ::U1<minus, minus, plus, plus> (p1, p2, pa, pb, pg, pem, pep);
U1[0][0][1][0] = HEJ::U1<minus, minus, plus, minus>(p1, p2, pa, pb, pg, pem, pep);
U1[0][0][0][1] = HEJ::U1<minus, minus, minus, plus> (p1, p2, pa, pb, pg, pem, pep);
U1[0][0][0][0] = HEJ::U1<minus, minus, minus, minus>(p1, p2, pa, pb, pg, pem, pep);
COM U2[2][2][2][2];
U2[1][1][1][1] = HEJ::U2<plus, plus, plus, plus> (p1, p2, pa, pb, pg, pem, pep);
U2[1][1][1][0] = HEJ::U2<plus, plus, plus, minus>(p1, p2, pa, pb, pg, pem, pep);
U2[1][1][0][1] = HEJ::U2<plus, plus, minus, plus> (p1, p2, pa, pb, pg, pem, pep);
U2[1][1][0][0] = HEJ::U2<plus, plus, minus, minus>(p1, p2, pa, pb, pg, pem, pep);
U2[1][0][1][1] = HEJ::U2<plus, minus, plus, plus> (p1, p2, pa, pb, pg, pem, pep);
U2[1][0][1][0] = HEJ::U2<plus, minus, plus, minus>(p1, p2, pa, pb, pg, pem, pep);
U2[1][0][0][1] = HEJ::U2<plus, minus, minus, plus> (p1, p2, pa, pb, pg, pem, pep);
U2[1][0][0][0] = HEJ::U2<plus, minus, minus, minus>(p1, p2, pa, pb, pg, pem, pep);
U2[0][1][1][1] = HEJ::U2<minus, plus, plus, plus> (p1, p2, pa, pb, pg, pem, pep);
U2[0][1][1][0] = HEJ::U2<minus, plus, plus, minus>(p1, p2, pa, pb, pg, pem, pep);
U2[0][1][0][1] = HEJ::U2<minus, plus, minus, plus> (p1, p2, pa, pb, pg, pem, pep);
U2[0][1][0][0] = HEJ::U2<minus, plus, minus, minus>(p1, p2, pa, pb, pg, pem, pep);
U2[0][0][1][1] = HEJ::U2<minus, minus, plus, plus> (p1, p2, pa, pb, pg, pem, pep);
U2[0][0][1][0] = HEJ::U2<minus, minus, plus, minus>(p1, p2, pa, pb, pg, pem, pep);
U2[0][0][0][1] = HEJ::U2<minus, minus, minus, plus> (p1, p2, pa, pb, pg, pem, pep);
U2[0][0][0][0] = HEJ::U2<minus, minus, minus, minus>(p1, p2, pa, pb, pg, pem, pep);
COM L[2][2][2][2];
L[1][1][1][1] = HEJ::L<plus, plus, plus, plus> (p1, p2, pa, pb, pg, pem, pep);
L[1][1][1][0] = HEJ::L<plus, plus, plus, minus>(p1, p2, pa, pb, pg, pem, pep);
L[1][1][0][1] = HEJ::L<plus, plus, minus, plus> (p1, p2, pa, pb, pg, pem, pep);
L[1][1][0][0] = HEJ::L<plus, plus, minus, minus>(p1, p2, pa, pb, pg, pem, pep);
L[1][0][1][1] = HEJ::L<plus, minus, plus, plus> (p1, p2, pa, pb, pg, pem, pep);
L[1][0][1][0] = HEJ::L<plus, minus, plus, minus>(p1, p2, pa, pb, pg, pem, pep);
L[1][0][0][1] = HEJ::L<plus, minus, minus, plus> (p1, p2, pa, pb, pg, pem, pep);
L[1][0][0][0] = HEJ::L<plus, minus, minus, minus>(p1, p2, pa, pb, pg, pem, pep);
L[0][1][1][1] = HEJ::L<minus, plus, plus, plus> (p1, p2, pa, pb, pg, pem, pep);
L[0][1][1][0] = HEJ::L<minus, plus, plus, minus>(p1, p2, pa, pb, pg, pem, pep);
L[0][1][0][1] = HEJ::L<minus, plus, minus, plus> (p1, p2, pa, pb, pg, pem, pep);
L[0][1][0][0] = HEJ::L<minus, plus, minus, minus>(p1, p2, pa, pb, pg, pem, pep);
L[0][0][1][1] = HEJ::L<minus, minus, plus, plus> (p1, p2, pa, pb, pg, pem, pep);
L[0][0][1][0] = HEJ::L<minus, minus, plus, minus>(p1, p2, pa, pb, pg, pem, pep);
L[0][0][0][1] = HEJ::L<minus, minus, minus, plus> (p1, p2, pa, pb, pg, pem, pep);
L[0][0][0][0] = HEJ::L<minus, minus, minus, minus>(p1, p2, pa, pb, pg, pem, pep);
for(int h1=0; h1<2; h1++){
for(int hl=0; hl<2; hl++){
for(int h2=0; h2<2; h2++){
for(int hg=0; hg<2; hg++){
X[h1][hl][h2][hg] = U1[h1][hl][h2][hg] - L[h1][hl][h2][hg];
Y[h1][hl][h2][hg] = U2[h1][hl][h2][hg] + L[h1][hl][h2][hg];
}
}
}
}
}
/**
* @brief Z+Jets Unordered Contribution, unordered opposite to Z side
* @param pa Incoming Particle 1 (Z emission)
* @param pb Incoming Particle 2 (unordered emission)
* @param p1 Outgoing Particle 1 (Z emission)
* @param p2 Outgoing Particle 2 (unordered emission)
* @param pg Unordered Gluon
* @param pep Outgoing positron
* @param pem Outgoing electron
* @param X Ouput: (U1-L)[h1][hl][h2][hg]
* @param Y Ouput: (U2+L)[h1][hl][h2][hg]
*
* Calculates j_Z^\mu j_{uno}_\mu. Ie, unordered with Z emission opposite side.
*/
- void jZ_juno(HLV pa, HLV pb, HLV p1, HLV p2, HLV pg, HLV pep, HLV pem,
- COM (&X)[2][2][2][2], COM (&Y)[2][2][2][2]
+ void jZ_juno(const HLV & pa, const HLV & pb, const HLV & p1, const HLV & p2, const HLV & pg,
+ const HLV & pep, const HLV & pem, COM (&X)[2][2][2][2], COM (&Y)[2][2][2][2]
){
using helicity::plus;
using helicity::minus;
COM U1[2][2][2][2];
U1[1][1][1][1] = HEJ::U1_jZ<plus, plus, plus, plus> (pa, p1, pb, p2, pg, pem, pep);
U1[1][1][1][0] = HEJ::U1_jZ<plus, plus, plus, minus>(pa, p1, pb, p2, pg, pem, pep);
U1[1][1][0][1] = HEJ::U1_jZ<plus, plus, minus, plus> (pa, p1, pb, p2, pg, pem, pep);
U1[1][1][0][0] = HEJ::U1_jZ<plus, plus, minus, minus>(pa, p1, pb, p2, pg, pem, pep);
U1[1][0][1][1] = HEJ::U1_jZ<plus, minus, plus, plus> (pa, p1, pb, p2, pg, pem, pep);
U1[1][0][1][0] = HEJ::U1_jZ<plus, minus, plus, minus>(pa, p1, pb, p2, pg, pem, pep);
U1[1][0][0][1] = HEJ::U1_jZ<plus, minus, minus, plus> (pa, p1, pb, p2, pg, pem, pep);
U1[1][0][0][0] = HEJ::U1_jZ<plus, minus, minus, minus>(pa, p1, pb, p2, pg, pem, pep);
U1[0][1][1][1] = HEJ::U1_jZ<minus, plus, plus, plus> (pa, p1, pb, p2, pg, pem, pep);
U1[0][1][1][0] = HEJ::U1_jZ<minus, plus, plus, minus>(pa, p1, pb, p2, pg, pem, pep);
U1[0][1][0][1] = HEJ::U1_jZ<minus, plus, minus, plus> (pa, p1, pb, p2, pg, pem, pep);
U1[0][1][0][0] = HEJ::U1_jZ<minus, plus, minus, minus>(pa, p1, pb, p2, pg, pem, pep);
U1[0][0][1][1] = HEJ::U1_jZ<minus, minus, plus, plus> (pa, p1, pb, p2, pg, pem, pep);
U1[0][0][1][0] = HEJ::U1_jZ<minus, minus, plus, minus>(pa, p1, pb, p2, pg, pem, pep);
U1[0][0][0][1] = HEJ::U1_jZ<minus, minus, minus, plus> (pa, p1, pb, p2, pg, pem, pep);
U1[0][0][0][0] = HEJ::U1_jZ<minus, minus, minus, minus>(pa, p1, pb, p2, pg, pem, pep);
COM U2[2][2][2][2];
U2[1][1][1][1] = HEJ::U2_jZ<plus, plus, plus, plus> (pa, p1, pb, p2, pg, pem, pep);
U2[1][1][1][0] = HEJ::U2_jZ<plus, plus, plus, minus>(pa, p1, pb, p2, pg, pem, pep);
U2[1][1][0][1] = HEJ::U2_jZ<plus, plus, minus, plus> (pa, p1, pb, p2, pg, pem, pep);
U2[1][1][0][0] = HEJ::U2_jZ<plus, plus, minus, minus>(pa, p1, pb, p2, pg, pem, pep);
U2[1][0][1][1] = HEJ::U2_jZ<plus, minus, plus, plus> (pa, p1, pb, p2, pg, pem, pep);
U2[1][0][1][0] = HEJ::U2_jZ<plus, minus, plus, minus>(pa, p1, pb, p2, pg, pem, pep);
U2[1][0][0][1] = HEJ::U2_jZ<plus, minus, minus, plus> (pa, p1, pb, p2, pg, pem, pep);
U2[1][0][0][0] = HEJ::U2_jZ<plus, minus, minus, minus>(pa, p1, pb, p2, pg, pem, pep);
U2[0][1][1][1] = HEJ::U2_jZ<minus, plus, plus, plus> (pa, p1, pb, p2, pg, pem, pep);
U2[0][1][1][0] = HEJ::U2_jZ<minus, plus, plus, minus>(pa, p1, pb, p2, pg, pem, pep);
U2[0][1][0][1] = HEJ::U2_jZ<minus, plus, minus, plus> (pa, p1, pb, p2, pg, pem, pep);
U2[0][1][0][0] = HEJ::U2_jZ<minus, plus, minus, minus>(pa, p1, pb, p2, pg, pem, pep);
U2[0][0][1][1] = HEJ::U2_jZ<minus, minus, plus, plus> (pa, p1, pb, p2, pg, pem, pep);
U2[0][0][1][0] = HEJ::U2_jZ<minus, minus, plus, minus>(pa, p1, pb, p2, pg, pem, pep);
U2[0][0][0][1] = HEJ::U2_jZ<minus, minus, minus, plus> (pa, p1, pb, p2, pg, pem, pep);
U2[0][0][0][0] = HEJ::U2_jZ<minus, minus, minus, minus>(pa, p1, pb, p2, pg, pem, pep);
COM L[2][2][2][2];
L[1][1][1][1] = HEJ::L_jZ<plus, plus, plus, plus> (pa, p1, pb, p2, pg, pem, pep);
L[1][1][1][0] = HEJ::L_jZ<plus, plus, plus, minus>(pa, p1, pb, p2, pg, pem, pep);
L[1][1][0][1] = HEJ::L_jZ<plus, plus, minus, plus> (pa, p1, pb, p2, pg, pem, pep);
L[1][1][0][0] = HEJ::L_jZ<plus, plus, minus, minus>(pa, p1, pb, p2, pg, pem, pep);
L[1][0][1][1] = HEJ::L_jZ<plus, minus, plus, plus> (pa, p1, pb, p2, pg, pem, pep);
L[1][0][1][0] = HEJ::L_jZ<plus, minus, plus, minus>(pa, p1, pb, p2, pg, pem, pep);
L[1][0][0][1] = HEJ::L_jZ<plus, minus, minus, plus> (pa, p1, pb, p2, pg, pem, pep);
L[1][0][0][0] = HEJ::L_jZ<plus, minus, minus, minus>(pa, p1, pb, p2, pg, pem, pep);
L[0][1][1][1] = HEJ::L_jZ<minus, plus, plus, plus> (pa, p1, pb, p2, pg, pem, pep);
L[0][1][1][0] = HEJ::L_jZ<minus, plus, plus, minus>(pa, p1, pb, p2, pg, pem, pep);
L[0][1][0][1] = HEJ::L_jZ<minus, plus, minus, plus> (pa, p1, pb, p2, pg, pem, pep);
L[0][1][0][0] = HEJ::L_jZ<minus, plus, minus, minus>(pa, p1, pb, p2, pg, pem, pep);
L[0][0][1][1] = HEJ::L_jZ<minus, minus, plus, plus> (pa, p1, pb, p2, pg, pem, pep);
L[0][0][1][0] = HEJ::L_jZ<minus, minus, plus, minus>(pa, p1, pb, p2, pg, pem, pep);
L[0][0][0][1] = HEJ::L_jZ<minus, minus, minus, plus> (pa, p1, pb, p2, pg, pem, pep);
L[0][0][0][0] = HEJ::L_jZ<minus, minus, minus, minus>(pa, p1, pb, p2, pg, pem, pep);
for(int h1=0; h1<2; h1++){
for(int hl=0; hl<2; hl++){
for(int h2=0; h2<2; h2++){
for(int hg=0; hg<2; hg++){
X[h1][hl][h2][hg] = U1[h1][hl][h2][hg] - L[h1][hl][h2][hg];
Y[h1][hl][h2][hg] = U2[h1][hl][h2][hg] + L[h1][hl][h2][hg];
}
}
}
}
}
} // Anonymous Namespace
-std::vector <double> ME_Z_qQ(HLV pa, HLV pb, HLV p1, HLV p2, HLV pep, HLV pem,
- ParticleID aptype, ParticleID bptype,
+std::vector <double> ME_Z_qQ(const HLV & pa, const HLV & pb, const HLV & p1, const HLV & p2,
+ const HLV & pep, const HLV & pem,
+ const ParticleID aptype, const ParticleID bptype,
ParticleProperties const & zprop,
- double stw2, double ctw
+ const double stw2, const double ctw
){
const HLV pZ = pep + pem;
const COM PZ = ZProp(pZ.m2(), zprop);
const COM PG = GProp(pZ.m2());
COM pref_top[2][2], pref_bot[2][2];
Z_amp_pref(aptype, PZ, PG, stw2, ctw, pref_top);
Z_amp_pref(bptype, PZ, PG, stw2, ctw, pref_bot);
COM Coeff_top[2][2][2], Coeff_bot[2][2][2];
jZ_j(pa, pb, p1, p2, pep, pem, Coeff_top);
jZ_j(pb, pa, p2, p1, pep, pem, Coeff_bot);
double sum_top=0., sum_bot=0., sum_mix=0.;
for(int h1=0; h1<2; h1++){
for(int hl=0; hl<2; hl++){
for(int h2=0; h2<2; h2++){
- COM res_top = pref_top[h1][hl] * Coeff_top[h1][hl][h2];
- COM res_bot = pref_bot[h2][hl] * Coeff_bot[h2][hl][h1];
+ const COM res_top = pref_top[h1][hl] * Coeff_top[h1][hl][h2];
+ const COM res_bot = pref_bot[h2][hl] * Coeff_bot[h2][hl][h1];
sum_top += norm(res_top);
sum_bot += norm(res_bot);
sum_mix += 2.0 * real(res_top * conj(res_bot));
}
}
}
const double t1_top = (pa-p1-pZ).m2();
const double t2_top = (pb-p2 ).m2();
const double t1_bot = (pa-p1 ).m2();
const double t2_bot = (pb-p2-pZ).m2();
sum_top /= t1_top * t2_top;
sum_bot /= t1_bot * t2_bot;
sum_mix /= sqrt(t1_top * t2_top * t1_bot * t2_bot);
// Colour factor: (CF*CA)/2
// Colour and helicity average: 1/(4*Nc^2)
const double pref = (HEJ::C_F*HEJ::C_A) / (8*HEJ::N_C*HEJ::N_C);
return {sum_top*pref, sum_bot*pref, sum_mix*pref};
}
-double ME_Z_qg(HLV pa, HLV pb, HLV p1, HLV p2, HLV pep, HLV pem,
- ParticleID aptype, ParticleID /*bptype*/,
+double ME_Z_qg(const HLV & pa, const HLV & pb, const HLV & p1, const HLV & p2,
+ const HLV & pep, const HLV & pem,
+ const ParticleID aptype, const ParticleID /*bptype*/,
ParticleProperties const & zprop,
- double stw2, double ctw
+ const double stw2, const double ctw
){
const HLV pZ = pep + pem;
const COM PZ = ZProp(pZ.m2(), zprop);
const COM PG = GProp(pZ.m2());
COM pref[2][2], Coeff[2][2][2];
Z_amp_pref(aptype, PZ, PG, stw2, ctw, pref);
jZ_j(pa, pb, p1, p2, pep, pem, Coeff);
double sum = 0.;
for(int h1=0; h1<2; h1++){
for(int hl=0; hl<2; hl++){
for(int h2=0; h2<2; h2++){
sum += norm(pref[h1][hl] * Coeff[h1][hl][h2]);
}
}
}
sum /= (pa-p1-pZ).m2()*(pb-p2).m2();
// Colour factor: (CF*CA)/2
// Colour and helicity average: 1/(4*Nc^2)
// Divide by CF because of gluon (K_g -> CA)
sum *= HEJ::C_A / (8*HEJ::N_C*HEJ::N_C);
// Multiply by CAM
return sum * K_g(p2, pb);
}
-std::vector <double> ME_Zuno_qQ(HLV pa, HLV pb, HLV pg, HLV p1, HLV p2, HLV pep, HLV pem,
- ParticleID aptype, ParticleID bptype,
+std::vector <double> ME_Zuno_qQ(const HLV & pa, const HLV & pb,
+ const HLV & pg, const HLV & p1, const HLV & p2,
+ const HLV & pep, const HLV & pem,
+ const ParticleID aptype, const ParticleID bptype,
ParticleProperties const & zprop,
- double stw2, double ctw
+ const double stw2, const double ctw
){
using HEJ::C_A;
using HEJ::C_F;
const HLV pZ = pep + pem;
const COM PZ = ZProp(pZ.m2(), zprop);
const COM PG = GProp(pZ.m2());
COM prefact_top[2][2], prefact_bot[2][2];
Z_amp_pref(aptype, PZ, PG, stw2, ctw, prefact_top);
Z_amp_pref(bptype, PZ, PG, stw2, ctw, prefact_bot);
COM CoeffX_top[2][2][2][2], CoeffY_top[2][2][2][2];
jZuno_j(pa, pb, pg, p1, p2, pep, pem, CoeffX_top, CoeffY_top);
COM CoeffX_bot[2][2][2][2], CoeffY_bot[2][2][2][2];
jZ_juno(pb, pa, p2, p1, pg, pep, pem, CoeffX_bot, CoeffY_bot);
double sum_top=0., sum_bot=0., sum_mix=0.;
for(int h1=0; h1<2; h1++){
for(int hl=0; hl<2; hl++){
for(int h2=0; h2<2; h2++){
for(int hg=0; hg<2; hg++){
- COM pref_top = prefact_top[h1][hl];
- COM X_top = CoeffX_top[h1][hl][h2][hg];
- COM Y_top = CoeffY_top[h1][hl][h2][hg];
+ const COM pref_top = prefact_top[h1][hl];
+ const COM X_top = CoeffX_top[h1][hl][h2][hg];
+ const COM Y_top = CoeffY_top[h1][hl][h2][hg];
- COM pref_bot = prefact_bot[h2][hl];
- COM X_bot = CoeffX_bot[h2][hl][h1][hg];
- COM Y_bot = CoeffY_bot[h2][hl][h1][hg];
+ const COM pref_bot = prefact_bot[h2][hl];
+ const COM X_bot = CoeffX_bot[h2][hl][h1][hg];
+ const COM Y_bot = CoeffY_bot[h2][hl][h1][hg];
sum_top += norm(pref_top) * (C_A*C_F*C_F/2.*(norm(X_top)+norm(Y_top))
- C_F/2.*(X_top*conj(Y_top)).real());
sum_bot += norm(pref_bot) * (C_A*C_F*C_F/2.*(norm(X_bot)+norm(Y_bot))
- C_F/2.*(X_bot*conj(Y_bot)).real());
- COM XX = C_A*C_F*C_F/2. * pref_top * X_top * conj(pref_bot * X_bot);
- COM YY = C_A*C_F*C_F/2. * pref_top * Y_top * conj(pref_bot * Y_bot);
- COM XY = -C_F/2. * (pref_top * X_top * conj(pref_bot * Y_bot)
- + pref_top * Y_top * conj(pref_bot * X_bot));
+ const COM XX = C_A*C_F*C_F/2. * pref_top * X_top * conj(pref_bot * X_bot);
+ const COM YY = C_A*C_F*C_F/2. * pref_top * Y_top * conj(pref_bot * Y_bot);
+ const COM XY = -C_F/2. * (pref_top * X_top * conj(pref_bot * Y_bot)
+ + pref_top * Y_top * conj(pref_bot * X_bot));
sum_mix += 2.0 * real(XX + YY + XY);
}
}
}
}
const double t1_top = (pa-pg-p1-pZ).m2();
const double t2_top = (pb-p2 ).m2();
const double t1_bot = (pa-pg-p1).m2();
const double t2_bot = (pb-p2-pZ).m2();
sum_top /= t1_top * t2_top;
sum_bot /= t1_bot * t2_bot;
sum_mix /= sqrt(t1_top * t2_top * t1_bot * t2_bot);
//Helicity sum and average over initial states
const double pref = 1./(4.*C_A*C_A);
return {sum_top*pref, sum_bot*pref, sum_mix*pref};
}
-double ME_Zuno_qg(HLV pa, HLV pb, HLV pg, HLV p1, HLV p2, HLV pep, HLV pem,
- ParticleID aptype, ParticleID /*bptype*/,
+double ME_Zuno_qg(const HLV & pa, const HLV & pb,
+ const HLV & pg, const HLV & p1, const HLV & p2,
+ const HLV & pep, const HLV & pem,
+ const ParticleID aptype, const ParticleID /*bptype*/,
ParticleProperties const & zprop,
- double stw2, double ctw
+ const double stw2, const double ctw
){
using HEJ::C_A;
using HEJ::C_F;
const HLV pZ = pep + pem;
const COM PZ = ZProp(pZ.m2(), zprop);
const COM PG = GProp(pZ.m2());
COM pref[2][2], CoeffX[2][2][2][2], CoeffY[2][2][2][2];
Z_amp_pref(aptype, PZ, PG, stw2, ctw, pref);
jZuno_j(pa, pb, pg, p1, p2, pep, pem, CoeffX, CoeffY);
double sum = 0.;
for(int h1=0; h1<2; h1++){
for(int hl=0; hl<2; hl++){
for(int h2=0; h2<2; h2++){
for(int hg=0; hg<2; hg++){
- COM X = CoeffX[h1][hl][h2][hg];
- COM Y = CoeffY[h1][hl][h2][hg];
+ const COM X = CoeffX[h1][hl][h2][hg];
+ const COM Y = CoeffY[h1][hl][h2][hg];
sum += norm(pref[h1][hl]) * (C_A*C_F*C_F/2.*(norm(X)+norm(Y))
- C_F/2.*(X*conj(Y)).real());
}
}
}
}
sum /= (pa-pg-p1-pZ).m2()*(p2-pb).m2();
//Helicity sum and average over initial states
sum /= (4.*C_A*C_A);
// Multiply by CAM
return sum * (K_g(p2, pb) / C_F);
}
\ No newline at end of file

File Metadata

Mime Type
text/x-diff
Expires
Tue, Nov 19, 3:50 PM (1 d, 19 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3805029
Default Alt Text
(115 KB)

Event Timeline