ComPWA
Common Partial-Wave-Analysis Framework
FormFactor.hpp
Go to the documentation of this file.
1 // Copyright (c) 2017 The ComPWA Team.
2 // This file is part of the ComPWA framework, check
3 // https://github.com/ComPWA/ComPWA/license.txt for details.
4 
5 #ifndef COMPWA_PHYSICS_DYNAMICS_FORMFACTOR_HPP_
6 #define COMPWA_PHYSICS_DYNAMICS_FORMFACTOR_HPP_
7 
8 #include <complex>
9 #include <exception>
10 
13 
14 namespace ComPWA {
15 namespace Physics {
16 namespace Dynamics {
17 
24 inline double qSquared(double S, double sqrtSA, double sqrtSB) {
25  double mapb = sqrtSA + sqrtSB;
26  double mamb = sqrtSA - sqrtSB;
27  double t1 = S - mapb * mapb;
28  double t2 = S - mamb * mamb;
29  return (t1 * t2 / (4 * S));
30 }
31 
32 inline double phspFactor(double sqrtS, double ma, double mb) {
33  return std::abs(std::sqrt(qSquared(sqrtS * sqrtS, ma, mb))) /
34  (8.0 * M_PI * sqrtS);
35 }
36 
42 inline std::complex<double> phspFactorAC(double sqrtS, double ma, double mb) {
43  // The PDG document states that these formulas are only in case of ma = mb
44  // and the implementation is also incorrect. Use this function at own risk!
45  double s = sqrtS * sqrtS;
46  std::complex<double> i(0, 1);
47 
48  // == Two types of analytic continuation
49  // 1) Complex sqrt
50  // std::complex<double> rhoOld;
51  // rhoOld = sqrt(std::complex<double>(qSqValue(sqrtS,ma,mb))) /
52  //(8*M_PI*sqrtS); //PDG definition
53  // rhoOld = sqrt(std::complex<double>(qSqValue(sqrtS,ma,mb))) /
54  //(0.5*sqrtS); //BaBar definition
55  // return rhoOld; //complex sqrt
56 
57  // 2) Correct analytic continuation
58  // proper analytic continuation (PDG 2014 - Resonances (47.2.2))
59  // I'm not sure of this is correct for the case of two different masses ma
60  // and mb. Furthermore we divide by the factor 16*Pi*Sqrt[s]). This is
61  // more or less arbitrary and not mentioned in the reference, but it leads
62  // to a good agreement between both approaches.
63  std::complex<double> rho;
64  double q = std::sqrt(std::fabs(qSquared(s, ma, mb) * 4 / s));
65  if ((ma + mb) * (ma + mb) < s) { // above threshold
66  rho = (-q / M_PI * log(std::fabs((1 + q) / (1 - q))) + i * q) /
67  (i * 16.0 * M_PI * sqrtS);
68  } else if (0 < s && s <= (ma + mb) * (ma + mb)) { // below threshold
69  rho = (-2.0 * q / M_PI * atan(1 / q)) / (i * 16.0 * M_PI * sqrtS);
70  } else if (s <= 0) { // below 0
71  rho = -q / M_PI * std::log(std::fabs((1 + q) / (1 - q)));
72  } else
73  throw std::runtime_error("phspFactor() | PhspFactor not "
74  "defined at sqrtS = " +
75  std::to_string((long double)sqrtS));
76 
77 #ifndef NDEBUG
78  if (rho.real() != rho.real() || rho.imag() != rho.imag()) {
79  std::stringstream ss;
80  ss << "phspFactor() | Result invalid (NaN)! sqrtS=" << sqrtS
81  << ", ma=" << ma << ", mb=" << mb;
82  throw std::runtime_error(ss.str());
83  }
84 #endif
85 
86  return rho; // correct analytical continuation
87 }
88 
95 inline std::complex<double> qValueAC(double sqrtS, double ma, double mb) {
96  return phspFactorAC(sqrtS, ma, mb) * 8.0 * M_PI * sqrtS;
97 }
98 
102 class FormFactor {
103 public:
104  virtual double operator()(double QSquared, unsigned int L,
105  double MesonRadius) const = 0;
106  virtual std::string getName() const = 0;
107 };
108 
109 class NoFormFactor : public FormFactor {
110 public:
111  double operator()(double QSquared, unsigned int L, double MesonRadius) const {
112  return 1.0;
113  }
114  std::string getName() const { return "NoFormFactor"; }
115 };
116 
122  double operator()(double qSquared, unsigned int L, double MesonRadius) const {
123  if (MesonRadius == 0.) {
124  return 1.0;
125  }
126 
127  double z = qSquared * MesonRadius * MesonRadius;
128  // Events below threshold. What should we do if event is below threshold?
129  // Shouldn't really influence the result because resonances at threshold
130  // don't have spin(?).
131  // Ref. for Blatt-Weisskopf: Phys. Rev. D 48, 1225
132  z = std::abs(z);
133 
134  double ff(1.0);
135  if (L == 1) {
136  ff = std::sqrt(2 * z / (z + 1));
137  } else if (L == 2) {
138  ff = std::sqrt(13 * z * z / ((z - 3) * (z - 3) + 9 * z));
139  } else if (L == 3) {
140  ff = std::sqrt(277 * z * z * z /
141  (z * (z - 15) * (z - 15) + 9 * (2 * z - 5) * (2 * z - 5)));
142  } else if (L == 4) {
143  ff = std::sqrt(12746 * z * z * z * z /
144  ((z * z - 45 * z + 105) * (z * z - 45 * z + 105) +
145  25 * z * (2 * z - 21) * (2 * z - 21)));
146  }
147 
148  return ff;
149  }
150  std::string getName() const { return "BlattWeisskopf"; }
151 };
152 
155  double operator()(double qSquared, unsigned int L, double MesonRadius) const {
156  if (MesonRadius == 0.) {
157  return 1.0;
158  }
159 
160  double ff(1.0);
161  if (L == 0) {
162  double alpha = MesonRadius * MesonRadius / 6;
163  ff = std::exp(-alpha * qSquared);
164  }
165 
166  return ff;
167  }
168  std::string getName() const { return "CrystalBarrel"; }
169 };
170 
171 std::shared_ptr<ComPWA::FunctionTree::TreeNode> createFunctionTree(
172  std::shared_ptr<ComPWA::FunctionTree::Value<std::vector<double>>>
173  InvMassSquaredDaughter1,
174  std::shared_ptr<ComPWA::FunctionTree::Value<std::vector<double>>>
175  InvMassSquaredDaughter2,
176  std::shared_ptr<ComPWA::FunctionTree::FitParameter> MesonRadius,
177  unsigned int L, std::shared_ptr<FormFactor> FormFactorFunctor,
178  std::shared_ptr<ComPWA::FunctionTree::Value<std::vector<double>>>
179  InvMassSquared);
180 
182 public:
183  FormFactorStrategy(std::shared_ptr<FormFactor> FF)
184  : ComPWA::FunctionTree::Strategy(ComPWA::FunctionTree::ParType::MDOUBLE,
185  "FormFactor"),
186  FormFactorFunctor(FF) {}
187 
188  virtual void execute(ComPWA::FunctionTree::ParameterList &paras,
189  std::shared_ptr<ComPWA::FunctionTree::Parameter> &out);
190 
191 private:
192  std::shared_ptr<FormFactor> FormFactorFunctor;
193 };
194 
195 } // namespace Dynamics
196 } // namespace Physics
197 } // namespace ComPWA
198 
199 #endif
double operator()(double qSquared, unsigned int L, double MesonRadius) const
Definition: FormFactor.hpp:155
double phspFactor(double sqrtS, double ma, double mb)
Definition: FormFactor.hpp:32
std::complex< double > phspFactorAC(double sqrtS, double ma, double mb)
Two body phsp factor.
Definition: FormFactor.hpp:42
double qSquared(double S, double sqrtSA, double sqrtSB)
Calculate Break-up momentum squared.
Definition: FormFactor.hpp:24
Blatt-Weisskopf form factors with normalization F(x=mR) = 1.
Definition: FormFactor.hpp:121
Defines interface for form factors It should be noted that when exchanging various form factor implem...
Definition: FormFactor.hpp:102
FormFactorStrategy(std::shared_ptr< FormFactor > FF)
Definition: FormFactor.hpp:183
virtual std::string getName() const =0
This file contains Functions implementing the Strategy interface so they can be used inside a node of...
std::shared_ptr< FormFactor > FormFactorFunctor
Definition: FormFactor.hpp:192
Form factor for a0(980) used by Crystal Barrel (Phys.Rev.D78-074023)
Definition: FormFactor.hpp:154
virtual double operator()(double QSquared, unsigned int L, double MesonRadius) const =0
double operator()(double qSquared, unsigned int L, double MesonRadius) const
Definition: FormFactor.hpp:122
std::shared_ptr< ComPWA::FunctionTree::TreeNode > createFunctionTree(std::shared_ptr< ComPWA::FunctionTree::Value< std::vector< double >>> InvMassSquaredDaughter1, std::shared_ptr< ComPWA::FunctionTree::Value< std::vector< double >>> InvMassSquaredDaughter2, std::shared_ptr< ComPWA::FunctionTree::FitParameter > MesonRadius, unsigned int L, std::shared_ptr< FormFactor > FormFactorFunctor, std::shared_ptr< ComPWA::FunctionTree::Value< std::vector< double >>> InvMassSquared)
Definition: FormFactor.cpp:17
std::complex< double > qValueAC(double sqrtS, double ma, double mb)
Calculate Break-up momentum.
Definition: FormFactor.hpp:95
ParType
Enums for the type of the parameter, should be extended if an new parameter type is added...
Definition: Parameter.hpp:34
TreeNode class.
double operator()(double QSquared, unsigned int L, double MesonRadius) const
Definition: FormFactor.hpp:111
Virtual base class for operations of FunctionTree nodes.
Definition: Functions.hpp:30
This class provides a list of parameters and values of different types.