Version: SMASH-3.1
scatteractionphoton.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2016-2022
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
11 
12 #include <algorithm>
13 
14 #include "smash/angles.h"
15 #include "smash/constants.h"
18 #include "smash/outputinterface.h"
19 #include "smash/particletype.h"
20 #include "smash/pow.h"
21 #include "smash/random.h"
22 
23 namespace smash {
24 static constexpr int LScatterAction = LogArea::ScatterAction::id;
25 
27  const ParticleList &in, const double time, const int n_frac_photons,
28  const double hadronic_cross_section_input)
29  : ScatterAction(in[0], in[1], time),
30  reac_(photon_reaction_type(in)),
31  number_of_fractional_photons_(n_frac_photons),
32  hadron_out_t_(outgoing_hadron_type(in)),
33  hadron_out_mass_(sample_out_hadron_mass(hadron_out_t_)),
34  hadronic_cross_section_(hadronic_cross_section_input) {}
35 
37  const ParticleList &in) {
38  if (in.size() != 2) {
40  }
41 
42  PdgCode a = in[0].pdgcode();
43  PdgCode b = in[1].pdgcode();
44 
45  // swap so that pion is first and there are less cases to be listed
46  if (!a.is_pion()) {
47  std::swap(a, b);
48  }
49 
50  switch (pack(a.code(), b.code())) {
51  case (pack(pdg::pi_p, pdg::pi_z)):
52  case (pack(pdg::pi_z, pdg::pi_p)):
54 
55  case (pack(pdg::pi_m, pdg::pi_z)):
56  case (pack(pdg::pi_z, pdg::pi_m)):
58 
59  case (pack(pdg::pi_p, pdg::rho_z)):
61 
62  case (pack(pdg::pi_m, pdg::rho_z)):
64 
65  case (pack(pdg::pi_m, pdg::rho_p)):
67 
68  case (pack(pdg::pi_p, pdg::rho_m)):
70 
71  case (pack(pdg::pi_z, pdg::rho_p)):
73 
74  case (pack(pdg::pi_z, pdg::rho_m)):
76 
77  case (pack(pdg::pi_p, pdg::pi_m)):
78  case (pack(pdg::pi_m, pdg::pi_p)):
80 
81  case (pack(pdg::pi_z, pdg::rho_z)):
83 
84  default:
86  }
87 }
88 
89 void ScatterActionPhoton::perform_photons(const OutputsList &outputs) {
90  for (int i = 0; i < number_of_fractional_photons_; i++) {
92  for (const auto &output : outputs) {
93  if (output->is_photon_output()) {
94  // we do not care about the local density
95  output->at_interaction(*this, 0.0);
96  }
97  }
98  }
99 }
100 
102  const ReactionType reaction) {
103  static const ParticleTypePtr rho_z_particle_ptr =
105  static const ParticleTypePtr rho_p_particle_ptr =
107  static const ParticleTypePtr rho_m_particle_ptr =
109  static const ParticleTypePtr pi_z_particle_ptr =
111  static const ParticleTypePtr pi_p_particle_ptr =
113  static const ParticleTypePtr pi_m_particle_ptr =
115 
116  switch (reaction) {
118  return rho_p_particle_ptr;
119  break;
121  return rho_m_particle_ptr;
122  break;
124  return rho_z_particle_ptr;
125  break;
126 
129  return pi_p_particle_ptr;
130 
133  return pi_m_particle_ptr;
134 
138  return pi_z_particle_ptr;
139  break;
140  default:
141  // default constructor constructs p with invalid index
142  ParticleTypePtr p{};
143  return p;
144  }
145 }
146 
148  const ParticleList &in) {
149  auto reac = photon_reaction_type(in);
150  return outgoing_hadron_type(reac);
151 }
152 
154  const ParticleList &in) {
155  auto reac = photon_reaction_type(in);
156  auto hadron = outgoing_hadron_type(in);
157 
158  if (reac == ReactionType::no_reaction)
159  return false;
160 
163  return false;
164  }
165 
166  // C15 has only s-channel. Make sure that CM-energy is high
167  // enough to produce mediating omega meson
168  if ((reac == ReactionType::pi_m_rho_p_pi_z ||
171  if (s_sqrt < omega_mass) {
172  return false;
173  }
174  }
175 
176  // for all other processes: if cm-energy is not high enough to produce final
177  // state particle reject the collision.
178  if (hadron->is_stable() && s_sqrt < hadron->mass()) {
179  return false;
180  // Make sure energy is high enough to not only create final state particle,
181  // but to also assign momentum.
182  } else if (!hadron->is_stable() &&
183  s_sqrt < (hadron->min_mass_spectral() + really_small)) {
184  return false;
185  } else {
186  return true;
187  }
188 }
189 
191  // we have only one reaction per incoming particle pair
192  if (collision_processes_photons_.size() != 1) {
193  logg[LScatterAction].fatal()
194  << "Problem in ScatterActionPhoton::generate_final_state().\n";
195  throw std::runtime_error("");
196  }
197  auto *proc = collision_processes_photons_[0].get();
198 
199  outgoing_particles_ = proc->particle_list();
200  process_type_ = proc->get_type();
201 
202  FourVector middle_point = get_interaction_point();
203 
204  // t is defined to be the momentum exchanged between the rho meson and the
205  // photon in pi + rho -> pi + photon channel. Therefore,
206  // get_t_range needs to be called with m2 being the rho mass instead of the
207  // pion mass. So, particles 1 and 2 are swapped if necessary.
208 
209  if (!incoming_particles_[0].pdgcode().is_pion()) {
210  std::swap(incoming_particles_[0], incoming_particles_[1]);
211  }
212 
213  // 2->2 inelastic scattering
214  // Sample the particle momenta in CM system
215  const double m1 = incoming_particles_[0].effective_mass();
216  const double m2 = incoming_particles_[1].effective_mass();
217 
218  const double &m_out = hadron_out_mass_;
219 
220  const double s = mandelstam_s();
221  const double sqrts = sqrt_s();
222  std::array<double, 2> mandelstam_t = get_t_range(sqrts, m1, m2, m_out, 0.0);
223  const double t1 = mandelstam_t[1];
224  const double t2 = mandelstam_t[0];
225  const double pcm_in = cm_momentum();
226  const double pcm_out = pCM(sqrts, m_out, 0.0);
227 
228  const double t = random::uniform(t1, t2);
229 
230  double costheta = (t - pow_int(m2, 2) +
231  0.5 * (s + pow_int(m2, 2) - pow_int(m1, 2)) *
232  (s - pow_int(m_out, 2)) / s) /
233  (pcm_in * (s - pow_int(m_out, 2)) / sqrts);
234 
235  // on very rare occasions near the kinematic threshold numerical issues give
236  // unphysical angles.
237  if (costheta > 1 || costheta < -1) {
238  logg[LScatterAction].warn()
239  << "Cos(theta)of photon scattering out of physical bounds in "
240  "the following scattering: "
241  << incoming_particles_ << "Clamping to [-1,1].";
242  if (costheta > 1.0)
243  costheta = 1.0;
244  if (costheta < -1.0)
245  costheta = -1.0;
246  }
247  Angles phitheta(random::uniform(0.0, twopi), costheta);
248  outgoing_particles_[0].set_4momentum(hadron_out_mass_,
249  phitheta.threevec() * pcm_out);
250  outgoing_particles_[1].set_4momentum(0.0, -phitheta.threevec() * pcm_out);
251 
252  // Set positions & boost to computational frame.
253  for (ParticleData &new_particle : outgoing_particles_) {
254  new_particle.set_4position(middle_point);
255  new_particle.boost_momentum(
257  }
258 
259  const double E_Photon = outgoing_particles_[1].momentum()[0];
260 
261  // Weighing of the fractional photons
263  // if rho in final state take already sampled mass (same as m_out). If rho
264  // is incoming take the mass of the incoming particle
265  const double m_rho = rho_mass();
266 
267  // compute the differential cross section with form factor included
268  const double diff_xs = diff_cross_section_w_ff(t, m_rho, E_Photon);
269 
270  weight_ = diff_xs * (t2 - t1) /
272  } else {
273  // compute the total cross section with form factor included
274  const double total_xs = total_cross_section_w_ff(E_Photon);
275 
276  weight_ = total_xs / hadronic_cross_section();
277  }
278  // Scale weight by cross section scaling factor of incoming particles
279  weight_ *= incoming_particles_[0].xsec_scaling_factor() *
280  incoming_particles_[1].xsec_scaling_factor();
281 
282  // Photons are not really part of the normal processes, so we have to set a
283  // constant arbitrary number.
284  const auto id_process = ID_PROCESS_PHOTON;
285  Action::check_conservation(id_process);
286 }
287 
289  double reaction_cross_section) {
290  CollisionBranchPtr dummy_process = std::make_unique<CollisionBranch>(
291  incoming_particles_[0].type(), incoming_particles_[1].type(),
292  reaction_cross_section, ProcessType::TwoToTwo);
293  add_collision(std::move(dummy_process));
294 }
295 
297  const ParticleTypePtr out_t) {
298  double mass = out_t->mass();
299  const double cms_energy = sqrt_s();
300  if (cms_energy <= out_t->min_mass_kinematic()) {
302  "Problem in ScatterActionPhoton::sample_hadron_mass");
303  }
304 
305  if (!out_t->is_stable()) {
306  mass = out_t->sample_resonance_mass(0, cms_energy);
307  }
308 
309  return mass;
310 }
311 
313  assert(reac_ != ReactionType::no_reaction);
314  switch (reac_) {
315  // rho in final state. use already sampled mass
319  return hadron_out_mass_;
320  // rho in initial state, use its mass
328  return (incoming_particles_[0].is_rho())
329  ? incoming_particles_[0].effective_mass()
330  : incoming_particles_[1].effective_mass();
332  default:
333  throw std::runtime_error(
334  "Invalid ReactionType in ScatterActionPhoton::rho_mass()");
335  }
336 }
337 
339  CollisionBranchList process_list;
340 
341  static ParticleTypePtr photon_particle = &ParticleType::find(pdg::photon);
342  double xsection = total_cross_section();
343 
344  process_list.push_back(std::make_unique<CollisionBranch>(
345  *hadron_out_t_, *photon_particle, xsection, ProcessType::TwoToTwo));
347  return process_list;
348 }
349 
351  CollisionBranchList process_list;
353 
354  const double s = mandelstam_s();
355  // the mass of the mediating particle depends on the channel. For an incoming
356  // rho it is the mass of the incoming particle, for an outgoing rho it is the
357  // sampled mass
358  const double m_rho = rho_mass();
359  double xsection = 0.0;
360 
361  switch (reac_) {
363  xsection = xs_object.xs_pi_pi_rho0(s, m_rho);
364  break;
365 
368  xsection = xs_object.xs_pi_pi0_rho(s, m_rho);
369  break;
370 
373  xsection = xs_object.xs_pi_rho0_pi(s, m_rho);
374  break;
375 
378  if (mediator == MediatorType::SUM) {
379  xsection = xs_object.xs_pi_rho_pi0(s, m_rho);
380  break;
381  } else if (mediator == MediatorType::PION) {
382  xsection = xs_object.xs_pi_rho_pi0_rho_mediated(s, m_rho);
383  break;
384  } else if (mediator == MediatorType::OMEGA) {
385  xsection = xs_object.xs_pi_rho_pi0_omega_mediated(s, m_rho);
386  break;
387  } else {
388  throw std::runtime_error("");
389  }
392  if (mediator == MediatorType::SUM) {
393  xsection = xs_object.xs_pi0_rho_pi(s, m_rho);
394  break;
395  } else if (mediator == MediatorType::PION) {
396  xsection = xs_object.xs_pi0_rho_pi_rho_mediated(s, m_rho);
397  break;
398  } else if (mediator == MediatorType::OMEGA) {
399  xsection = xs_object.xs_pi0_rho_pi_omega_mediated(s, m_rho);
400  break;
401  } else {
402  throw std::runtime_error("");
403  }
404 
406  xsection = xs_object.xs_pi0_rho0_pi0(s, m_rho);
407  break;
408 
410  // never reached
411  break;
412  }
413 
414  if (xsection == 0.0) {
415  // Vanishing cross sections are problematic for the creation of a
416  // CollisionBranch. For infrastructure reasons it is however necessary to
417  // create such a collision branch whenever the underlying hadronic
418  // scattering is a candidate for a photon interaction. In these cases we
419  // need to manually set a dummy value for the cross section and produce the
420  // photon. This photon will however automatically be assigned a 0 weight
421  // because of the vanishing cross section and therefore not be of relevance
422  // for any analysis.
423  // In other cases, where the collision branch was already created, we
424  // do not want to overwrite the cross section, of course.
425  xsection = collision_branch_created_ ? 0.0 : 0.01;
426  } else if (xsection < 0) {
427  // Due to numerical reasons it can happen that the calculated cross sections
428  // are negative (approximately -1e-15) if sqrt(s) is close to the threshold
429  // energy. In those cases the cross section is manually set to 0.1 mb, which
430  // is a reasonable value for the processes we are looking at (C14,C15,C16).
431  xsection = 0.1;
432  logg[LScatterAction].warn(
433  "Calculated negative cross section.\nParticles ", incoming_particles_,
434  " mass rho particle: ", m_rho, ", sqrt_s: ", std::sqrt(s));
435  }
436  return xsection;
437 }
438 
439 double ScatterActionPhoton::total_cross_section_w_ff(const double E_photon) {
449  /* C12, C13, C15, C16 need special treatment. These processes have identical
450  incoming and outgoing particles, but diffrent mediating particles and
451  hence different form factors. If both channels are added up
452  (MediatorType::SUM), each contribution is corrected by the corresponding
453  form factor.
454  */
455  switch (reac_) {
461  std::pair<double, double> FF = form_factor_pair(E_photon);
462  std::pair<double, double> xs = total_cross_section_pair();
463  const double xs_ff =
464  pow_int(FF.first, 4) * xs.first + pow_int(FF.second, 4) * xs.second;
465  return cut_off(xs_ff);
466  } else if (default_mediator_ == MediatorType::PION) {
467  const double FF = form_factor_pion(E_photon);
468  const double xs = total_cross_section();
469  return cut_off(pow_int(FF, 4) * xs);
470  } else if (default_mediator_ == MediatorType::OMEGA) {
471  const double FF = form_factor_omega(E_photon);
472  const double xs = total_cross_section();
473  return cut_off(pow_int(FF, 4) * xs);
474  }
475  break;
476  }
482  const double FF = form_factor_pion(E_photon);
483  const double xs = total_cross_section();
484  const double xs_ff = pow_int(FF, 4) * xs;
485  return cut_off(xs_ff);
486  }
487 
489  const double FF = form_factor_omega(E_photon);
490  const double xs = total_cross_section();
491  const double xs_ff = pow_int(FF, 4) * xs;
492  return cut_off(xs_ff);
493  }
494 
496  default:
497  throw std::runtime_error("");
498  return 0;
499  }
500 }
501 
503  const double m_rho,
504  MediatorType mediator) const {
505  const double s = mandelstam_s();
506  double diff_xsection = 0.0;
507 
509 
510  switch (reac_) {
512  diff_xsection = xs_object.xs_diff_pi_pi_rho0(s, t, m_rho);
513  break;
514 
517  diff_xsection = xs_object.xs_diff_pi_pi0_rho(s, t, m_rho);
518  break;
519 
522  diff_xsection = xs_object.xs_diff_pi_rho0_pi(s, t, m_rho);
523  break;
524 
527  if (mediator == MediatorType::SUM) {
528  diff_xsection =
529  xs_object.xs_diff_pi_rho_pi0_rho_mediated(s, t, m_rho) +
530  xs_object.xs_diff_pi_rho_pi0_omega_mediated(s, t, m_rho);
531  } else if (mediator == MediatorType::OMEGA) {
532  diff_xsection =
533  xs_object.xs_diff_pi_rho_pi0_omega_mediated(s, t, m_rho);
534  } else if (mediator == MediatorType::PION) {
535  diff_xsection = xs_object.xs_diff_pi_rho_pi0_rho_mediated(s, t, m_rho);
536  }
537  break;
538 
541  if (mediator == MediatorType::SUM) {
542  diff_xsection =
543  xs_object.xs_diff_pi0_rho_pi_rho_mediated(s, t, m_rho) +
544  xs_object.xs_diff_pi0_rho_pi_omega_mediated(s, t, m_rho);
545  } else if (mediator == MediatorType::OMEGA) {
546  diff_xsection =
547  xs_object.xs_diff_pi0_rho_pi_omega_mediated(s, t, m_rho);
548  } else if (mediator == MediatorType::PION) {
549  diff_xsection = xs_object.xs_diff_pi0_rho_pi_rho_mediated(s, t, m_rho);
550  }
551  break;
552 
554  diff_xsection = xs_object.xs_diff_pi0_rho0_pi0(s, t, m_rho);
555  break;
557  // never reached
558  break;
559  }
560 
561  // Rarely, it can happen that the computed differential cross sections slip
562  // slightly below zero for numerical reasons. This is unphysical. We
563  // approximate them with dSigma/dt = 0.01 mb/GeV^2, which is a reasonable
564  // value in the kinetic regime where this occurs.
565  if (diff_xsection < 0) {
566  diff_xsection = 0.01;
567  }
568  return diff_xsection;
569 }
570 
572  const double m_rho,
573  const double E_photon) {
583  /* C12, C13, C15, C16 need special treatment. These processes have identical
584  incoming and outgoing particles, but diffrent mediating particles and
585  hence different form factors. If both channels are added up
586  (MediatorType::SUM), each contribution is corrected by the corresponding
587  form factor.
588  */
589  switch (reac_) {
595  std::pair<double, double> FF = form_factor_pair(E_photon);
596  std::pair<double, double> diff_xs = diff_cross_section_pair(t, m_rho);
597  const double xs_ff = pow_int(FF.first, 4) * diff_xs.first +
598  pow_int(FF.second, 4) * diff_xs.second;
599  return cut_off(xs_ff);
600  } else if (default_mediator_ == MediatorType::PION) {
601  const double FF = form_factor_pion(E_photon);
602  const double diff_xs = diff_cross_section(t, m_rho);
603  return cut_off(pow_int(FF, 4) * diff_xs);
604  } else if (default_mediator_ == MediatorType::OMEGA) {
605  const double FF = form_factor_omega(E_photon);
606  const double diff_xs = diff_cross_section(t, m_rho);
607  return cut_off(pow_int(FF, 4) * diff_xs);
608  }
609  break;
610  }
616  const double FF = form_factor_pion(E_photon);
617  const double xs = diff_cross_section(t, m_rho);
618  const double xs_ff = pow_int(FF, 4) * xs;
619  return cut_off(xs_ff);
620  }
621 
623  const double FF = form_factor_omega(E_photon);
624  const double xs = diff_cross_section(t, m_rho);
625  const double xs_ff = pow_int(FF, 4) * xs;
626  return cut_off(xs_ff);
627  }
628 
630  default:
631  throw std::runtime_error("");
632  return 0;
633  }
634 }
635 
636 double ScatterActionPhoton::form_factor_pion(const double E_photon) const {
637  const double Lambda = 1.0;
638  const double Lambda2 = Lambda * Lambda;
639 
640  const double t_ff = 34.5096 * std::pow(E_photon, 0.737) -
641  67.557 * std::pow(E_photon, 0.7584) +
642  32.858 * std::pow(E_photon, 0.7806);
643  const double ff = 2 * Lambda2 / (2 * Lambda2 - t_ff);
644 
645  return ff * ff;
646 }
647 
648 double ScatterActionPhoton::form_factor_omega(const double E_photon) const {
649  const double Lambda = 1.0;
650  const double Lambda2 = Lambda * Lambda;
651 
652  const double t_ff = -61.595 * std::pow(E_photon, 0.9979) +
653  28.592 * std::pow(E_photon, 1.1579) +
654  37.738 * std::pow(E_photon, 0.9317) -
655  5.282 * std::pow(E_photon, 1.3686);
656  const double ff = 2 * Lambda2 / (2 * Lambda2 - t_ff);
657 
658  return ff * ff;
659 }
660 
661 std::pair<double, double> ScatterActionPhoton::form_factor_pair(
662  const double E_photon) {
663  return std::pair<double, double>(form_factor_pion(E_photon),
664  form_factor_omega(E_photon));
665 }
666 
668  const double xs_pion = total_cross_section(MediatorType::PION);
669  const double xs_omega = total_cross_section(MediatorType::OMEGA);
670 
671  return std::pair<double, double>(xs_pion, xs_omega);
672 }
673 
675  const double t, const double m_rho) {
676  const double diff_xs_pion = diff_cross_section(t, m_rho, MediatorType::PION);
677  const double diff_xs_omega =
679 
680  return std::pair<double, double>(diff_xs_pion, diff_xs_omega);
681 }
682 
683 } // namespace smash
Thrown for example when ScatterAction is called to perform with a wrong number of final-state particl...
Definition: action.h:330
FourVector total_momentum_of_outgoing_particles() const
Calculate the total kinetic momentum of the outgoing particles.
Definition: action.cc:157
ParticleList outgoing_particles_
Initially this stores only the PDG codes of final-state particles.
Definition: action.h:363
virtual double check_conservation(const uint32_t id_process) const
Check various conservation laws.
Definition: action.cc:475
double sqrt_s() const
Determine the total energy in the center-of-mass frame [GeV].
Definition: action.h:271
ParticleList incoming_particles_
List with data of incoming particles.
Definition: action.h:355
FourVector get_interaction_point() const
Get the interaction point.
Definition: action.cc:68
ProcessType process_type_
type of process
Definition: action.h:372
Angles provides a common interface for generating directions: i.e., two angles that should be interpr...
Definition: angles.h:59
ThreeVector threevec() const
Definition: angles.h:288
Class to calculate the cross-section of a meson-meson to meson-photon process.
static double xs_diff_pi0_rho_pi_omega_mediated(const double s, const double t, const double m_rho)
Differential cross section for given photon process.
static double xs_diff_pi_rho0_pi(const double s, const double t, const double m_rho)
Differential cross section for given photon process.
static double xs_diff_pi0_rho_pi_rho_mediated(const double s, const double t, const double m_rho)
Differential cross section for given photon process.
static double xs_diff_pi_rho_pi0_omega_mediated(const double s, const double t, const double m_rho)
Differential cross section for given photon process.
static double xs_pi_rho_pi0(const double s, const double m_rho)
Total cross sections for given photon process:
static double xs_diff_pi_pi_rho0(const double s, const double t, const double m_rho)
Differential cross section for given photon process.
static double xs_pi_rho0_pi(const double s, const double m_rho)
Total cross sections for given photon process:
static double xs_pi_pi_rho0(const double s, const double m_rho)
Total cross sections for given photon process:
static double xs_diff_pi_pi0_rho(const double s, const double t, const double m_rho)
Differential cross section for given photon process.
static double xs_diff_pi_rho_pi0_rho_mediated(const double s, const double t, const double m_rho)
Differential cross section for given photon process.
static double xs_pi0_rho_pi(const double s, const double m_rho)
Total cross sections for given photon process:
static double xs_pi0_rho_pi_omega_mediated(const double s, const double m_rho)
Total cross sections for given photon process:
static double xs_pi0_rho0_pi0(const double s, const double m_rho)
Total cross sections for given photon process:
static double xs_diff_pi0_rho0_pi0(const double s, const double t, const double m_rho)
Differential cross section for given photon process.
static double xs_pi_pi0_rho(const double s, const double m_rho)
Total cross sections for given photon process:
static double xs_pi_rho_pi0_omega_mediated(const double s, const double m_rho)
Total cross sections for given photon process:
static double xs_pi_rho_pi0_rho_mediated(const double s, const double m_rho)
Total cross sections for given photon process:
static double xs_pi0_rho_pi_rho_mediated(const double s, const double m_rho)
Total cross sections for given photon process:
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
Definition: fourvector.h:33
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:58
A pointer-like interface to global references to ParticleType objects.
Definition: particletype.h:676
double sample_resonance_mass(const double mass_stable, const double cms_energy, int L=0) const
Resonance mass sampling for 2-particle final state with one resonance (type given by 'this') and one ...
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
Definition: particletype.cc:99
bool is_stable() const
Definition: particletype.h:246
double mass() const
Definition: particletype.h:145
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
Definition: pdgcode.h:111
std::int32_t code() const
Definition: pdgcode.h:322
bool is_pion() const
Definition: pdgcode.h:457
std::pair< double, double > diff_cross_section_pair(const double t, const double m_rho)
For processes which can happen via (pi, a1, rho) and omega exchange, return the differential cross se...
double diff_cross_section(const double t, const double m_rho, MediatorType mediator=default_mediator_) const
Calculate the differential cross section of the photon process.
ScatterActionPhoton(const ParticleList &in, const double time, const int n_frac_photons, const double hadronic_cross_section_input)
Construct a ScatterActionPhoton object.
const int number_of_fractional_photons_
Number of photons created for each hadronic scattering, needed for correct weighting.
std::pair< double, double > total_cross_section_pair()
For processes which can happen via (pi, a1, rho) and omega exchange, return the total cross section f...
ReactionType
Enum for encoding the photon process.
double total_cross_section_w_ff(const double E_photon)
Compute the total cross corrected for form factors.
const ReactionType reac_
Photonic process as determined from incoming particles.
double form_factor_omega(const double E_photon) const
Compute the form factor for a process with a omega as the lightest exchange particle.
double diff_cross_section_w_ff(const double t, const double m_rho, const double E_photon)
Compute the differential cross section corrected for form factors.
MediatorType
Compile-time switch for setting the handling of processes which can happen via different mediating pa...
void perform_photons(const OutputsList &outputs)
Create the photon final state and write to output.
CollisionBranchList collision_processes_photons_
Holds the photon branch.
double total_cross_section(MediatorType mediator=default_mediator_) const
Calculate the total cross section of the photon process.
void generate_final_state() override
Generate the final-state for the photon scatter process.
bool collision_branch_created_
Was the collision branch already created?
double rho_mass() const
Find the mass of the participating rho-particle.
double form_factor_pion(const double E_photon) const
Compute the form factor for a process with a pion as the lightest exchange particle.
static ParticleTypePtr outgoing_hadron_type(const ParticleList &in)
Return ParticleTypePtr of hadron in the out channel, given the incoming particles.
double weight_
Weight of the produced photon.
CollisionBranchList create_collision_branch()
Creates a CollisionBranchList containing the photon processes.
std::pair< double, double > form_factor_pair(const double E_photon)
For processes which can happen via (pi, a1, rho) and omega exchange, return the form factor for the (...
static constexpr MediatorType default_mediator_
Value used for default exchange particle. See MediatorType.
const double hadron_out_mass_
Mass of outgoing hadron.
void add_dummy_hadronic_process(double reaction_cross_section)
Adds one hadronic process with a given cross-section.
static ReactionType photon_reaction_type(const ParticleList &in)
Determine photon process from incoming particles.
static bool is_kinematically_possible(const double s_sqrt, const ParticleList &in)
Check if CM-energy is sufficient to produce hadron in final state.
double hadronic_cross_section() const
Return the total cross section of the underlying hadronic scattering.
const ParticleTypePtr hadron_out_t_
ParticleTypePtr to the type of the outgoing hadron.
double sample_out_hadron_mass(const ParticleTypePtr out_type)
Sample the mass of the outgoing hadron.
ScatterAction is a special action which takes two incoming particles and performs a scattering,...
Definition: scatteraction.h:30
void add_collision(CollisionBranchPtr p)
Add a new collision channel.
double mandelstam_s() const
Determine the Mandelstam s variable,.
double cm_momentum() const
Get the momentum of the center of mass of the incoming particles in the calculation frame.
Collection of useful constants that are known at compile time.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
Definition: logging.cc:39
constexpr int pi_p
π⁺.
constexpr int rho_p
ρ⁺.
constexpr int rho_m
ρ⁻.
constexpr int p
Proton.
constexpr int pi_z
π⁰.
constexpr int photon
Photon.
constexpr int rho_z
ρ⁰.
constexpr int Lambda
Λ.
constexpr int pi_m
π⁻.
T uniform(T min, T max)
Definition: random.h:88
Definition: action.h:24
T pCM(const T sqrts, const T mass_a, const T mass_b) noexcept
Definition: kinematics.h:79
constexpr std::uint32_t ID_PROCESS_PHOTON
Process ID for any photon process.
Definition: constants.h:118
@ TwoToTwo
See here for a short description.
constexpr double twopi
.
Definition: constants.h:45
std::array< T, 2 > get_t_range(const T sqrts, const T m1, const T m2, const T m3, const T m4)
Get the range of Mandelstam-t values allowed in a particular 2->2 process, see PDG 2014 booklet,...
Definition: kinematics.h:109
constexpr T pow_int(const T base, unsigned const exponent)
Efficient template for calculating integer powers using squaring.
Definition: pow.h:23
constexpr uint64_t pack(int32_t x, int32_t y)
Pack two int32_t into an uint64_t.
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:37
static constexpr int LScatterAction
double cut_off(const double sigma_mb)
Cross section after cut off.
constexpr double omega_mass
omega mass in GeV.
Definition: constants.h:79