flexiblesusy is hosted by Hepforge, IPPP Durham
FlexibleSUSY
decay.cpp
Go to the documentation of this file.
1// ====================================================================
2// This file is part of FlexibleSUSY.
3//
4// FlexibleSUSY is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published
6// by the Free Software Foundation, either version 3 of the License,
7// or (at your option) any later version.
8//
9// FlexibleSUSY is distributed in the hope that it will be useful, but
10// WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with FlexibleSUSY. If not, see
16// <http://www.gnu.org/licenses/>.
17// ====================================================================
18
19#include "decay.hpp"
20#include "error.hpp"
21#include "wrappers.hpp"
22
23#include <boost/functional/hash.hpp>
24
25#include <algorithm>
26#include <sstream>
27
28#include "string_utils.hpp"
29
30namespace flexiblesusy {
31
32namespace {
33
34template <class Container>
35std::size_t hash_pid_list(int pid_in, Container pids_out)
36{
37 Container sorted(pids_out);
38 std::sort(sorted.begin(), sorted.end());
39
40 boost::hash<int> hash_pid;
41 auto seed = hash_pid(pid_in);
42 boost::hash_range(seed, sorted.begin(), sorted.end());
43
44 return seed;
45}
46
47} // anonymous namespace
48
49static std::array<int, 2> pdg_id_pairs[PDG_id_pairs::NUMBER_OF_PDG_IDS] = {
50 {-1, 1},
51 {-2, 2},
52 {-3, 3},
53 {-4, 4},
54 {-5, 5},
55 {-6, 6},
56 {-11, 11},
57 {-13, 13},
58 {-15, 15},
59 {-24, 24},
60 {23, 23},
61 {22, 22},
62 {22, 23},
63 {21, 21},
64 {-11, 13},
65 {-11, 15},
66 {-13, 15}
67};
68
69std::size_t hash_decay(const Decay& decay)
70{
71 int pid_in = decay.get_initial_particle_id();
72 const auto& pids_out = decay.get_final_state_particle_ids();
73 return hash_pid_list(pid_in, pids_out);
74}
75
76Decays_list::Decays_list(int initial_pdg_)
77 : initial_pdg(initial_pdg_)
78{
79}
80
82{
83 decays.clear();
84 total_width = 0.;
85}
86
88 std::initializer_list<int> product_pdgs) const
89{
90 const Decay decay(initial_pdg, product_pdgs, 0., std::string());
91 const auto decay_hash = hash_decay(decay);
92
93 const auto pos = decays.find(decay_hash);
94
95 if (pos == std::end(decays)) {
96 std::ostringstream msg;
97 msg << "Decay of particle " << initial_pdg
98 << " into particles {"
99 << concat(product_pdgs.begin(), product_pdgs.end(), ", ")
100 << "} not found\n";
101
102 throw OutOfBoundsError(msg.str());
103 }
104
105 return pos->second;
106}
107
111std::vector<Decay> sort_decays_list(const Decays_list& decays_list) {
112 std::vector<Decay> decays_list_as_vector;
113 decays_list_as_vector.reserve(decays_list.size());
114 for (const auto& el : decays_list) {
115 decays_list_as_vector.push_back(el.second);
116 }
117
118 std::sort(
119 decays_list_as_vector.begin(),
120 decays_list_as_vector.end(),
121 [](const auto& d1, const auto& d2) {
122 return d1.get_width() > d2.get_width();
123 }
124 );
125
126 return decays_list_as_vector;
127}
128
129std::string strip_field_namespace(std::string const& s) {
130 std::string result = s.substr(s.find_last_of(':')+1);
131 if (s.find("bar") != std::string::npos) {
132 result.pop_back();
133 return "bar" + result;
134 } else if (s.find("conj") != std::string::npos) {
135 result.pop_back();
136 return "conj" + result;
137 } else {
138 return result;
139 }
140}
141
142double hVV_4body(double *q2, size_t /* dim */, void *params)
143{
144 struct hVV_4body_params * fp = static_cast<struct hVV_4body_params*>(params);
145 const double mHOS = fp->mHOS;
146 if (q2[1] > Sqr(mHOS - std::sqrt(q2[0]))) return 0.;
147 const double mVOS = fp->mVOS;
148 const double GammaV = fp->GammaV;
149 const double kl = KallenLambda(1., q2[0]/Sqr(mHOS), q2[1]/Sqr(mHOS));
150 return
151 mVOS*GammaV/(Sqr(q2[0] - Sqr(mVOS)) + Sqr(mVOS*GammaV))
152 * mVOS*GammaV/(Sqr(q2[1] - Sqr(mVOS)) + Sqr(mVOS*GammaV))
153 * std::sqrt(kl)*(kl + 12.*q2[0]*q2[1]/Power4(mHOS));
154}
155
156void EffectiveCoupling_list::set_invisible_width(std::string const& p, double c) {
157 auto found = std::find_if(
159 [&p](NeutralHiggsEffectiveCouplings const& effC) {return effC.particle == p;}
160 );
161 if (found == std::end(effective_coupling_list)) {
162 auto effC = NeutralHiggsEffectiveCouplings {};
163 effC.particle = p;
164 effC.invWidth = c;
165 effective_coupling_list.push_back(std::move(effC));
166 }
167 else {
168 found->invWidth = c;
169 }
170}
171
172void EffectiveCoupling_list::add_coupling(std::string const& p, std::array<int, 2> const& fs, std::pair<std::string, double> const& c, double partialW) {
173 auto found = std::find_if(
175 [&p](NeutralHiggsEffectiveCouplings const& effC) {return effC.particle == p;}
176 );
177 auto are_the_same = [](std::array<int, 2> const& a1, std::array<int, 2> const& a2) {return std::is_permutation(a1.begin(), a1.end(), a2.begin(), a2.end());};
178 if (found == std::end(effective_coupling_list)) {
179 auto effC = NeutralHiggsEffectiveCouplings {};
180 effC.particle = p;
181 if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::gg])) {
182 effC.gg = c;
183 effC.undetectedWidth -= partialW;
184 }
185 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::gamgam])) {
186 effC.gamgam = c;
187 effC.undetectedWidth -= partialW;
188 }
189 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::ZZ])) {
190 effC.ZZ = c;
191 effC.undetectedWidth -= partialW;
192 }
193 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::WW])) {
194 effC.WW = c;
195 effC.undetectedWidth -= partialW;
196 }
197 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::Zgam])) {
198 effC.Zgam = c;
199 effC.undetectedWidth -= partialW;
200 }
201 effective_coupling_list.push_back(std::move(effC));
202 }
203 else {
204 if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::gg])) {
205 found->gg = c;
206 found->undetectedWidth -= partialW;
207 }
208 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::gamgam])) {
209 found->gamgam = c;
210 found->undetectedWidth -= partialW;
211 }
212 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::ZZ])) {
213 found->ZZ = c;
214 found->undetectedWidth -= partialW;
215 }
216 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::WW])) {
217 found->WW = c;
218 found->undetectedWidth -= partialW;
219 }
220 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::Zgam])) {
221 found->Zgam = c;
222 found->undetectedWidth -= partialW;
223 }
224 }
225 }
226
227void EffectiveCoupling_list::add_coupling(std::string const& p, std::array<int, 2> const& fs, std::pair<std::string, std::complex<double>> const& c, double partialW) {
228
229 auto found = std::find_if(
231 [&p](NeutralHiggsEffectiveCouplings const& effC) {return effC.particle == p;}
232 );
233
234 auto are_the_same = [](std::array<int, 2> const& a1, std::array<int, 2> const& a2) {
235 return std::is_permutation(a1.begin(), a1.end(), a2.begin(), a2.end());
236 };
237 auto negate = [](std::array<int, 2> in) {
238 std::for_each(in.begin(), in.end(), [](int& el){el *= -1; });
239 return in;
240 };
241
242 if (found == std::end(effective_coupling_list)) {
243 auto effC = NeutralHiggsEffectiveCouplings {};
244 effC.particle = p;
245 if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::dd])) {
246 effC.dd = c;
247 effC.undetectedWidth -= partialW;
248 }
249 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::uu])) {
250 effC.uu = c;
251 effC.undetectedWidth -= partialW;
252 }
253 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::ss])) {
254 effC.ss = c;
255 effC.undetectedWidth -= partialW;
256 }
257 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::cc])) {
258 effC.cc = c;
259 effC.undetectedWidth -= partialW;
260 }
261 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::bb])) {
262 effC.bb = c;
263 effC.undetectedWidth -= partialW;
264 }
265 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::tt])) {
266 effC.tt = c;
267 effC.undetectedWidth -= partialW;
268 }
269 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::ee])) {
270 effC.ee = c;
271 effC.undetectedWidth -= partialW;
272 }
273 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::mumu])) {
274 effC.mumu = c;
275 effC.undetectedWidth -= partialW;
276 }
277 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::tautau])) {
278 effC.tautau = c;
279 effC.undetectedWidth -= partialW;
280 }
281 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::emu]) || are_the_same(fs, negate(pdg_id_pairs[PDG_id_pairs::emu]))) {
282 effC.emu.first = c.first;
283 effC.emu.second += c.second;
284 effC.undetectedWidth -= partialW;
285 }
286 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::etau]) || are_the_same(fs, negate(pdg_id_pairs[PDG_id_pairs::etau]))) {
287 effC.etau.first = c.first;
288 effC.etau.second += c.second;
289 effC.undetectedWidth -= partialW;
290 }
291 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::mutau]) || are_the_same(fs, negate(pdg_id_pairs[PDG_id_pairs::mutau]))) {
292 effC.mutau.first = c.first;
293 effC.mutau.second = c.second;
294 effC.undetectedWidth -= partialW;
295 }
296 else {
297 WARNING("HiggsTools interface warning: trying to add an unknown decay channel {" + std::to_string(fs[0]) + ", " + std::to_string(fs[1]) + "}");
298 }
299 effective_coupling_list.push_back(std::move(effC));
300 }
301 else {
302 if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::dd])) {
303 found->dd = c;
304 found->undetectedWidth -= partialW;
305 }
306 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::uu])) {
307 found->uu = c;
308 found->undetectedWidth -= partialW;
309 }
310 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::ss])) {
311 found->ss = c;
312 found->undetectedWidth -= partialW;
313 }
314 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::cc])) {
315 found->cc = c;
316 found->undetectedWidth -= partialW;
317 }
318 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::bb])) {
319 found->bb = c;
320 found->undetectedWidth -= partialW;
321 }
322 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::tt])) {
323 found->tt = c;
324 found->undetectedWidth -= partialW;
325 }
326 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::ee])) {
327 found->ee = c;
328 found->undetectedWidth -= partialW;
329 }
330 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::mumu])) {
331 found->mumu = c;
332 found->undetectedWidth -= partialW;
333 }
334 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::tautau])) {
335 found->tautau = c;
336 found->undetectedWidth -= partialW;
337 }
338 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::emu]) || are_the_same(fs, negate(pdg_id_pairs[PDG_id_pairs::emu]))) {
339 found->emu.first = c.first;
340 found->emu.second += c.second;
341 found->undetectedWidth -= partialW;
342 }
343 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::etau]) || are_the_same(fs, negate(pdg_id_pairs[PDG_id_pairs::etau]))) {
344 found->etau.first = c.first;
345 found->etau.second += c.second;
346 found->undetectedWidth -= partialW;
347 }
348 else if (are_the_same(fs, pdg_id_pairs[PDG_id_pairs::mutau]) || are_the_same(fs, negate(pdg_id_pairs[PDG_id_pairs::mutau]))) {
349 found->mutau.first = c.first;
350 found->mutau.second += c.second;
351 found->undetectedWidth -= partialW;
352 }
353 else {
354 WARNING("HiggsTools interface warning: trying to add an unknown decay channel {" + std::to_string(fs[0]) + ", " + std::to_string(fs[1]) + "}");
355 }
356 }
357}
358
359} // namespace flexiblesusy
int get_initial_particle_id() const
Definition decay.hpp:56
const std::vector< int > & get_final_state_particle_ids() const
Definition decay.hpp:57
const Decay & get_decay(std::initializer_list< int > products) const
Definition decay.cpp:87
std::size_t size() const noexcept
Definition decay.hpp:162
std::vector< NeutralHiggsEffectiveCouplings > effective_coupling_list
Definition decay.hpp:135
void add_coupling(std::string const &, std::array< int, 2 > const &, std::pair< std::string, double > const &, double)
Definition decay.cpp:172
void set_invisible_width(std::string const &p, double)
Definition decay.cpp:156
std::pair< std::string, std::complex< double > > tautau
Definition decay.hpp:90
std::pair< std::string, std::complex< double > > uu
Definition decay.hpp:83
std::pair< std::string, double > ZZ
Definition decay.hpp:95
std::pair< std::string, std::complex< double > > dd
Definition decay.hpp:82
std::pair< std::string, std::complex< double > > tt
Definition decay.hpp:87
std::pair< std::string, std::complex< double > > ee
Definition decay.hpp:88
std::pair< std::string, std::complex< double > > cc
Definition decay.hpp:85
std::pair< std::string, double > WW
Definition decay.hpp:94
std::pair< std::string, std::complex< double > > mumu
Definition decay.hpp:89
std::pair< std::string, std::complex< double > > mutau
Definition decay.hpp:93
std::pair< std::string, double > gamgam
Definition decay.hpp:97
std::pair< std::string, double > gg
Definition decay.hpp:98
std::pair< std::string, std::complex< double > > ss
Definition decay.hpp:84
std::pair< std::string, std::complex< double > > etau
Definition decay.hpp:92
std::pair< std::string, double > Zgam
Definition decay.hpp:96
std::pair< std::string, std::complex< double > > emu
Definition decay.hpp:91
std::pair< std::string, std::complex< double > > bb
Definition decay.hpp:86
Out of bounds access.
Definition error.hpp:208
#define WARNING(msg)
Definition logger.hpp:63
std::size_t hash_pid_list(int pid_in, Container pids_out)
Definition decay.cpp:35
std::string strip_field_namespace(std::string const &s)
Definition decay.cpp:129
static std::array< int, 2 > pdg_id_pairs[PDG_id_pairs::NUMBER_OF_PDG_IDS]
Definition decay.cpp:49
@ NUMBER_OF_PDG_IDS
Definition decay.hpp:377
double hVV_4body(double *q2, size_t, void *params)
Definition decay.cpp:142
constexpr std::complex< T > Sqr(const std::complex< T > &a) noexcept
Definition wrappers.hpp:633
std::vector< Decay > sort_decays_list(const Decays_list &decays_list)
sort decays w.r.t. their width
Definition decay.cpp:111
T KallenLambda(T x, T y, T z) noexcept
Definition wrappers.hpp:837
constexpr Base Power4(Base b) noexcept
Definition wrappers.hpp:495
std::string concat(const std::vector< std::string > &strings)
concatenate strings
std::size_t hash_decay(const Decay &decay)
Definition decay.cpp:69