All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Constants.cpp
Go to the documentation of this file.
1 #include "Constants.h"
2 
3 #include <cassert>
4 #include <iostream>
5 
6 namespace evgen {
7 namespace ldm {
8 
9 // Set values
11  // P.A. Zylaet al.(Particle Data Group), Prog. Theor. Exp. Phys.2020, 083C01 (2020)
12 
13  // Masses
14  elec_mass = 0.0005109989461; // GeV https://pdg.lbl.gov/2020/listings/rpp2020-list-K-plus-minus.pdf
15  muon_mass = 0.1056583745; // GeV https://pdg.lbl.gov/2020/listings/rpp2020-list-muon.pdf
16  piplus_mass = 0.13957039; // GeV https://pdg.lbl.gov/2020/tables/rpp2020-tab-mesons-light.pdf
17  pizero_mass = 0.1349768; // GeV https://pdg.lbl.gov/2020/tables/rpp2020-tab-mesons-light.pdf
18  kplus_mass = 0.493677; // GeV https://pdg.lbl.gov/2020/listings/rpp2020-list-K-plus-minus.pdf
19  klong_mass = 0.497611; // GeV https://pdg.lbl.gov/2020/listings/rpp2020-list-K-zero.pdf
20  tquark_mass = 172.76; // GeV https://pdg.lbl.gov/2020/tables/rpp2020-sum-quarks.pdf (direct measurements)
21 
22  // Couplings
23  Gfermi = 1.166379e-5; // 1/GeV^2 https://pdg.lbl.gov/2020/reviews/rpp2020-rev-phys-constants.pdf
24  higgs_vev = 1. / sqrt(sqrt(2)*Gfermi); // GeV (246.22)
25  sin2thetaW = 0.2312; // electroweak mixing angle https://pdg.lbl.gov/2020/reviews/rpp2020-rev-phys-constants.pdf
26  gL = -0.5 + sin2thetaW;
27  gR = sin2thetaW;
28  fpion = 0.1302; // Pion decay constant [GeV] https://pdg.lbl.gov/2020/reviews/rpp2020-rev-pseudoscalar-meson-decay-cons.pdf (FLAG 19 average)
29 
30  // unit conversion
31  hbar = 6.582119569e-16; // GeV*ns or eV*s https://pdg.lbl.gov/2020/reviews/rpp2020-rev-phys-constants.pdf
32  c_cm_per_ns = 29.9792458; // cm / ns https://pdg.lbl.gov/2020/reviews/rpp2020-rev-phys-constants.pdf
33 
34  // kaon lifetimes
35  kplus_lifetime = 1.238e1; // ns https://pdg.lbl.gov/2020/listings/rpp2020-list-K-plus-minus.pdf
36  klong_lifetime = 5.116e1; // ns https://pdg.lbl.gov/2020/listings/rpp2020-list-K-zero-L.pdf (FIT)
37 
38  // Kaon decay branching ratios
39  kaonp_mup_numu = 0.6356; // From PDG: https://pdg.lbl.gov/2020/listings/rpp2020-list-K-plus-minus.pdf
40  kaonp_ep_nue = 1.582e-5; // From PDG: https://pdg.lbl.gov/2020/listings/rpp2020-list-K-plus-minus.pdf
41 
42  // CKM matrix
43  abs_Vud_squared = 0.97370 * 0.97370; // https://pdg.lbl.gov/2020/reviews/rpp2020-rev-ckm-matrix.pdf (12.7)
44 
45  // Computed using the Wolfenstein parameterization, where:
46  // Vts = -A \lambda^2
47  // Vtd = A \lambda^3 (1 - \rho - I\eta)
48  //
49  // With, from https://pdg.lbl.gov/2020/reviews/rpp2020-rev-ckm-matrix.pdf:
50  // A = 0.790
51  // \lambda = 0.2265
52  // \rho = 0.141
53  // \eta = 0.357
54  abs_VtsVtd_squared = 1.19777e-7;
55  rel_VtsVtd_squared = 1.02136e-7;
56  // (OLD: 1.0185e-07)
57 }
58 
59 // Configure values
60 void Constants::Configure(const fhicl::ParameterSet &p) {
61  // For now, which values to override:
62  //
63  // top quark mass, electroweak mixing angle
64  if (p.has_key("tquark_mass")) InstanceMut().tquark_mass = p.get<double>("tquark_mass");
65  if (p.has_key("sin2thetaW")) InstanceMut().sin2thetaW = p.get<double>("sin2thetaW");
66 
67  // Reset downstream constants
68  InstanceMut().gL = -0.5 + Instance().sin2thetaW;
70 }
71 
72 // Useful computation
73 double twobody_momentum(double parent_mass, double childA_mass, double childB_mass) {
74  if (parent_mass < childA_mass + childB_mass) return -1.;
75 
76  return sqrt(parent_mass * parent_mass * parent_mass * parent_mass
77  -2 * parent_mass * parent_mass * childA_mass * childA_mass
78  -2 * parent_mass * parent_mass * childB_mass * childB_mass
79  + childA_mass * childA_mass * childA_mass * childA_mass
80  + childB_mass * childB_mass * childB_mass * childB_mass
81  -2 * childA_mass * childA_mass * childB_mass * childB_mass) / ( 2 * parent_mass );
82 
83 }
84 
85 // (Somewhat) Adapted from the EnuWgt code in dk2nugenie for neutrinos.
86 //
87 // Changed to allow for a massive particle, as well as cleaned up
88 //
89 // Given the momentum in the rest frame of the parent particle, the
90 // desired direction in the lab frame, and the boost vector
91 // of the parent particle in the lab frame: computes the momentum and "weight"
92 // of the daughter going through the input end point.
93 //
94 // The weight is given as the ratio of the solid angle between the lab frame and
95 // parent rest frame. I.e. -- it should be converted to an event weight as:
96 //
97 // event weight = weight * (detector lab frame solid angle) / (4*pi)
98 //
99 // For an isotropic decay in the parent rest frame
100 //
101 // Returns 0 if the calculation works. Returns -1 if the perscribed kinematics are not possible.
102 int calcPrtlRayWgt(double rest_frame_p, double M, TVector3 dir, TVector3 boost, double rand,
103  double& lab_frame_p_out, double& costh_rest_out, double& wgt)
104 {
105  // preset values
106  lab_frame_p_out = 0.;
107  costh_rest_out = 0.;
108  wgt = 0.;
109 
110  double beta = boost.Mag();
111  double gamma = 1. / sqrt(1 - beta*beta);
112  double E_rest = sqrt(rest_frame_p*rest_frame_p + M*M);
113 
114  // cos angle between kaon direction and daughter direction (in lab frame)
115  double costh_lab = boost.Unit().Dot(dir.Unit());
116  double sinth_lab_sq = 1 - costh_lab*costh_lab;
117 
118  // The problem: we are given the rest frame momentum and lab frame angle. Given this,
119  // determine the lab frame momentum and rest frame angle.
120  //
121  // Unlike in the massless case, there are 1 OR 0 OR 2 possible solutions to this problem.
122  auto costh_rest = [costh_lab, sinth_lab_sq, beta, gamma, M, rest_frame_p, E_rest](int SIGN) { return -(-SIGN * costh_lab*\
123  sqrt(-M*M + (E_rest*E_rest)/(gamma*gamma) + (M*M)*(beta*beta)*(costh_lab*costh_lab)) \
124  +E_rest*beta*gamma*sinth_lab_sq) / \
125  (rest_frame_p*gamma*(1 - beta*beta*costh_lab*costh_lab)); };
126 
127  double costh_rest_plus = costh_rest(1);
128  double costh_rest_minus = costh_rest(-1);
129 
130  auto lab_frame_p = [costh_lab, beta, gamma, M, E_rest](int SIGN) { return (1. / (1 - beta*beta * costh_lab*costh_lab)) *\
131  (E_rest * beta * costh_lab / gamma \
132  + SIGN * sqrt(-M*M + (E_rest*E_rest)/(gamma*gamma) + M*M * beta*beta * costh_lab*costh_lab)); };
133 
134  double lab_frame_p_plus = lab_frame_p(1);
135  double lab_frame_p_minus = lab_frame_p(-1);
136 
137  bool plus_valid = !isnan(lab_frame_p_plus) && lab_frame_p_plus > 0.;
138  bool minus_valid = !isnan(lab_frame_p_minus) && lab_frame_p_minus > 0.;
139 
140  // Now compute the weight
141  auto wgtf = [costh_lab, rest_frame_p, E_rest, M, beta, gamma](double p_lab, int SIGN) {
142  double E_lab = sqrt(p_lab*p_lab + M*M);
143 
144  double dp_labdp_rest = (rest_frame_p / (E_rest * gamma)) * (beta*costh_lab +\
145  SIGN*E_rest / (gamma * sqrt(E_rest*E_rest / (gamma*gamma) - M*M + M*M * beta*beta * costh_lab*costh_lab))) /\
146  (1 - beta*beta * costh_lab*costh_lab);
147  return (E_rest / E_lab) * (p_lab*p_lab / (rest_frame_p*rest_frame_p)) * abs(dp_labdp_rest);
148  };
149 
150  double plus_wgt = plus_valid ? wgtf(lab_frame_p_plus, 1) : 0.;
151  double minus_wgt = minus_valid ? wgtf(lab_frame_p_minus, -1) : 0.;
152 
153  //double threshold = (plus_valid || minus_valid) ? minus_valid / (plus_valid + minus_valid) : -1;
154  double threshold = 0.5;
155 
156  // Select the solution to use
157  bool select_plus = plus_valid && (!minus_valid || (rand >= threshold));
158  bool select_minus = minus_valid && (!plus_valid || (rand < threshold));
159 
160  // Prints out stuff
161  std::cout << "COSTH LAB: " << costh_lab << std::endl;
162  std::cout << "PREST: " << rest_frame_p << std::endl;
163  std::cout << "MASS: " << M << std::endl;
164  std::cout << "BETA: " << beta << std::endl;
165  std::cout << "GAMMA: " << gamma << std::endl;
166 
167  std::cout << "COSTH REST PLUS: " << costh_rest_plus << std::endl;
168  std::cout << "COSTH REST MINUS: " << costh_rest_minus << std::endl;
169  std::cout << "PLAB PLUS: " << lab_frame_p_plus << std::endl;
170  std::cout << "PLAB MINUS: " << lab_frame_p_minus << std::endl;
171  std::cout << "WGT PLUS: " << plus_wgt << std::endl;
172  std::cout << "WGT MINUS: " << minus_wgt << std::endl;
173 
174  if (select_plus) std::cout << "SELECTED PLUS" << std::endl;
175  else if (select_minus) std::cout << "SELECTED MINUS" << std::endl;
176  else std::cout << "SELECTED NONE" << std::endl;
177 
178  if (select_plus) {
179  costh_rest_out = costh_rest_plus;
180  lab_frame_p_out = lab_frame_p_plus;
181  wgt = plus_wgt * (plus_valid + minus_valid);
182  }
183  else if (select_minus) {
184  costh_rest_out = costh_rest_minus;
185  lab_frame_p_out = lab_frame_p_minus;
186  wgt = minus_wgt * (plus_valid + minus_valid);
187  }
188  else { // No solution!
189  return -1;
190  }
191 
192  return 0;
193 }
194 
195 double minKinematicCosTheta(double parentM, double secM, double prtlM, double parentE) {
196  // guard against parent-at-rest
197  if (parentE - parentM < 1e-4) return 0.;
198 
199  // look up the rest frame prtl momentum
200  double rest_prtlP = twobody_momentum(parentM, secM, prtlM);
201 
202  // set the dir and boost in the same direction
203  double gamma = parentE / parentM;
204  double beta = sqrt(1. - 1. / (gamma*gamma));
205 
206  double rest_prtlE = sqrt(prtlM*prtlM + rest_prtlP*rest_prtlP);
207 
208  return sqrt(prtlM*prtlM - rest_prtlE * rest_prtlE / (gamma*gamma)) / (prtlM*beta);
209 }
210 
211 // Get the energy of a forward going prtl from a parent with mass M / energy E
212 double forwardPrtlEnergy(double parentM, double secM, double prtlM, double parentE) {
213  // look up the rest frame prtl momentum
214  double rest_prtlP = twobody_momentum(parentM, secM, prtlM);
215 
216  // set the dir and boost in the same direction
217  double gamma = parentE / parentM;
218  double beta = sqrt(1. - 1. / (gamma*gamma));
219  TVector3 dir(0., 0., 1.);
220  TVector3 boost(0., 0., beta);
221 
222  // make sure we get the positive (more energetic) solution
223  double rand = 1.;
224 
225  double lab_frame_p_out, costh_rest_out, wgt;
226  int err = calcPrtlRayWgt(rest_prtlP, prtlM, dir, boost, rand,
227  lab_frame_p_out, costh_rest_out, wgt);
228  assert(!err);
229  (void) err;
230 
231  double lab_prtlE = sqrt(lab_frame_p_out*lab_frame_p_out + prtlM*prtlM);
232  return lab_prtlE;
233 }
234 
235 // TODO: use particle database
236 double secPDG2Mass(int pdg) {
237  switch (pdg) {
238  case 11:
239  case -11:
241  break;
242  case 13:
243  case -13:
245  break;
246  case 211:
247  case -211:
249  break;
250  default:
251  std::cerr << "BAD secondary pdg: " << pdg << std::endl;
252  std::cout << "BAD secondary pdg: " << pdg << std::endl;
253  return 0.;
254  }
255 }
256 
257 } // end namespace
258 } // end namespace
double abs_VtsVtd_squared
Definition: Constants.h:54
var pdg
Definition: selectors.fcl:14
BEGIN_PROLOG could also be cerr
double secPDG2Mass(int pdg)
Definition: Constants.cpp:236
EResult err(const char *call)
pdgs p
Definition: selectors.fcl:22
double twobody_momentum(double parent_mass, double childA_mass, double childB_mass)
Definition: Constants.cpp:73
T abs(T value)
static void Configure(const fhicl::ParameterSet &p)
Definition: Constants.cpp:60
j template void())
Definition: json.hpp:3108
double minKinematicCosTheta(double parentM, double secM, double prtlM, double parentE)
Definition: Constants.cpp:195
tuple dir
Definition: dropbox.py:28
static const Constants & Instance()
Definition: Constants.h:68
double rel_VtsVtd_squared
Definition: Constants.h:55
do i e
double forwardPrtlEnergy(double parentM, double secM, double prtlM, double parentE)
Definition: Constants.cpp:212
static Constants & InstanceMut()
Definition: Constants.h:16
BEGIN_PROLOG could also be cout
int calcPrtlRayWgt(double rest_frame_p, double M, TVector3 dir, TVector3 boost, double rand, double &lab_frame_p_out, double &costh_rest_out, double &wgt)
Definition: Constants.cpp:102