OscCalculator.cxx
Go to the documentation of this file.
1 
2 // //
3 // \file OscCalculator.cxx //
4 // //
5 // Class with methods for calculating all things related to oscillation //
6 // probabilities. //
7 // <rbpatter@caltech.edu> //
8 // //
9 #include "OscCalculator.h"
10 
11 #include <iostream>
12 #include <cmath>
13 
14 #include "TF1.h"
15 #include "TMath.h"
16 
17 namespace osc {
18 
20  {
21 
22  // put some sensible defaults here...
23 
24  fRho = 2.75; // g/cm^3
25  fL = 810; // km
26  fDmsq21 = 7.59E-5; // eV^2
27  fDmsq32 = 2.43E-3; //eV^2
28  fTh12 = 0.601;
29  fTh13 = 0.0;
30  fTh23 = 7.85398163397448279e-01; // pi/4
31  fdCP = 0;
32 
33  fUpdated = false;
34  }
35 
36 
38  {
39  }
40 
41 
42  double OscCalculator::P(int flavBefore, int flavAfter, double E) {
43  bool antinu = (flavBefore<0&&flavAfter<0);
44  if (antinu) {
45  flavBefore *= -1;
46  flavAfter *= -1;
47  }
48  if (flavBefore==12&&flavAfter==12) return P_ee(E,antinu);
49  else if (flavBefore==12&&flavAfter==14) return P_em(E,antinu);
50  else if (flavBefore==12&&flavAfter==16) return P_et(E,antinu);
51  else if (flavBefore==14&&flavAfter==12) return P_me(E,antinu);
52  else if (flavBefore==14&&flavAfter==14) return P_mm(E,antinu);
53  else if (flavBefore==14&&flavAfter==16) return P_mt(E,antinu);
54  else if (flavBefore==16&&flavAfter==12) return P_te(E,antinu);
55  else if (flavBefore==16&&flavAfter==14) return P_tm(E,antinu);
56  else if (flavBefore==16&&flavAfter==16) return P_tt(E,antinu);
57  else return 0;
58  }
59 
60  double OscCalculator::P_ee(double E, bool antinu) { return P_internal_ee(E,antinu,0); }
61  double OscCalculator::P_em(double E, bool antinu) { return P_internal_me(E,antinu,1); }
62  double OscCalculator::P_et(double E, bool antinu) { return P_internal_te(E,antinu,1); }
63 
64  double OscCalculator::P_me(double E, bool antinu) { return P_internal_me(E,antinu,0); }
65  double OscCalculator::P_mm(double E, bool antinu) { return 1-P_me(E,antinu)-P_mt(E,antinu); }
66  double OscCalculator::P_mt(double E, bool antinu) { return P_internal_mt(E,antinu,0); }
67 
68  double OscCalculator::P_te(double E, bool antinu) { return P_internal_te(E,antinu,0); }
69  double OscCalculator::P_tm(double E, bool antinu) { return P_internal_mt(E,antinu,1); }
70  double OscCalculator::P_tt(double E, bool antinu) { return 1 - P_te(E,antinu) - P_tm(E,antinu); }
71 
72  TF1* OscCalculator::GetTF1(int flavBefore, int flavAfter) {
73  TF1 *theTF1 = new TF1(Form("OscCalculatorFunction_%d_%d_%p",flavBefore,flavAfter,this),
74  this,&osc::OscCalculator::P_wrapper,0,120,2,"OscCalculator","P_wrapper");
75  theTF1->SetParameters(flavBefore,flavAfter);
76  theTF1->SetNpx(1000);
77  return theTF1;
78  }
79 
80  double OscCalculator::P_wrapper(double *x, double *p) {
81  // function for use by TF1
82  int flavBefore = int(p[0]);
83  int flavAfter = int(p[1]);
84  bool antinu = (flavBefore<0&&flavAfter<0);
85  if (antinu) {
86  flavBefore *= -1;
87  flavAfter *= -1;
88  }
89 
90  double (osc::OscCalculator::*P_xx)(double,bool);
91  if (flavBefore==12&&flavAfter==12) P_xx = &osc::OscCalculator::P_ee;
92  else if (flavBefore==12&&flavAfter==14) P_xx = &osc::OscCalculator::P_em;
93  else if (flavBefore==12&&flavAfter==16) P_xx = &osc::OscCalculator::P_et;
94  else if (flavBefore==14&&flavAfter==12) P_xx = &osc::OscCalculator::P_me;
95  else if (flavBefore==14&&flavAfter==14) P_xx = &osc::OscCalculator::P_mm;
96  else if (flavBefore==14&&flavAfter==16) P_xx = &osc::OscCalculator::P_mt;
97  else if (flavBefore==16&&flavAfter==12) P_xx = &osc::OscCalculator::P_te;
98  else if (flavBefore==16&&flavAfter==14) P_xx = &osc::OscCalculator::P_tm;
99  else if (flavBefore==16&&flavAfter==16) P_xx = &osc::OscCalculator::P_tt;
100  else P_xx = &osc::OscCalculator::P_null;
101 
102  return (this->*P_xx)(x[0],antinu);
103  }
104 
105  // -----------------------------------------------
106 
107 
109  if (fUpdated) return;
110 
111  fDmsq31 = fDmsq21 + fDmsq32;
112  if (fDmsq31!=0) {
114  }
115  else {
116  std::cerr << "OscCalculator::UpdateBasic() -- fDmsq31 should never be zero, but it is" << std::endl;
117  falpha = 0;
118  }
119  fsin_th12 = sin(fTh12);
120  fsin_th13 = sin(fTh13);
121  fsin_th23 = sin(fTh23);
122  fcos_th12 = cos(fTh12);
123  fcos_th13 = cos(fTh13);
124  fcos_th23 = cos(fTh23);
125  fsin_2th12 = sin(2*fTh12);
126  fsin_2th13 = sin(2*fTh13);
127  fsin_2th23 = sin(2*fTh23);
128  fcos_2th12 = cos(2*fTh12);
129  fcos_2th13 = cos(2*fTh13);
130  fcos_2th23 = cos(2*fTh23);
143 
144  static const double ZperA = 0.5; // e- per nucleon
145  static const double G_F = 1.16637E-23; // eV^-2
146  static const double hbar_c_eV_cm = 1.97326938E-5; // eV-cm
147 
148  fV = TMath::Sqrt2()*G_F*fRho*ZperA*TMath::Na()*hbar_c_eV_cm*hbar_c_eV_cm*hbar_c_eV_cm;
149 
150  fUpdated = true;
151  }
152 
153 
154  void OscCalculator::UpdateEDep(double E, bool antinu, bool fliptime) {
155 
156  static const double hbar_c_eV_km = 1.97326938E-10; // eV-km
157  static const double eVPerGeV = 1E9;
158 
159  int s = (antinu)?-1:1;
160  int t = (fliptime)?-1:1;
161 
162  fA = s*2*fV*E*eVPerGeV/fDmsq31;
163  fD = fDmsq31*fL/(4*E*eVPerGeV*hbar_c_eV_km);
164 
165  fdCPproxy = s*t*fdCP;
166  fsin_dCPproxy = sin(fdCPproxy);
167  fcos_dCPproxy = cos(fdCPproxy);
168 
169  if (falpha!=0) {
170  fC12 = TMath::Sqrt(fsin_sq_2th12+(fcos_2th12 - fA/falpha)*(fcos_2th12 - fA/falpha));
171  }
172  else {
173  std::cerr << "OscCalculator::UpdateEDep() -- falpha should never be zero, but it is" << std::endl;
174  fC12 = 1;
175  }
176  fC13 = TMath::Sqrt(fsin_sq_2th13+(fA-fcos_2th13)*(fA-fcos_2th13));
177  }
178 
179 
180 
181  // --------------------------------------------
182 
183  double OscCalculator::P_internal_me(double E, bool antinu, bool fliptime) {
184 
185  UpdateBasic();
186  UpdateEDep(E,antinu,fliptime);
187 
188  double cosC13D = cos(fC13*fD);
189  double sinC13D = sin(fC13*fD);
190  double sin1pAD = sin((fA+1)*fD);
191  double cos1pAD = cos((fA+1)*fD);
192  double sinAD = sin(fA*fD);
193  double sinAm1D = sin((fA-1)*fD);
194  double cosdpD = cos(fdCPproxy+fD);
195  double sinApam2D = sin((fA+falpha-2)*fD);
196  double cosApam2D = cos((fA+falpha-2)*fD);
197  double cosaC12D = cos(falpha*fC12*fD);
198  double sinaC12D = sin(falpha*fC12*fD);
199 
200  // This is coming straight from the MINOS NueAna package...
201 
202  // First we calculate the terms for the alpha expansion (good to all orders in th13)
203 
204  // Leading order term
205  double p1 = fsin_sq_th23*fsin_sq_2th13*sinC13D*sinC13D/(fC13*fC13);
206 
207  // Terms that appear at order alpha
208  double p2Inner =
209  fD*cosC13D*(1-fA*fcos_2th13)/fC13 -
210  fA*sinC13D*(fcos_2th13-fA)/(fC13*fC13);
211 
212  double p2 = -2*fsin_sq_th12*fsin_sq_th23*fsin_sq_2th13*sinC13D/(fC13*fC13)*p2Inner*falpha;
213 
214  double p3Inner =
215  -fsin_dCPproxy*(cosC13D - cos1pAD)*fC13
216  + fcos_dCPproxy*(fC13*sin1pAD - (1-fA*fcos_2th13)*sinC13D);
217 
218  double p3 = fsin_2th12*fsin_2th23*fsin_th13*sinC13D/(fA*fC13*fC13)*p3Inner*falpha;
219 
220  // p1 + p2 + p3 is the complete contribution for this expansion
221 
222  // Now for the expansion in orders of sin(th13) (good to all order alpha)
223 
224  double pa1 = 0.0, pa2 = 0.0;
225  if (fabs(falpha)>1E-10) {
226  // leading order term
227  pa1 = fcos_th23*fcos_th23*fsin_sq_2th12*sinaC12D*sinaC12D/(fC12*fC12);
228 
229  // the first order in s13 term
230  double t1 = (fcos_2th12 - fA/falpha)/fC12
232  double t2 = -fcos_dCPproxy*(sinApam2D-sinaC12D*t1);
233  double t3 = -(cosaC12D-cosApam2D)*fsin_dCPproxy;
234  double denom = (1-fA-falpha+fA*falpha*fcos_th12*fcos_th12)*fC12;
235  double t4 = fsin_2th12*fsin_2th23*(1-falpha)*sinaC12D/denom;
236 
237  pa2 = t4*(t3+t2)*fsin_th13;
238  }
239  // pa1+pa2 is the complete contribution from this expansion
240 
241  // Now we need to add the two expansions and subtract off the terms that are
242  // in both (falpha^1, s13^1)
243 
244  double t1 = sinAD*cosdpD*sinAm1D/(fA*(fA-1));
245  double repeated = 2*falpha*fsin_2th12*fsin_2th23*fsin_th13*t1;
246 
247  // Calculate the total probability
248  double totalP = p1+p2+p3 + (pa1+pa2) - repeated;
249  return totalP;
250  }
251 
252  // --------------------------------------------
253 
254  double OscCalculator::P_internal_te(double E, bool antinu, bool fliptime) {
255 
256  UpdateBasic();
257  UpdateEDep(E,antinu,fliptime);
258 
259  double cosC13D = cos(fC13*fD);
260  double sinC13D = sin(fC13*fD);
261  double sin1pAD = sin((fA+1)*fD);
262  double cos1pAD = cos((fA+1)*fD);
263  double sinAD = sin(fA*fD);
264  double sinAm1D = sin((fA-1)*fD);
265  double cosdpD = cos(fdCPproxy+fD);
266  double sinApam2D = sin((fA+falpha-2)*fD);
267  double cosApam2D = cos((fA+falpha-2)*fD);
268  double cosaC12D = cos(falpha*fC12*fD);
269  double sinaC12D = sin(falpha*fC12*fD);
270 
271  // This is coming straight from the MINOS NueAna package...
272 
273  // First we calculate the terms for the alpha expansion (good to all orders in th13)
274 
275  // Leading order term
276  double p1 = fcos_sq_th23*fsin_sq_2th13*sinC13D*sinC13D/(fC13*fC13);
277 
278  // Terms that appear at order alpha
279  double p2Inner =
280  fD*cosC13D*(1-fA*fcos_2th13)/fC13 -
281  fA*sinC13D*(fcos_2th13-fA)/(fC13*fC13);
282 
283  double p2 = -2*fsin_sq_th12*fcos_sq_th23*fsin_sq_2th13*sinC13D/(fC13*fC13)*p2Inner*falpha;
284 
285  double p3Inner =
286  -fsin_dCPproxy*(cosC13D - cos1pAD)*fC13
287  + fcos_dCPproxy*(fC13*sin1pAD - (1-fA*fcos_2th13)*sinC13D);
288 
289  double p3 = fsin_2th12*(-fsin_2th23)*fsin_th13*sinC13D/(fA*fC13*fC13)*p3Inner*falpha;
290 
291  // p1 + p2 + p3 is the complete contribution for this expansion
292 
293  // Now for the expansion in orders of sin(th13) (good to all order falpha)
294 
295  double pa1 = 0.0, pa2 = 0.0;
296  if (fabs(falpha)>1E-10) {
297  // leading order term
298  pa1 = fsin_th23*fsin_th23*fsin_sq_2th12*sinaC12D*sinaC12D/(fC12*fC12);
299 
300  // the first order in s13 term
301  double t1 = (fcos_2th12 - fA/falpha)/fC12
302  - falpha*fA*fC12*fsin_sq_2th12/(2*(1-falpha)*fC12*fC12);
303  double t2 = -fcos_dCPproxy*(sinApam2D-sinaC12D*t1);
304  double t3 = -(cosaC12D-cosApam2D)*fsin_dCPproxy;
305  double denom = (1-fA-falpha+fA*falpha*fcos_th12*fcos_th12)*fC12;
306  double t4 = fsin_2th12*(-fsin_2th23)*(1-falpha)*sinaC12D/denom;
307 
308  pa2 = t4*(t3+t2)*fsin_th13;
309  }
310  // pa1+pa2 is the complete contribution from this expansion
311 
312  // Now we need to add the two expansions and subtract off the terms that are
313  // in both (falpha^1, s13^1)
314 
315  double t1 = sinAD*cosdpD*sinAm1D/(fA*(fA-1));
316  double repeated = 2*falpha*fsin_2th12*(-fsin_2th23)*fsin_th13*t1;
317 
318  // Calculate the total probability
319  double totalP = p1+p2+p3 + (pa1+pa2) - repeated;
320  return totalP;
321  }
322 
323  // --------------------------------------------
324 
325  double OscCalculator::P_internal_ee(double E, bool antinu, bool fliptime) {
326 
327  UpdateBasic();
328  UpdateEDep(E,antinu,fliptime);
329 
330  double cosC13D = cos(fC13*fD);
331  double sinC13D = sin(fC13*fD);
332  double sinaC12D = sin(falpha*fC12*fD);
333 
334  // This is coming straight from the MINOS NueAna package...
335 
336  // First we calculate the terms for the alpha expansion (good to all orders in th13)
337 
338  // Leading order term
339  double p1 = 1 - fsin_sq_2th13*sinC13D*sinC13D/(fC13*fC13);
340 
341  // Terms that appear at order alpha
342  double p2Inner =
343  fD*cosC13D*(1-fA*fcos_2th13)/fC13 -
344  fA*sinC13D*(fcos_2th13-fA)/(fC13*fC13);
345 
346  double p2 = 2*fsin_th12*fsin_th12*fsin_sq_2th13*sinC13D/(fC13*fC13)*p2Inner*falpha;
347 
348  // p1 + p2 is the complete contribution for this expansion
349 
350  // Now for the expansion in orders of sin(th13) (good to all order alpha)
351 
352  double pa1 = 1.0, pa2 = 0.0;
353  if (fabs(falpha)>1E-10) {
354  // leading order term
355  pa1 = 1 - fsin_sq_2th12*sinaC12D*sinaC12D/(fC12*fC12);
356  }
357  // pa1 is the complete contribution from this expansion, there is no order s13^1 term
358 
359  // Now we need to add the two expansions and subtract off the terms that are
360  // in both (falpha^1, s13^1)
361 
362  double repeated = 1;
363 
364  // Calculate the total probability
365  double totalP = p1+p2 + (pa1+pa2) - repeated;
366  return totalP;
367  }
368 
369 
370  // --------------------------------------------
371 
372  double OscCalculator::P_internal_mt(double E, bool antinu, bool fliptime) {
373 
374  UpdateBasic();
375  UpdateEDep(E,antinu,fliptime);
376 
377  double cosC13D = cos(fC13*fD);
378  double sinC13D = sin(fC13*fD);
379  double sin1pAD = sin((fA+1)*fD);
380  double cos1pAD = cos((fA+1)*fD);
381  double sinAD = sin(fA*fD);
382  double sinAm1D = sin((fA-1)*fD);
383  double cosAm1D = cos((fA-1)*fD);
384  double sinApam2D = sin((fA+falpha-2)*fD);
385  double cosApam2D = cos((fA+falpha-2)*fD);
386  double cosaC12D = cos(falpha*fC12*fD);
387  double sinaC12D = sin(falpha*fC12*fD);
388  double sin1pAmCD = sin(0.5*(fA+1-fC13)*fD);
389  double sin1pApCD = sin(0.5*(fA+1+fC13)*fD);
390  double sinD = sin(fD);
391  double sin2D = sin(2*fD);
392  double cosaC12pApam2D = cos((falpha*fC12+fA+falpha-2)*fD);
393 
394  // This is coming straight from the MINOS NueAna package...
395 
396  // First we calculate the terms for the alpha expansion (good to all orders in th13)
397 
398  // Leading order term
399  double pmt_0 = 0.5*fsin_sq_2th23;
400  pmt_0 *= (1 - (fcos_2th13-fA)/fC13)*sin1pAmCD*sin1pAmCD
401  + (1 + (fcos_2th13-fA)/fC13)*sin1pApCD*sin1pApCD
402  - 0.5*fsin_sq_2th13*sinC13D*sinC13D/(fC13*fC13);
403 
404  // Terms that appear at order alpha
405  double t0, t1, t2, t3;
407  *(1+2*fsin_th13*fsin_th13*fA+fA*fA)/(fC13*fC13))*cosC13D*sin1pAD*2;
411  t1 *= sinC13D*cos1pAD/fC13;
412 
413  t2 = fsin_th12*fsin_th12*fsin_sq_2th13*sinC13D/(fC13*fC13*fC13);
414  t2 *= fA/fD*sin1pAD+fA/fD*(fcos_2th13-fA)/fC13*sinC13D
415  - (1-fA*fcos_2th13)*cosC13D;
416 
417  double pmt_1 = -0.5*fsin_sq_2th23*fD*(t0+t1+t2);
418 
419  t0 = cosC13D-cos1pAD;
420  t1 = 2*fcos_th13*fcos_th13*fsin_dCPproxy*sinC13D/fC13*t0;
421  t2 = -fcos_2th23*fcos_dCPproxy*(1+fA)*t0*t0;
422 
423  t3 = fcos_2th23*fcos_dCPproxy*(sin1pAD+(fcos_2th13-fA)/fC13*sinC13D);
424  t3 *= (1+2*fsin_th13*fsin_th13*fA + fA*fA)*sinC13D/fC13 - (1+fA)*sin1pAD;
425 
426  pmt_1 += (t1+t2+t3)*fsin_th13*fsin_2th12*fsin_2th23/(2*fA*fcos_th13*fcos_th13);
427  pmt_1 *= falpha;
428 
429  // pmt_0 + pmt_1 is the complete contribution for this expansion
430 
431  // Now for the expansion in orders of sin(th13) (good to all order alpha)
432 
433  // Leading order term
434  double pmt_a0 = 0.5*fsin_sq_2th23;
435 
436  pmt_a0 *= 1 - 0.5*fsin_sq_2th12*sinaC12D*sinaC12D/(fC12*fC12)
437  - cosaC12pApam2D
438  - (1 - (fcos_2th12 - fA/falpha)/fC12)*sinaC12D*sinApam2D;
439 
440  double denom = (1-fA-falpha+fA*falpha*fcos_th12*fcos_th12)*fC12;
441 
442  t0 = (cosaC12D-cosApam2D)*(cosaC12D-cosApam2D);
443  t1 = (fcos_2th12 - fA/falpha)/fC12*sinaC12D+sinApam2D;
444  t2 = ((fcos_2th12 - fA/falpha)/fC12+2*(1-falpha)/(falpha*fA*fC12))*sinaC12D + sinApam2D;
445 
446  t3 = (falpha*fA*fC12)/2*fcos_2th23*fcos_dCPproxy*(t0 + t1*t2);
447  t3 += fsin_dCPproxy*(1-falpha)*(cosaC12D-cosApam2D)*sinaC12D;
448 
449  double pmt_a1 = fsin_th13*fsin_2th12*fsin_2th23/denom*t3;
450 
451  // pmt_a1+pmt_a2 is the complete contribution from this expansion
452 
453  // Now we need to add the two expansions and subtract off the terms that are
454  // in both (falpha^1, s13^1)
455 
456  t1 = fsin_dCPproxy*sinD*sinAD*sinAm1D/(fA*(fA-1));
457  t2 = -1/(fA-1)*fcos_dCPproxy*sinD*(fA*sinD-sinAD*cosAm1D/fA)*fcos_2th23/denom;
458 
459  t0 = 2*falpha*fsin_2th12*fsin_2th23*fsin_th13*(t1+t2);
460 
461  t1 = fsin_sq_2th23*sinD*sinD
463 
464  double repeated = t0+t1;
465 
466  // Calculate the total probability
467  double totalP = pmt_0 + pmt_1 + pmt_a0 + pmt_a1 - repeated;
468 
469  return totalP;
470  }
471 }//namespace
double P_mm(double E, bool antinu=false)
double P_et(double E, bool antinu=false)
double P_null(double, bool)
Definition: OscCalculator.h:37
double P_te(double E, bool antinu=false)
double P_tm(double E, bool antinu=false)
double P(int flavBefore, int flavAfter, double E)
double P_wrapper(double *x, double *p)
double P_internal_mt(double E, bool antinu, bool fliptime)
virtual ~OscCalculator()
double P_mt(double E, bool antinu=false)
void UpdateEDep(double E, bool antinu, bool fliptime)
double P_tt(double E, bool antinu=false)
double P_internal_me(double E, bool antinu, bool fliptime)
Definition: EarthModel.h:12
p
Definition: test.py:223
TF1 * GetTF1(int flavBefore, int flavAfter)
double P_ee(double E, bool antinu=false)
double P_em(double E, bool antinu=false)
double P_internal_ee(double E, bool antinu, bool fliptime)
list x
Definition: train.py:276
int bool
Definition: qglobal.h:345
double P_internal_te(double E, bool antinu, bool fliptime)
double P_me(double E, bool antinu=false)
static QCString * s
Definition: config.cpp:1042
QTextStream & endl(QTextStream &s)