cepgen is hosted by Hepforge, IPPP Durham
CepGen 1.2.5
Central exclusive processes event generator
Loading...
Searching...
No Matches
NachtmannAmplitudes.cpp
Go to the documentation of this file.
1/*
2 * CepGen: a central exclusive processes event generator
3 * Copyright (C) 2019-2024 Laurent Forthomme
4 * 2017-2019 Wolfgang Schaefer
5 * 2019 Marta Luszczak
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
25
26using namespace std::complex_literals;
27
28namespace cepgen {
30 : SteeredObject(params),
31 mode_(steerAs<int, NachtmannAmplitudes::Mode>("model")),
32 eft_ext_(steer<ParametersList>("eftParameters")),
33 G_EM_SQ(constants::G_EM_SQ),
34 G_EM(sqrt(G_EM_SQ)) {
35 CG_DEBUG("NachtmannAmplitudes") << "Nachtmann amplitudes evaluation framework built for mode=" << mode_ << ".";
36 }
37
38 NachtmannAmplitudes::EFTParameters::EFTParameters(const ParametersList& params)
39 : SteeredObject(params), s1(steer<double>("s1")), mH(steer<double>("mH")) {}
40
41 ParametersDescription NachtmannAmplitudes::EFTParameters::description() {
42 auto desc = ParametersDescription();
43 desc.add<double>("s1", 0.);
44 desc.add<double>("mH", 0.).setDescription("Higgs mass (in GeV/c2)");
45 return desc;
46 }
47
48 NachtmannAmplitudes::Kinematics::Kinematics(double mw2, double shat, double that, double uhat)
49 : shat(shat),
50 that(that),
51 uhat(uhat),
52 mw2_(mw2),
53 shat2(shat * shat),
54 beta2(1. - 4. * mw2_ / shat),
55 beta(sqrt(beta2)),
56 inv_gamma2(1. - beta2),
57 gamma2(1. / inv_gamma2),
58 gamma(sqrt(gamma2)),
59 inv_gamma(1. / gamma) {
60 setCosTheta((that - uhat) / shat / beta);
61 }
62
64 double cos_theta,
65 double mw2) {
66 Kinematics kin(mw2, shat, 0., 0.);
67 kin.setCosTheta(cos_theta);
68 return kin;
69 }
70
71 void NachtmannAmplitudes::Kinematics::setCosTheta(double cth) {
72 cos_theta = cth;
73 cos_theta2 = cos_theta * cos_theta;
74 sin_theta2 = 1. - cos_theta2;
75 sin_theta = sqrt(fabs(sin_theta2));
76 invA = 1. / (1. - beta2 * cos_theta2);
77 }
78
80 // checking only the base variables as all others are computed from these three
81 return shat != oth.shat || that != oth.that || uhat != oth.uhat;
82 }
83
84 std::ostream& operator<<(std::ostream& os, const NachtmannAmplitudes::Kinematics& kin) {
85 return os << "Kin{mW2=" << kin.mw2_ << ",shat=" << kin.shat << ",that=" << kin.that << ",uhat=" << kin.uhat
86 << ",beta=" << kin.beta << ",gamma=" << kin.gamma << ",cos(theta)=" << kin.cos_theta
87 << "->1/A=" << kin.invA << "}";
88 }
89
90 std::complex<double> NachtmannAmplitudes::operator()(
91 const Kinematics& kin, short lam1, short lam2, short lam3, short lam4) const {
92 const Helicities hel{lam1, lam2, lam3, lam4};
93
94 //--- per-helicity amplitude
95 switch (mode_) {
96 case Mode::SM:
97 return amplitudeSM(kin, hel);
98 case Mode::W:
99 return amplitudeW(kin, hel);
100 case Mode::Wbar:
101 return amplitudeWbar(kin, hel);
102 case Mode::phiW:
103 return amplitudephiW(kin, hel);
104 case Mode::phiWbar:
105 return 2i * double(lam1) * amplitudephiW(kin, hel);
106 case Mode::phiB:
107 return std::pow(eft_ext_.c1() / eft_ext_.s1, 2) * amplitudephiW(kin, hel);
108 case Mode::phiBbar:
109 return 2i * double(lam1) * std::pow(eft_ext_.c1() / eft_ext_.s1, 2) * amplitudephiW(kin, hel);
110 case Mode::WB:
111 return amplitudeWB(kin, hel);
112 case Mode::WbarB:
113 return amplitudeWbarB(kin, hel);
114 }
115 throw CG_FATAL("NachtmannAmplitudes") << "Invalid mode: " << mode_ << "!";
116 }
117
118 std::complex<double> NachtmannAmplitudes::amplitudeSM(const Kinematics& kin, const Helicities& hel) const {
119 if (hel.lam3 == 0 && hel.lam4 == 0) // longitudinal-longitudinal
120 return 1i * G_EM_SQ * kin.invA * kin.inv_gamma2 *
121 ((kin.gamma2 + 1.) * (1. - hel.lam1 * hel.lam2) * kin.sin_theta2 - (1. + hel.lam1 * hel.lam2));
122
123 if (hel.lam4 == 0) // transverse-longitudinal
124 return -1i * G_EM_SQ * M_SQRT2 * kin.invA * kin.inv_gamma * double(hel.lam1 - hel.lam2) *
125 (1. + hel.lam1 * hel.lam3 * kin.cos_theta) * kin.sin_theta;
126
127 if (hel.lam3 == 0) // longitudinal-transverse
128 return amplitudeSM(kin, {hel.lam2, hel.lam1, hel.lam4, hel.lam3});
129
130 // transverse-transverse
131 return -0.5i * G_EM_SQ * kin.invA *
132 (2. * kin.beta * double(hel.lam1 + hel.lam2) * (hel.lam3 + hel.lam4) -
133 kin.inv_gamma2 * (1. + hel.lam3 * hel.lam4) *
134 (2. * hel.lam1 * hel.lam2 + (1. - hel.lam1 * hel.lam2) * kin.cos_theta2) +
135 (1. + hel.lam1 * hel.lam2 * hel.lam3 * hel.lam4) * (3. + hel.lam1 * hel.lam2) +
136 2. * (hel.lam1 - hel.lam2) * (hel.lam3 - hel.lam4) * kin.cos_theta +
137 (1. - hel.lam1 * hel.lam2) * (1. - hel.lam3 * hel.lam4) * kin.cos_theta2);
138 }
139
140 std::complex<double> NachtmannAmplitudes::amplitudeW(const Kinematics& kin, const Helicities& hel) const {
141 if (hel.lam3 == 0 && hel.lam4 == 0) // longitudinal-longitudinal
142 return 3i * G_EM * kin.shat * eft_ext_.s1 * M_SQRT2 * constants::G_F * kin.invA * kin.inv_gamma2 *
143 kin.sin_theta2 * (1. + hel.lam1 * hel.lam2);
144
145 if (hel.lam4 == 0) // transverse-longitudinal
146 return 1.5i * G_EM * kin.shat * eft_ext_.s1 * constants::G_F * kin.invA * kin.inv_gamma * kin.sin_theta *
147 ((hel.lam1 - hel.lam2) * kin.beta2 - kin.beta * kin.cos_theta * (hel.lam1 + hel.lam2) -
148 2 * hel.lam3 * kin.cos_theta * (hel.lam1 * hel.lam2 + kin.inv_gamma2));
149
150 if (hel.lam3 == 0) // longitudinal-transverse
151 return amplitudeW(kin, {hel.lam2, hel.lam1, hel.lam4, hel.lam3});
152
153 // transverse-transverse
154 return 0.75i * G_EM * kin.shat * eft_ext_.s1 * M_SQRT2 * constants::G_F *
155 (-kin.inv_gamma2 * kin.beta * (1. + kin.cos_theta2) * (hel.lam1 + hel.lam2) * (hel.lam3 + hel.lam4) +
156 2 * kin.sin_theta2 *
157 (3. + hel.lam3 * hel.lam4 + hel.lam1 * hel.lam2 * (1 - hel.lam3 * hel.lam4) -
158 kin.beta * (hel.lam1 + hel.lam2) * (hel.lam3 + hel.lam4)) -
159 2 * kin.inv_gamma2 *
160 (2 + (1 - hel.lam1 * hel.lam2) * hel.lam3 * hel.lam4 -
161 kin.cos_theta2 * (3 + hel.lam1 * hel.lam2 + 2 * hel.lam3 * hel.lam4)));
162 }
163
164 std::complex<double> NachtmannAmplitudes::amplitudeWbar(const Kinematics& kin, const Helicities& hel) const {
165 if (hel.lam3 == 0 && hel.lam4 == 0) // longitudinal-longitudinal
166 return -3 * G_EM * kin.shat * eft_ext_.s1 * M_SQRT2 * constants::G_F * kin.inv_gamma2 * kin.invA *
167 kin.sin_theta2 * (hel.lam1 + hel.lam2);
168
169 if (hel.lam4 == 0) // transverse-longitudinal
170 return 1.5 * G_EM * kin.shat * eft_ext_.s1 * constants::G_F * kin.inv_gamma * kin.invA * kin.sin_theta *
171 (kin.beta * (hel.lam1 - hel.lam2) * hel.lam3 +
172 kin.cos_theta * (2 * kin.beta + (2. - kin.beta2) * (hel.lam1 + hel.lam2) * hel.lam3));
173
174 if (hel.lam3 == 0) // longitudinal-transverse
175 return amplitudeWbar(kin, {hel.lam2, hel.lam1, hel.lam4, hel.lam3});
176
177 // transverse-transverse
178 return -1.5 * G_EM * kin.shat * eft_ext_.s1 * M_SQRT2 * constants::G_F * kin.invA *
179 (2 * kin.sin_theta2 * (hel.lam1 + hel.lam2 - kin.beta * (hel.lam3 + hel.lam4)) +
180 kin.inv_gamma2 * ((hel.lam1 + hel.lam2) * (kin.cos_theta2 * (2 + hel.lam3 * hel.lam4) - 1) -
181 kin.beta * (kin.cos_theta2 + hel.lam1 * hel.lam2) * (hel.lam3 + hel.lam4)));
182 }
183
184 std::complex<double> NachtmannAmplitudes::amplitudephiW(const Kinematics& kin, const Helicities& hel) const {
185 const double invB = 1. / (kin.shat - eft_ext_.mH * eft_ext_.mH);
186 if (hel.lam3 == 0 && hel.lam4 == 0) // longitudinal-longitudinal
187 return -0.25i * kin.shat2 * eft_ext_.s1 * eft_ext_.s1 * M_SQRT2 * constants::G_F * invB * (1. + kin.beta2) *
188 (1. + hel.lam1 * hel.lam2);
189
190 if (hel.lam4 == 0 || hel.lam3 == 0) // transverse-longitudinal or longitudinal-transverse
191 return 0.;
192
193 // transverse-transverse
194 return -0.125i * kin.shat2 * eft_ext_.s1 * eft_ext_.s1 * M_SQRT2 * constants::G_F * kin.inv_gamma2 * invB *
195 (1. + hel.lam1 * hel.lam2) * (1. + hel.lam3 * hel.lam4);
196 }
197
198 std::complex<double> NachtmannAmplitudes::amplitudeWB(const Kinematics& kin, const Helicities& hel) const {
199 const auto invB = 1. / (kin.shat - eft_ext_.mH * eft_ext_.mH);
200 if (hel.lam3 == 0 && hel.lam4 == 0) // longitudinal-longitudinal
201 return 2i * G_EM_SQ * kin.invA * eft_ext_.c1() / eft_ext_.s1 *
202 (1 - hel.lam1 * hel.lam2 - 2 * kin.cos_theta2 -
203 kin.gamma2 * (1. + hel.lam1 * hel.lam2) * kin.sin_theta2) +
204 0.5i * kin.shat2 * constants::G_F * M_SQRT2 * invB * eft_ext_.s1 * eft_ext_.c1() * (1. + kin.beta2) *
205 (1. + hel.lam1 * hel.lam2);
206
207 if (hel.lam4 == 0) // transverse-longitudinal
208 return 0.5i * G_EM_SQ * kin.gamma * M_SQRT2 * kin.invA * eft_ext_.c1() / eft_ext_.s1 * kin.sin_theta *
209 ((hel.lam2 - hel.lam1) * (1. + kin.inv_gamma2) +
210 (kin.beta * double(hel.lam1 + hel.lam2) + 2 * hel.lam3 * (hel.lam1 * hel.lam2 - kin.inv_gamma2)) *
211 kin.cos_theta);
212
213 if (hel.lam3 == 0) // longitudinal-transverse
214 return amplitudeWB(kin, {hel.lam2, hel.lam1, hel.lam4, hel.lam3});
215
216 // transverse-transverse
217 return -0.5i * G_EM_SQ * kin.invA * eft_ext_.c1() / eft_ext_.s1 *
218 (kin.beta * double(hel.lam1 + hel.lam2) * (hel.lam3 + hel.lam4) * (1. + kin.cos_theta2) +
219 2 * (2 + (hel.lam1 - hel.lam2) * (hel.lam3 - hel.lam4) * kin.cos_theta +
220 ((hel.lam1 * hel.lam2 - 1) * kin.cos_theta2 + 1. + hel.lam1 * hel.lam2) * hel.lam3 * hel.lam4)) +
221 0.25i * kin.shat2 * M_SQRT2 * constants::G_F * kin.inv_gamma2 * invB * eft_ext_.s1 * eft_ext_.c1() *
222 (1. + hel.lam1 * hel.lam2) * (1. + hel.lam3 * hel.lam4);
223 }
224
225 std::complex<double> NachtmannAmplitudes::amplitudeWbarB(const Kinematics& kin, const Helicities& hel) const {
226 CG_WARNING("NachtmannAmplitudes") << "Mode " << mode_ << " is not yet properly handled!";
227 const auto invB = 1. / (kin.shat - eft_ext_.mH * eft_ext_.mH);
228 if (hel.lam3 == 0 && hel.lam4 == 0) // longitudinal-longitudinal
229 return 2. * G_EM_SQ * eft_ext_.c1() / eft_ext_.s1 * kin.gamma2 * double(hel.lam1 + hel.lam2) -
230 0.5 * kin.shat2 * M_SQRT2 * constants::G_F /* /e^2 */ * eft_ext_.s1 * eft_ext_.c1() * (1. + kin.beta2) *
231 double(hel.lam1 + hel.lam2);
232
233 if (hel.lam4 == 0) // transverse-longitudinal
234 return 0.5 * G_EM_SQ * kin.invA * kin.gamma * M_SQRT2 * eft_ext_.c1() / eft_ext_.s1 * kin.sin_theta *
235 (kin.beta * (hel.lam2 - hel.lam1) * hel.lam3 -
236 kin.cos_theta * (2. * kin.beta + kin.beta2 * double(hel.lam1 + hel.lam2) * hel.lam3));
237
238 if (hel.lam3 == 0) // longitudinal-transverse
239 return amplitudeWbarB(kin, {hel.lam2, hel.lam1, hel.lam4, hel.lam3});
240
241 // transverse-transverse
242 return kin.invA * G_EM_SQ * eft_ext_.c1() * eft_ext_.c1() / eft_ext_.s1 *
243 (hel.lam3 * double(hel.lam1 + hel.lam2) + kin.beta * (hel.lam1 * hel.lam2 + kin.cos_theta2)) *
244 (hel.lam3 + hel.lam4) -
245 0.25 * kin.shat2 * M_SQRT2 * constants::G_F /* /e^2 */ * kin.inv_gamma2 * invB * eft_ext_.s1 *
246 eft_ext_.c1() * eft_ext_.c1() * double(hel.lam1 + hel.lam2) * (1. + hel.lam3 * hel.lam4);
247 }
248
250 auto desc = ParametersDescription();
251 desc.addAs<int, Mode>("model", Mode::SM).setDescription("SM/anomalous model to consider");
252 desc.add<ParametersDescription>("eftParameters", EFTParameters::description());
253 return desc;
254 }
255
256 std::ostream& operator<<(std::ostream& os, const NachtmannAmplitudes::Mode& mode) {
257 switch (mode) {
259 return os << "Standard model";
261 return os << "W";
263 return os << "Wbar";
265 return os << "phi-W";
267 return os << "phi-Wbar";
269 return os << "phi-B";
271 return os << "phi-Bbar";
273 return os << "W-B";
275 return os << "Wbar-B";
276 }
277 return os << (int)mode;
278 }
279} // namespace cepgen
#define CG_FATAL(mod)
Definition Exception.h:61
#define CG_WARNING(mod)
Definition Message.h:228
#define CG_DEBUG(mod)
Definition Message.h:220
List of kinematic constraints to apply on the process phase space.
Definition Kinematics.h:27
Helper container to handle all kinematics variables computation once.
static Kinematics fromScosTheta(double shat, double cos_theta, double mw2)
Kinematics(double mw2, double shat, double that, double uhat)
bool operator!=(const Kinematics &) const
Amplitudes computational tool, as developed by Nachtmann et al. .
NachtmannAmplitudes(const ParametersList &)
Mode
Model giving an amplitude for the two-photon WW production.
friend std::ostream & operator<<(std::ostream &, const Mode &)
std::complex< double > operator()(const Kinematics &, short lam1, short lam2, short lam3, short lam4) const
Compute the amplitude for a given kinematics and a given set of helicity components.
static ParametersDescription description()
A description object for parameters collection.
Base user-steerable object.
constexpr double G_F
Fermi coupling constant, in GeV .
Definition Constants.h:42
Common namespace for this Monte Carlo generator.