Jpp  17.0.0-rc.1
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JPDF.hh
Go to the documentation of this file.
1 #ifndef __JPHYSICS__JPDF__
2 #define __JPHYSICS__JPDF__
3 
4 #include <vector>
5 #include <algorithm>
6 #include <cmath>
7 #include <limits>
8 
9 #include "JLang/JCC.hh"
10 #include "JLang/JException.hh"
11 #include "JPhysics/JConstants.hh"
12 #include "JTools/JQuadrature.hh"
14 #include "JPhysics/JDispersion.hh"
15 #include "JPhysics/JAbstractPMT.hh"
17 #include "JPhysics/JPDFToolkit.hh"
18 #include "JPhysics/JPDFTypes.hh"
19 #include "JPhysics/JGeane.hh"
20 #include "JPhysics/JGeant.hh"
21 #include "JPhysics/JGeanz.hh"
22 
23 
24 /**
25  * \author mdejong
26  */
27 
28 namespace JPHYSICS {}
29 namespace JPP { using namespace JPHYSICS; }
30 
31 namespace JPHYSICS {
32 
33  using JLANG::JException;
34 
35  /**
36  * Radius of optical module [m].
37  *
38  * This parameter is used to implement shadowing of the PMT by the optical module.
39  */
40  static double MODULE_RADIUS_M = 0.25;
41 
42 
43  /**
44  * Low level interface for the calculation of the Probability Density Functions (PDFs) of
45  * the arrival time of Cherenkov light from a muon or an EM-shower on a photo-multiplier tube (PMT).
46  * The calculation of the PDF covers direct light light and single-scattered light.
47  * The direct light is attenuated by absorption and any form of light scattering.\n
48  * The attenuation length is defined as:
49  \f[
50  \frac{1}{\lambda_{att}} ~\equiv~ \frac{1}{\lambda_{abs}} + \frac{1}{\lambda_{s}}
51  \f]
52  * where
53  \f$ \lambda_{abs} \f$ and
54  \f$ \lambda_{s} \f$
55  refer to the absorption and scattering length, respectively.\n
56  * The scattered light is attenuated by absorption and light scattering weighed with the scattering angle \f$ \theta_{s} \f$.
57  * The attenuation length is in this case defined as:
58  \f[
59  \frac{1}{\lambda_{att}} ~\equiv~ \frac{1}{\lambda_{abs}} + \frac{1-\left<\cos\theta_s\right>}{\lambda_{s}}
60  \f]
61  *
62  * The PDFs of a muon are evaluated as a function of:
63  * - distance of closest approach of the muon to the PMT, and
64  * - orientation of the PMT (zenith and azimuth angle).
65  *
66  * The PDFs of an EM-shower are evaluated as a function of:
67  * - distance between the EM-shower and the PMT,
68  * - cosine angle EM-shower direction and EM-shower - PMT position, and
69  * - orientation of the PMT (zenith and azimuth angle).
70  *
71  * The intensity of light from an EM-shower is assumed to be proportional to the energy of the shower.\n
72  * For a given energy of the EM-shower, the longitudinal profile of the EM-shower is taken into account.
73  *
74  * The coordinate system is defined such that z-axis corresponds to the muon trajectory (EM-shower).\n
75  * The orientation of the PMT (i.e.\ zenith and azimuth angle) are defined following a rotation around the z-axis,
76  * such that the PMT is located in the x-z plane.
77  *
78  * Schematics of the PDF of direct light from a muon:
79  *
80  \f{center}\setlength{\unitlength}{0.7cm}\begin{picture}(8,12)
81 
82  \put( 1.0, 0.5){\vector(0,1){9}}
83  \put( 1.0,10.0){\makebox(0,0){$z$}}
84  \put( 1.0, 0.0){\makebox(0,0){muon}}
85 
86  \put( 1.0, 8.0){\line(1,0){6}}
87  \put( 4.0, 8.5){\makebox(0,0)[c]{$R$}}
88 
89  \multiput( 1.0, 2.0)(0.5, 0.5){12}{\qbezier(0.0,0.0)(-0.1,0.35)(0.25,0.25)\qbezier(0.25,0.25)(0.6,0.15)(0.5,0.5)}
90  \put( 4.5, 4.5){\makebox(0,0)[l]{photon}}
91 
92  \put( 1.0, 2.0){\circle*{0.2}}
93  \put( 0.5, 2.0){\makebox(0,0)[r]{$(0,0,z,t_{0})$}}
94 
95  \put( 1.0, 8.0){\circle*{0.2}}
96  \put( 0.5, 8.0){\makebox(0,0)[r]{$(0,0,0)$}}
97 
98  \put( 7.0, 8.0){\circle*{0.2}}
99  \put( 7.0, 9.0){\makebox(0,0)[c]{PMT}}
100  \put( 7.5, 8.0){\makebox(0,0)[l]{$(R,0,0,t_{1})$}}
101 
102  \put( 1.1, 2.1){
103  \put(0.0,1.00){\vector(-1,0){0.1}}
104  \qbezier(0.0,1.0)(0.25,1.0)(0.5,0.75)
105  \put(0.5,0.75){\vector(1,-1){0.1}}
106  \put(0.4,1.5){\makebox(0,0){$\theta_{c}$}}
107  }
108 
109  \end{picture}
110  \f}
111  *
112  * For the PDF of a muon, the time is defined such that \f$ t ~=~ 0 \f$
113  * refers to the time when the muon passes through the point at minimal approach to the PMT
114  * (i.e.\ position \f$ (0,0,0) \f$ in the above figure).
115  *
116  * The delay for the Cherenkov cone to actually pass through the PMT is defined as
117  \f[
118  \Delta t ~\equiv~ R \tan(\theta_{c}) / c
119  \f]
120  * where \f$ \tan(\theta_{c}) \f$ is given by method getTanThetaC.
121  *
122  * Given a measured hit time, \f$ t_{hit} \f$, the PDF should be probed at \f$ (t_{hit} - t_1) \f$,
123  * where \f$ t_1 \f$ is given by:
124  *
125  \f[
126  ct_1 = ct_0 - z + R \tan(\theta_{c})
127  \f]
128  *
129  * In this, \f$ t_0 \f$ refers to the time the muon passes through point \f$ (0,0,z) \f$.
130  *
131  * Schematics of single scattered light from a muon:
132  *
133  \f{center}\setlength{\unitlength}{0.7cm}\begin{picture}(8,12)
134 
135  \put( 1.0, 0.5){\vector(0,1){9}}
136  \put( 1.0,10.0){\makebox(0,0){$z$}}
137  \put( 1.0, 0.0){\makebox(0,0){muon}}
138 
139  \put( 1.0, 8.0){\line(1,0){2}}
140  \put( 2.0, 8.5){\makebox(0,0)[c]{$R$}}
141 
142  \multiput( 1.0, 2.0)( 0.5, 0.5){8}{\qbezier(0.0,0.0)(-0.1,0.35)( 0.25,0.25)\qbezier( 0.25,0.25)( 0.6,0.15)( 0.5,0.5)}
143  \multiput( 5.0, 6.0)(-0.5, 0.5){4}{\qbezier(0.0,0.0)(+0.1,0.35)(-0.25,0.25)\qbezier(-0.25,0.25)(-0.6,0.15)(-0.5,0.5)}
144 
145  \put( 5.0, 6.0){\circle*{0.2}}
146 
147  \put( 3.5, 3.5){\makebox(0,0)[c]{$\bar{u}$}}
148  \put( 5.0, 7.0){\makebox(0,0)[c]{$\bar{v}$}}
149 
150  \put( 1.0, 2.0){\circle*{0.2}}
151  \put( 0.5, 2.0){\makebox(0,0)[r]{$(0,0,z,t_0)$}}
152 
153  \put( 1.0, 8.0){\circle*{0.2}}
154  \put( 0.5, 8.0){\makebox(0,0)[r]{$(0,0,0)$}}
155 
156  \put( 3.0, 8.0){\circle*{0.2}}
157  \put( 3.0, 9.0){\makebox(0,0)[c]{PMT}}
158  \put( 3.5, 8.0){\makebox(0,0)[l]{$(R,0,0,t_1)$}}
159 
160  \end{picture}
161  \f}
162  *
163  * In this,
164  *
165  \f{math}{
166  \bar{u} ~\equiv~ u ~ \hat{u}
167  ~\equiv~ u \left(\begin{array}{c} \sin(\theta_{0}) \cos(\phi_{0}) \\ \sin(\theta_{0}) \sin(\phi_{0}) \\ \cos(\theta_{0})\end{array}\right)
168  \textrm{ and }
169  \bar{v} ~\equiv~ v ~ \hat{v}
170  ~\equiv~ v \left(\begin{array}{c} \sin(\theta_{1}) \cos(\phi_{1}) \\ \sin(\theta_{1}) \sin(\phi_{1}) \\ \cos(\theta_{1})\end{array}\right)
171  \f}
172  *
173  * The vectors \f$ \bar{u} \f$ and \f$ \bar{v} \f$ are subject to the following constraint:
174  \f{math}{
175  \begin{array}{ccccccc}
176 
177  \begin{array}{c}
178  \mathrm{start}\\
179  \mathrm{point}
180  \end{array}
181 
182  &&
183 
184  \begin{array}{c}
185  \mathrm{before}\\
186  \mathrm{scattering}
187  \end{array}
188 
189  &&
190 
191  \begin{array}{c}
192  \mathrm{after}\\
193  \mathrm{scattering}
194  \end{array}
195 
196  &&
197 
198  \mathrm{PMT}
199 
200  \\
201  \\
202 
203  \left(\begin{array}{c} 0 \\ 0 \\ z \end{array}\right)
204  & + &
205  u \left(\begin{array}{c} \sin(\theta_{0}) \cos(\phi_{0}) \\ \sin(\theta_{0}) \sin(\phi_{0}) \\ \cos(\theta_{0})\end{array}\right)
206  & + &
207  v \left(\begin{array}{c} \sin(\theta_{1}) \cos(\phi_{1}) \\ \sin(\theta_{1}) \sin(\phi_{1}) \\ \cos(\theta_{1})\end{array}\right)
208  & = &
209  \left(\begin{array}{c} R \\ 0 \\ 0 \end{array}\right)
210  \end{array}
211  * \f}
212  *
213  * Note that an expression for the cosine of the scattering angle, \f$ \cos(\theta_s) ~\equiv~ \hat{u} \cdot \hat{v} \f$,
214  * can directly be obtained by multiplying the left hand side and the right hand side with \f$ \hat{u} \f$:
215  *
216  \f[
217  \cos\theta_s = \frac{R\sin\theta_0\cos\phi_0 - z\cos\theta_0 - u}{v}
218  \f]
219  *
220  *
221  * The arrival time of the single scattered light can be expressed as:
222  *
223  \f[
224  ct_1 = ct_0 + n (u + v)
225  \f]
226  *
227  * where \f$ n \f$ is the index of refraction.
228  *
229  * Schematics of direct light from a EM-shower:
230  *
231  \f{center}\setlength{\unitlength}{0.7cm}\begin{picture}(8,12)
232 
233  \put( 1.0, 2.0){\vector(0,1){1}}
234  \put( 1.0, 3.5){\multiput(0,0)(0,0.5){12}{\line(0,1){0.2}}}
235  \put( 1.0,10.0){\makebox(0,0){$z$}}
236  \put( 1.0, 1.0){\makebox(0,0){EM-shower}}
237 
238  \put( 1.0, 8.0){\line(1,0){6}}
239  \put( 4.0, 8.5){\makebox(0,0)[c]{$R$}}
240 
241  \multiput( 1.0, 2.0)(0.5, 0.5){12}{\qbezier(0.0,0.0)(-0.1,0.35)(0.25,0.25)\qbezier(0.25,0.25)(0.6,0.15)(0.5,0.5)}
242  \put( 4.5, 4.5){\makebox(0,0)[l]{photon}}
243 
244  \put( 1.0, 2.0){\circle*{0.2}}
245  \put( 0.5, 2.0){\makebox(0,0)[r]{$(0,0,z,t_0)$}}
246 
247  \put( 1.0, 8.0){\circle*{0.2}}
248  \put( 0.5, 8.0){\makebox(0,0)[r]{$(0,0,0)$}}
249 
250  \put( 7.0, 8.0){\circle*{0.2}}
251  \put( 7.0, 9.0){\makebox(0,0)[c]{PMT}}
252  \put( 7.5, 8.0){\makebox(0,0)[l]{$(R,0,0,t_1)$}}
253 
254  \put( 1.1, 2.1){
255  \put(0.0,1.00){\vector(-1,0){0.1}}
256  \qbezier(0.0,1.0)(0.25,1.0)(0.5,0.75)
257  \put(0.5,0.75){\vector(1,-1){0.1}}
258  \put(0.4,1.5){\makebox(0,0){$\theta_0$}}
259  }
260 
261  \end{picture}
262  \f}
263  *
264  * Note that the emission angle \f$ \theta_0 \f$ is in general not equal to the Cherenkov angle \f$ \theta_c \f$.\n
265  * For an EM-shower, the arrival time of the light can be expressed as:
266  *
267  \f[
268  ct_1 = ct_0 + n D
269  \f]
270  *
271  * where \f$ D \f$ is the total distance traveled by the photon from its emission point to the PMT,
272  * including possible scattering.
273  *
274  * For the computation of the various integrals, it is assumed that the index of refraction
275  * decreases monotonously as a function of the wavelength of the light.
276  */
277  class JPDF :
278  public JTOOLS::JGaussLegendre,
279  public virtual JDispersionInterface,
280  public virtual JAbstractPMT,
281  public virtual JAbstractMedium
282  {
283 
285 
286  public:
287  /**
288  * Constructor.
289  *
290  * \param Wmin minimal wavelength for integration [nm]
291  * \param Wmax maximal wavelength for integration [nm]
292  * \param numberOfPoints number of points for integration
293  * \param epsilon precision of points for integration
294  */
295  JPDF(const double Wmin,
296  const double Wmax,
297  const int numberOfPoints = 20,
298  const double epsilon = 1e-12) :
300  wmin(Wmin),
301  wmax(Wmax)
302  {
303  // phi integration points
304 
305  const double dx = PI / numberOfPoints;
306 
307  for (double x = 0.5*dx; x < PI; x += dx) {
308  phd.push_back(element_type(cos(x),sin(x)));
309  }
310  }
311 
312 
313  /**
314  * Virtual destructor.
315  */
316  virtual ~JPDF()
317  {}
318 
319 
320  /**
321  * Number of Cherenkov photons per unit track length
322  *
323  * \return number of photons per unit track length [m^-1]
324  */
325  double getNumberOfPhotons() const
326  {
327  double value = 0.0;
328 
329  const double xmin = 1.0 / wmax;
330  const double xmax = 1.0 / wmin;
331 
332  for (const_iterator i = begin(); i != end(); ++i) {
333 
334  const double x = 0.5 * (xmax + xmin) + i->getX() * 0.5 * (xmax - xmin);
335  const double dx = i->getY() * 0.5 * (xmax - xmin);
336 
337  const double w = 1.0 / x;
338  const double dw = dx * w*w;
339 
340  const double n = getIndexOfRefractionPhase(w);
341 
342  value += cherenkov(w,n) * dw;
343  }
344 
345  return value;
346  }
347 
348 
349  /**
350  * Number of photo-electrons from direct Cherenkov light from muon.
351  *
352  * \param R_m distance between muon and PMT [m]
353  * \param theta zenith angle orientation PMT [rad]
354  * \param phi azimuth angle orientation PMT [rad]
355  * \return P [npe]
356  */
357  double getDirectLightFromMuon(const double R_m,
358  const double theta,
359  const double phi) const
360  {
361  double value = 0;
362 
363  const double R = std::max(R_m, getRmin());
364  const double A = getPhotocathodeArea();
365 
366  const double px = sin(theta)*cos(phi);
367  const double pz = cos(theta);
368 
369  for (const_iterator m = begin(); m != end(); ++m) {
370 
371  const double w = 0.5 * (wmax + wmin) + m->getX() * 0.5 * (wmax - wmin);
372  const double dw = m->getY() * 0.5 * (wmax - wmin);
373 
374  const double n = getIndexOfRefractionPhase(w);
375 
376  const double l_abs = getAbsorptionLength(w);
377  const double ls = getScatteringLength(w);
378 
379  const double npe = cherenkov(w,n) * dw * getQE(w);
380 
381  const double ct0 = 1.0 / n;
382  const double st0 = sqrt((1.0 + ct0)*(1.0 - ct0));
383 
384  const double d = R / st0; // distance traveled by photon
385  const double ct = st0*px + ct0*pz; // cosine angle of incidence on PMT
386 
387  const double U = getAngularAcceptance(ct); // PMT angular acceptance
388  const double V = exp(-d/l_abs) * exp(-d/ls); // absorption & scattering
389  const double W = A / (2.0*PI*R*st0); // solid angle
390 
391  value += npe * U * V * W;
392  }
393 
394  return value;
395  }
396 
397 
398  /**
399  * Probability density function for direct light from muon.
400  *
401  * \param R_m distance between muon and PMT [m]
402  * \param theta zenith angle orientation PMT [rad]
403  * \param phi azimuth angle orientation PMT [rad]
404  * \param t_ns time difference relative to direct Cherenkov light [ns]
405  * \return dP/dt [npe/ns]
406  */
407  double getDirectLightFromMuon(const double R_m,
408  const double theta,
409  const double phi,
410  const double t_ns) const
411  {
412  static const int N = 100; // maximal number of iterations
413  static const double eps = 1.0e-6; // precision index of refraction
414 
415  const double R = std::max(R_m, getRmin());
416  const double t = R * getTanThetaC() / C + t_ns; // time [ns]
417  const double a = C*t/R; // target value
418  const double A = getPhotocathodeArea();
419 
420  const double px = sin(theta)*cos(phi);
421  const double pz = cos(theta);
422 
423  // check validity range for index of refraction
424 
425  for (double buffer[] = { wmin, wmax, 0.0 }, *p = buffer; *p != 0.0; ++p) {
426 
427  const double n = getIndexOfRefractionPhase(*p);
428  const double ng = getIndexOfRefractionGroup(*p);
429 
430  const double ct0 = 1.0 / n;
431  const double st0 = sqrt((1.0 + ct0)*(1.0 - ct0));
432 
433  const double b = (ng - ct0) / st0; // running value
434 
435  if (*p == wmin && b < a) { return 0.0; }
436  if (*p == wmax && b > a) { return 0.0; }
437  }
438 
439 
440  double umin = wmin;
441  double umax = wmax;
442 
443  for (int i = 0; i != N; ++i) { // binary search for wavelength
444 
445  const double w = 0.5 * (umin + umax);
446 
447  const double n = getIndexOfRefractionPhase(w);
448  const double ng = getIndexOfRefractionGroup(w);
449 
450  const double ct0 = 1.0 / n;
451  const double st0 = sqrt((1.0 + ct0)*(1.0 - ct0));
452 
453  const double b = (ng - ct0) / st0; // running value
454 
455  if (fabs(b-a) < a*eps) {
456 
457  const double np = getDispersionPhase(w);
458  const double ngp = getDispersionGroup(w);
459 
460  const double l_abs = getAbsorptionLength(w);
461  const double ls = getScatteringLength(w);
462 
463  const double d = R / st0; // distance traveled by photon
464  const double ct = st0*px + ct0*pz; // cosine angle of incidence on PMT
465 
466  const double i3 = ct0*ct0*ct0 / (st0*st0*st0);
467 
468  const double U = getAngularAcceptance(ct); // PMT angular acceptance
469  const double V = exp(-d/l_abs - d/ls); // absorption & scattering
470  const double W = A / (2.0*PI*R*st0); // solid angle
471 
472  const double Ja = R * (ngp/st0 + np*(n-ng)*i3) / C; // dt/dlambda
473 
474  return cherenkov(w,n) * getQE(w) * U * V * W / fabs(Ja);
475  }
476 
477  if (b > a)
478  umin = w;
479  else
480  umax = w;
481  }
482 
483  return 0.0;
484  }
485 
486 
487  /**
488  * Probability density function for scattered light from muon.
489  *
490  * \param R_m distance between muon and PMT [m]
491  * \param theta zenith angle orientation PMT [rad]
492  * \param phi azimuth angle orientation PMT [rad]
493  * \param t_ns time difference relative to direct Cherenkov light [ns]
494  * \return dP/dt [npe/ns]
495  */
496  double getScatteredLightFromMuon(const double R_m,
497  const double theta,
498  const double phi,
499  const double t_ns) const
500  {
501  static const double eps = 1.0e-10;
502 
503  double value = 0;
504 
505  const double R = std::max(R_m, getRmin());
506  const double t = R * getTanThetaC() / C + t_ns; // time [ns]
507  const double A = getPhotocathodeArea();
508 
509  const double px = sin(theta)*cos(phi);
510  const double py = sin(theta)*sin(phi);
511  const double pz = cos(theta);
512 
513  const double n0 = getIndexOfRefractionGroup(wmax);
514  const double n1 = getIndexOfRefractionGroup(wmin);
515  const double ni = sqrt(R*R + C*t*C*t) / R; // maximal index of refraction
516 
517  if (n0 >= ni) {
518  return value;
519  }
520 
521  const double nj = std::min(ni,n1);
522 
523  double w = wmax;
524 
525  for (const_iterator i = begin(); i != end(); ++i) {
526 
527  const double ng = 0.5 * (nj + n0) + i->getX() * 0.5 * (nj - n0);
528  const double dn = i->getY() * 0.5 * (nj - n0);
529 
530  w = getWavelength(ng, w, 1.0e-5);
531 
532  const double dw = dn / fabs(getDispersionGroup(w));
533 
534  const double n = getIndexOfRefractionPhase(w);
535 
536  const double l_abs = getAbsorptionLength(w);
537  const double ls = getScatteringLength(w);
538 
539  const double npe = cherenkov(w,n) * dw * getQE(w);
540 
541  if (npe <= 0) { continue; }
542 
543  const double Jc = 1.0 / ls; // dN/dx
544 
545  const double ct0 = 1.0 / n; // photon direction before scattering
546  const double st0 = sqrt((1.0 + ct0)*(1.0 - ct0));
547 
548  JRoot rz(R, ng, t); // square root
549 
550  if (!rz.is_valid) { continue; }
551 
552  const double zmin = rz.first;
553  const double zmax = rz.second;
554 
555  const double zap = 1.0 / l_abs;
556 
557  const double xmin = exp(zap*zmax);
558  const double xmax = exp(zap*zmin);
559 
560  for (const_iterator j = begin(); j != end(); ++j) {
561 
562  const double x = 0.5 * (xmax + xmin) + j->getX() * 0.5 * (xmax - xmin);
563  const double dx = j->getY() * 0.5 * (xmax - xmin);
564 
565  const double z = log(x) / zap;
566  const double dz = -dx / (zap*x);
567 
568  const double D = sqrt(z*z + R*R);
569  const double cd = -z / D;
570  const double sd = R / D;
571 
572  const double d = (C*t - z) / ng; // photon path
573 
574  //const double V = exp(-d/l_abs); // absorption
575 
576  const double cta = cd*ct0 + sd*st0;
577  const double dca = d - 0.5*(d+D)*(d-D) / (d - D*cta);
578  const double tip = -log(D*D/(dca*dca) + eps) / PI;
579 
580  const double ymin = exp(tip*PI);
581  const double ymax = 1.0;
582 
583  for (const_iterator k = begin(); k != end(); ++k) {
584 
585  const double y = 0.5 * (ymax + ymin) + k->getX() * 0.5 * (ymax - ymin);
586  const double dy = k->getY() * 0.5 * (ymax - ymin);
587 
588  const double phi = log(y) / tip;
589  const double dp = -dy / (tip*y);
590 
591  const double cp0 = cos(phi);
592  const double sp0 = sin(phi);
593 
594  const double u = (R*R + z*z - d*d) / (2*R*st0*cp0 - 2*z*ct0 - 2*d);
595  const double v = d - u;
596 
597  if (u <= 0) { continue; }
598  if (v <= 0) { continue; }
599 
600  const double vi = 1.0 / v;
601  const double cts = (R*st0*cp0 - z*ct0 - u)*vi; // cosine scattering angle
602 
603  const double V = exp(-d*getInverseAttenuationLength(l_abs, ls, cts));
604 
605  if (cts < 0.0 && v * sqrt((1.0 + cts) * (1.0 - cts)) < MODULE_RADIUS_M) { continue; }
606 
607  const double vx = R - u*st0*cp0;
608  const double vy = - u*st0*sp0;
609  const double vz = -z - u*ct0;
610 
611  const double ct[] = { // cosine angle of incidence on PMT
612  (vx*px + vy*py + vz*pz) * vi,
613  (vx*px - vy*py + vz*pz) * vi
614  };
615 
616  const double U =
617  getAngularAcceptance(ct[0]) +
618  getAngularAcceptance(ct[1]); // PMT angular acceptance
619  const double W = std::min(A*vi*vi, 2.0*PI); // solid angle
620 
621  const double Ja = getScatteringProbability(cts); // d^2P/dcos/dphi
622  const double Jd = ng * (1.0 - cts) / C; // dt/du
623 
624  value += (npe * dz * dp / (2*PI)) * U * V * W * Ja * Jc / fabs(Jd);
625  }
626  }
627  }
628 
629  return value;
630  }
631 
632 
633  /**
634  * Probability density function for direct light from EM-showers.
635  *
636  * \param R_m distance between muon and PMT [m]
637  * \param theta zenith angle orientation PMT [rad]
638  * \param phi azimuth angle orientation PMT [rad]
639  * \param t_ns time difference relative to direct Cherenkov light [ns]
640  * \return dP/dt [npe/ns/GeV]
641  */
642  double getDirectLightFromEMshowers(const double R_m,
643  const double theta,
644  const double phi,
645  const double t_ns) const
646  {
647  double value = 0;
648 
649  const double R = std::max(R_m, getRmin());
650  const double t = R * getTanThetaC() / C + t_ns; // time [ns]
651  const double A = getPhotocathodeArea();
652  const double D = 2.0*sqrt(A/PI);
653 
654  const double px = sin(theta)*cos(phi);
655  //const double py = sin(theta)*sin(phi);
656  const double pz = cos(theta);
657 
658  const double n0 = getIndexOfRefractionGroup(wmax);
659  const double n1 = getIndexOfRefractionGroup(wmin);
660  const double ni = sqrt(R*R + C*t*C*t) / R; // maximal index of refraction
661 
662  if (n0 >= ni) {
663  return value;
664  }
665 
666  const double nj = std::min(n1, ni);
667 
668  double w = wmax;
669 
670  for (const_iterator i = begin(); i != end(); ++i) {
671 
672  const double ng = 0.5 * (nj + n0) + i->getX() * 0.5 * (nj - n0);
673  const double dn = i->getY() * 0.5 * (nj - n0);
674 
675  w = getWavelength(ng, w, 1.0e-5);
676 
677  const double dw = dn / fabs(getDispersionGroup(w));
678 
679  const double n = getIndexOfRefractionPhase(w);
680 
681  const double l_abs = getAbsorptionLength(w);
682  const double ls = getScatteringLength(w);
683 
684  const double npe = cherenkov(w,n) * dw * getQE(w);
685 
686  JRoot rz(R, ng, t); // square root
687 
688  if (!rz.is_valid) { continue; }
689 
690  for (int j = 0; j != 2; ++j) {
691 
692  const double z = rz[j];
693 
694  if (C*t <= z) continue;
695 
696  const double d = sqrt(z*z + R*R); // distance traveled by photon
697 
698  const double ct0 = -z / d;
699  const double st0 = R / d;
700 
701  const double dz = D / st0; // average track length
702 
703  const double ct = st0*px + ct0*pz; // cosine angle of incidence on PMT
704 
705  const double U = getAngularAcceptance(ct); // PMT angular acceptance
706  const double V = exp(-d/l_abs - d/ls); // absorption & scattering
707  const double W = A/(d*d); // solid angle
708 
709  const double Ja = geant(n,ct0); // d^2N/dcos/dphi
710  const double Jd = (1.0 - ng*ct0) / C; // d t/ dz
711  const double Je = ng*st0*st0*st0 / (R*C); // d^2t/(dz)^2
712 
713  value += gWater() * npe * U * V * W * Ja / (fabs(Jd) + 0.5*Je*dz);
714  }
715  }
716 
717  return value;
718  }
719 
720 
721  /**
722  * Probability density function for scattered light from EM-showers.
723  *
724  * \param R_m distance between muon and PMT [m]
725  * \param theta zenith angle orientation PMT [rad]
726  * \param phi azimuth angle orientation PMT [rad]
727  * \param t_ns time difference relative to direct Cherenkov light [ns]
728  * \return dP/dt [npe/ns/GeV]
729  */
730  double getScatteredLightFromEMshowers(const double R_m,
731  const double theta,
732  const double phi,
733  const double t_ns) const
734  {
735  double value = 0;
736 
737  const double R = std::max(R_m, getRmin());
738  const double t = R * getTanThetaC() / C + t_ns; // time [ns]
739  const double A = getPhotocathodeArea();
740 
741  const double px = sin(theta)*cos(phi);
742  const double py = sin(theta)*sin(phi);
743  const double pz = cos(theta);
744 
745  const double n0 = getIndexOfRefractionGroup(wmax);
746  const double n1 = getIndexOfRefractionGroup(wmin);
747  const double ni = sqrt(R*R + C*t*C*t) / R; // maximal index of refraction
748 
749  if (n0 >= ni) {
750  return value;
751  }
752 
753  const double nj = std::min(ni,n1);
754 
755  double w = wmax;
756 
757  for (const_iterator i = begin(); i != end(); ++i) {
758 
759  const double ng = 0.5 * (nj + n0) + i->getX() * 0.5 * (nj - n0);
760  const double dn = i->getY() * 0.5 * (nj - n0);
761 
762  w = getWavelength(ng, w, 1.0e-5);
763 
764  const double dw = dn / fabs(getDispersionGroup(w));
765 
766  const double n = getIndexOfRefractionPhase(w);
767 
768  const double l_abs = getAbsorptionLength(w);
769  const double ls = getScatteringLength(w);
770 
771  const double npe = cherenkov(w,n) * dw * getQE(w);
772 
773  if (npe <= 0) { continue; }
774 
775  const double Jc = 1.0 / ls; // dN/dx
776 
777  JRoot rz(R, ng, t); // square root
778 
779  if (!rz.is_valid) { continue; }
780 
781  const double zmin = rz.first;
782  const double zmax = rz.second;
783 
784  const double zap = 1.0 / l_abs;
785 
786  const double xmin = exp(zap*zmax);
787  const double xmax = exp(zap*zmin);
788 
789  for (const_iterator j = begin(); j != end(); ++j) {
790 
791  const double x = 0.5 * (xmax + xmin) + j->getX() * 0.5 * (xmax - xmin);
792  const double dx = j->getY() * 0.5 * (xmax - xmin);
793 
794  const double z = log(x) / zap;
795  const double dz = -dx / (zap*x);
796 
797  const double D = sqrt(z*z + R*R);
798  const double cd = -z / D;
799  const double sd = R / D;
800 
801  const double qx = cd*px + 0 - sd*pz;
802  const double qy = 1*py;
803  const double qz = sd*px + 0 + cd*pz;
804 
805  const double d = (C*t - z) / ng; // photon path
806 
807  //const double V = exp(-d/l_abs); // absorption
808 
809  const double ds = 2.0 / (size() + 1);
810 
811  for (double sb = 0.5*ds; sb < 1.0 - 0.25*ds; sb += ds) {
812 
813  for (int buffer[] = { -1, +1, 0}, *k = buffer; *k != 0; ++k) {
814 
815  const double cb = (*k) * sqrt((1.0 + sb)*(1.0 - sb));
816  const double dcb = (*k) * ds*sb/cb;
817 
818  const double v = 0.5 * (d + D) * (d - D) / (d - D*cb);
819  const double u = d - v;
820 
821  if (u <= 0) { continue; }
822  if (v <= 0) { continue; }
823 
824  const double cts = (D*cb - v) / u; // cosine scattering angle
825 
826  const double V = exp(-d*getInverseAttenuationLength(l_abs, ls, cts));
827 
828  if (cts < 0.0 && v * sqrt((1.0 + cts) * (1.0 - cts)) < MODULE_RADIUS_M) { continue; }
829 
830  const double W = std::min(A/(v*v), 2.0*PI); // solid angle
831  const double Ja = getScatteringProbability(cts); // d^2P/dcos/dphi
832  const double Jd = ng * (1.0 - cts) / C; // dt/du
833 
834  const double ca = (D - v*cb) / u;
835  const double sa = v*sb / u;
836 
837  const double dp = PI / phd.size();
838  const double dom = dcb*dp * v*v / (u*u);
839 
840  for (const_iterator l = phd.begin(); l != phd.end(); ++l) {
841 
842  const double cp = l->getX();
843  const double sp = l->getY();
844 
845  const double ct0 = cd*ca - sd*sa*cp;
846 
847  const double vx = sb*cp * qx;
848  const double vy = sb*sp * qy;
849  const double vz = cb * qz;
850 
851  const double U =
852  getAngularAcceptance(vx + vy + vz) +
853  getAngularAcceptance(vx - vy + vz); // PMT angular acceptance
854 
855  const double Jb = geant(n,ct0); // d^2N/dcos/dphi
856 
857  value += dom * gWater() * npe * dz * U * V * W * Ja * Jb * Jc / fabs(Jd);
858  }
859  }
860  }
861  }
862  }
863 
864  return value;
865  }
866 
867 
868  /**
869  * Probability density function for scattered light from muon.
870  *
871  * \param D_m distance between track segment and PMT [m]
872  * \param cd cosine angle muon direction and track segment - PMT position
873  * \param theta zenith angle orientation PMT [rad]
874  * \param phi azimuth angle orientation PMT [rad]
875  * \param t_ns time difference relative to direct Cherenkov light [ns]
876  * \return d^2P/dt/dx [npe/ns/m]
877  */
878  double getScatteredLightFromMuon(const double D_m,
879  const double cd,
880  const double theta,
881  const double phi,
882  const double t_ns) const
883  {
884  static const double eps = 1.0e-10;
885 
886  double value = 0;
887 
888  const double sd = sqrt((1.0 + cd)*(1.0 - cd));
889  const double D = std::max(D_m, getRmin());
890  const double R = sd * D; // minimal distance of approach [m]
891  const double Z = -cd * D; // photon emission point
892  const double L = D;
893  const double t = D * getIndexOfRefraction() / C + t_ns; // time [ns]
894  const double A = getPhotocathodeArea();
895 
896  const double px = sin(theta)*cos(phi);
897  const double py = sin(theta)*sin(phi);
898  const double pz = cos(theta);
899 
900  const double n0 = getIndexOfRefractionGroup(wmax);
901  const double n1 = getIndexOfRefractionGroup(wmin);
902 
903  const double ni = C*t / L; // maximal index of refraction
904 
905  if (n0 >= ni) {
906  return value;
907  }
908 
909  const double nj = std::min(ni,n1);
910 
911  double w = wmax;
912 
913  for (const_iterator i = begin(); i != end(); ++i) {
914 
915  const double ng = 0.5 * (nj + n0) + i->getX() * 0.5 * (nj - n0);
916  const double dn = i->getY() * 0.5 * (nj - n0);
917 
918  w = getWavelength(ng, w, 1.0e-5);
919 
920  const double dw = dn / fabs(getDispersionGroup(w));
921 
922  const double n = getIndexOfRefractionPhase(w);
923 
924  const double l_abs = getAbsorptionLength(w);
925  const double ls = getScatteringLength(w);
926 
927  const double npe = cherenkov(w,n) * dw * getQE(w);
928 
929  if (npe <= 0) { continue; }
930 
931  const double Jc = 1.0 / ls; // dN/dx
932 
933  const double ct0 = 1.0 / n; // photon direction before scattering
934  const double st0 = sqrt((1.0 + ct0)*(1.0 - ct0));
935 
936  const double d = C*t / ng; // photon path
937 
938  //const double V = exp(-d/l_abs); // absorption
939 
940  const double cta = cd*ct0 + sd*st0;
941  const double dca = d - 0.5*(d+L)*(d-L) / (d - L*cta);
942  const double tip = -log(L*L/(dca*dca) + eps) / PI;
943 
944  const double ymin = exp(tip*PI);
945  const double ymax = 1.0;
946 
947  for (const_iterator j = begin(); j != end(); ++j) {
948 
949  const double y = 0.5 * (ymax + ymin) + j->getX() * 0.5 * (ymax - ymin);
950  const double dy = j->getY() * 0.5 * (ymax - ymin);
951 
952  const double phi = log(y) / tip;
953  const double dp = -dy / (tip*y);
954 
955  const double cp0 = cos(phi);
956  const double sp0 = sin(phi);
957 
958  const double u = (R*R + Z*Z - d*d) / (2*R*st0*cp0 - 2*Z*ct0 - 2*d);
959  const double v = d - u;
960 
961  if (u <= 0) { continue; }
962  if (v <= 0) { continue; }
963 
964  const double vi = 1.0 / v;
965  const double cts = (R*st0*cp0 - Z*ct0 - u)*vi; // cosine scattering angle
966 
967  const double V = exp(-d*getInverseAttenuationLength(l_abs, ls, cts));
968 
969  if (cts < 0.0 && v * sqrt((1.0 + cts) * (1.0 - cts)) < MODULE_RADIUS_M) { continue; }
970 
971  const double vx = R - u*st0*cp0;
972  const double vy = - u*st0*sp0;
973  const double vz = -Z - u*ct0;
974 
975  const double ct[] = { // cosine angle of incidence on PMT
976  (vx*px + vy*py + vz*pz) * vi,
977  (vx*px - vy*py + vz*pz) * vi
978  };
979 
980  const double U =
981  getAngularAcceptance(ct[0]) +
982  getAngularAcceptance(ct[1]); // PMT angular acceptance
983  const double W = std::min(A*vi*vi, 2.0*PI); // solid angle
984 
985  const double Ja = getScatteringProbability(cts); // d^2P/dcos/dphi
986  const double Jd = ng * (1.0 - cts) / C; // dt/du
987 
988  value += (npe * dp / (2*PI)) * U * V * W * Ja * Jc / fabs(Jd);
989  }
990  }
991 
992  return value;
993  }
994 
995 
996  /**
997  * Probability density function for direct light from EM-shower.
998  *
999  * \param D_m distance between EM-shower and PMT [m]
1000  * \param cd cosine angle EM-shower direction and EM-shower - PMT position
1001  * \param theta zenith angle orientation PMT [rad]
1002  * \param phi azimuth angle orientation PMT [rad]
1003  * \param t_ns time difference relative to direct Cherenkov light [ns]
1004  * \return d^2P/dt/dE [npe/ns/GeV]
1005  */
1006  double getDirectLightFromEMshower(const double D_m,
1007  const double cd,
1008  const double theta,
1009  const double phi,
1010  const double t_ns) const
1011  {
1012  const double ct0 = cd;
1013  const double st0 = sqrt((1.0 + ct0)*(1.0 - ct0));
1014 
1015  const double D = std::max(D_m, getRmin());
1016  const double t = D * getIndexOfRefraction() / C + t_ns; // time [ns]
1017  const double A = getPhotocathodeArea();
1018 
1019  const double px = sin(theta)*cos(phi);
1020  const double pz = cos(theta);
1021 
1022  const double n0 = getIndexOfRefractionGroup(wmax);
1023  const double n1 = getIndexOfRefractionGroup(wmin);
1024  const double ng = C*t/D; // index of refraction
1025 
1026  if (n0 >= ng) { return 0.0; }
1027  if (n1 <= ng) { return 0.0; }
1028 
1029  const double w = getWavelength(ng);
1030  const double n = getIndexOfRefractionPhase(w);
1031 
1032  const double l_abs = getAbsorptionLength(w);
1033  const double ls = getScatteringLength(w);
1034 
1035  const double npe = cherenkov(w,n) * getQE(w);
1036 
1037  const double ct = st0*px + ct0*pz; // cosine angle of incidence on PMT
1038 
1039  const double U = getAngularAcceptance(ct); // PMT angular acceptance
1040  const double V = exp(-D/l_abs - D/ls); // absorption & scattering
1041  const double W = A/(D*D); // solid angle
1042 
1043  const double ngp = getDispersionGroup(w);
1044 
1045  const double Ja = D * ngp / C; // dt/dlambda
1046  const double Jb = geant(n,ct0); // d^2N/dcos/dphi
1047 
1048  return npe * geanc() * U * V * W * Jb / fabs(Ja);
1049  }
1050 
1051 
1052  /**
1053  * Probability density function for scattered light from EM-shower.
1054  *
1055  * \param D_m distance between EM-shower and PMT [m]
1056  * \param cd cosine angle EM-shower direction and EM-shower - PMT position
1057  * \param theta zenith angle orientation PMT [rad]
1058  * \param phi azimuth angle orientation PMT [rad]
1059  * \param t_ns time difference relative to direct Cherenkov light [ns]
1060  * \return d^2P/dt/dE [npe/ns/GeV]
1061  */
1062  double getScatteredLightFromEMshower(const double D_m,
1063  const double cd,
1064  const double theta,
1065  const double phi,
1066  const double t_ns) const
1067  {
1068  double value = 0;
1069 
1070  const double sd = sqrt((1.0 + cd)*(1.0 - cd));
1071  const double D = std::max(D_m, getRmin());
1072  const double L = D;
1073  const double t = D * getIndexOfRefraction() / C + t_ns; // time [ns]
1074 
1075  const double A = getPhotocathodeArea();
1076 
1077  const double px = sin(theta)*cos(phi);
1078  const double py = sin(theta)*sin(phi);
1079  const double pz = cos(theta);
1080 
1081  const double qx = cd*px + 0 - sd*pz;
1082  const double qy = 1*py;
1083  const double qz = sd*px + 0 + cd*pz;
1084 
1085  const double n0 = getIndexOfRefractionGroup(wmax);
1086  const double n1 = getIndexOfRefractionGroup(wmin);
1087 
1088  const double ni = C*t / L; // maximal index of refraction
1089 
1090  if (n0 >= ni) {
1091  return value;
1092  }
1093 
1094  const double nj = std::min(ni,n1);
1095 
1096  double w = wmax;
1097 
1098  for (const_iterator i = begin(); i != end(); ++i) {
1099 
1100  const double ng = 0.5 * (nj + n0) + i->getX() * 0.5 * (nj - n0);
1101  const double dn = i->getY() * 0.5 * (nj - n0);
1102 
1103  w = getWavelength(ng, w, 1.0e-5);
1104 
1105  const double dw = dn / fabs(getDispersionGroup(w));
1106 
1107  const double n = getIndexOfRefractionPhase(w);
1108 
1109  const double l_abs = getAbsorptionLength(w);
1110  const double ls = getScatteringLength(w);
1111 
1112  const double npe = cherenkov(w,n) * dw * getQE(w);
1113 
1114  if (npe <= 0) { continue; }
1115 
1116  const double Jc = 1.0 / ls; // dN/dx
1117 
1118  const double d = C*t / ng; // photon path
1119 
1120  //const double V = exp(-d/l_abs); // absorption
1121 
1122  const double ds = 2.0 / (size() + 1);
1123 
1124  for (double sb = 0.5*ds; sb < 1.0 - 0.25*ds; sb += ds) {
1125 
1126  for (int buffer[] = { -1, +1, 0}, *k = buffer; *k != 0; ++k) {
1127 
1128  const double cb = (*k) * sqrt((1.0 + sb)*(1.0 - sb));
1129  const double dcb = (*k) * ds*sb/cb;
1130 
1131  const double v = 0.5 * (d + L) * (d - L) / (d - L*cb);
1132  const double u = d - v;
1133 
1134  if (u <= 0) { continue; }
1135  if (v <= 0) { continue; }
1136 
1137  const double cts = (L*cb - v) / u; // cosine scattering angle
1138 
1139  const double V = exp(-d*getInverseAttenuationLength(l_abs, ls, cts));
1140 
1141  if (cts < 0.0 && v * sqrt((1.0 + cts) * (1.0 - cts)) < MODULE_RADIUS_M) { continue; }
1142 
1143  const double W = std::min(A/(v*v), 2.0*PI); // solid angle
1144  const double Ja = getScatteringProbability(cts); // d^2P/dcos/dphi
1145  const double Jd = ng * (1.0 - cts) / C; // dt/du
1146 
1147  const double ca = (L - v*cb) / u;
1148  const double sa = v*sb / u;
1149 
1150  const double dp = PI / phd.size();
1151  const double dom = dcb*dp * v*v / (u*u);
1152  const double dos = sqrt(dom);
1153 
1154  for (const_iterator l = phd.begin(); l != phd.end(); ++l) {
1155 
1156  const double cp = l->getX();
1157  const double sp = l->getY();
1158 
1159  const double ct0 = cd*ca - sd*sa*cp;
1160 
1161  const double vx = -sb*cp * qx;
1162  const double vy = -sb*sp * qy;
1163  const double vz = cb * qz;
1164 
1165  const double U =
1166  getAngularAcceptance(vx + vy + vz) +
1167  getAngularAcceptance(vx - vy + vz); // PMT angular acceptance
1168 
1169  //const double Jb = geant(n,ct0); // d^2N/dcos/dphi
1170 
1171  //value += npe * geanc() * dom * U * V * W * Ja * Jb * Jc / fabs(Jd);
1172 
1173  const double Jb = geant(n,
1174  ct0 - 0.5*dos,
1175  ct0 + 0.5*dos); // dN/dphi
1176 
1177  value += npe * geanc() * dos * U * V * W * Ja * Jb * Jc / fabs(Jd);
1178  }
1179  }
1180  }
1181  }
1182 
1183  return value;
1184  }
1185 
1186 
1187  /**
1188  * Probability density function for direct light from EM-shower.
1189  *
1190  * \param E EM-shower energy [GeV]
1191  * \param D_m distance between EM-shower and PMT [m]
1192  * \param cd cosine angle EM-shower direction and EM-shower - PMT position
1193  * \param theta zenith angle orientation PMT [rad]
1194  * \param phi azimuth angle orientation PMT [rad]
1195  * \param t_ns time difference relative to direct Cherenkov light [ns]
1196  * \return dP/dt [npe/ns]
1197  */
1198  double getDirectLightFromEMshower(const double E,
1199  const double D_m,
1200  const double cd,
1201  const double theta,
1202  const double phi,
1203  const double t_ns) const
1204  {
1205  double value = 0;
1206 
1207  const double sd = sqrt((1.0 + cd)*(1.0 - cd));
1208  const double D = std::max(D_m, getRmin());
1209  const double R = D * sd; // minimal distance of approach [m]
1210  const double Z = -D * cd;
1211  const double t = D * getIndexOfRefraction() / C + t_ns; // time [ns]
1212 
1213  const double n0 = getIndexOfRefractionGroup(wmax);
1214  const double n1 = getIndexOfRefractionGroup(wmin);
1215 
1216  double zmin = 0.0; // minimal shower length [m]
1217  double zmax = geanz.getLength(E, 1.0); // maximal shower length [m]
1218 
1219  const double d = sqrt((Z+zmax)*(Z+zmax) + R*R);
1220 
1221  if (C*t > std::max(n1*D, zmax + n1*d)) {
1222  return value;
1223  }
1224 
1225  if (C*t < n0*D) {
1226 
1227  JRoot rz(R, n0, t + Z/C); // square root
1228 
1229  if (!rz.is_valid) {
1230  return value;
1231  }
1232 
1233  if (rz.second > Z) { zmin = rz.second - Z; }
1234  if (rz.first > Z) { zmin = rz.first - Z; }
1235  }
1236 
1237  if (C*t > n1*D) {
1238 
1239  JRoot rz(R, n1, t + Z/C); // square root
1240 
1241  if (!rz.is_valid) {
1242  return value;
1243  }
1244 
1245  if (rz.second > Z) { zmin = rz.second - Z; }
1246  if (rz.first > Z) { zmin = rz.first - Z; }
1247  }
1248 
1249  if (C*t < zmax + n0*d) {
1250 
1251  JRoot rz(R, n0, t + Z/C); // square root
1252 
1253  if (!rz.is_valid) {
1254  return value;
1255  }
1256 
1257  if (rz.first > Z) { zmax = rz.first - Z; }
1258  if (rz.second > Z) { zmax = rz.second - Z; }
1259  }
1260 
1261  if (zmin < 0.0) {
1262  zmin = 0.0;
1263  }
1264 
1265  if (zmax > zmin) {
1266 
1267  const double ymin = geanz.getIntegral(E, zmin);
1268  const double ymax = geanz.getIntegral(E, zmax);
1269  const double dy = (ymax - ymin) / size();
1270 
1271  if (dy > 2*std::numeric_limits<double>::epsilon()) {
1272 
1273  for (double y = ymin + 0.5*dy; y < ymax; y += dy) {
1274 
1275  const double z = Z + geanz.getLength(E, y);
1276  const double d = sqrt(R*R + z*z);
1277  const double t1 = t + (Z - z) / C - d * getIndexOfRefraction() / C;
1278 
1279  value += dy * E * getDirectLightFromEMshower(d, -z/d, theta, phi, t1);
1280  }
1281 
1282  }
1283  }
1284 
1285  return value;
1286  }
1287 
1288 
1289  /**
1290  * Probability density function for scattered light from EM-shower.
1291  *
1292  * \param E EM-shower energy [GeV]
1293  * \param D_m distance between EM-shower and PMT [m]
1294  * \param cd cosine angle EM-shower direction and EM-shower - PMT position
1295  * \param theta zenith angle orientation PMT [rad]
1296  * \param phi azimuth angle orientation PMT [rad]
1297  * \param t_ns time difference relative to direct Cherenkov light [ns]
1298  * \return dP/dt [npe/ns]
1299  */
1300  double getScatteredLightFromEMshower(const double E,
1301  const double D_m,
1302  const double cd,
1303  const double theta,
1304  const double phi,
1305  const double t_ns) const
1306  {
1307  double value = 0;
1308 
1309  const double sd = sqrt((1.0 + cd)*(1.0 - cd));
1310  const double D = std::max(D_m, getRmin());
1311  const double R = D * sd; // minimal distance of approach [m]
1312  const double Z = -D * cd;
1313  const double t = D * getIndexOfRefraction() / C + t_ns; // time [ns]
1314 
1315  const double n0 = getIndexOfRefractionGroup(wmax);
1316 
1317  double zmin = 0.0; // minimal shower length [m]
1318  double zmax = geanz.getLength(E, 1.0); // maximal shower length [m]
1319 
1320  const double d = sqrt((Z+zmax)*(Z+zmax) + R*R);
1321 
1322  if (C*t < n0*D) {
1323 
1324  JRoot rz(R, n0, t + Z/C); // square root
1325 
1326  if (!rz.is_valid) {
1327  return value;
1328  }
1329 
1330  if (rz.second > Z) { zmin = rz.second - Z; }
1331  if (rz.first > Z) { zmin = rz.first - Z; }
1332  }
1333 
1334  if (C*t < zmax + n0*d) {
1335 
1336  JRoot rz(R, n0, t + Z/C); // square root
1337 
1338  if (!rz.is_valid) {
1339  return value;
1340  }
1341 
1342  if (rz.first > Z) { zmax = rz.first - Z; }
1343  if (rz.second > Z) { zmax = rz.second - Z; }
1344  }
1345 
1346  const double ymin = geanz.getIntegral(E, zmin);
1347  const double ymax = geanz.getIntegral(E, zmax);
1348  const double dy = (ymax - ymin) / size();
1349 
1350  if (dy > 2*std::numeric_limits<double>::epsilon()) {
1351 
1352  for (double y = ymin + 0.5*dy; y < ymax; y += dy) {
1353 
1354  const double z = Z + geanz.getLength(E, y);
1355  const double d = sqrt(R*R + z*z);
1356  const double t1 = t + (Z - z) / C - d * getIndexOfRefraction() / C;
1357 
1358  value += dy * E * getScatteredLightFromEMshower(d, -z/d, theta, phi, t1);
1359  }
1360  }
1361 
1362  return value;
1363  }
1364 
1365 
1366  /**
1367  * Probability density function for direct light from delta-rays.
1368  *
1369  * \param R_m distance between muon and PMT [m]
1370  * \param theta zenith angle orientation PMT [rad]
1371  * \param phi azimuth angle orientation PMT [rad]
1372  * \param t_ns time difference relative to direct Cherenkov light [ns]
1373  * \return d^2P/dt/dE [npe/ns x m/GeV]
1374  */
1375  double getDirectLightFromDeltaRays(const double R_m,
1376  const double theta,
1377  const double phi,
1378  const double t_ns) const
1379  {
1380  double value = 0;
1381 
1382  const double R = std::max(R_m, getRmin());
1383  const double t = R * getTanThetaC() / C + t_ns; // time [ns]
1384  const double A = getPhotocathodeArea();
1385  const double D = 2.0*sqrt(A/PI);
1386 
1387  const double px = sin(theta)*cos(phi);
1388  const double pz = cos(theta);
1389 
1390  const double n0 = getIndexOfRefractionGroup(wmax);
1391  const double n1 = getIndexOfRefractionGroup(wmin);
1392  const double ni = sqrt(R*R + C*t*C*t) / R; // maximal index of refraction
1393 
1394  if (n0 >= ni) {
1395  return value;
1396  }
1397 
1398  const double nj = std::min(n1, ni);
1399 
1400  double w = wmax;
1401 
1402  for (const_iterator i = begin(); i != end(); ++i) {
1403 
1404  const double ng = 0.5 * (nj + n0) + i->getX() * 0.5 * (nj - n0);
1405  const double dn = i->getY() * 0.5 * (nj - n0);
1406 
1407  w = getWavelength(ng, w, 1.0e-5);
1408 
1409  const double dw = dn / fabs(getDispersionGroup(w));
1410 
1411  const double n = getIndexOfRefractionPhase(w);
1412 
1413  const double l_abs = getAbsorptionLength(w);
1414  const double ls = getScatteringLength(w);
1415 
1416  const double npe = cherenkov(w,n) * dw * getQE(w);
1417 
1418  JRoot rz(R, ng, t); // square root
1419 
1420  if (!rz.is_valid) { continue; }
1421 
1422  for (int j = 0; j != 2; ++j) {
1423 
1424  const double z = rz[j];
1425 
1426  if (C*t <= z) continue;
1427 
1428  const double d = sqrt(z*z + R*R); // distance traveled by photon
1429 
1430  const double ct0 = -z / d;
1431  const double st0 = R / d;
1432 
1433  const double dz = D / st0; // average track length
1434  const double ct = st0*px + ct0*pz; // cosine angle of incidence on PMT
1435 
1436  const double U = getAngularAcceptance(ct); // PMT angular acceptance
1437  const double V = exp(-d/l_abs - d/ls); // absorption & scattering
1438  const double W = A/(d*d); // solid angle
1439 
1440  const double Ja = getDeltaRayProbability(ct0); // d^2N/dcos/dphi
1441  const double Jd = (1.0 - ng*ct0) / C; // d t/ dz
1442  const double Je = ng*st0*st0*st0 / (R*C); // d^2t/(dz)^2
1443 
1444  value += npe * geanc() * U * V * W * Ja / (fabs(Jd) + 0.5*Je*dz);
1445  }
1446  }
1447 
1448  return value;
1449  }
1450 
1451 
1452  /**
1453  * Probability density function for direct light from delta-rays.
1454  *
1455  * \param R_m distance between muon and PMT [m]
1456  * \param theta zenith angle orientation PMT [rad]
1457  * \param phi azimuth angle orientation PMT [rad]
1458  * \param t_ns time difference relative to direct Cherenkov light [ns]
1459  * \return d^2P/dt/dx [npe/ns x m/GeV]
1460  */
1461  double getScatteredLightFromDeltaRays(const double R_m,
1462  const double theta,
1463  const double phi,
1464  const double t_ns) const
1465  {
1466  double value = 0;
1467 
1468  const double R = std::max(R_m, getRmin());
1469  const double t = R * getTanThetaC() / C + t_ns; // time [ns]
1470  const double A = getPhotocathodeArea();
1471 
1472  const double px = sin(theta)*cos(phi);
1473  const double py = sin(theta)*sin(phi);
1474  const double pz = cos(theta);
1475 
1476  const double n0 = getIndexOfRefractionGroup(wmax);
1477  const double n1 = getIndexOfRefractionGroup(wmin);
1478  const double ni = sqrt(R*R + C*t*C*t) / R; // maximal index of refraction
1479 
1480  if (n0 >= ni) {
1481  return value;
1482  }
1483 
1484  const double nj = std::min(ni,n1);
1485 
1486  double w = wmax;
1487 
1488  for (const_iterator i = begin(); i != end(); ++i) {
1489 
1490  const double ng = 0.5 * (nj + n0) + i->getX() * 0.5 * (nj - n0);
1491  const double dn = i->getY() * 0.5 * (nj - n0);
1492 
1493  w = getWavelength(ng, w, 1.0e-5);
1494 
1495  const double dw = dn / fabs(getDispersionGroup(w));
1496 
1497  const double n = getIndexOfRefractionPhase(w);
1498 
1499  const double l_abs = getAbsorptionLength(w);
1500  const double ls = getScatteringLength(w);
1501 
1502  const double npe = cherenkov(w,n) * dw * getQE(w);
1503 
1504  if (npe <= 0) { continue; }
1505 
1506  const double Jc = 1.0 / ls; // dN/dx
1507 
1508  JRoot rz(R, ng, t); // square root
1509 
1510  if (!rz.is_valid) { continue; }
1511 
1512  const double zmin = rz.first;
1513  const double zmax = rz.second;
1514 
1515  const double zap = 1.0 / l_abs;
1516 
1517  const double xmin = exp(zap*zmax);
1518  const double xmax = exp(zap*zmin);
1519 
1520  for (const_iterator j = begin(); j != end(); ++j) {
1521 
1522  const double x = 0.5 * (xmax + xmin) + j->getX() * 0.5 * (xmax - xmin);
1523  const double dx = j->getY() * 0.5 * (xmax - xmin);
1524 
1525  const double z = log(x) / zap;
1526  const double dz = -dx / (zap*x);
1527 
1528  const double D = sqrt(z*z + R*R);
1529  const double cd = -z / D;
1530  const double sd = R / D;
1531 
1532  const double qx = cd*px + 0 - sd*pz;
1533  const double qy = 1*py;
1534  const double qz = sd*px + 0 + cd*pz;
1535 
1536  const double d = (C*t - z) / ng; // photon path
1537 
1538  //const double V = exp(-d/l_abs); // absorption
1539 
1540  const double ds = 2.0 / (size() + 1);
1541 
1542  for (double sb = 0.5*ds; sb < 1.0 - 0.25*ds; sb += ds) {
1543 
1544  for (int buffer[] = { -1, +1, 0}, *k = buffer; *k != 0; ++k) {
1545 
1546  const double cb = (*k) * sqrt((1.0 + sb)*(1.0 - sb));
1547  const double dcb = (*k) * ds*sb/cb;
1548 
1549  const double v = 0.5 * (d + D) * (d - D) / (d - D*cb);
1550  const double u = d - v;
1551 
1552  if (u <= 0) { continue; }
1553  if (v <= 0) { continue; }
1554 
1555  const double cts = (D*cb - v) / u; // cosine scattering angle
1556 
1557  const double V = exp(-d*getInverseAttenuationLength(l_abs, ls, cts));
1558 
1559  if (cts < 0.0 && v * sqrt((1.0 + cts) * (1.0 - cts)) < MODULE_RADIUS_M) { continue; }
1560 
1561  const double W = std::min(A/(v*v), 2.0*PI); // solid angle
1562  const double Ja = getScatteringProbability(cts); // d^2P/dcos/dphi
1563  const double Jd = ng * (1.0 - cts) / C; // dt/du
1564 
1565  const double ca = (D - v*cb) / u;
1566  const double sa = v*sb / u;
1567 
1568  const double dp = PI / phd.size();
1569  const double dom = dcb*dp * v*v / (u*u);
1570 
1571  for (const_iterator l = phd.begin(); l != phd.end(); ++l) {
1572 
1573  const double cp = l->getX();
1574  const double sp = l->getY();
1575 
1576  const double ct0 = cd*ca - sd*sa*cp;
1577 
1578  const double vx = sb*cp * qx;
1579  const double vy = sb*sp * qy;
1580  const double vz = cb * qz;
1581 
1582  const double U =
1583  getAngularAcceptance(vx + vy + vz) +
1584  getAngularAcceptance(vx - vy + vz); // PMT angular acceptance
1585 
1586  const double Jb = getDeltaRayProbability(ct0); // d^2N/dcos/dphi
1587 
1588  value += dom * npe * geanc() * dz * U * V * W * Ja * Jb * Jc / fabs(Jd);
1589  }
1590  }
1591  }
1592  }
1593  }
1594 
1595  return value;
1596  }
1597 
1598 
1599  /**
1600  * Probability density function for direct light from isotropic light source.
1601  *
1602  * \param D_m distance between light source and PMT [m]
1603  * \param ct cosine angle PMT
1604  * \param t_ns time difference relative to direct Cherenkov light [ns]
1605  * \return d^2P/dt/dE [npe/ns/GeV]
1606  */
1607  double getDirectLightFromBrightPoint(const double D_m,
1608  const double ct,
1609  const double t_ns) const
1610  {
1611  const double D = std::max(D_m, getRmin());
1612  const double t = D * getIndexOfRefraction() / C + t_ns; // time [ns]
1613  const double A = getPhotocathodeArea();
1614 
1615  const double n0 = getIndexOfRefractionGroup(wmax);
1616  const double n1 = getIndexOfRefractionGroup(wmin);
1617  const double ng = C*t/D; // index of refraction
1618 
1619  if (n0 >= ng) { return 0.0; }
1620  if (n1 <= ng) { return 0.0; }
1621 
1622  const double w = getWavelength(ng);
1623  const double n = getIndexOfRefractionPhase(w);
1624 
1625  const double l_abs = getAbsorptionLength(w);
1626  const double ls = getScatteringLength(w);
1627 
1628  const double npe = cherenkov(w,n) * getQE(w);
1629 
1630  const double U = getAngularAcceptance(ct); // PMT angular acceptance
1631  const double V = exp(-D/l_abs - D/ls); // absorption & scattering
1632  const double W = A/(D*D); // solid angle
1633 
1634  const double ngp = getDispersionGroup(w);
1635 
1636  const double Ja = D * ngp / C; // dt/dlambda
1637  const double Jb = 1.0 / (4.0*PI); // d^2N/dOmega
1638 
1639  return npe * geanc() * U * V * W * Jb / fabs(Ja);
1640  }
1641 
1642 
1643  /**
1644  * Probability density function for scattered light from isotropic light source.
1645  *
1646  * \param D_m distance between light source and PMT [m]
1647  * \param ct cosine angle PMT
1648  * \param t_ns time difference relative to direct Cherenkov light [ns]
1649  * \return d^2P/dt/dE [npe/ns/GeV]
1650  */
1651  double getScatteredLightFromBrightPoint(const double D_m,
1652  const double ct,
1653  const double t_ns) const
1654  {
1655  double value = 0;
1656 
1657  const double D = std::max(D_m, getRmin());
1658  const double t = D * getIndexOfRefraction() / C + t_ns; // time [ns]
1659  const double st = sqrt((1.0 + ct)*(1.0 - ct));
1660 
1661  const double A = getPhotocathodeArea();
1662 
1663  const double n0 = getIndexOfRefractionGroup(wmax);
1664  const double n1 = getIndexOfRefractionGroup(wmin);
1665 
1666  const double ni = C*t / D; // maximal index of refraction
1667 
1668  if (n0 >= ni) {
1669  return value;
1670  }
1671 
1672  const double nj = std::min(ni,n1);
1673 
1674  double w = wmax;
1675 
1676  for (const_iterator i = begin(); i != end(); ++i) {
1677 
1678  const double ng = 0.5 * (nj + n0) + i->getX() * 0.5 * (nj - n0);
1679  const double dn = i->getY() * 0.5 * (nj - n0);
1680 
1681  w = getWavelength(ng, w, 1.0e-5);
1682 
1683  const double dw = dn / fabs(getDispersionGroup(w));
1684 
1685  const double n = getIndexOfRefractionPhase(w);
1686 
1687  const double npe = cherenkov(w,n) * dw * getQE(w);
1688 
1689  if (npe <= 0) { continue; }
1690 
1691  const double l_abs = getAbsorptionLength(w);
1692  const double ls = getScatteringLength(w);
1693 
1694  const double Jc = 1.0 / ls; // dN/dx
1695  const double Jb = 1.0 / (4.0*PI); // d^2N/dcos/dphi
1696 
1697  const double d = C*t / ng; // photon path
1698 
1699  const double dcb = 2.0 / (size() + 1);
1700 
1701  for (double cb = -1.0 + 0.5*dcb; cb < +1.0; cb += dcb) {
1702 
1703  const double sb = sqrt((1.0 + cb)*(1.0 - cb));
1704 
1705  const double v = 0.5 * (d + D) * (d - D) / (d - D*cb);
1706  const double u = d - v;
1707 
1708  if (u <= 0) { continue; }
1709  if (v <= 0) { continue; }
1710 
1711  const double cts = (D*cb - v) / u; // cosine scattering angle
1712 
1713  const double V = exp(-d*getInverseAttenuationLength(l_abs, ls, cts));
1714 
1715  if (cts < 0.0 && v * sqrt((1.0 + cts) * (1.0 - cts)) < MODULE_RADIUS_M) { continue; }
1716 
1717  const double W = std::min(A/(v*v), 2.0*PI); // solid angle
1718  const double Ja = getScatteringProbability(cts); // d^2P/dcos/dphi
1719  const double Jd = ng * (1.0 - cts) / C; // dt/du
1720 
1721  const double dp = PI / phd.size();
1722  const double dom = dcb*dp * v*v / (u*u); // dOmega
1723 
1724  for (const_iterator l = phd.begin(); l != phd.end(); ++l) {
1725 
1726  const double cp = l->getX();
1727  const double dot = cb*ct + sb*cp*st;
1728 
1729  const double U = 2 * getAngularAcceptance(dot); // PMT angular acceptance
1730 
1731  value += npe * geanc() * dom * U * V * W * Ja * Jb * Jc / fabs(Jd);
1732  }
1733  }
1734  }
1735 
1736  return value;
1737  }
1738 
1739 
1740  /**
1741  * Probability density function for light from muon.
1742  *
1743  * \param type PDF type
1744  * \param E_GeV muon energy [GeV]
1745  * \param R_m distance between muon and PMT [m]
1746  * \param theta zenith angle orientation PMT [rad]
1747  * \param phi azimuth angle orientation PMT [rad]
1748  * \param t_ns time difference relative to direct Cherenkov light [ns]
1749  * \return d^2P/dt/dx [npe/ns]
1750  */
1751  double getLightFromMuon(const int type,
1752  const double E_GeV,
1753  const double R_m,
1754  const double theta,
1755  const double phi,
1756  const double t_ns) const
1757  {
1758  switch (type) {
1759 
1761  return getDirectLightFromMuon (R_m, theta, phi, t_ns);
1762 
1764  return getScatteredLightFromMuon (R_m, theta, phi, t_ns);
1765 
1767  return getDirectLightFromEMshowers (R_m, theta, phi, t_ns) * E_GeV;
1768 
1770  return getScatteredLightFromEMshowers(R_m, theta, phi, t_ns) * E_GeV;
1771 
1773  return getDirectLightFromDeltaRays (R_m, theta, phi, t_ns) * getDeltaRaysFromMuon(E_GeV);
1774 
1776  return getScatteredLightFromDeltaRays(R_m, theta, phi, t_ns) * getDeltaRaysFromMuon(E_GeV);
1777 
1778  default:
1779  return 0.0;
1780  }
1781  }
1782 
1783 
1784  /**
1785  * Probability density function for light from muon.
1786  *
1787  * \param E_GeV muon energy [GeV]
1788  * \param R_m distance between muon and PMT [m]
1789  * \param theta zenith angle orientation PMT [rad]
1790  * \param phi azimuth angle orientation PMT [rad]
1791  * \param t_ns time difference relative to direct Cherenkov light [ns]
1792  * \return d^2P/dt/dx [npe/ns]
1793  */
1794  double getLightFromMuon(const double E_GeV,
1795  const double R_m,
1796  const double theta,
1797  const double phi,
1798  const double t_ns) const
1799  {
1800  return (getDirectLightFromMuon (R_m, theta, phi, t_ns) +
1801  getScatteredLightFromMuon (R_m, theta, phi, t_ns) +
1802  getDirectLightFromEMshowers (R_m, theta, phi, t_ns) * E_GeV +
1803  getScatteredLightFromEMshowers(R_m, theta, phi, t_ns) * E_GeV +
1804  getDirectLightFromDeltaRays (R_m, theta, phi, t_ns) * getDeltaRaysFromMuon(E_GeV) +
1805  getScatteredLightFromDeltaRays(R_m, theta, phi, t_ns) * getDeltaRaysFromMuon(E_GeV));
1806  }
1807 
1808 
1809  /**
1810  * Probability density function for light from EM-shower.
1811  *
1812  * \param type PDF type
1813  * \param D_m distance between EM-shower and PMT [m]
1814  * \param cd cosine angle EM-shower direction and EM-shower - PMT position
1815  * \param theta zenith angle orientation PMT [rad]
1816  * \param phi azimuth angle orientation PMT [rad]
1817  * \param t_ns time difference relative to direct Cherenkov light [ns]
1818  * \return d^2P/dt/dE [npe/ns/GeV]
1819  */
1820  double getLightFromEMshower(const int type,
1821  const double D_m,
1822  const double cd,
1823  const double theta,
1824  const double phi,
1825  const double t_ns) const
1826  {
1827  switch (type) {
1828 
1830  return getDirectLightFromEMshower (D_m, cd, theta, phi, t_ns);
1831 
1833  return getScatteredLightFromEMshower(D_m, cd, theta, phi, t_ns);
1834 
1835  default:
1836  return 0.0;
1837  }
1838  }
1839 
1840 
1841  /**
1842  * Probability density function for light from EM-shower.
1843  *
1844  * \param D_m distance between EM-shower and PMT [m]
1845  * \param cd cosine angle EM-shower direction and EM-shower - PMT position
1846  * \param theta zenith angle orientation PMT [rad]
1847  * \param phi azimuth angle orientation PMT [rad]
1848  * \param t_ns time difference relative to direct Cherenkov light [ns]
1849  * \return d^2P/dt/dE [npe/ns/GeV]
1850  */
1851  double getLightFromEMshower(const double D_m,
1852  const double cd,
1853  const double theta,
1854  const double phi,
1855  const double t_ns) const
1856  {
1857  return (getDirectLightFromEMshower (D_m, cd, theta, phi, t_ns) +
1858  getScatteredLightFromEMshower(D_m, cd, theta, phi, t_ns));
1859  }
1860 
1861 
1862  /**
1863  * Probability density function for light from EM-shower.
1864  *
1865  * \param type PDF type
1866  * \param E_GeV EM-shower energy [GeV]
1867  * \param D_m distance between EM-shower and PMT [m]
1868  * \param cd cosine angle EM-shower direction and EM-shower - PMT position
1869  * \param theta zenith angle orientation PMT [rad]
1870  * \param phi azimuth angle orientation PMT [rad]
1871  * \param t_ns time difference relative to direct Cherenkov light [ns]
1872  * \return d^2P/dt/dE [npe/ns/GeV]
1873  */
1874  double getLightFromEMshower(const int type,
1875  const double E_GeV,
1876  const double D_m,
1877  const double cd,
1878  const double theta,
1879  const double phi,
1880  const double t_ns) const
1881  {
1882  switch (type) {
1883 
1885  return getDirectLightFromEMshower (E_GeV, D_m, cd, theta, phi, t_ns);
1886 
1888  return getScatteredLightFromEMshower(E_GeV, D_m, cd, theta, phi, t_ns);
1889 
1890  default:
1891  return 0.0;
1892  }
1893  }
1894 
1895 
1896  /**
1897  * Probability density function for light from EM-shower.
1898  *
1899  * \param E_GeV EM-shower energy [GeV]
1900  * \param D_m distance between EM-shower and PMT [m]
1901  * \param cd cosine angle EM-shower direction and EM-shower - PMT position
1902  * \param theta zenith angle orientation PMT [rad]
1903  * \param phi azimuth angle orientation PMT [rad]
1904  * \param t_ns time difference relative to direct Cherenkov light [ns]
1905  * \return d^2P/dt/dE [npe/ns/GeV]
1906  */
1907  double getLightFromEMshower(const double E_GeV,
1908  const double D_m,
1909  const double cd,
1910  const double theta,
1911  const double phi,
1912  const double t_ns) const
1913  {
1914  return (getDirectLightFromEMshower (E_GeV, D_m, cd, theta, phi, t_ns) +
1915  getScatteredLightFromEMshower(E_GeV, D_m, cd, theta, phi, t_ns));
1916  }
1917 
1918 
1919  /**
1920  * Probability density function for direct light from isotropic light source.
1921  *
1922  * \param type PDF type
1923  * \param D_m distance between light source and PMT [m]
1924  * \param ct cosine angle PMT
1925  * \param t_ns time difference relative to direct Cherenkov light [ns]
1926  * \return d^2P/dt/dE [npe/ns/GeV]
1927  */
1928  double getLightFromBrightPoint(const int type,
1929  const double D_m,
1930  const double ct,
1931  const double t_ns) const
1932  {
1933  switch (type) {
1934 
1936  return getDirectLightFromBrightPoint (D_m, ct, t_ns);
1937 
1939  return getScatteredLightFromBrightPoint(D_m, ct, t_ns);
1940 
1941  default:
1942  return 0.0;
1943  }
1944  }
1945 
1946 
1947  /**
1948  * Probability density function for direct light from isotropic light source.
1949  *
1950  * \param D_m distance between light source and PMT [m]
1951  * \param ct cosine angle PMT
1952  * \param t_ns time difference relative to direct Cherenkov light [ns]
1953  * \return d^2P/dt/dE [npe/ns/GeV]
1954  */
1955  double getLightFromBrightPoint(const double D_m,
1956  const double ct,
1957  const double t_ns) const
1958  {
1959  return (getDirectLightFromBrightPoint (D_m, ct, t_ns) +
1960  getScatteredLightFromBrightPoint(D_m, ct, t_ns));
1961  }
1962 
1963 
1964  /**
1965  * Auxiliary class to find solution(s) to \f$ z \f$ of the square root expression:
1966  \f{eqnarray*}
1967  ct(z=0) & = & z + n \sqrt(z^2 + R^2)
1968  \f}
1969  * where \f$ n = 1/\cos(\theta_{c}) \f$ is the index of refraction.
1970  */
1971  class JRoot {
1972  public:
1973  /**
1974  * Determine solution(s) of quadratic equation.
1975  *
1976  * \param R minimal distance of approach [m]
1977  * \param n index of refraction
1978  * \param t time at z = 0 [ns]
1979  */
1980  JRoot(const double R,
1981  const double n,
1982  const double t) :
1983  is_valid(false),
1984  first (0.0),
1985  second(0.0)
1986  {
1987  const double a = n*n - 1.0;
1988  const double b = 2*C*t;
1989  const double c = R*n * R*n - C*t * C*t;
1990 
1991  const double q = b*b - 4*a*c;
1992 
1993  if (q >= 0.0) {
1994 
1995  first = (-b - sqrt(q)) / (2*a);
1996  second = (-b + sqrt(q)) / (2*a);
1997 
1998  is_valid = C*t > second;
1999  }
2000  }
2001 
2002 
2003  /**
2004  * Get result by index.
2005  *
2006  * \param i index (0 or 1)
2007  * \return i == 0, first; i == 1, second; else throws exception
2008  */
2009  double operator[](const int i) const
2010  {
2011  switch (i) {
2012 
2013  case 0:
2014  return first;
2015 
2016  case 1:
2017  return second;
2018 
2019  default:
2020  throw JException("JRoot::operator[] invalid index");
2021  }
2022  }
2023 
2024  bool is_valid; //!< validity of solutions
2025  double first; //!< most upstream solution
2026  double second; //!< most downstream solution
2027  };
2028 
2029 
2030  protected:
2031  /**
2032  * Determine wavelength for a given index of refraction corresponding to the group velocity.
2033  *
2034  * \param n index of refraction
2035  * \param eps precision index of refraction
2036  * \return wavelength [nm]
2037  */
2038  virtual double getWavelength(const double n,
2039  const double eps = 1.0e-10) const
2040  {
2041  //return getWavelength(n, 0.5*(wmin + wmax), eps);
2042 
2043  double vmin = wmin;
2044  double vmax = wmax;
2045 
2046  for (int i = 0; i != 1000; ++i) {
2047 
2048  const double v = 0.5 * (vmin + vmax);
2049  const double y = getIndexOfRefractionGroup(v);
2050 
2051  if (fabs(y - n) < eps) {
2052  return v;
2053  }
2054 
2055  if (y < n)
2056  vmax = v;
2057  else
2058  vmin = v;
2059  }
2060 
2061  return 0.5 * (vmin + vmax);
2062  }
2063 
2064 
2065  /**
2066  * Determine wavelength for a given index of refraction corresponding to the group velocity.
2067  * The estimate of the wavelength is made by successive linear extrapolations.
2068  * The procedure starts from the given wavelength and terminates if the index of refraction
2069  * is equal to the target value within the given precision.
2070  *
2071  * \param n index of refraction
2072  * \param w start value wavelength [nm]
2073  * \param eps precision index of refraction
2074  * \return return value wavelength [nm]
2075  */
2076  virtual double getWavelength(const double n,
2077  const double w,
2078  const double eps) const
2079  {
2080  double v = w;
2081 
2082  // determine wavelength by linear extrapolation
2083 
2084  for ( ; ; ) {
2085 
2086  const double y = getIndexOfRefractionGroup(v);
2087 
2088  if (fabs(y - n) < eps) {
2089  break;
2090  }
2091 
2092  v += (n - y) / getDispersionGroup(v);
2093  }
2094 
2095  return v;
2096  }
2097 
2098 
2099  static double getRmin() { return 1.0e-1; } //!< minimal distance of approach of muon to PMT [m]
2100 
2101 
2102  /**
2103  * Get the inverse of the attenuation length.
2104  *
2105  * \param l_abs absorption length [m]
2106  * \param ls scattering length [m]
2107  * \param cts cosine scattering angle
2108  * \return inverse attenuation length [m^-1]
2109  */
2110  virtual double getInverseAttenuationLength(const double l_abs, const double ls, const double cts) const
2111  {
2113 
2114  if (f1.empty()) {
2115 
2116  const int nx = 100000;
2117  const double xmin = -1.0;
2118  const double xmax = +1.0;
2119 
2120  const double dx = (xmax - xmin) / (nx - 1);
2121 
2122  for (double x = xmin, W = 0.0; x < xmax; x += dx) {
2123 
2124  f1[x] = W;
2125 
2126  W += 2*PI * dx * getScatteringProbability(x + 0.5*dx);
2127  }
2128 
2129  f1[xmin] = 0.0;
2130  f1[xmax] = 1.0;
2131 
2132  f1.compile();
2133  }
2134 
2135  return 1.0/l_abs + f1(cts)/ls;
2136  }
2137 
2138 
2139  protected:
2140  /**
2141  * Integration limits
2142  */
2143  const double wmin; //!< minimal wavelength for integration [nm]
2144  const double wmax; //!< maximal wavelength for integration [nm]
2145 
2146  std::vector<element_type> phd; //!< fast evaluation of phi integral
2147  };
2148 
2149 
2150  /**
2151  * Probability Density Functions of the time response of a PMT
2152  * with an implementation for the JDispersionInterface interface.
2153  */
2154  class JAbstractPDF :
2155  public JPDF,
2156  public JDispersion
2157  {
2158  public:
2159  /**
2160  * Constructor.
2161  *
2162  * \param P_atm ambient pressure [atm]
2163  * \param Wmin minimal wavelength for integration [nm]
2164  * \param Wmax maximal wavelength for integration [nm]
2165  * \param numberOfPoints number of points for integration
2166  * \param epsilon precision of points for integration
2167  */
2168  JAbstractPDF(const double P_atm,
2169  const double Wmin,
2170  const double Wmax,
2171  const int numberOfPoints = 20,
2172  const double epsilon = 1e-12) :
2173  JPDF(Wmin, Wmax, numberOfPoints, epsilon),
2174  JDispersion(P_atm)
2175  {}
2176  };
2177 
2178 
2179  /**
2180  * Probability Density Functions of the time response of a PMT
2181  * with an implementation of the JAbstractPMT and JAbstractMedium interfaces via C-like methods.
2182  */
2183  class JPDF_C :
2184  public JAbstractPDF
2185  {
2186  public:
2187  /**
2188  * Constructor.
2189  *
2190  * \param Apmt photo-cathode area [m^2]
2191  * \param pF_qe pointer to function for quantum efficiency of PMT
2192  * \param pF_pmt pointer to function for angular acceptance of PMT
2193  * \param pF_l_abs pointer to function for absorption length [m]
2194  * \param pF_ls pointer to function for scattering length [m]
2195  * \param pF_ps pointer to model specific function to describe light scattering in water
2196  * \param P_atm ambient pressure [atm]
2197  * \param Wmin minimal wavelength for integration [nm]
2198  * \param Wmax maximal wavelength for integration [nm]
2199  * \param numberOfPoints number of points for integration
2200  * \param epsilon precision of points for integration
2201  */
2202  JPDF_C(const double Apmt,
2203  //
2204  // pointers to static functions
2205  //
2206  double (*pF_qe) (const double),
2207  double (*pF_pmt) (const double),
2208  double (*pF_l_abs)(const double),
2209  double (*pF_ls) (const double),
2210  double (*pF_ps) (const double),
2211  //
2212  // parameters for base class
2213  //
2214  const double P_atm,
2215  const double Wmin,
2216  const double Wmax,
2217  const int numberOfPoints = 20,
2218  const double epsilon = 1e-12) :
2219  JAbstractPDF(P_atm, Wmin, Wmax, numberOfPoints, epsilon),
2220  A (Apmt),
2221  qe (pF_qe),
2222  l_abs(pF_l_abs),
2223  ls (pF_ls),
2224  pmt (pF_pmt),
2225  ps (pF_ps)
2226  {}
2227 
2228 
2229  /**
2230  * Photo-cathode area of PMT.
2231  *
2232  * \return photo-cathode area [m^2]
2233  */
2234  virtual double getPhotocathodeArea() const override
2235  {
2236  return A;
2237  }
2238 
2239 
2240  /**
2241  * Quantum efficiency of PMT (incl. absorption in glass, gel, etc.).
2242  *
2243  * \param lambda wavelenth [nm]
2244  * \return QE
2245  */
2246  virtual double getQE(const double lambda) const override
2247  {
2248  return qe(lambda);
2249  }
2250 
2251 
2252  /**
2253  * Angular acceptance of PMT.
2254  *
2255  * \param ct cosine angle of incidence
2256  * \return relative efficiency
2257  */
2258  virtual double getAngularAcceptance(const double ct) const override
2259  {
2260  return pmt(ct);
2261  }
2262 
2263 
2264  /**
2265  * Absorption length.
2266  *
2267  * \param lambda wavelenth [nm]
2268  * \return absorption length [m]
2269  */
2270  virtual double getAbsorptionLength(const double lambda) const override
2271  {
2272  return l_abs(lambda);
2273  }
2274 
2275 
2276  /**
2277  * Scattering length.
2278  *
2279  * \param lambda wavelenth [nm]
2280  * \return scattering length [m]
2281  */
2282  virtual double getScatteringLength(const double lambda) const override
2283  {
2284  return ls(lambda);
2285  }
2286 
2287 
2288  /**
2289  * Model specific function to describe light scattering in water
2290  * (integral over full solid angle normalised to one).
2291  *
2292  * \param ct cosine scattering angle
2293  * \return probability
2294  */
2295  virtual double getScatteringProbability(const double ct) const override
2296  {
2297  return ps(ct);
2298  }
2299 
2300  protected:
2301  /**
2302  * photo-cathode area [m2]
2303  */
2304  const double A;
2305 
2306  /**
2307  * Quantum efficiency of PMT (incl. absorption in glass, gel, etc.)
2308  *
2309  * \param lambda wavelenth [nm]
2310  * \return QE
2311  */
2312  double (*qe)(const double lambda);
2313 
2314  /**
2315  * Absorption length
2316  *
2317  * \param lambda wavelenth [nm]
2318  * \return absorption length [m]
2319  */
2320  double (*l_abs)(const double lambda);
2321 
2322  /**
2323  * Scattering length
2324  *
2325  * \param lambda wavelenth [nm]
2326  * \return scattering length [m]
2327  */
2328  double (*ls)(const double lambda);
2329 
2330  /**
2331  * Angular acceptance of PMT
2332  *
2333  * \param ct cosine angle of incidence
2334  * \return relative efficiency
2335  */
2336  double (*pmt)(const double ct);
2337 
2338  /**
2339  * Model specific function to describe light scattering in water
2340  *
2341  * \param ct cosine scattering angle
2342  * \return probability
2343  */
2344  double (*ps)(const double ct);
2345  };
2346 }
2347 
2348 
2349 #endif
then cat $TRIPOD_INITIAL<< EOF1 256877.5 4743716.7-2438.42 256815.5 4743395.0-2435.53 257096.2 4743636.0-2439.5EOFfiJEditDetector-a $DETECTOR_INITIAL-s"-1 addz -6.9"-o $DETECTOReval`JPrintDetector-a $DETECTOR-O SUMMARY`for STRING in ${STRINGS[*]};do set_variable MODULE`getModule-a $DETECTOR-L"$STRING 0"`JEditDetector-a $DETECTOR-M"$MODULE setz -2.9"-o $DETECTORdonecp-p $TRIPOD_INITIAL $TRIPODJAcoustics.sh $DETECTOR_IDcat > acoustics_trigger_parameters txt<< EOFQ=0.0;TMax_s=0.020;numberOfHits=90;EOFJAcousticsEventBuilder.sh $DETECTOR $RUNS[*]INPUT_FILES=(`ls KM3NeT_ ${(l:8::0::0:) DETECTOR_ID}_0 *${^RUNS}_event.root`) cd $WORKDIRif[!$HOMEDIR-ef $WORKDIR];then cp-p $HOMEDIR/$DETECTOR $WORKDIR cp-p $HOMEDIR/$TRIPOD $WORKDIR cp-p $HOMEDIR/${^INPUT_FILES}$WORKDIR cp-p $HOMEDIR/{acoustics_fit_parameters, acoustics_trigger_parameters, disable, hydrophone, mechanics, sound_velocity, tripod, waveform}.txt $WORKDIRfisource $JPP_DIR/examples/JAcoustics/acoustics-fit-toolkit.shtimer_startinitialise stage_1B > &stage log
const double xmax
Definition: JQuadrature.cc:24
General exception.
Definition: JException.hh:23
Photon emission profile EM-shower.
double getLightFromMuon(const double E_GeV, const double R_m, const double theta, const double phi, const double t_ns) const
Probability density function for light from muon.
Definition: JPDF.hh:1794
data_type w[N+1][M+1]
Definition: JPolint.hh:757
Exceptions.
then fatal No hydrophone data file $HYDROPHONE_TXT fi sort gr k
double getDirectLightFromEMshower(const double D_m, const double cd, const double theta, const double phi, const double t_ns) const
Probability density function for direct light from EM-shower.
Definition: JPDF.hh:1006
double getScatteredLightFromEMshower(const double E, const double D_m, const double cd, const double theta, const double phi, const double t_ns) const
Probability density function for scattered light from EM-shower.
Definition: JPDF.hh:1300
Numerical integrator for .
Definition: JQuadrature.hh:111
double getScatteredLightFromEMshower(const double D_m, const double cd, const double theta, const double phi, const double t_ns) const
Probability density function for scattered light from EM-shower.
Definition: JPDF.hh:1062
JTOOLS::JElement2D< double, double > element_type
Definition: JPDF.hh:284
Auxiliary methods for PDF calculations.
double(* ls)(const double lambda)
Scattering length.
Definition: JPDF.hh:2328
double second
most downstream solution
Definition: JPDF.hh:2026
double getNumberOfPhotons() const
Number of Cherenkov photons per unit track length.
Definition: JPDF.hh:325
then usage E
Definition: JMuonPostfit.sh:35
double geanc()
Equivalent muon track length per unit shower energy.
Definition: JGeane.hh:28
double getIndexOfRefraction()
Get average index of refraction of water corresponding to group velocity.
Energy loss of muon.
Probability Density Functions of the time response of a PMT with an implementation for the JDispersio...
Definition: JPDF.hh:2154
scattered light from EM shower
Definition: JPDFTypes.hh:38
Implementation of dispersion for water in deep sea.
Definition: JDispersion.hh:26
double getDirectLightFromMuon(const double R_m, const double theta, const double phi) const
Number of photo-electrons from direct Cherenkov light from muon.
Definition: JPDF.hh:357
double getLightFromMuon(const int type, const double E_GeV, const double R_m, const double theta, const double phi, const double t_ns) const
Probability density function for light from muon.
Definition: JPDF.hh:1751
JRoot(const double R, const double n, const double t)
Determine solution(s) of quadratic equation.
Definition: JPDF.hh:1980
direct light from EM showers
Definition: JPDFTypes.hh:29
virtual double getAbsorptionLength(const double lambda) const override
Absorption length.
Definition: JPDF.hh:2270
then JShowerPostfit f $INPUT_FILE o $OUTPUT_FILE N
double getLightFromEMshower(const int type, const double E_GeV, const double D_m, const double cd, const double theta, const double phi, const double t_ns) const
Probability density function for light from EM-shower.
Definition: JPDF.hh:1874
double getScatteredLightFromEMshowers(const double R_m, const double theta, const double phi, const double t_ns) const
Probability density function for scattered light from EM-showers.
Definition: JPDF.hh:730
virtual double getDispersionGroup(const double lambda) const =0
Dispersion of light for group velocity.
static const JGeaneWater gWater
Function object for energy loss of muon in sea water.
Definition: JGeane.hh:381
JPDF_C(const double Apmt, double(*pF_qe)(const double), double(*pF_pmt)(const double), double(*pF_l_abs)(const double), double(*pF_ls)(const double), double(*pF_ps)(const double), const double P_atm, const double Wmin, const double Wmax, const int numberOfPoints=20, const double epsilon=1e-12)
Constructor.
Definition: JPDF.hh:2202
virtual ~JPDF()
Virtual destructor.
Definition: JPDF.hh:316
direct light from bright point
Definition: JPDFTypes.hh:42
virtual double getPhotocathodeArea() const override
Photo-cathode area of PMT.
Definition: JPDF.hh:2234
virtual double getQE(const double lambda) const override
Quantum efficiency of PMT (incl.
Definition: JPDF.hh:2246
V(JDAQEvent-JTriggerReprocessor)*1.0/(JDAQEvent+1.0e-10)
static const JGeant geant(geanx, 0.0001)
Function object for the number of photons from EM-shower as a function of emission angle...
direct light from muon
Definition: JPDFTypes.hh:26
double getScatteredLightFromMuon(const double R_m, const double theta, const double phi, const double t_ns) const
Probability density function for scattered light from muon.
Definition: JPDF.hh:496
JAbstractPDF(const double P_atm, const double Wmin, const double Wmax, const int numberOfPoints=20, const double epsilon=1e-12)
Constructor.
Definition: JPDF.hh:2168
PMT interface.
Definition: JAbstractPMT.hh:17
Numbering scheme for PDF types.
double operator[](const int i) const
Get result by index.
Definition: JPDF.hh:2009
Auxiliary class to find solution(s) to of the square root expression: where is the index of refrac...
Definition: JPDF.hh:1971
Type definition of a 1st degree polynomial interpolation based on a JGridCollection with result type ...
double getLightFromBrightPoint(const double D_m, const double ct, const double t_ns) const
Probability density function for direct light from isotropic light source.
Definition: JPDF.hh:1955
static const double C
Physics constants.
const JPolynome f1(1.0, 2.0, 3.0)
Function.
double getLightFromEMshower(const double E_GeV, const double D_m, const double cd, const double theta, const double phi, const double t_ns) const
Probability density function for light from EM-shower.
Definition: JPDF.hh:1907
const int n
Definition: JPolint.hh:676
std::vector< element_type > phd
fast evaluation of phi integral
Definition: JPDF.hh:2146
scattered light from muon
Definition: JPDFTypes.hh:27
static double MODULE_RADIUS_M
Radius of optical module [m].
Definition: JPDF.hh:40
Compiler version dependent expressions, macros, etc.
double(* pmt)(const double ct)
Angular acceptance of PMT.
Definition: JPDF.hh:2336
double(* l_abs)(const double lambda)
Absorption length.
Definition: JPDF.hh:2320
double getDirectLightFromEMshower(const double E, const double D_m, const double cd, const double theta, const double phi, const double t_ns) const
Probability density function for direct light from EM-shower.
Definition: JPDF.hh:1198
virtual double getScatteringLength(const double lambda) const =0
Scattering length.
static const JGeanz geanz(1.85, 0.62, 0.54)
Function object for longitudinal EM-shower profile.
Probability Density Functions of the time response of a PMT with an implementation of the JAbstractPM...
Definition: JPDF.hh:2183
scattered light from delta-rays
Definition: JPDFTypes.hh:33
virtual double getAbsorptionLength(const double lambda) const =0
Absorption length.
Physics constants.
direct light from EM shower
Definition: JPDFTypes.hh:37
virtual double getWavelength(const double n, const double eps=1.0e-10) const
Determine wavelength for a given index of refraction corresponding to the group velocity.
Definition: JPDF.hh:2038
static const double PI
Mathematical constants.
scattered light from EM showers
Definition: JPDFTypes.hh:30
virtual double getIndexOfRefractionPhase(const double lambda) const =0
Index of refraction for phase velocity.
double getDirectLightFromDeltaRays(const double R_m, const double theta, const double phi, const double t_ns) const
Probability density function for direct light from delta-rays.
Definition: JPDF.hh:1375
virtual double getPhotocathodeArea() const =0
Photo-cathode area of PMT.
then usage $script[distance] fi case set_variable R
Definition: JDrawLED.sh:43
scattered light from bright point
Definition: JPDFTypes.hh:43
bool is_valid
validity of solutions
Definition: JPDF.hh:2024
double(* ps)(const double ct)
Model specific function to describe light scattering in water.
Definition: JPDF.hh:2344
direct light from delta-rays
Definition: JPDFTypes.hh:32
static double getRmin()
minimal distance of approach of muon to PMT [m]
Definition: JPDF.hh:2099
const double wmax
maximal wavelength for integration [nm]
Definition: JPDF.hh:2144
double cherenkov(const double lambda, const double n)
Number of Cherenkov photons per unit track length and per unit wavelength.
Definition: JPDFToolkit.hh:50
const double xmin
Definition: JQuadrature.cc:23
Auxiliary classes for numerical integration.
virtual double getIndexOfRefractionGroup(const double lambda) const
Index of refraction for group velocity.
double getIntegral(const double E, const double z) const
Integral of PDF (starting from 0).
Definition: JGeanz.hh:95
then JMuonMCEvt f $INPUT_FILE o $INTERMEDIATE_FILE d
Definition: JMuonPath.sh:47
then JCalibrateToT a
Definition: JTuneHV.sh:116
virtual double getWavelength(const double n, const double w, const double eps) const
Determine wavelength for a given index of refraction corresponding to the group velocity.
Definition: JPDF.hh:2076
virtual double getInverseAttenuationLength(const double l_abs, const double ls, const double cts) const
Get the inverse of the attenuation length.
Definition: JPDF.hh:2110
double getScatteredLightFromBrightPoint(const double D_m, const double ct, const double t_ns) const
Probability density function for scattered light from isotropic light source.
Definition: JPDF.hh:1651
int numberOfPoints
Definition: JResultPDF.cc:22
const double wmin
Integration limits.
Definition: JPDF.hh:2143
double getDirectLightFromBrightPoint(const double D_m, const double ct, const double t_ns) const
Probability density function for direct light from isotropic light source.
Definition: JPDF.hh:1607
double getDeltaRaysFromMuon(const double E)
Equivalent EM-shower energy due to delta-rays per unit muon track length.
Definition: JPDFToolkit.hh:67
virtual double getAngularAcceptance(const double ct) const =0
Angular acceptence of PMT.
double getScatteredLightFromDeltaRays(const double R_m, const double theta, const double phi, const double t_ns) const
Probability density function for direct light from delta-rays.
Definition: JPDF.hh:1461
2D Element.
Definition: JElement.hh:46
then cp
double getDeltaRayProbability(const double x)
Emission profile of photons from delta-rays.
Definition: JPDFToolkit.hh:123
double getTanThetaC()
Get average tangent of Cherenkov angle of water corresponding to group velocity.
double getScatteredLightFromMuon(const double D_m, const double cd, const double theta, const double phi, const double t_ns) const
Probability density function for scattered light from muon.
Definition: JPDF.hh:878
do set_variable MODULE getModule a $WORKDIR detector_a datx L $STRING JEditDetector a $WORKDIR detector_a datx M $MODULE setz o $WORKDIR detector_a datx JEditDetector a $WORKDIR detector_b datx M $MODULE setz o $WORKDIR detector_b datx done echo Output stored at $WORKDIR detector_a datx and $WORKDIR tripod_a txt JDrawDetector2D a $WORKDIR detector_a datx a $WORKDIR detector_b datx L BL o detector $FORMAT $BATCH JDrawDetector2D T $WORKDIR tripod_a txt T $WORKDIR tripod_b txt L BL o tripod $FORMAT $BATCH JCompareDetector a $WORKDIR detector_a datx b $WORKDIR detector_b datx o $WORKDIR abc root &dev null for KEY in X Y Z
container_type::const_iterator const_iterator
Definition: JCollection.hh:91
int j
Definition: JPolint.hh:682
virtual double getScatteringProbability(const double ct) const override
Model specific function to describe light scattering in water (integral over full solid angle normali...
Definition: JPDF.hh:2295
$WORKDIR ev_configure_domsimulator txt echo process $DOM_SIMULATOR $i $SOURCE_HOST[$index] csh c(setenv ROOTSYS $ROOTSYS &&source $JPP_DIR/setenv.csh $JPP_DIR &&($DOM_SIMULATOR\-u\$NAME\$\-H\$SERVER\$\-M\$LOGGER\$\-d $DEBUG</dev/null > &/dev/null &))'
double getLightFromEMshower(const int type, const double D_m, const double cd, const double theta, const double phi, const double t_ns) const
Probability density function for light from EM-shower.
Definition: JPDF.hh:1820
Longitudinal emission profile EM-shower.
double getLightFromEMshower(const double D_m, const double cd, const double theta, const double phi, const double t_ns) const
Probability density function for light from EM-shower.
Definition: JPDF.hh:1851
double getLength(const double E, const double P, const double eps=1.0e-3) const
Get shower length for a given integrated probability.
Definition: JGeanz.hh:122
virtual double getQE(const double lambda) const =0
Quantum efficiency of PMT (incl.
double getDirectLightFromEMshowers(const double R_m, const double theta, const double phi, const double t_ns) const
Probability density function for direct light from EM-showers.
Definition: JPDF.hh:642
data_type v[N+1][M+1]
Definition: JPolint.hh:756
double u[N+1]
Definition: JPolint.hh:755
double getLightFromBrightPoint(const int type, const double D_m, const double ct, const double t_ns) const
Probability density function for direct light from isotropic light source.
Definition: JPDF.hh:1928
Light dispersion inteface.
source $JPP_DIR setenv csh $JPP_DIR &dev null eval JShellParser o a A
virtual double getScatteringLength(const double lambda) const override
Scattering length.
Definition: JPDF.hh:2282
double getDirectLightFromMuon(const double R_m, const double theta, const double phi, const double t_ns) const
Probability density function for direct light from muon.
Definition: JPDF.hh:407
do echo Generating $dir eval D
Definition: JDrawLED.sh:53
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable STRING $argv[2] set_array QUANTILES set_variable FORMULA *[0] exp(-0.5 *(x-[1])*(x-[1])/([2]*[2]))" set_variable MODULE `getModule -a $DETECTOR -L "$STRING 0"` source JAcousticsToolkit.sh typeset -A TRIPODS get_tripods $WORKDIR/tripod.txt TRIPODS XMEAN
virtual double getDispersionPhase(const double lambda) const =0
Dispersion of light for phase velocity.
const double epsilon
Definition: JQuadrature.cc:21
virtual double getScatteringProbability(const double ct) const =0
Model specific function to describe light scattering in water (integral over full solid angle normali...
double first
most upstream solution
Definition: JPDF.hh:2025
JPDF(const double Wmin, const double Wmax, const int numberOfPoints=20, const double epsilon=1e-12)
Constructor.
Definition: JPDF.hh:295
double(* qe)(const double lambda)
Quantum efficiency of PMT (incl.
Definition: JPDF.hh:2312
const double A
photo-cathode area [m2]
Definition: JPDF.hh:2304
virtual double getAngularAcceptance(const double ct) const override
Angular acceptance of PMT.
Definition: JPDF.hh:2258
Low level interface for the calculation of the Probability Density Functions (PDFs) of the arrival ti...
Definition: JPDF.hh:277