-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SMEFT 4-fermion corrections #306
base: master
Are you sure you want to change the base?
Changes from 4 commits
87d5e18
a9d4585
5313249
1d18e0f
02a67c0
a36576f
60fd649
0d3e636
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,6 +46,24 @@ def __init__(self, theory_config, obs_config): | |
# neutrinos | ||
for pid in [12, 14, 16]: | ||
self.weak_isospin_3[pid] = 1 / 2 | ||
|
||
# BSM couplings ------------------------------------------------------- | ||
# Temporary couplings to Olq3 | ||
self.BSM_coupling_vectorial = {21: 0} | ||
self.BSM_coupling_axial = {21: 0} | ||
for q in range(1, 7): | ||
self.BSM_coupling_vectorial[q] = -1 if q % 2 == 0 else 1 # u if stmt else d | ||
self.BSM_coupling_axial[q] = -1 if q % 2 == 0 else 1 # u if stmt else d | ||
# leptons: 11 = e-(!) | ||
for pid in [11, 13, 15]: | ||
self.BSM_coupling_vectorial[pid] = 1 | ||
self.BSM_coupling_axial[pid] = 1 | ||
# neutrinos | ||
# CC not yet implemented | ||
for pid in [12, 14, 16]: | ||
self.BSM_coupling_vectorial[pid] = 0 | ||
self.BSM_coupling_axial[pid] = 0 | ||
|
||
self.log() | ||
|
||
def log(self): | ||
|
@@ -92,9 +110,14 @@ def leptonic_coupling(self, mode, quark_coupling_type): | |
# load Z coupling | ||
projectile_v = 0.0 | ||
projectile_a = 0.0 | ||
if mode in ["phZ", "ZZ"]: | ||
if mode in ["phZ", "ZZ", "Z4F"]: | ||
felixhekhorn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
projectile_v = self.vectorial_coupling(abs(projectile_pid)) | ||
projectile_a = self.weak_isospin_3[abs(projectile_pid)] | ||
projectile_BSM_v = self.BSM_coupling_vectorial(abs(projectile_pid)) | ||
felixhekhorn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
projectile_BSM_a = self.BSM_coupling_axial[abs(projectile_pid)] | ||
if mode in ["ph4F"]: | ||
projectile_BSM_v = self.BSM_coupling_vectorial(abs(projectile_pid)) | ||
felixhekhorn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
projectile_BSM_a = self.BSM_coupling_axial[abs(projectile_pid)] | ||
# switch mode | ||
if mode == "phph": | ||
if quark_coupling_type in ["VV", "AA"]: | ||
|
@@ -121,6 +144,26 @@ def leptonic_coupling(self, mode, quark_coupling_type): | |
return 2.0 * projectile_v * projectile_a + pol * ( | ||
projectile_v**2 + projectile_a**2 | ||
) | ||
elif mode == "ph4F": | ||
if quark_coupling_type in ["VV", "AA"]: | ||
return self.electric_charge[abs(projectile_pid)] * ( | ||
projectile_BSM_v + pol * projectile_BSM_a | ||
) | ||
else: | ||
return self.electric_charge[abs(projectile_pid)] * ( | ||
projectile_BSM_a + pol * projectile_BSM_v | ||
) | ||
elif mode == "Z4F": | ||
if quark_coupling_type in ["VV", "AA"]: | ||
return ( | ||
projectile_v * projectile_BSM_v | ||
+ projectile_a * projectile_BSM_a | ||
+ pol * (projectile_v * projectile_BSM_a + projectile_BSM_v * projectile_a) | ||
) | ||
else: | ||
return projectile_v * projectile_BSM_a + projectile_BSM_v * projectile_a + pol * ( | ||
projectile_v * projectile_BSM_v + projectile_a * projectile_BSM_a | ||
) | ||
raise ValueError(f"Unknown mode: {mode}") | ||
|
||
def nc_partonic_coupling(self, pid): | ||
|
@@ -130,7 +173,12 @@ def nc_partonic_coupling(self, pid): | |
"A": 0, # axial coupling of the photon to the quark is not there of course | ||
} | ||
qZ = {"V": self.vectorial_coupling(pid), "A": self.weak_isospin_3[pid]} | ||
return qph, qZ | ||
|
||
q4F = { | ||
"V": self.BSM_coupling_vectorial[pid], | ||
"A": self.BSM_coupling_axial[pid], | ||
} | ||
return qph, qZ, q4F | ||
|
||
def partonic_coupling(self, mode, pid, quark_coupling_type, cc_mask=None): | ||
"""Compute the coupling of the boson to the parton. | ||
|
@@ -157,7 +205,7 @@ def partonic_coupling(self, mode, pid, quark_coupling_type, cc_mask=None): | |
if mode == "WW": | ||
return np.sum(self.theory_config["CKM"].masked(cc_mask)(pid)) | ||
# load couplings | ||
qph, qZ = self.nc_partonic_coupling(pid) | ||
qph, qZ, q4F = self.nc_partonic_coupling(pid) | ||
|
||
first = quark_coupling_type[0] | ||
second = quark_coupling_type[1] | ||
|
@@ -168,6 +216,10 @@ def partonic_coupling(self, mode, pid, quark_coupling_type, cc_mask=None): | |
return qph[first] * qZ[second] | ||
if mode == "ZZ": | ||
return qZ[first] * qZ[second] | ||
if mode == "ph4F": | ||
return qph[first] * q4F[second] | ||
if mode == "Z4F": | ||
return qZ[first] * q4F[second] | ||
raise ValueError(f"Unknown mode: {mode}") | ||
|
||
def partonic_coupling_fl11(self, mode, pid, nf, quark_coupling_type): | ||
|
@@ -247,10 +299,22 @@ def propagator_factor(self, mode, Q2): | |
* (1.0 - self.theory_config["sin2theta_weak"]) | ||
) | ||
eta_phZ /= 1 - self.obs_config["propagatorCorrection"] | ||
|
||
# Need to specify Wilson coefficient? | ||
C_4F = 1/4 | ||
# Modify with more precise value | ||
alpha = 1 / 137 | ||
# Should get it from param card | ||
BSM_scale = 1000 | ||
eta_ph4F = ((C_4F) / (4 * np.pi*alpha)) *(Q2/BSM_scale**2) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess, all three parameters should come from the outside? Then I wonder if we should condense them all into one There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In practice there is a redundancy between There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would say this depends if there is another dependency on either of these things - if there is not, I think we should collapse them to avoid an ambiguous configuration |
||
if mode == "phZ": | ||
return eta_phZ | ||
if mode == "ZZ": | ||
return eta_phZ**2 | ||
if mode == "ph4F": | ||
return eta_ph4F | ||
if mode == "Z4F": | ||
return eta_phZ * eta_ph4F | ||
if mode == "WW": | ||
eta_W = ( | ||
(eta_phZ / 2) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder is "BSM" too generic? i.e. should we be more specific, like e.g. "4F"*? please tell me! because from my non-existent BSM experience I only know there are many BSM models 🙃
*Python variables can not start with a number, but we can solve that problem 🙃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed you are right! I realise I have already started mixing up BSM and 4F labels, 4F is a more precise one and I'll try to stick with it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd even be more specific and use
Olq3
, as you can have multiple 4F operators right?