Version: SMASH-3.3
scatteractionphoton.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2016-2022,2024-2025
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  const SpinInteractionType spin_interaction_type)
30  : ScatterAction(in[0], in[1], time),
31  reac_(photon_reaction_type(in)),
32  number_of_fractional_photons_(n_frac_photons),
33  hadron_out_t_(outgoing_hadron_type(in)),
34  hadron_out_mass_(sample_out_hadron_mass(hadron_out_t_)),
35  hadronic_cross_section_(hadronic_cross_section_input),
36  spin_interaction_type_(spin_interaction_type) {}
37 
39  const ParticleList &in) {
40  if (in.size() != 2) {
42  }
43 
44  PdgCode a = in[0].pdgcode();
45  PdgCode b = in[1].pdgcode();
46 
47  // swap so that pion is first and there are less cases to be listed
48  if (!a.is_pion()) {
49  std::swap(a, b);
50  }
51 
52  switch (pack(a.code(), b.code())) {
53  case (pack(pdg::pi_p, pdg::pi_z)):
54  case (pack(pdg::pi_z, pdg::pi_p)):
56 
57  case (pack(pdg::pi_m, pdg::pi_z)):
58  case (pack(pdg::pi_z, pdg::pi_m)):
60 
61  case (pack(pdg::pi_p, pdg::rho_z)):
63 
64  case (pack(pdg::pi_m, pdg::rho_z)):
66 
67  case (pack(pdg::pi_m, pdg::rho_p)):
69 
70  case (pack(pdg::pi_p, pdg::rho_m)):
72 
73  case (pack(pdg::pi_z, pdg::rho_p)):
75 
76  case (pack(pdg::pi_z, pdg::rho_m)):
78 
79  case (pack(pdg::pi_p, pdg::pi_m)):
80  case (pack(pdg::pi_m, pdg::pi_p)):
82 
83  case (pack(pdg::pi_z, pdg::rho_z)):
85 
86  default:
88  }
89 }
90 
91 void ScatterActionPhoton::perform_photons(const OutputsList &outputs) {
92  for (int i = 0; i < number_of_fractional_photons_; i++) {
94  for (const auto &output : outputs) {
95  if (output->is_photon_output()) {
96  // we do not care about the local density
97  output->at_interaction(*this, 0.0);
98  }
99  }
100  }
101 }
102 
104  const ReactionType reaction) {
105  static const ParticleTypePtr rho_z_particle_ptr =
107  static const ParticleTypePtr rho_p_particle_ptr =
109  static const ParticleTypePtr rho_m_particle_ptr =
111  static const ParticleTypePtr pi_z_particle_ptr =
113  static const ParticleTypePtr pi_p_particle_ptr =
115  static const ParticleTypePtr pi_m_particle_ptr =
117 
118  switch (reaction) {
120  return rho_p_particle_ptr;
121  break;
123  return rho_m_particle_ptr;
124  break;
126  return rho_z_particle_ptr;
127  break;
128 
131  return pi_p_particle_ptr;
132 
135  return pi_m_particle_ptr;
136 
140  return pi_z_particle_ptr;
141  break;
142  default:
143  // default constructor constructs p with invalid index
144  ParticleTypePtr p{};
145  return p;
146  }
147 }
148 
150  const ParticleList &in) {
151  auto reac = photon_reaction_type(in);
152  return outgoing_hadron_type(reac);
153 }
154 
156  const ParticleList &in) {
157  auto reac = photon_reaction_type(in);
158  auto hadron = outgoing_hadron_type(in);
159 
160  if (reac == ReactionType::no_reaction)
161  return false;
162 
165  return false;
166  }
167 
168  // C15 has only s-channel. Make sure that CM-energy is high
169  // enough to produce mediating omega meson
170  if ((reac == ReactionType::pi_m_rho_p_pi_z ||
173  if (s_sqrt < omega_mass) {
174  return false;
175  }
176  }
177 
178  // for all other processes: if cm-energy is not high enough to produce final
179  // state particle reject the collision.
180  if (hadron->is_stable() && s_sqrt < hadron->mass()) {
181  return false;
182  // Make sure energy is high enough to not only create final state particle,
183  // but to also assign momentum.
184  } else if (!hadron->is_stable() &&
185  s_sqrt < (hadron->min_mass_spectral() + really_small)) {
186  return false;
187  } else {
188  return true;
189  }
190 }
191 
193  // we have only one reaction per incoming particle pair
194  if (collision_processes_photons_.size() != 1) {
195  logg[LScatterAction].fatal()
196  << "Problem in ScatterActionPhoton::generate_final_state().\n";
197  throw std::runtime_error("");
198  }
199  auto *proc = collision_processes_photons_[0].get();
200 
201  outgoing_particles_ = proc->particle_list();
202  process_type_ = proc->get_type();
203 
204  FourVector middle_point = get_interaction_point();
205 
206  // t is defined to be the momentum exchanged between the rho meson and the
207  // photon in pi + rho -> pi + photon channel. Therefore,
208  // get_t_range needs to be called with m2 being the rho mass instead of the
209  // pion mass. So, particles 1 and 2 are swapped if necessary.
210 
211  if (!incoming_particles_[0].pdgcode().is_pion()) {
212  std::swap(incoming_particles_[0], incoming_particles_[1]);
213  }
214 
215  // 2->2 inelastic scattering
216  // Sample the particle momenta in CM system
217  const double m1 = incoming_particles_[0].effective_mass();
218  const double m2 = incoming_particles_[1].effective_mass();
219 
220  const double &m_out = hadron_out_mass_;
221 
222  const double s = mandelstam_s();
223  const double sqrts = sqrt_s();
224  std::array<double, 2> mandelstam_t = get_t_range(sqrts, m1, m2, m_out, 0.0);
225  const double t1 = mandelstam_t[1];
226  const double t2 = mandelstam_t[0];
227  const double pcm_in = cm_momentum();
228  const double pcm_out = pCM(sqrts, m_out, 0.0);
229 
230  const double t = random::uniform(t1, t2);
231 
232  double costheta = (t - pow_int(m2, 2) +
233  0.5 * (s + pow_int(m2, 2) - pow_int(m1, 2)) *
234  (s - pow_int(m_out, 2)) / s) /
235  (pcm_in * (s - pow_int(m_out, 2)) / sqrts);
236 
237  // on very rare occasions near the kinematic threshold numerical issues give
238  // unphysical angles.
239  if (costheta > 1 || costheta < -1) {
240  logg[LScatterAction].warn()
241  << "Cos(theta)of photon scattering out of physical bounds in "
242  "the following scattering: "
243  << incoming_particles_ << "Clamping to [-1,1].";
244  if (costheta > 1.0)
245  costheta = 1.0;
246  if (costheta < -1.0)
247  costheta = -1.0;
248  }
249  Angles phitheta(random::uniform(0.0, twopi), costheta);
250  outgoing_particles_[0].set_4momentum(hadron_out_mass_,
251  phitheta.threevec() * pcm_out);
252  outgoing_particles_[1].set_4momentum(0.0, -phitheta.threevec() * pcm_out);
253 
254  // Set positions & boost to computational frame.
255  for (ParticleData &new_particle : outgoing_particles_) {
256  new_particle.set_4position(middle_point);
257  new_particle.boost_momentum(
259  }
260  // Set unpolarized spin vector for outgoing particles
263  }
264 
265  const double E_Photon = outgoing_particles_[1].momentum()[0];
266 
267  // Weighing of the fractional photons
269  // if rho in final state take already sampled mass (same as m_out). If rho
270  // is incoming take the mass of the incoming particle
271  const double m_rho = rho_mass();
272 
273  // compute the differential cross section with form factor included
274  const double diff_xs = diff_cross_section_w_ff(t, m_rho, E_Photon);
275 
276  weight_ = diff_xs * (t2 - t1) /
278  } else {
279  // compute the total cross section with form factor included
280  const double total_xs = total_cross_section_w_ff(E_Photon);
281 
282  weight_ = total_xs / hadronic_cross_section();
283  }
284  // Scale weight by cross section scaling factor of incoming particles
285  weight_ *= incoming_particles_[0].xsec_scaling_factor() *
286  incoming_particles_[1].xsec_scaling_factor();
287 
288  // Photons are not really part of the normal processes, so we have to set a
289  // constant arbitrary number.
290  const auto id_process = ID_PROCESS_PHOTON;
291  Action::check_conservation(id_process);
292 }
293 
295  double reaction_cross_section) {
296  CollisionBranchPtr dummy_process = std::make_unique<CollisionBranch>(
297  incoming_particles_[0].type(), incoming_particles_[1].type(),
298  reaction_cross_section, ProcessType::TwoToTwo);
299  add_collision(std::move(dummy_process));
300 }
301 
303  const ParticleTypePtr out_t) {
304  double mass = out_t->mass();
305  const double cms_energy = sqrt_s();
306  if (cms_energy <= out_t->min_mass_kinematic()) {
308  "Problem in ScatterActionPhoton::sample_hadron_mass");
309  }
310 
311  if (!out_t->is_stable()) {
312  mass = out_t->sample_resonance_mass(0, cms_energy);
313  }
314 
315  return mass;
316 }
317 
319  assert(reac_ != ReactionType::no_reaction);
320  switch (reac_) {
321  // rho in final state. use already sampled mass
325  return hadron_out_mass_;
326  // rho in initial state, use its mass
334  return (incoming_particles_[0].is_rho())
335  ? incoming_particles_[0].effective_mass()
336  : incoming_particles_[1].effective_mass();
338  default:
339  throw std::runtime_error(
340  "Invalid ReactionType in ScatterActionPhoton::rho_mass()");
341  }
342 }
343 
345  CollisionBranchList process_list;
346 
347  static ParticleTypePtr photon_particle = &ParticleType::find(pdg::photon);
348  double xsection = total_cross_section();
349 
350  process_list.push_back(std::make_unique<CollisionBranch>(
351  *hadron_out_t_, *photon_particle, xsection, ProcessType::TwoToTwo));
353  return process_list;
354 }
355 
357  CollisionBranchList process_list;
359 
360  const double s = mandelstam_s();
361  // the mass of the mediating particle depends on the channel. For an incoming
362  // rho it is the mass of the incoming particle, for an outgoing rho it is the
363  // sampled mass
364  const double m_rho = rho_mass();
365  double xsection = 0.0;
366 
367  switch (reac_) {
369  xsection = xs_object.xs_pi_pi_rho0(s, m_rho);
370  break;
371 
374  xsection = xs_object.xs_pi_pi0_rho(s, m_rho);
375  break;
376 
379  xsection = xs_object.xs_pi_rho0_pi(s, m_rho);
380  break;
381 
384  if (mediator == MediatorType::SUM) {
385  xsection = xs_object.xs_pi_rho_pi0(s, m_rho);
386  break;
387  } else if (mediator == MediatorType::PION) {
388  xsection = xs_object.xs_pi_rho_pi0_rho_mediated(s, m_rho);
389  break;
390  } else if (mediator == MediatorType::OMEGA) {
391  xsection = xs_object.xs_pi_rho_pi0_omega_mediated(s, m_rho);
392  break;
393  } else {
394  throw std::runtime_error("");
395  }
398  if (mediator == MediatorType::SUM) {
399  xsection = xs_object.xs_pi0_rho_pi(s, m_rho);
400  break;
401  } else if (mediator == MediatorType::PION) {
402  xsection = xs_object.xs_pi0_rho_pi_rho_mediated(s, m_rho);
403  break;
404  } else if (mediator == MediatorType::OMEGA) {
405  xsection = xs_object.xs_pi0_rho_pi_omega_mediated(s, m_rho);
406  break;
407  } else {
408  throw std::runtime_error("");
409  }
410 
412  xsection = xs_object.xs_pi0_rho0_pi0(s, m_rho);
413  break;
414 
416  // never reached
417  break;
418  }
419 
420  if (xsection == 0.0) {
421  // Vanishing cross sections are problematic for the creation of a
422  // CollisionBranch. For infrastructure reasons it is however necessary to
423  // create such a collision branch whenever the underlying hadronic
424  // scattering is a candidate for a photon interaction. In these cases we
425  // need to manually set a dummy value for the cross section and produce the
426  // photon. This photon will however automatically be assigned a 0 weight
427  // because of the vanishing cross section and therefore not be of relevance
428  // for any analysis.
429  // In other cases, where the collision branch was already created, we
430  // do not want to overwrite the cross section, of course.
431  xsection = collision_branch_created_ ? 0.0 : 0.01;
432  } else if (xsection < 0) {
433  // Due to numerical reasons it can happen that the calculated cross sections
434  // are negative (approximately -1e-15) if sqrt(s) is close to the threshold
435  // energy. In those cases the cross section is manually set to 0.1 mb, which
436  // is a reasonable value for the processes we are looking at (C14,C15,C16).
437  xsection = 0.1;
438  logg[LScatterAction].warn(
439  "Calculated negative cross section.\nParticles ", incoming_particles_,
440  " mass rho particle: ", m_rho, ", sqrt_s: ", std::sqrt(s));
441  }
442  return xsection;
443 }
444 
445 double ScatterActionPhoton::total_cross_section_w_ff(const double E_photon) {
455  /* C12, C13, C15, C16 need special treatment. These processes have identical
456  incoming and outgoing particles, but diffrent mediating particles and
457  hence different form factors. If both channels are added up
458  (MediatorType::SUM), each contribution is corrected by the corresponding
459  form factor.
460  */
461  switch (reac_) {
467  std::pair<double, double> FF = form_factor_pair(E_photon);
468  std::pair<double, double> xs = total_cross_section_pair();
469  const double xs_ff =
470  pow_int(FF.first, 4) * xs.first + pow_int(FF.second, 4) * xs.second;
471  return cut_off(xs_ff);
472  } else if (default_mediator_ == MediatorType::PION) {
473  const double FF = form_factor_pion(E_photon);
474  const double xs = total_cross_section();
475  return cut_off(pow_int(FF, 4) * xs);
476  } else if (default_mediator_ == MediatorType::OMEGA) {
477  const double FF = form_factor_omega(E_photon);
478  const double xs = total_cross_section();
479  return cut_off(pow_int(FF, 4) * xs);
480  }
481  break;
482  }
488  const double FF = form_factor_pion(E_photon);
489  const double xs = total_cross_section();
490  const double xs_ff = pow_int(FF, 4) * xs;
491  return cut_off(xs_ff);
492  }
493 
495  const double FF = form_factor_omega(E_photon);
496  const double xs = total_cross_section();
497  const double xs_ff = pow_int(FF, 4) * xs;
498  return cut_off(xs_ff);
499  }
500 
502  default:
503  throw std::runtime_error("");
504  return 0;
505  }
506 }
507 
509  const double m_rho,
510  MediatorType mediator) const {
511  const double s = mandelstam_s();
512  double diff_xsection = 0.0;
513 
515 
516  switch (reac_) {
518  diff_xsection = xs_object.xs_diff_pi_pi_rho0(s, t, m_rho);
519  break;
520 
523  diff_xsection = xs_object.xs_diff_pi_pi0_rho(s, t, m_rho);
524  break;
525 
528  diff_xsection = xs_object.xs_diff_pi_rho0_pi(s, t, m_rho);
529  break;
530 
533  if (mediator == MediatorType::SUM) {
534  diff_xsection =
535  xs_object.xs_diff_pi_rho_pi0_rho_mediated(s, t, m_rho) +
536  xs_object.xs_diff_pi_rho_pi0_omega_mediated(s, t, m_rho);
537  } else if (mediator == MediatorType::OMEGA) {
538  diff_xsection =
539  xs_object.xs_diff_pi_rho_pi0_omega_mediated(s, t, m_rho);
540  } else if (mediator == MediatorType::PION) {
541  diff_xsection = xs_object.xs_diff_pi_rho_pi0_rho_mediated(s, t, m_rho);
542  }
543  break;
544 
547  if (mediator == MediatorType::SUM) {
548  diff_xsection =
549  xs_object.xs_diff_pi0_rho_pi_rho_mediated(s, t, m_rho) +
550  xs_object.xs_diff_pi0_rho_pi_omega_mediated(s, t, m_rho);
551  } else if (mediator == MediatorType::OMEGA) {
552  diff_xsection =
553  xs_object.xs_diff_pi0_rho_pi_omega_mediated(s, t, m_rho);
554  } else if (mediator == MediatorType::PION) {
555  diff_xsection = xs_object.xs_diff_pi0_rho_pi_rho_mediated(s, t, m_rho);
556  }
557  break;
558 
560  diff_xsection = xs_object.xs_diff_pi0_rho0_pi0(s, t, m_rho);
561  break;
563  // never reached
564  break;
565  }
566 
567  // Rarely, it can happen that the computed differential cross sections slip
568  // slightly below zero for numerical reasons. This is unphysical. We
569  // approximate them with dSigma/dt = 0.01 mb/GeV^2, which is a reasonable
570  // value in the kinetic regime where this occurs.
571  if (diff_xsection < 0) {
572  diff_xsection = 0.01;
573  }
574  return diff_xsection;
575 }
576 
578  const double m_rho,
579  const double E_photon) {
589  /* C12, C13, C15, C16 need special treatment. These processes have identical
590  incoming and outgoing particles, but diffrent mediating particles and
591  hence different form factors. If both channels are added up
592  (MediatorType::SUM), each contribution is corrected by the corresponding
593  form factor.
594  */
595  switch (reac_) {
601  std::pair<double, double> FF = form_factor_pair(E_photon);
602  std::pair<double, double> diff_xs = diff_cross_section_pair(t, m_rho);
603  const double xs_ff = pow_int(FF.first, 4) * diff_xs.first +
604  pow_int(FF.second, 4) * diff_xs.second;
605  return cut_off(xs_ff);
606  } else if (default_mediator_ == MediatorType::PION) {
607  const double FF = form_factor_pion(E_photon);
608  const double diff_xs = diff_cross_section(t, m_rho);
609  return cut_off(pow_int(FF, 4) * diff_xs);
610  } else if (default_mediator_ == MediatorType::OMEGA) {
611  const double FF = form_factor_omega(E_photon);
612  const double diff_xs = diff_cross_section(t, m_rho);
613  return cut_off(pow_int(FF, 4) * diff_xs);
614  }
615  break;
616  }
622  const double FF = form_factor_pion(E_photon);
623  const double xs = diff_cross_section(t, m_rho);
624  const double xs_ff = pow_int(FF, 4) * xs;
625  return cut_off(xs_ff);
626  }
627 
629  const double FF = form_factor_omega(E_photon);
630  const double xs = diff_cross_section(t, m_rho);
631  const double xs_ff = pow_int(FF, 4) * xs;
632  return cut_off(xs_ff);
633  }
634 
636  default:
637  throw std::runtime_error("");
638  return 0;
639  }
640 }
641 
642 double ScatterActionPhoton::form_factor_pion(const double E_photon) const {
643  const double Lambda = 1.0;
644  const double Lambda2 = Lambda * Lambda;
645 
646  const double t_ff = 34.5096 * std::pow(E_photon, 0.737) -
647  67.557 * std::pow(E_photon, 0.7584) +
648  32.858 * std::pow(E_photon, 0.7806);
649  const double ff = 2 * Lambda2 / (2 * Lambda2 - t_ff);
650 
651  return ff * ff;
652 }
653 
654 double ScatterActionPhoton::form_factor_omega(const double E_photon) const {
655  const double Lambda = 1.0;
656  const double Lambda2 = Lambda * Lambda;
657 
658  const double t_ff = -61.595 * std::pow(E_photon, 0.9979) +
659  28.592 * std::pow(E_photon, 1.1579) +
660  37.738 * std::pow(E_photon, 0.9317) -
661  5.282 * std::pow(E_photon, 1.3686);
662  const double ff = 2 * Lambda2 / (2 * Lambda2 - t_ff);
663 
664  return ff * ff;
665 }
666 
667 std::pair<double, double> ScatterActionPhoton::form_factor_pair(
668  const double E_photon) {
669  return std::pair<double, double>(form_factor_pion(E_photon),
670  form_factor_omega(E_photon));
671 }
672 
674  const double xs_pion = total_cross_section(MediatorType::PION);
675  const double xs_omega = total_cross_section(MediatorType::OMEGA);
676 
677  return std::pair<double, double>(xs_pion, xs_omega);
678 }
679 
681  const double t, const double m_rho) {
682  const double diff_xs_pion = diff_cross_section(t, m_rho, MediatorType::PION);
683  const double diff_xs_omega =
685 
686  return std::pair<double, double>(diff_xs_pion, diff_xs_omega);
687 }
688 
689 } // 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:160
ParticleList outgoing_particles_
Initially this stores only the PDG codes of final-state particles.
Definition: action.h:372
void assign_unpolarized_spin_vector_to_outgoing_particles()
Assign an unpolarized spin vector to all outgoing particles.
Definition: action.cc:478
virtual double check_conservation(const uint32_t id_process) const
Check various conservation laws.
Definition: action.cc:484
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:364
FourVector get_interaction_point() const
Get the interaction point.
Definition: action.cc:68
ProcessType process_type_
type of process
Definition: action.h:381
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:59
A pointer-like interface to global references to ParticleType objects.
Definition: particletype.h:682
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:249
double mass() const
Definition: particletype.h:145
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
Definition: pdgcode.h:108
std::int32_t code() const
Definition: pdgcode.h:319
bool is_pion() const
Definition: pdgcode.h:471
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.
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...
const SpinInteractionType spin_interaction_type_
Type of spin interaction to use.
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.
ScatterActionPhoton(const ParticleList &in, const double time, const int n_frac_photons, const double hadronic_cross_section_input, const SpinInteractionType spin_interaction_type=SpinInteractionType::Off)
Construct a ScatterActionPhoton object.
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.
SpinInteractionType
Possible spin interaction types.
@ Off
No spin interactions.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
Definition: logging.cc:40
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:122
@ TwoToTwo
See here for a short description.
constexpr double twopi
.
Definition: constants.h:49
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:41
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:83