1 #ifndef __JPHYSICS__JPDF__
2 #define __JPHYSICS__JPDF__
297 const double epsilon = 1e-12) :
306 for (
double x = 0.5*dx; x <
PI; x += dx) {
328 const double xmin = 1.0 /
wmax;
329 const double xmax = 1.0 /
wmin;
333 const double x = 0.5 * (xmax + xmin) + i->getX() * 0.5 * (xmax - xmin);
334 const double dx = i->getY() * 0.5 * (xmax - xmin);
336 const double w = 1.0 / x;
337 const double dw = dx *
w*
w;
358 const double phi)
const
364 const double R = std::max(R_m,
getRmin());
367 const double px = sin(theta)*cos(phi);
368 const double pz = cos(theta);
373 const double dw = m->getY() * 0.5 * (
wmax -
wmin);
382 const double ct0 = 1.0 /
n;
383 const double st0 = sqrt((1.0 + ct0)*(1.0 - ct0));
385 const double d = R / st0;
386 const double ct = st0*px + ct0*pz;
389 const double V = exp(-d/l_abs) * exp(-d/ls);
390 const double W = A / (2.0*
PI*R*st0);
392 value += npe * U * V * W;
411 const double t_ns)
const
415 static const int N = 100;
416 static const double eps = 1.0e-6;
418 const double R = std::max(R_m,
getRmin());
420 const double a =
C*t/R;
423 const double px = sin(theta)*cos(phi);
424 const double pz = cos(theta);
428 for (
double buffer[] = {
wmin,
wmax, 0.0 }, *p = buffer; *p != 0.0; ++p) {
433 const double ct0 = 1.0 /
n;
434 const double st0 = sqrt((1.0 + ct0)*(1.0 - ct0));
436 const double b = (ng - ct0) / st0;
438 if (*p ==
wmin && b < a) {
return 0.0; }
439 if (*p ==
wmax && b > a) {
return 0.0; }
446 for (
int i = 0; i != N; ++i) {
448 const double w = 0.5 * (umin + umax);
453 const double ct0 = 1.0 /
n;
454 const double st0 = sqrt((1.0 + ct0)*(1.0 - ct0));
456 const double b = (ng - ct0) / st0;
458 if (fabs(b-a) < a*eps) {
466 const double d = R / st0;
467 const double ct = st0*px + ct0*pz;
469 const double i3 = ct0*ct0*ct0 / (st0*st0*st0);
472 const double V = exp(-d/l_abs - d/ls);
473 const double W = A / (2.0*
PI*R*st0);
475 const double Ja = R * (ngp/st0 + np*(
n-ng)*i3) /
C;
502 const double t_ns)
const
506 static const double eps = 1.0e-10;
510 const double R = std::max(R_m,
getRmin());
514 const double px = sin(theta)*cos(phi);
515 const double py = sin(theta)*sin(phi);
516 const double pz = cos(theta);
520 const double ni = sqrt(R*R +
C*t*
C*t) / R;
522 if (n0 >= ni)
return value;
524 const double nj = std::min(ni,n1);
530 const double ng = 0.5 * (nj + n0) + i->getX() * 0.5 * (nj - n0);
531 const double dn = i->getY() * 0.5 * (nj - n0);
544 if (npe <= 0) {
continue; }
546 const double Jc = 1.0 / ls;
548 const double ct0 = 1.0 /
n;
549 const double st0 = sqrt((1.0 + ct0)*(1.0 - ct0));
555 const double zmin = rz.
first;
556 const double zmax = rz.
second;
558 const double zap = 1.0 / l_abs;
560 const double xmin = exp(zap*zmax);
561 const double xmax = exp(zap*zmin);
565 const double x = 0.5 * (xmax + xmin) +
j->getX() * 0.5 * (xmax - xmin);
566 const double dx =
j->getY() * 0.5 * (xmax - xmin);
568 const double z = log(x) / zap;
569 const double dz = -dx / (zap*x);
571 const double D = sqrt(z*z + R*R);
572 const double cd = -z / D;
573 const double sd = R / D;
575 const double d = (
C*t - z) / ng;
579 const double cta = cd*ct0 + sd*st0;
580 const double dca = d - 0.5*(d+D)*(d-D) / (d - D*cta);
581 const double tip = -log(D*D/(dca*dca) + eps) /
PI;
583 const double ymin = exp(tip*
PI);
584 const double ymax = 1.0;
588 const double y = 0.5 * (ymax + ymin) + k->getX() * 0.5 * (ymax - ymin);
589 const double dy = k->getY() * 0.5 * (ymax - ymin);
591 const double phi = log(y) / tip;
592 const double dp = -dy / (tip*y);
594 const double cp0 = cos(phi);
595 const double sp0 = sin(phi);
597 const double u = (R*R + z*z - d*d) / (2*R*st0*cp0 - 2*z*ct0 - 2*d);
598 const double v = d -
u;
600 if (
u <= 0) {
continue; }
601 if (
v <= 0) {
continue; }
603 const double vi = 1.0 /
v;
604 const double cts = (R*st0*cp0 - z*ct0 -
u)*vi;
608 if (cts < 0.0 &&
v * sqrt((1.0 + cts) * (1.0 - cts)) <
MODULE_RADIUS_M) {
continue; }
610 const double vx = R -
u*st0*cp0;
611 const double vy = -
u*st0*sp0;
612 const double vz = -z -
u*ct0;
614 const double ct[] = {
615 (vx*px + vy*py + vz*pz) * vi,
616 (vx*px - vy*py + vz*pz) * vi
622 const double W = std::min(A*vi*vi, 2.0*
PI);
625 const double Jd = ng * (1.0 - cts) /
C;
627 value += (npe * dz * dp / (2*
PI)) * U * V * W * Ja * Jc / fabs(Jd);
648 const double t_ns)
const
654 const double R = std::max(R_m,
getRmin());
657 const double D = 2.0*sqrt(A/
PI);
659 const double px = sin(theta)*cos(phi);
661 const double pz = cos(theta);
665 const double ni = sqrt(R*R +
C*t*
C*t) / R;
667 if (n0 >= ni)
return value;
669 const double nj = std::min(n1, ni);
675 const double ng = 0.5 * (nj + n0) + i->getX() * 0.5 * (nj - n0);
676 const double dn = i->getY() * 0.5 * (nj - n0);
693 for (
int j = 0;
j != 2; ++
j) {
695 const double z = rz[
j];
697 if (
C*t <= z)
continue;
699 const double d = sqrt(z*z + R*R);
701 const double ct0 = -z / d;
702 const double st0 = R / d;
704 const double dz = D / st0;
706 const double ct = st0*px + ct0*pz;
709 const double V = exp(-d/l_abs - d/ls);
710 const double W = A/(d*d);
712 const double Ja =
geant(
n,ct0);
713 const double Jd = (1.0 - ng*ct0) /
C;
714 const double Je = ng*st0*st0*st0 / (R*
C);
716 value +=
gWater() * npe * U * V * W * Ja / (fabs(Jd) + 0.5*Je*dz);
736 const double t_ns)
const
742 const double R = std::max(R_m,
getRmin());
746 const double px = sin(theta)*cos(phi);
747 const double py = sin(theta)*sin(phi);
748 const double pz = cos(theta);
752 const double ni = sqrt(R*R +
C*t*
C*t) / R;
754 if (n0 >= ni)
return value;
756 const double nj = std::min(ni,n1);
762 const double ng = 0.5 * (nj + n0) + i->getX() * 0.5 * (nj - n0);
763 const double dn = i->getY() * 0.5 * (nj - n0);
776 if (npe <= 0) {
continue; }
778 const double Jc = 1.0 / ls;
784 const double zmin = rz.
first;
785 const double zmax = rz.
second;
787 const double zap = 1.0 / l_abs;
789 const double xmin = exp(zap*zmax);
790 const double xmax = exp(zap*zmin);
794 const double x = 0.5 * (xmax + xmin) +
j->getX() * 0.5 * (xmax - xmin);
795 const double dx =
j->getY() * 0.5 * (xmax - xmin);
797 const double z = log(x) / zap;
798 const double dz = -dx / (zap*x);
800 const double D = sqrt(z*z + R*R);
801 const double cd = -z / D;
802 const double sd = R / D;
804 const double qx = cd*px + 0 - sd*pz;
805 const double qy = 1*py;
806 const double qz = sd*px + 0 + cd*pz;
808 const double d = (
C*t - z) / ng;
812 const double ds = 2.0 / (size() + 1);
814 for (
double sb = 0.5*ds; sb < 1.0 - 0.25*ds; sb += ds) {
816 for (
int buffer[] = { -1, +1, 0}, *k = buffer; *k != 0; ++k) {
818 const double cb = (*k) * sqrt((1.0 + sb)*(1.0 - sb));
819 const double dcb = (*k) * ds*sb/cb;
821 const double v = 0.5 * (d + D) * (d - D) / (d - D*cb);
822 const double u = d -
v;
824 if (
u <= 0) {
continue; }
825 if (
v <= 0) {
continue; }
827 const double cts = (D*cb -
v) /
u;
831 if (cts < 0.0 &&
v * sqrt((1.0 + cts) * (1.0 - cts)) <
MODULE_RADIUS_M) {
continue; }
833 const double W = std::min(A/(
v*
v), 2.0*
PI);
835 const double Jd = ng * (1.0 - cts) /
C;
837 const double ca = (D -
v*cb) /
u;
838 const double sa =
v*sb /
u;
840 const double dp =
PI /
phd.size();
841 const double dom = dcb*dp *
v*
v / (
u*
u);
845 const double cp = l->getX();
846 const double sp = l->getY();
848 const double ct0 = cd*ca - sd*sa*cp;
850 const double vx = sb*cp * qx;
851 const double vy = sb*sp * qy;
852 const double vz = cb * qz;
858 const double Jb =
geant(
n,ct0);
860 value += dom *
gWater() * npe * dz * U * V * W * Ja * Jb * Jc / fabs(Jd);
885 const double t_ns)
const
889 static const double eps = 1.0e-10;
893 const double sd = sqrt((1.0 + cd)*(1.0 - cd));
894 const double D = std::max(D_m,
getRmin());
895 const double R = sd * D;
896 const double Z = -cd * D;
901 const double px = sin(theta)*cos(phi);
902 const double py = sin(theta)*sin(phi);
903 const double pz = cos(theta);
908 const double ni =
C*t / L;
914 const double nj = std::min(ni,n1);
920 const double ng = 0.5 * (nj + n0) + i->getX() * 0.5 * (nj - n0);
921 const double dn = i->getY() * 0.5 * (nj - n0);
934 if (npe <= 0) {
continue; }
936 const double Jc = 1.0 / ls;
938 const double ct0 = 1.0 /
n;
939 const double st0 = sqrt((1.0 + ct0)*(1.0 - ct0));
941 const double d =
C*t / ng;
945 const double cta = cd*ct0 + sd*st0;
946 const double dca = d - 0.5*(d+L)*(d-L) / (d - L*cta);
947 const double tip = -log(L*L/(dca*dca) + eps) /
PI;
949 const double ymin = exp(tip*
PI);
950 const double ymax = 1.0;
954 const double y = 0.5 * (ymax + ymin) +
j->getX() * 0.5 * (ymax - ymin);
955 const double dy =
j->getY() * 0.5 * (ymax - ymin);
957 const double phi = log(y) / tip;
958 const double dp = -dy / (tip*y);
960 const double cp0 = cos(phi);
961 const double sp0 = sin(phi);
963 const double u = (R*R + Z*Z - d*d) / (2*R*st0*cp0 - 2*Z*ct0 - 2*d);
964 const double v = d -
u;
966 if (
u <= 0) {
continue; }
967 if (
v <= 0) {
continue; }
969 const double vi = 1.0 /
v;
970 const double cts = (R*st0*cp0 - Z*ct0 -
u)*vi;
974 if (cts < 0.0 &&
v * sqrt((1.0 + cts) * (1.0 - cts)) <
MODULE_RADIUS_M) {
continue; }
976 const double vx = R -
u*st0*cp0;
977 const double vy = -
u*st0*sp0;
978 const double vz = -Z -
u*ct0;
980 const double ct[] = {
981 (vx*px + vy*py + vz*pz) * vi,
982 (vx*px - vy*py + vz*pz) * vi
988 const double W = std::min(A*vi*vi, 2.0*
PI);
991 const double Jd = ng * (1.0 - cts) /
C;
993 value += (npe * dp / (2*
PI)) * U * V * W * Ja * Jc / fabs(Jd);
1015 const double t_ns)
const
1019 const double ct0 = cd;
1020 const double st0 = sqrt((1.0 + ct0)*(1.0 - ct0));
1022 const double D = std::max(D_m,
getRmin());
1026 const double px = sin(theta)*cos(phi);
1027 const double pz = cos(theta);
1031 const double ng =
C*t/D;
1033 if (n0 >= ng) {
return 0.0; }
1034 if (n1 <= ng) {
return 0.0; }
1044 const double ct = st0*px + ct0*pz;
1047 const double V = exp(-D/l_abs - D/ls);
1048 const double W = A/(D*D);
1052 const double Ja = D * ngp /
C;
1053 const double Jb =
geant(
n,ct0);
1055 return npe *
geanc() * U * V * W * Jb / fabs(Ja);
1073 const double t_ns)
const
1079 const double sd = sqrt((1.0 + cd)*(1.0 - cd));
1080 const double D = std::max(D_m,
getRmin());
1086 const double px = sin(theta)*cos(phi);
1087 const double py = sin(theta)*sin(phi);
1088 const double pz = cos(theta);
1090 const double qx = cd*px + 0 - sd*pz;
1091 const double qy = 1*py;
1092 const double qz = sd*px + 0 + cd*pz;
1097 const double ni =
C*t / L;
1103 const double nj = std::min(ni,n1);
1109 const double ng = 0.5 * (nj + n0) + i->getX() * 0.5 * (nj - n0);
1110 const double dn = i->getY() * 0.5 * (nj - n0);
1123 if (npe <= 0) {
continue; }
1125 const double Jc = 1.0 / ls;
1127 const double d =
C*t / ng;
1131 const double ds = 2.0 / (size() + 1);
1133 for (
double sb = 0.5*ds; sb < 1.0 - 0.25*ds; sb += ds) {
1135 for (
int buffer[] = { -1, +1, 0}, *k = buffer; *k != 0; ++k) {
1137 const double cb = (*k) * sqrt((1.0 + sb)*(1.0 - sb));
1138 const double dcb = (*k) * ds*sb/cb;
1140 const double v = 0.5 * (d + L) * (d - L) / (d - L*cb);
1141 const double u = d -
v;
1143 if (
u <= 0) {
continue; }
1144 if (
v <= 0) {
continue; }
1146 const double cts = (L*cb -
v) /
u;
1150 if (cts < 0.0 &&
v * sqrt((1.0 + cts) * (1.0 - cts)) <
MODULE_RADIUS_M) {
continue; }
1152 const double W = std::min(A/(
v*
v), 2.0*
PI);
1154 const double Jd = ng * (1.0 - cts) /
C;
1156 const double ca = (L -
v*cb) /
u;
1157 const double sa =
v*sb /
u;
1159 const double dp =
PI /
phd.size();
1160 const double dom = dcb*dp *
v*
v / (
u*
u);
1161 const double dos = sqrt(dom);
1165 const double cp = l->getX();
1166 const double sp = l->getY();
1168 const double ct0 = cd*ca - sd*sa*cp;
1170 const double vx = -sb*cp * qx;
1171 const double vy = -sb*sp * qy;
1172 const double vz = cb * qz;
1182 const double Jb =
geant(
n,
1186 value += npe *
geanc() * dos * U * V * W * Ja * Jb * Jc / fabs(Jd);
1212 const double t_ns)
const
1218 const double sd = sqrt((1.0 + cd)*(1.0 - cd));
1219 const double D = std::max(D_m,
getRmin());
1220 const double R = D * sd;
1221 const double Z = -D * cd;
1230 const double d = sqrt((Z+zmax)*(Z+zmax) + R*R);
1232 if (
C*t > std::max(n1*D, zmax + n1*d)) {
1238 JRoot rz(R, n0, t + Z/
C);
1250 JRoot rz(R, n1, t + Z/
C);
1260 if (
C*t < zmax + n0*d) {
1262 JRoot rz(R, n0, t + Z/
C);
1280 const double dy = (ymax - ymin) / size();
1282 if (dy > 2*std::numeric_limits<double>::epsilon()) {
1284 for (
double y = ymin + 0.5*dy; y < ymax; y += dy) {
1287 const double d = sqrt(R*R + z*z);
1316 const double t_ns)
const
1322 const double sd = sqrt((1.0 + cd)*(1.0 - cd));
1323 const double D = std::max(D_m,
getRmin());
1324 const double R = D * sd;
1325 const double Z = -D * cd;
1333 const double d = sqrt((Z+zmax)*(Z+zmax) + R*R);
1337 JRoot rz(R, n0, t + Z/
C);
1347 if (
C*t < zmax + n0*d) {
1349 JRoot rz(R, n0, t + Z/
C);
1361 const double dy = (ymax - ymin) / size();
1363 if (dy > 2*std::numeric_limits<double>::epsilon()) {
1365 for (
double y = ymin + 0.5*dy; y < ymax; y += dy) {
1368 const double d = sqrt(R*R + z*z);
1391 const double t_ns)
const
1397 const double R = std::max(R_m,
getRmin());
1400 const double D = 2.0*sqrt(A/
PI);
1402 const double px = sin(theta)*cos(phi);
1403 const double pz = cos(theta);
1407 const double ni = sqrt(R*R +
C*t*
C*t) / R;
1409 if (n0 >= ni)
return value;
1411 const double nj = std::min(n1, ni);
1417 const double ng = 0.5 * (nj + n0) + i->getX() * 0.5 * (nj - n0);
1418 const double dn = i->getY() * 0.5 * (nj - n0);
1435 for (
int j = 0;
j != 2; ++
j) {
1437 const double z = rz[
j];
1439 if (
C*t <= z)
continue;
1441 const double d = sqrt(z*z + R*R);
1443 const double ct0 = -z / d;
1444 const double st0 = R / d;
1446 const double dz = D / st0;
1447 const double ct = st0*px + ct0*pz;
1450 const double V = exp(-d/l_abs - d/ls);
1451 const double W = A/(d*d);
1453 const double Ja = 1.0/(4*
PI);
1454 const double Jd = (1.0 - ng*ct0) /
C;
1455 const double Je = ng*st0*st0*st0 / (R*
C);
1457 value += npe *
geanc() * U * V * W * Ja / (fabs(Jd) + 0.5*Je*dz);
1477 const double t_ns)
const
1483 const double R = std::max(R_m,
getRmin());
1487 const double px = sin(theta)*cos(phi);
1488 const double py = sin(theta)*sin(phi);
1489 const double pz = cos(theta);
1493 const double ni = sqrt(R*R +
C*t*
C*t) / R;
1495 if (n0 >= ni)
return value;
1497 const double nj = std::min(ni,n1);
1503 const double ng = 0.5 * (nj + n0) + i->getX() * 0.5 * (nj - n0);
1504 const double dn = i->getY() * 0.5 * (nj - n0);
1517 if (npe <= 0) {
continue; }
1519 const double Jc = 1.0 / ls;
1525 const double zmin = rz.
first;
1526 const double zmax = rz.
second;
1528 const double zap = 1.0 / l_abs;
1530 const double xmin = exp(zap*zmax);
1531 const double xmax = exp(zap*zmin);
1535 const double x = 0.5 * (xmax + xmin) +
j->getX() * 0.5 * (xmax - xmin);
1536 const double dx =
j->getY() * 0.5 * (xmax - xmin);
1538 const double z = log(x) / zap;
1539 const double dz = -dx / (zap*x);
1541 const double D = sqrt(z*z + R*R);
1542 const double cd = -z / D;
1543 const double sd = R / D;
1545 const double qx = cd*px + 0 - sd*pz;
1546 const double qy = 1*py;
1547 const double qz = sd*px + 0 + cd*pz;
1549 const double d = (
C*t - z) / ng;
1553 const double ds = 2.0 / (size() + 1);
1555 for (
double sb = 0.5*ds; sb < 1.0 - 0.25*ds; sb += ds) {
1557 for (
int buffer[] = { -1, +1, 0}, *k = buffer; *k != 0; ++k) {
1559 const double cb = (*k) * sqrt((1.0 + sb)*(1.0 - sb));
1560 const double dcb = (*k) * ds*sb/cb;
1562 const double v = 0.5 * (d + D) * (d - D) / (d - D*cb);
1563 const double u = d -
v;
1565 if (
u <= 0) {
continue; }
1566 if (
v <= 0) {
continue; }
1568 const double cts = (D*cb -
v) /
u;
1572 if (cts < 0.0 &&
v * sqrt((1.0 + cts) * (1.0 - cts)) <
MODULE_RADIUS_M) {
continue; }
1574 const double W = std::min(A/(
v*
v), 2.0*
PI);
1576 const double Jd = ng * (1.0 - cts) /
C;
1578 const double dp =
PI /
phd.size();
1579 const double dom = dcb*dp *
v*
v / (
u*
u);
1583 const double cp = l->getX();
1584 const double sp = l->getY();
1586 const double vx = sb*cp * qx;
1587 const double vy = sb*sp * qy;
1588 const double vz = cb * qz;
1594 const double Jb = 1.0/(4*
PI);
1596 value += dom * npe *
geanc() * dz * U * V * W * Ja * Jb * Jc / fabs(Jd);
1623 const double t_ns)
const
1665 const double t_ns)
const
1692 const double t_ns)
const
1722 const double t_ns)
const
1747 const double t_ns)
const
1779 const double t_ns)
const
1811 const double a =
n*
n - 1.0;
1812 const double b = 2*
C*t;
1813 const double c = R*
n * R*
n -
C*t *
C*t;
1815 const double q = b*b - 4*a*c;
1819 first = (-b - sqrt(q)) / (2*a);
1820 second = (-b + sqrt(q)) / (2*a);
1844 throw JException(
"JRoot::operator[] invalid index");
1863 const double eps = 1.0e-10)
const
1870 for (
int i = 0; i != 1000; ++i) {
1872 const double v = 0.5 * (vmin + vmax);
1875 if (fabs(y -
n) < eps) {
1885 return 0.5 * (vmin + vmax);
1902 const double eps)
const
1912 if (fabs(y -
n) < eps) {
1940 const int nx = 100000;
1941 const double xmin = -1.0;
1942 const double xmax = +1.0;
1944 const double dx = (xmax - xmin) / (nx - 1);
1946 for (
double x = xmin, W = 0.0; x < xmax; x += dx) {
1959 return 1.0/l_abs + f1(cts)/ls;
1996 const double epsilon = 1e-12) :
2030 double (*pF_qe) (
const double),
2031 double (*pF_pmt) (
const double),
2032 double (*pF_l_abs)(
const double),
2033 double (*pF_ls) (
const double),
2034 double (*pF_ps) (
const double),
2042 const double epsilon = 1e-12) :
2070 virtual double getQE(
const double lambda)
const
2096 return l_abs(lambda);
2136 double (*qe)(
const double lambda);
2144 double (*l_abs)(
const double lambda);
2152 double (*ls)(
const double lambda);
2160 double (*pmt)(
const double ct);
2168 double (*ps)(
const double ct);