68 u = 2 * ((double) rand() / (RAND_MAX)) - 1;
69 v = 2 * ((double) rand() / (RAND_MAX)) - 1;
71 }
while (r > 1 || r == 0);
72 gauss = u * std::sqrt(-2 * std::log(r) / r);
73 return (mean + gauss * stddev);
121 mX1 = r * std::sin(th) * std::cos(Angle);
122 mX2 = r * std::sin(th) * std::sin(Angle);
129 mX1 = r * sin(Angle) * cos(ph);
130 mX2 = r * sin(Angle) * sin(ph);
131 mX3 = r * cos(Angle);
143 mX1 = r * sin(th) * cos(ph);
144 mX2 = r * sin(th) * sin(ph);
169 return std::atan2(
mX2,
mX1);
202 double tmp = std::tan(
theta() / 2.);
207 return -std::log(tmp);
240 return std::sqrt((*
this) * (*
this) + mass * mass);
246 if (tmp <= 0.) tmp = 1
e-20;
264 T yPrime = cos(Angle) *
mX2 - sin(Angle) *
mX3;
265 T zPrime = sin(Angle) *
mX2 + cos(Angle) *
mX3;
272 T zPrime = cos(Angle) *
mX3 - sin(Angle) *
mX1;
273 T xPrime = sin(Angle) *
mX3 + cos(Angle) *
mX1;
280 T xPrime = cos(Angle) *
mX1 - sin(Angle) *
mX2;
281 T yPrime = sin(Angle) *
mX1 + cos(Angle) *
mX2;
320 return norm > 0 ? std::acos(this->
dot(vec) / (std::sqrt(norm))) : 0;
348 return !(*
this ==
v);
374 for (
size_t i = 0; i < 3; i++)
452 mH = (q * B <= 0) ? 1 : -1;
453 if (p.
y() == 0 && p.
x() == 0)
518 return (B > 0 ? -
mH :
mH);
526 DCA2dPosition.
setZ(0);
533 momVec = this->
at(1) - this->
at(0);
542 T cross = DCAVec.
x() * momVec.
y() - DCAVec.
y() * momVec.
x();
543 T theSign = (cross >= 0) ? 1. : -1.;
544 return theSign * DCAVec.
perp();
559 T theSign = (sdca2d >= 0) ? 1. : -1.;
560 return (this->
distance(pos)) * theSign;
566 T theSign = (sdca2d >= 0) ? 1. : -1.;
567 return (this->
distance(pos)) * theSign;
572 mH = (h >= 0) ? 1 : -1;
655 std::pair<T, T>
value;
656 std::pair<T, T>
VALUE(999999999., 999999999.);
660 std::cerr <<
" singularity!" << std::endl;
671 t20 = std::sqrt(t20);
673 value.second = (t1 + t20) / (mCosDipAngle * mCosDipAngle);
694 T t38 = 8.0 * t4 * t6 - 4.0 * t1 * t2 * t8 - 4.0 * t11 * mCurvature * t6 +
695 4.0 * t15 * t6 + t17 * t3 + t19 * t3 + 2.0 * t21 * t8 + 4.0 * t8 * t23 -
696 4.0 * t8 *
mOrigin.x() * mCurvature * t5 - 4.0 * t11 * t23 -
697 4.0 * t11 *
mOrigin.y() * mCurvature * t2 + 4.0 * t11 - 4.0 * t14 +
698 t32 * t3 + 4.0 * t15 * t4 - 2.0 * t35 * t11 - 2.0 * t35 * t8;
705 t40 = std::sqrt(t40);
708 T t45 = 2.0 * t5 - t35 + t21 + 2.0 - 2.0 * t1 * t2 - 2.0 * t43 - 2.0 * t43 * t5 + t8 * t3;
711 value.first = (-
mPhase + 2.0 * std::atan((-2.0 * t1 + 2.0 * t2 + t40) / t45)) / t46;
712 value.second = -(
mPhase + 2.0 * std::atan((2.0 * t1 - 2.0 * t2 + t40) / t45)) / t46;
715 if (!std::isnan(value.first))
717 if (std::fabs(value.first - p) < std::fabs(value.first))
719 value.first = value.first -
p;
721 else if (std::fabs(value.first + p) < std::fabs(value.first))
723 value.first = value.first +
p;
728 std::cerr <<
"value.first = isnan" << std::endl;
731 if (!std::isnan(value.second))
733 if (std::fabs(value.second - p) < std::fabs(value.second))
735 value.second = value.second -
p;
737 else if (fabs(value.second + p) < fabs(value.second))
738 value.second = value.second +
p;
742 std::cerr <<
"value.second = isnan" << std::endl;
746 if (value.first > value.second)
781 const T MaxPrecisionNeeded = 0.0001;
782 const int MaxIterations = 100;
786 T t6, t7, t11, t12, t19;
795 for (j = 1; j < MaxIterations; j++)
797 if ((d =
abs(
at(s + j * ds) - p)) < dmin)
807 for (j = -1; - j < MaxIterations; j--)
809 if ((d =
abs(
at(s + j * ds) - p)) < dmin)
826 for (
int i = 0; i < MaxIterations; i++)
833 s -= (t11 * t12 *
mH * mCosDipAngle - t19 * t7 *
mH * mCosDipAngle -
835 (t12 * t12 * mCosDipAngle * mCosDipAngle + t11 * t7 * t34 +
836 t7 * t7 * mCosDipAngle * mCosDipAngle + t19 * t12 * t34 + t41);
837 if (std::fabs(sOld - s) < MaxPrecisionNeeded)
868 const T MaxPrecisionNeeded = 0.0001;
869 const int MaxIterations = 20;
879 const T angMax = 0.21;
880 T deltas = std::fabs(angMax / (
mCurvature * mCosDipAngle));
883 for (i = 0; i < MaxIterations; i++)
886 T sina = std::sin(a);
887 T cosa = std::cos(a);
888 f = A + n.
x() * cosa + n.
y() * sina + u *
s;
889 fp = -n.
x() * sina * t + n.
y() * cosa * t +
u;
890 if (std::fabs(fp) * deltas <= std::fabs(f))
901 shift = sgn * deltas;
913 if (std::fabs(sOld - s) < MaxPrecisionNeeded)
919 if (i == MaxIterations)
951 s2 = (k - ab *
g) / (ab * ab - 1.);
953 return std::pair<T, T>(
s1, s2);
959 T dd = std::sqrt(dx * dx + dy * dy);
961 T r2 = 1 /
h().curvature();
962 T cosAlpha = (r1 * r1 + dd * dd - r2 *
r2) / (2 * r1 * dd);
966 if (std::fabs(cosAlpha) < 1)
968 T sinAlpha = std::sin(std::acos(cosAlpha));
969 x =
xcenter() + r1 * (cosAlpha * dx - sinAlpha *
dy) / dd;
970 y =
ycenter() + r1 * (sinAlpha * dx + cosAlpha *
dy) / dd;
972 x =
xcenter() + r1 * (cosAlpha * dx + sinAlpha *
dy) / dd;
973 y =
ycenter() + r1 * (cosAlpha * dy - sinAlpha *
dx) / dd;
982 int rsign = ((r2 -
r1) > dd ? -1 : 1);
983 x =
xcenter() + rsign * r1 * dx / dd;
984 y =
ycenter() + rsign * r1 * dy / dd;
988 T dmin =
h().distance(
at(s));
991 T slast = -999999, ss,
d;
995 while (ds > minStepSize)
997 for (ss = s1; ss < s2 + ds; ss += ds)
999 d =
h().distance(
at(ss));
1009 d = 0.8 * (s2 -
s1);
1013 else if (s == slast)
1015 d = 0.8 * (s2 -
s1);
1026 return std::pair<T, T>(
s,
h().pathLength(
at(s)));
1056 return 3 + ierr * 100;
1188 Data(
const std::vector<std::vector<T>>& hits_)
1230 T sXX = 0., sYY = 0., scaling;
1234 sYY += hits[i][1] * hits[i][1];
1236 scaling = std::sqrt((sXX + sYY) / hits_size / 2.0);
1239 hits[i][0] /= scaling;
1240 hits[i][1] /= scaling;
1250 template <
typename T>
1283 return !std::isnan(
a) && !std::isnan(
b) && !std::isnan(
r) &&
1300 template <
typename T>
1304 :
a(std::numeric_limits<
T>::infinity())
1305 ,
b(std::numeric_limits<
T>::infinity())
1308 ,
chi2(std::numeric_limits<
T>::infinity())
1323 return !std::isnan(
a) && !std::isnan(
b) && !std::isnan(
chi2) &&
1333 template <
typename T>
1336 return std::fabs(std::sqrt(std::pow(x - circle->
a, 2) + std::pow(y - circle->
b, 2)) - circle->
r);
1339 template <
typename T>
1342 return std::fabs(std::sqrt(std::pow(x - a, 2) + std::pow(y - b, 2)) - r);
1345 template <
typename T>
1350 return std::fabs((b * x) + (-1 * y) + a) / std::sqrt(std::pow(b, 2) + std::pow(-1, 2));
1386 for (
size_t i = 0; i < data.
hits_size; i++)
1388 dx = data.
hits[i][0] - circle->
a;
1389 dy = data.
hits[i][1] - circle->
b;
1390 sum += std::pow(std::sqrt(
dx *
dx + dy * dy) - circle->
r, 2);
1398 for (
size_t i = 0; i < data.
hits_size; i++)
1400 dx = data.
hits[i][0] - circle->
a;
1401 dy = data.
hits[i][1] - circle->
b;
1402 sum += std::pow(std::sqrt(
dx *
dx + dy * dy) - circle->
r, 2);
1410 size_t i, iter, IterMAX = 99;
1413 T Mz, Mxy, Mxx, Myy, Mxz, Myz, Mzz, Cov_xy, Var_z;
1415 T Dy, xnew,
x, ynew,
y;
1416 T DET, Xcenter, Ycenter;
1419 circle->
a = std::numeric_limits<T>::infinity();
1420 circle->
b = std::numeric_limits<T>::infinity();
1421 circle->
r = std::numeric_limits<T>::infinity();
1428 Mxx = Myy = Mxy = Mxz = Myz = Mzz = 0.;
1434 Zi = Xi * Xi + Yi * Yi;
1450 Cov_xy = Mxx * Myy - Mxy * Mxy;
1451 Var_z = Mzz - Mz * Mz;
1453 A2 = 4.0 * Cov_xy - 3.0 * Mz * Mz - Mzz;
1454 A1 = Var_z * Mz + 4.0 * Cov_xy * Mz - Mxz * Mxz - Myz * Myz;
1455 A0 = Mxz * (Mxz * Myy - Myz * Mxy) + Myz * (Myz * Mxx - Mxz * Mxy) - Var_z * Cov_xy;
1458 for (x = 0., y = A0, iter = 0; iter < IterMAX; iter++)
1460 Dy = A1 + x * (A22 + 16. * x *
x);
1466 ynew = A0 + xnew * (A1 + xnew * (A2 + 4.0 * xnew * xnew));
1475 DET = x * x - x * Mz + Cov_xy;
1476 Xcenter = (Mxz * (Myy -
x) - Myz * Mxy) / DET / 2.0;
1477 Ycenter = (Myz * (Mxx -
x) - Mxz * Mxy) / DET / 2.0;
1479 circle->
a = Xcenter + data.
meanX;
1480 circle->
b = Ycenter + data.
meanY;
1481 circle->
r = std::sqrt(Xcenter * Xcenter + Ycenter * Ycenter + Mz - x - x);
1482 circle->
s =
Sigma(data, circle);
1492 size_t i, iter, IterMAX = 99;
1495 T Mz, Mxy, Mxx, Myy, Mxz, Myz, Mzz, Cov_xy, Var_z;
1497 T Dy, xnew,
x, ynew,
y;
1498 T DET, Xcenter, Ycenter;
1505 Mxx = Myy = Mxy = Mxz = Myz = Mzz = 0.;
1507 for (i = 0; i < data.hits_size; i++)
1509 Xi = data.hits[i][0] - data.meanX;
1510 Yi = data.hits[i][0] - data.meanY;
1511 Zi = Xi * Xi + Yi * Yi;
1520 Mxx /= data.hits_size;
1521 Myy /= data.hits_size;
1522 Mxy /= data.hits_size;
1523 Mxz /= data.hits_size;
1524 Myz /= data.hits_size;
1525 Mzz /= data.hits_size;
1528 Cov_xy = Mxx * Myy - Mxy * Mxy;
1529 Var_z = Mzz - Mz * Mz;
1531 A2 = -3.0 * Mz * Mz - Mzz;
1532 A1 = Var_z * Mz + 4.0 * Cov_xy * Mz - Mxz * Mxz - Myz * Myz;
1533 A0 = Mxz * (Mxz * Myy - Myz * Mxy) + Myz * (Myz * Mxx - Mxz * Mxy) - Var_z * Cov_xy;
1537 for (x = 0., y = A0, iter = 0; iter < IterMAX; iter++)
1539 Dy = A1 + x * (A22 + A33 *
x);
1545 ynew = A0 + xnew * (A1 + xnew * (A2 + xnew * A3));
1554 DET = x * x - x * Mz + Cov_xy;
1555 Xcenter = (Mxz * (Myy -
x) - Myz * Mxy) / DET / 2.0;
1556 Ycenter = (Myz * (Mxx -
x) - Mxz * Mxy) / DET / 2.0;
1558 circle->
a = Xcenter + data.meanX;
1559 circle->
b = Ycenter + data.meanY;
1560 circle->
r = std::sqrt(Xcenter * Xcenter + Ycenter * Ycenter + Mz);
1561 circle->
s =
Sigma(data, circle);
1571 size_t i, iter, IterMAX = 99;
1574 T Mz, Mxy, Mxx, Myy, Mxz, Myz, Mzz, Cov_xy, Var_z;
1576 T Dy, xnew,
x, ynew,
y;
1577 T DET, Xcenter, Ycenter;
1584 Mxx = Myy = Mxy = Mxz = Myz = Mzz = 0.;
1586 for (i = 0; i < data.hits_size; i++)
1588 Xi = data.hits[i][0] - data.meanX;
1589 Yi = data.hits[i][1] - data.meanY;
1590 Zi = Xi * Xi + Yi * Yi;
1599 Mxx /= data.hits_size;
1600 Myy /= data.hits_size;
1601 Mxy /= data.hits_size;
1602 Mxz /= data.hits_size;
1603 Myz /= data.hits_size;
1604 Mzz /= data.hits_size;
1607 Cov_xy = Mxx * Myy - Mxy * Mxy;
1608 Var_z = Mzz - Mz * Mz;
1610 A2 = 4.0 * Cov_xy - 3.0 * Mz * Mz - Mzz;
1611 A1 = Var_z * Mz + 4.0 * Cov_xy * Mz - Mxz * Mxz - Myz * Myz;
1612 A0 = Mxz * (Mxz * Myy - Myz * Mxy) + Myz * (Myz * Mxx - Mxz * Mxy) - Var_z * Cov_xy;
1615 for (x = 0., y = A0, iter = 0; iter < IterMAX; iter++)
1617 Dy = A1 + x * (A22 + 16. * x *
x);
1623 ynew = A0 + xnew * (A1 + xnew * (A2 + 4.0 * xnew * xnew));
1632 DET = x * x - x * Mz + Cov_xy;
1633 Xcenter = (Mxz * (Myy -
x) - Myz * Mxy) / DET / 2.0;
1634 Ycenter = (Myz * (Mxx -
x) - Mxz * Mxy) / DET / 2.0;
1636 circle->
a = Xcenter + data.meanX;
1637 circle->
b = Ycenter + data.meanY;
1638 circle->
r = std::sqrt(Xcenter * Xcenter + Ycenter * Ycenter + Mz + x + x);
1639 circle->
s =
Sigma(data, circle);
1651 return absa * std::sqrt(1.0 + std::pow(absb / absa, 2));
1653 return (absb == 0.0 ? 0.0 : absb * std::sqrt(1.0 + std::pow(absa / absb, 2)));
1659 for (
size_t i = 0; i < data.
hits_size; i++)
1661 dx = data.
hits[i][0] - circle.
a;
1662 dy = data.
hits[i][1] - circle.
b;
1663 Mr += std::sqrt(
dx *
dx + dy * dy);
1671 disc =
pythag(a - b, 2.0 * c);
1672 d1 = (a + b > 0.) ? (a + b + disc) / 2.0 : (a + b - disc) / 2.0;
1673 d2 = (a * b - c *
c) / d1;
1676 if ((f =
pythag(c, d1 - a)) == 0.)
1690 if ((f =
pythag(c, d1 - b)) == 0.)
1709 std::vector<T>
D(n);
1710 T LargeCircle = 10.0,
a0, b0, del,
s,
c,
x,
y,
z,
p,
t,
g, W,
Z;
1713 for (i = 0; i <
n; i++)
1715 dx = data.
hits[i][0] - circle.
a;
1716 dy = data.
hits[i][1] - circle.
b;
1717 D[i] = std::sqrt(
dx *
dx + dy * dy);
1721 for (sum = 0., i = 0; i <
n; i++)
1723 sum += std::pow(D[i] - r, 2);
1730 b0 = circle.
b - data.
meanY;
1731 del = 1.0 / std::sqrt(
a0 *
a0 + b0 * b0);
1734 for (W = Z = 0., i = 0; i <
n; i++)
1740 t = del * z - 2.0 *
p;
1741 g = t / (1.0 + std::sqrt(1.0 + del * t));
1742 W += (z + p *
g) / (2.0 + del * g);
1747 return Z - W * (2.0 + del * del * W);
1754 T LargeCircle = 10.0,
dx,
dy,
r,
u,
v, Mr, Mu, Mv, Muu, Mvv, Muv, Muur, Mvvr, Muvr;
1755 T a0, b0, del, dd,
s,
c,
x,
y,
a,
b,
z,
p,
t,
w,
g, g1, gg1, gg2;
1756 T X,
Y,
R, U, V, Tr, W, AA, BB, AB, AG, BG, GG, UUR, VVR, UVR;
1760 for (Mr = Mu = Mv = Muu = Mvv = Muv = Muur = Mvvr = Muvr = 0., i = 0; i <
n; i++)
1762 dx = data.
hits[i][0] - circle.
a;
1763 dy = data.
hits[i][1] - circle.
b;
1764 r = std::sqrt(
dx *
dx + dy * dy);
1787 F1 = circle.
a + Mu * Mr - data.
meanX;
1788 F2 = circle.
b + Mv * Mr - data.
meanY;
1790 A11 = 1.0 - Mu * Mu - Mr * Mvvr;
1791 A22 = 1.0 - Mv * Mv - Mr * Muur;
1792 A12 = -Mu * Mv + Mr * Muvr;
1796 a0 = circle.
a - data.
meanX;
1797 b0 = circle.
b - data.
meanY;
1798 del = 1.0 / std::sqrt(a0 * a0 + b0 * b0);
1802 for (X = Y = R = Tr = W = AA = BB = AB = AG = BG = GG = 0., i = 0; i <
n; i++)
1808 t = 2.0 * p - del *
z;
1809 w = std::sqrt(1.0 - del * t);
1811 g1 = 1.0 / (1.0 + del *
g);
1813 gg2 = g / (2.0 + del *
g);
1814 a = (x + g *
c) / w;
1815 b = (y + g *
s) / w;
1840 U = (Tr - del * W) * c / 2.0 - X + R * c / 2.0;
1841 V = (Tr - del * W) * s / 2.0 - Y + R * s / 2.0;
1843 F1 = del * ((dd * R * U - del * W * c + Tr *
c) / 2.0 - X);
1844 F2 = del * ((dd * R * V - del * W * s + Tr *
s) / 2.0 - Y);
1846 UUR = ((GG - R / 2.0) * c + 2.0 * (AG - U)) * c + AA;
1847 VVR = ((GG - R / 2.0) * s + 2.0 * (BG - V)) * s + BB;
1848 UVR = ((GG - R / 2.0) * c + (AG - U)) * s + (BG - V) * c + AB;
1850 A11 = dd * (U * (2.0 * c - dd * U) - R * s * s / 2.0 - VVR * (1.0 + dd * R / 2.0));
1851 A22 = dd * (V * (2.0 * s - dd * V) - R * c * c / 2.0 - UUR * (1.0 + dd * R / 2.0));
1852 A12 = dd * (U * s + V * c + R * s * c / 2.0 - dd * U * V + UVR * (1.0 + dd * R / 2.0));
1864 int i,
n = data.
hits_size, iter, inner, IterMAX = 200, check_line = 1,
code;
1867 T F1,
F2,
A11,
A22,
A12,
dX,
dY, Mxx, Myy, Mxy, Mxxy,
dx,
dy;
1868 T d1,
d2, dmin = 1.0, Vx, Vy, dL1, dL2, VLx = 0, VLy = 0, aL = 0, bL = 0,
R = 0, G1, G2, sBest, gBest, AB, progress;
1872 T factor1 = 32., factor2 = 32.;
1874 T factorUp = 10., factorDown = 0.1;
1887 New.
g = std::sqrt(F1 * F1 + F2 * F2);
1890 iter = inner =
code = 0;
1896 bool break_outer =
false;
1901 (std::pow(Old.
a, 2) + std::pow(Old.
b, 2) + 1.0);
1905 if (++iter > IterMAX)
1910 eigen2x2(A11, A22, A12, d1, d2, Vx, Vy);
1911 dmin = (d1 <
d2) ? d1 : d2;
1913 AB = std::sqrt(std::pow(Old.
a, 2) + std::pow(Old.
b, 2)) + 1.0;
1920 if ((Old.
s >= sBest) && (Old.
g >= gBest))
1934 G1 = Vx * F1 + Vy *
F2;
1935 G2 = Vx * F2 - Vy *
F1;
1940 if (lambda <
std::abs(G1) / AB / ccc - d1)
1944 if (lambda <
std::abs(G2) / AB / ccc - d2)
1949 dX = Old.
Gx * (Vx * Vx / (d1 +
lambda) + Vy * Vy / (d2 + lambda)) + Old.
Gy * Vx * Vy * (1.0 / (d1 + lambda) - 1.0 / (d2 +
lambda));
1950 dY = Old.
Gx * Vx * Vy * (1.0 / (d1 +
lambda) - 1.0 / (d2 + lambda)) + Old.
Gy * (Vx * Vx / (d2 + lambda) + Vy * Vy / (d1 +
lambda));
1955 if ((New.
a == Old.
a) && (New.
b == Old.
b))
1964 for (Mxx = Myy = Mxy = 0., i = 0; i <
n; i++)
1973 eigen2x2(Mxx, Myy, Mxy, dL1, dL2, VLx, VLy);
1975 for (Mxxy = 0., i = 0; i <
n; i++)
1979 Mxxy += dx * dx *
dy;
1982 R = (Mxxy > 0.) ? ParLimit2 : -ParLimit2;
1988 if ((New.
a * VLy - New.
b * VLx) *
R > 0.)
1996 New.
g = std::sqrt(F1 * F1 + F2 * F2);
2008 New.
g = std::sqrt(F1 * F1 + F2 * F2);
2012 lambda *= factorDown;
2017 if (++inner > IterMAX)
2022 lambda = factorUp *
lambda;
2039 circleIni->initFromCircle(&Old);
2040 circleIni->chi2 =
ChiSqr(data, circleIni);
2046 if (inner > IterMAX)
2050 if ((dmin <= 0.) && (
code == 0))
2069 size_t n =
hits.size();
2071 T ss, sx = 0., sy = 0., st2 = 0.,
t, sxoss, sigdat = 0.,
2072 a = 0.,
b = 0., siga = 0., sigb = 0., chi2 = 0.;
2073 for (
size_t i = 0; i <
n; i++)
2080 for (
size_t i = 0; i <
n; i++)
2082 t =
hits[i][0] - sxoss;
2084 b += t *
hits[i][1];
2087 a = (sy - sx *
b) / ss;
2088 siga = std::sqrt((1.0 + sx * sx / (ss * st2)) / ss);
2089 sigb = std::sqrt(1.0 / st2);
2090 for (
size_t i = 0; i <
n; i++)
2092 chi2 += std::pow(
hits[i][1] -
a -
b *
hits[i][0], 2);
2096 sigdat = std::sqrt(chi2 / (n - 2));
2101 chi2 = chi2 / (n - 2);
2111 size_t n =
hits.size();
2131 b2 = b +
SIGN(3.0 * sigb, f1);
2138 while (f1 * f2 > 0.0)
2140 b = b2 + 1.6 * (b2 - b1);
2149 b = b1 + 0.5 * (b2 - b1);
2150 if (b == b1 || b == b2)
break;
2166 line->sigb = sigb * 100.0;
2175 size_t n =
hits.size();
2179 std::vector<T> arr(n);
2180 for (j = 0; j <
n; j++)
2182 arr[j] =
hits[j][1] - b *
hits[j][0];
2186 a =
select((n - 1) >> 1, arr);
2194 for (j = 0; j <
n; j++)
2198 if (
hits[j][1] != 0.0)
2204 sum += (d >= 0.0 ?
hits[j][0] : -
hits[j][0]);
2211 int i, ir, j, l, mid,
n = arr.size();
2219 if (ir == l + 1 && arr[ir] < arr[l])
2221 SWAP(arr[l], arr[ir]);
2227 mid = (l + ir) >> 1;
2228 SWAP(arr[mid], arr[l + 1]);
2229 if (arr[l] > arr[ir])
2231 SWAP(arr[l], arr[ir]);
2233 if (arr[l + 1] > arr[ir])
2235 SWAP(arr[l + 1], arr[ir]);
2237 if (arr[l] > arr[l + 1])
2239 SWAP(arr[l], arr[l + 1]);
2249 }
while (arr[i] < a);
2253 }
while (arr[j] > a);
2258 SWAP(arr[i], arr[j]);
2260 arr[l + 1] = arr[j];
2275 static inline T SIGN(
const T&
a,
const T&
b) {
return b >= 0 ? (a >= 0 ? a : -
a) : (a >= 0 ? -a : a); }
2276 static inline float SIGN(
const float&
a,
const double&
b) {
return b >= 0 ? (a >= 0 ? a : -
a) : (a >= 0 ? -a : a); }
2277 static inline float SIGN(
const double&
a,
const float&
b) {
return (
float) (b >= 0 ? (a >= 0 ? a : -
a) : (a >= 0 ? -a : a)); }
2286 template <
typename T>
2289 std::vector<std::vector<T>>
pts;
2296 const T d0 = p1[0] -
pts[idx_p2][0];
2297 const T d1 = p1[1] - pts[idx_p2][1];
2298 const T d2 = p1[2] - pts[idx_p2][2];
2299 return d0 * d0 + d1 * d1 + d2 *
d2;
2310 template <
class BBOX>
2317 template <
typename T>
2342 size_t n =
hits.size();
2381 return mHits.size();
2391 return mHits.back();
2402 std::vector<std::vector<T>>().
swap(
mHits);
2418 return (s *
mB) < 0 ? -1. : 1;
2423 return std::sqrt(std::pow(
Pt(), 2) + std::pow(
Pl(), 2));
2428 return 0.3 * std::fabs(
mB) *
mCircle->r * 0.01;
2456 std::vector<T>& myHit =
mHits[i];
2458 T ptX = -pt * std::sin(phi);
2459 T ptY = +pt * std::cos(phi);
2462 std::vector<T>& myHitBefore =
mHits[i - 1];
2463 T difX = myHit[0] - myHitBefore[0];
2464 T difY = myHit[1] - myHitBefore[1];
2465 if ((ptX * difX + ptY * difY) < 0)
2471 else if (!
mHits.empty())
2473 std::vector<T>& myHitAfter =
mHits[1];
2474 T difX = myHitAfter[0] - myHit[0];
2475 T difY = myHitAfter[1] - myHit[1];
2476 if ((ptX * difX + ptY * difY) < 0)
2482 std::vector<T> result(3);
2494 std::vector<T> result(3);
2516 length = helix.pathLength(
TVector<T>(oL[0], oL[1], oL[2]),
false);
2520 for (
size_t i = 1, ilen =
mHits.size(); i < ilen; i++)
2522 length += std::sqrt(std::pow(
mHits[i][0] -
mHits[i - 1][0], 2) +
2567 return std::cos(std::atan(
mLine->b));
2572 return DistanceToCircle<T>(
mCircle,
x,
y);
2577 return DistanceToCircle<T>(
mCircle, hit[0], hit[1]);
2586 std::vector<std::vector<T>>&
hits = candidate->
getHits();
2595 std::vector<std::vector<T>>&
hits = candidate->
getHits();
2605 std::cout <<
"--- track params ---" << std::endl;
2612 std::cout <<
" xy fit either not done or failed" << std::endl;
2616 std::cout <<
" z0: " <<
mLine->a <<
", tanl: " <<
mLine->b <<
", sig_z0: " <<
mLine->siga <<
", sig_tanl: " <<
mLine->sigb <<
", chi2: " <<
mLine->chi2 << std::endl;
2620 std::cout <<
" sz fit either not done or failed" << std::endl;
2624 std::cout <<
" Length: " <<
approxLength() <<
", Pt: " <<
Pt() <<
", Pl: " <<
Pl() <<
", mom: " <<
momentum() << std::endl;
2630 std::cout <<
"--- xy track params ---" << std::endl;
2632 for (
size_t i = 0; i <
mHits.size(); i++)
2634 std::cout << i <<
"-th hit, x: " <<
mHits[i][0] <<
", y: " <<
mHits[i][1] << std::endl;
2640 std::cout <<
"--- sz track params ---" << std::endl;
2641 for (
size_t i = 0; i <
mHits.size(); i++)
2643 std::cout << i <<
"-th hit, s: " <<
getS(i) <<
", z: " <<
mHits[i][2] << std::endl;
2659 for (
size_t i = 1, ilen = mHits.size(); i < ilen; i++)
2661 radius = std::sqrt(mHits[i][0] * mHits[i][0] + mHits[i][1] * mHits[i][1]);
2700 std::vector<std::vector<T>> szhits;
2701 szhits.reserve(
mHits.size());
2702 for (
size_t i = 0, ilen =
mHits.size(); i < ilen; i++)
2704 std::vector<T> szhit(2);
2706 szhit[1] =
mHits[i][2];
2707 szhits.emplace_back(szhit);
2714 if (
mLine->chi2 > 5.0)
2760 template <
typename T>
2763 return ((a[0] * a[0] + a[1] * a[1]) > (b[0] * b[0] + b[1] * b[1]));
2766 template <
typename T>
2772 template <
typename T>
2775 T ad = std::sqrt(x1 * x1 + y1 * y1 + z1 * z1), bd = std::sqrt(x2 * x2 + y2 * y2 + z2 * z2);
2776 T c0 = (x1 / ad + x2 / bd),
c1 = (y1 / ad + y2 / bd),
c2 = (z1 / ad + z2 / bd);
2777 T d0 = (x1 / ad - x2 / bd),
d1 = (y1 / ad - y2 / bd),
d2 = (z1 / ad - z2 / bd);
2778 return (
T)(2.0 * std::atan(std::sqrt(d0 * d0 +
d1 *
d1 +
d2 *
d2) / std::sqrt(c0 * c0 +
c1 *
c1 +
c2 *
c2)));
2781 template <
typename T>
2782 void make_triplets(
size_t triplet_begin,
size_t triplet_end, std::vector<std::vector<double>>&
hits,
2785 T search_radius = 10,
T search_angle =
M_PI / 8)
2787 search_radius *= search_radius;
2790 std::vector<std::pair<size_t, T>> ret_matches;
2791 double query_pt[3] = {0., 0., 0.};
2792 size_t nMatches = 0;
2794 T current_search_radius, current_search_angle;
2796 for (
size_t h = triplet_begin;
h < triplet_end;
h++)
2798 std::vector<T>& hit =
hits[
h];
2799 current_search_radius = search_radius;
2800 current_search_angle = search_angle;
2802 query_pt[0] =
hits[
h][0];
2803 query_pt[1] =
hits[
h][1];
2804 query_pt[2] =
hits[
h][2];
2805 nMatches = index.radiusSearch(&query_pt[0], current_search_radius, ret_matches, params);
2810 current_search_radius += 0.5 * search_radius;
2811 current_search_angle +=
M_PI / 32;
2812 nMatches = index.radiusSearch(&query_pt[0], current_search_radius, ret_matches, params);
2818 current_search_radius += 0.5 * search_radius;
2819 current_search_angle +=
M_PI / 32;
2820 nMatches = index.radiusSearch(&query_pt[0], current_search_radius, ret_matches, params);
2828 for (
size_t i = 1; i < nMatches; i++)
2831 if (!triplets[
h].empty() && i > 6)
2836 std::vector<T>& hit1 =
hits[ret_matches[i].first];
2837 dist1 = ret_matches[i].second;
2838 for (
size_t j = i + 1; j < nMatches; j++)
2840 if (!triplets[
h].empty() && i > 6)
2845 std::vector<T>& hit2 =
hits[ret_matches[j].first];
2846 dist2 = ret_matches[j].second;
2848 hit2[0] - hit[0], hit2[1] - hit[1], hit2[2] - hit[2]);
2849 if (angle > current_search_angle)
2858 t.
n1 = ret_matches[i].first;
2859 t.
n2 = ret_matches[j].first;
2860 triplets[
h].push_back(t);
2865 if (!triplets.empty())
2867 std::sort(triplets[
h].begin(), triplets[
h].end(), tripletsort<T>);
2872 template <
typename T>
2873 std::vector<std::vector<std::vector<T>>>
find_tracks(std::vector<std::vector<T>>& points, std::vector<std::vector<T>>& unused_hits,
2874 T search_radius = 10,
T search_angle =
M_PI / 8,
size_t min_track_size = 10,
2875 size_t nthreads = 1,
2878 auto start0 = std::chrono::system_clock::now();
2880 const size_t TOTALHITS = points.size();
2883 std::vector<bool> used_hits(TOTALHITS,
false);
2889 auto start1 = std::chrono::system_clock::now();
2890 cloud.
pts.resize(TOTALHITS);
2891 for (
size_t i = 0, ilen = TOTALHITS; i < ilen; i++)
2893 cloud.
pts[i] = points[i];
2895 auto end1 = std::chrono::system_clock::now();
2898 std::vector<std::vector<double>>&
hits = cloud.
pts;
2906 auto start3 = std::chrono::system_clock::now();
2908 auto end3 = std::chrono::system_clock::now();
2911 auto start4 = std::chrono::system_clock::now();
2913 std::vector<std::vector<KDTriplet<T>>> triplets(TOTALHITS);
2916 std::vector<std::thread>
t(nthreads);
2917 size_t dnthreads = TOTALHITS / nthreads, triplet_begin = 0, triplet_end = 0;
2918 for (
size_t i = 0; i < nthreads; i++)
2920 triplet_begin = i * dnthreads;
2921 triplet_end = (i + 1) * dnthreads;
2922 if (triplet_end > TOTALHITS)
2924 triplet_end = TOTALHITS;
2926 if (i == (nthreads - 1))
2928 triplet_end = TOTALHITS;
2930 t[i] = std::thread(make_triplets<T>, triplet_begin, triplet_end, std::ref(hits),
2931 std::ref(index), std::ref(triplets), search_radius, search_angle);
2933 for (
size_t i = 0; i < nthreads; i++)
2940 make_triplets<T>(0, TOTALHITS,
hits, index, triplets, search_radius, search_angle);
2943 auto end4 = std::chrono::system_clock::now();
2946 size_t triplet_ctr = 0;
2949 for (
size_t i = 0, ilen = triplets.size(); i < ilen; i++)
2951 triplet_ctr += triplets[i].size();
2956 auto start5 = std::chrono::system_clock::now();
2958 std::vector<std::vector<size_t>> reco_tracks;
2961 for (
size_t i = 0; i < TOTALHITS; i++)
2963 if (used_hits[i] !=
false)
2967 if (triplets[i].size() == 0)
2973 std::vector<size_t>
track;
2974 track.emplace_back(i);
2975 used_hits[i] =
true;
2977 if (used_hits[triplet.
n1] ==
false)
2984 track.emplace(track.begin(),
n1);
2985 used_hits[
n1] =
true;
2986 if (triplets[n1].size() == 0)
2991 for (
size_t t = 0;
t < triplets[
n1].size();
t++)
2993 if (triplets[n1][
t].n1 == n0 && used_hits[triplets[n1][
t].n2] ==
false)
2996 n1 = triplets[
n1][
t].n2;
3000 else if (triplets[n1][
t].n2 == n0 && used_hits[triplets[n1][
t].n1] ==
false)
3003 n1 = triplets[
n1][
t].n1;
3008 }
while (found ==
true);
3011 if (used_hits[triplet.
n2] ==
false)
3018 track.emplace_back(n1);
3019 used_hits[
n1] =
true;
3020 if (triplets[n1].size() == 0)
3025 for (
size_t t = 0;
t < triplets[
n1].size();
t++)
3027 if (triplets[n1][
t].n1 == n0 && used_hits[triplets[n1][
t].n2] ==
false)
3030 n1 = triplets[
n1][
t].n2;
3034 else if (triplets[n1][
t].n2 == n0 && used_hits[triplets[n1][
t].n1] ==
false)
3037 n1 = triplets[
n1][
t].n1;
3042 }
while (found ==
true);
3045 if ((TOTALHITS < 1000 && track.size() >= 5) || track.size() >= min_track_size)
3048 reco_tracks.emplace_back(track);
3053 for (
size_t i = 0, ilen = track.size(); i < ilen; i++)
3055 used_hits[track[i]] =
false;
3059 auto end5 = std::chrono::system_clock::now();
3063 auto start6 = std::chrono::system_clock::now();
3064 std::vector<std::vector<std::vector<T>>> final_tracks;
3065 final_tracks.reserve(reco_tracks.size());
3066 for (
size_t i = 0, ilen = reco_tracks.size(); i < ilen; i++)
3068 std::vector<std::vector<T>> final_track;
3069 for (
size_t j = 0, jlen = reco_tracks[i].size(); j < jlen; j++)
3071 final_track.emplace_back(hits[reco_tracks[i][j]]);
3073 final_tracks.emplace_back(final_track);
3075 auto end6 = std::chrono::system_clock::now();
3077 size_t un_hits = 0, us_hits = 0;
3078 for (
size_t i = 0, ilen = used_hits.size(); i < ilen; i++)
3087 unused_hits.emplace_back(hits[i]);
3091 auto end0 = std::chrono::system_clock::now();
3095 double us_pct = roundf(((
double) us_hits / (
double) used_hits.size() * 100.0) * 1000) / 1000;
3096 double un_pct = roundf(((
double) un_hits / (
double) used_hits.size() * 100.0) * 1000) / 1000;
3098 std::cout <<
"---------- KDfinder stats ----------\n";
3099 std::chrono::duration<double> elapsed_seconds1 = end1 - start1;
3100 std::cout <<
" data import: " << elapsed_seconds1.count() <<
"s\n";
3101 std::chrono::duration<double> elapsed_seconds3 = end3 - start3;
3102 std::cout <<
" kd index build: " << elapsed_seconds3.count() <<
"s\n";
3103 std::chrono::duration<double> elapsed_seconds4 = end4 - start4;
3104 std::cout <<
" triplet build: " << elapsed_seconds4.count() <<
"s\n";
3105 std::chrono::duration<double> elapsed_seconds5 = end5 - start5;
3106 std::cout <<
" track reco: " << elapsed_seconds5.count() <<
"s\n";
3107 std::chrono::duration<double> elapsed_seconds6 = end6 - start6;
3108 std::cout <<
" hit converter: " << elapsed_seconds6.count() <<
"s\n";
3109 std::chrono::duration<double> elapsed_seconds0 = end0 - start0;
3110 std::cout <<
" = total time: " << elapsed_seconds0.count() <<
"s\n";
3111 std::cout <<
" --- objects --- \n";
3112 std::cout <<
" triplets created: " << triplet_ctr << std::endl;
3113 std::cout <<
" tracks created: " << final_tracks.size() << std::endl;
3114 std::cout <<
" --- hits --- \n";
3115 std::cout <<
" hits used: " << us_hits <<
"\t\t or " << us_pct <<
"%"
3117 std::cout <<
" hits unused: " << un_hits <<
"\t\t or " << un_pct <<
"%"
3121 return final_tracks;
3124 template <
typename T>
3126 T search_radius1 = 10,
T search_angle1 =
M_PI / 8,
size_t min_track_size1 = 10,
3127 T search_radius2 = 12,
T search_angle2 =
M_PI / 8,
size_t min_track_size2 = 6,
3128 size_t nthreads = 1,
3133 std::vector<std::vector<std::vector<T>>> tracks = kdfinder::find_tracks<T>(
hits, unused_hits,
3134 search_radius1, search_angle1, min_track_size1, nthreads, stats);
3135 if (unused_hits.size() > 10)
3138 hits.insert(hits.begin(), std::make_move_iterator(unused_hits.begin()), std::make_move_iterator(unused_hits.end()));
3139 unused_hits.erase(unused_hits.begin(), unused_hits.end());
3140 std::vector<std::vector<std::vector<T>>> extra_tracks = kdfinder::find_tracks<T>(
hits, unused_hits,
3141 search_radius2, search_angle2, min_track_size2, nthreads, stats);
3142 if (!extra_tracks.empty())
3144 tracks.insert(tracks.end(), std::make_move_iterator(extra_tracks.begin()), std::make_move_iterator(extra_tracks.end()));
3145 extra_tracks.erase(extra_tracks.begin(), extra_tracks.end());
3152 template <
typename T>
3153 std::vector<TrackCandidate<T>*>
get_track_candidates(std::vector<std::vector<std::vector<T>>>& tracks,
T B,
bool stats =
false)
3155 auto begin1 = std::chrono::system_clock::now();
3157 std::vector<TrackCandidate<T>*> candidates;
3158 for (
size_t i = 0, ilen = tracks.size(); i < ilen; i++)
3164 candidates.emplace_back(trk);
3173 auto end1 = std::chrono::system_clock::now();
3177 std::cout <<
"---------- KDcandidates stats ----------\n";
3178 std::chrono::duration<double> elapsed_seconds1 = end1 - begin1;
3179 std::cout <<
" conversion time : " << elapsed_seconds1.count() <<
"s\n";
3180 std::cout <<
" input tracks : " << tracks.size() <<
"\n";
3181 std::cout <<
" candidates : " << candidates.size() <<
"\n";
3187 template <
typename T>
3193 template <
typename T>
3199 template <
typename T>
3202 return (o->
nhits() == 0);
3205 template <
typename T>
3208 T c_tanl = 5.0 ,
T c_xy = 5.0 ,
T c_dist = 60.0 ,
3211 auto start = std::chrono::system_clock::now();
3212 size_t tracks_before_merge = candidates.size();
3213 if (candidates.size() < 2)
3218 std::sort(candidates.begin(), candidates.end(), candidatesortradius<T>);
3220 for (
size_t i = 0, ilen = candidates.size(); i < ilen; i++)
3222 if (!candidates[i]->nhits())
3226 if (!candidates[i]->isFitted())
3230 if ((candidates[i]->maxR() - candidates[i]->minR()) < 10.0)
3235 for (
size_t j = i + 1, jlen = candidates.size(); j < jlen; j++)
3237 if (!candidates[i]->nhits())
3241 if (!candidates[j]->nhits())
3245 if (!candidates[j]->isFitted())
3249 if (candidates[j]->maxR() > candidates[i]->minR())
3253 if ((candidates[j]->maxR() - candidates[j]->minR()) < 10.0)
3258 T distTanlErr = candidates[i]->nhits() > candidates[j]->nhits() ? candidates[i]->tanl_err() : candidates[j]->tanl_err();
3259 if (std::fabs(candidates[i]->tanl() - candidates[j]->tanl()) > (c_tanl * distTanlErr))
3264 T distToCircle = candidates[i]->nhits() > candidates[j]->nhits() ? std::fabs(candidates[i]->distanceToCircle(candidates[j]->getLastHit())) : std::fabs(candidates[j]->distanceToCircle(candidates[i]->getFirstHit()));
3265 T circleErr = candidates[i]->nhits() > candidates[j]->nhits() ? candidates[i]->radius_err() : candidates[j]->radius_err();
3266 if (std::fabs(distToCircle) > (c_xy * circleErr))
3271 std::vector<T>& hit1 = candidates[i]->getFirstHit();
3272 std::vector<T>& hit2 = candidates[j]->getLastHit();
3273 T dist = std::sqrt(std::pow(hit1[0] - hit2[0], 2) + std::pow(hit1[1] - hit2[1], 2) + std::pow(hit1[2] - hit2[2], 2));
3279 candidates[i]->mergeCandidate(candidates[j]);
3284 candidates.erase(std::remove_if(candidates.begin(), candidates.end(), ismergedcandidate<T>), candidates.end());
3286 auto stop = std::chrono::system_clock::now();
3289 size_t tracks_after_merge = candidates.size();
3290 std::cout <<
"---------- KDmerger stats ----------\n";
3291 std::chrono::duration<double> elapsed_seconds = stop -
start;
3292 std::cout <<
" tracks before: " << tracks_before_merge <<
"\n";
3293 std::cout <<
" tracks merged: " << (tracks_before_merge - tracks_after_merge) <<
" = " << roundf((
double) (tracks_before_merge - tracks_after_merge) / (
double) tracks_before_merge * 100.0 * 100) / 100.0 <<
"%\n";
3294 std::cout <<
" tracks after : " << tracks_after_merge <<
"\n";
3295 std::cout <<
" time: " << elapsed_seconds.count() <<
"s\n";
3301 template <
typename T>
3304 return (std::get<0>(
a) < std::get<0>(
b));
3307 template <
typename T>
3308 bool vertexsort(
const std::pair<std::vector<T>, std::vector<size_t>>
a,
const std::pair<std::vector<T>, std::vector<size_t>>
b)
3310 return ((std::get<1>(
a)).size() > (std::get<1>(
b)).size());
3313 template <
typename T>
3314 std::vector<std::pair<std::vector<T>, std::vector<size_t>>>
3316 T c_z_dist = 0.5 ,
T c_xy_dist = 2.0 ,
T c_min_tracks = 3,
bool stats =
false)
3318 auto start = std::chrono::system_clock::now();
3320 std::vector<std::pair<std::vector<T>, std::vector<size_t>>> vertices;
3322 std::vector<std::tuple<T, Helix<T>*,
size_t>>
elements;
3323 std::vector<std::tuple<T, Helix<T>*,
size_t>> sequence;
3327 size_t stat_candidates = candidates.size(),
3329 stat_good_sequences = 0,
3330 stat_bad_sequences = 0;
3332 for (
size_t i = 0, ilen = candidates.size(); i < ilen; i++)
3335 std::vector<T> o = candidates[i]->getPosForHit(0);
3336 std::vector<T>
p = candidates[i]->getMomForHit(0);
3341 dca_xy = pos.
perp();
3342 if (dca_xy > c_xy_dist)
3346 elements.push_back(std::make_tuple(dca_z, helix, i));
3348 stat_elements = elements.size();
3351 std::sort(elements.begin(), elements.end(), elementsort<T>);
3354 for (
size_t i = 0, ilen = elements.size(); i < ilen; i++)
3356 if (sequence.empty())
3359 sequence.push_back(elements[i]);
3364 T dz = std::fabs(std::get<0>(elements[i]) - std::get<0>(sequence.back()));
3370 if (sequence.size() >= c_min_tracks)
3373 std::vector<T> mean(6, 0);
3374 std::vector<size_t> track_ids;
3375 track_ids.reserve(sequence.size());
3378 for (
size_t k = 0, klen = sequence.size();
k < klen;
k++)
3380 Helix<T>* helix = std::get<1>(sequence[
k]);
3386 track_ids.push_back(std::get<2>(sequence[
k]));
3388 mean[0] /= sequence.size();
3389 mean[1] /= sequence.size();
3390 mean[2] /= sequence.size();
3393 for (
size_t k = 0, klen = sequence.size();
k < klen;
k++)
3395 Helix<T>* helix = std::get<1>(sequence[
k]);
3398 mean[3] += std::fabs(mean[0] - pos.
x());
3399 mean[4] += std::fabs(mean[1] - pos.
y());
3400 mean[5] += std::fabs(mean[2] - pos.
z());
3402 mean[3] /= sequence.size();
3403 mean[4] /= sequence.size();
3404 mean[5] /= sequence.size();
3406 vertices.push_back(std::make_pair(mean, track_ids));
3407 stat_good_sequences += 1;
3411 stat_bad_sequences += 1;
3415 for (
auto it = sequence.begin();
it != sequence.end(); ++
it)
3417 delete std::get<1>(*it);
3424 sequence.push_back(elements[i]);
3430 std::sort(vertices.begin(), vertices.end(), vertexsort<T>);
3432 auto stop = std::chrono::system_clock::now();
3436 std::cout <<
"---------- KDvertexer stats ----------\n";
3437 std::cout <<
" input candidates: " << stat_candidates <<
"\n";
3438 std::cout <<
" proj. candidates: " << stat_elements <<
"\n";
3439 std::cout <<
" good pre-vertices: " << stat_good_sequences <<
"\n";
3440 std::cout <<
" weak pre-vertices: " << stat_bad_sequences <<
"\n";
3441 std::chrono::duration<double> elapsed_seconds = stop -
start;
3442 std::cout <<
" time: " << elapsed_seconds.count() <<
"s\n";
3448 template <
typename T>
3451 T r = 0,
g = 0,
b = 0,
p = std::fabs(pt), maxp = 4.5, colval =
std::min(1.0,
p / maxp), colvaltimes4 = colval * 4.0;
3454 b =
g = colvaltimes4;
3455 b += 1.0 - colvaltimes4;
3457 else if (colval < 0.5)
3459 b =
g = 1.0 - (colvaltimes4 - 1.0);
3460 g += colvaltimes4 - 1.0;
3462 else if (colval < 0.75)
3464 g = r = colvaltimes4 - 2.0;
3465 g += 1.0 - (colvaltimes4 - 2.0);
3469 g = r = 1.0 - (colvaltimes4 - 3.0);
3470 r += colvaltimes4 - 3.0;
3472 if (rand() % 1000 < 10)
3476 return ((
int(r * 255) & 0xff) << 16) + ((
int(
g * 255) & 0xff) << 8) + (
int(
b * 255) & 0xff);
3479 template <
typename T>
3481 size_t run = 0,
size_t event_number = 0,
size_t evt_time = 0,
double B = -0.5)
3483 std::stringstream ofs;
3486 <<
" \"EVENT\": { \n"
3487 <<
" \"runid\": " << run <<
", \n"
3488 <<
" \"evtid\": " << event_number <<
", \n"
3489 <<
" \"time\": " << evt_time <<
", \n"
3490 <<
" \"B\": " <<
B <<
" \n"
3493 ofs <<
"\"META\": { \n"
3494 <<
" \"HITS\": { \n"
3496 <<
" \"type\": \"3D\", \n"
3497 <<
" \"options\": { \n"
3498 <<
" \"size\": 2, \n"
3499 <<
" \"color\": 16777215 \n"
3503 <<
" \"TRACKS\": { \n"
3505 <<
" \"r_min\": 0,\n"
3506 <<
" \"r_max\": 2000,\n"
3507 <<
" \"size\": 2, \n"
3508 <<
" \"thickness\": 2 \n"
3512 <<
" \"TRACKS\": {\n"
3515 for (
int i = 0, ilen = candidates.size(); i < ilen; i++)
3517 std::vector<T> hit = candidates[i]->getPosForHit(0);
3518 std::vector<T>
mom = candidates[i]->getMomForHit(0);
3519 size_t nhits = candidates[i]->nhits();
3520 T pt = candidates[i]->Pt();
3521 T sign = candidates[i]->sign();
3522 T length = candidates[i]->approxLength();
3523 size_t color = get_track_color<T>(
pt);
3524 ofs <<
"{ \"color\": " << color <<
", \"pt\": " << pt <<
", \"xyz\":[" << hit[0] <<
"," << hit[1] <<
"," << hit[2] <<
"], \"pxyz\":[" << mom[0] <<
"," << mom[1] <<
"," << mom[2] <<
"],\"l\":" << length <<
",\"nh\":" << nhits <<
",\"q\":" << sign <<
"}";
3525 if (i != (ilen - 1))
3540 for (
int i = 0, ilen =
hits.size(); i < ilen; i++)
3542 ofs <<
"[ " <<
hits[i][0] <<
"," <<
hits[i][1] <<
"," <<
hits[i][2] <<
" ]";
3543 if (i != (ilen - 1))
3560 template <
typename T>
3561 std::string
export_json(std::vector<std::vector<std::vector<T>>>& tracks, std::vector<std::vector<T>>&
hits,
3562 size_t run = 0,
size_t event_number = 0,
size_t evt_time = 0,
double B = -0.5)
3564 std::stringstream ofs;
3567 <<
" \"EVENT\": { \n"
3568 <<
" \"runid\": " << run <<
", \n"
3569 <<
" \"evtid\": " << event_number <<
", \n"
3570 <<
" \"time\": " << evt_time <<
", \n"
3571 <<
" \"B\": " <<
B <<
" \n"
3574 ofs <<
"\"META\": { \n"
3575 <<
" \"HITS\": { \n"
3577 <<
" \"type\": \"3D\", \n"
3578 <<
" \"options\": { \n"
3579 <<
" \"size\": 2, \n"
3580 <<
" \"color\": 16777215 \n"
3584 <<
" \"TRACKS\": { \n"
3586 <<
" \"size\": 2, \n"
3587 <<
" \"thickness\": 2, \n"
3588 <<
" \"color\": 255 \n"
3592 <<
" \"TRACKS\": {\n"
3595 for (
int i = 0, ilen = tracks.size(); i < ilen; i++)
3597 ofs <<
"{ \"nh\": " << tracks[i].size() <<
", \"pts\": [ ";
3598 for (
int j = 0, jlen = tracks[i].size(); j < jlen; j++)
3600 ofs <<
"[ " << tracks[i][j][0] <<
"," << tracks[i][j][1] <<
"," << tracks[i][j][2] <<
" ]";
3601 if (j != (jlen - 1))
3607 if (i != (ilen - 1))
3618 for (
int i = 0, ilen =
hits.size(); i < ilen; i++)
3620 ofs <<
"[ " <<
hits[i][0] <<
"," <<
hits[i][1] <<
"," <<
hits[i][2] <<
" ]";
3621 if (i != (ilen - 1))
3638 template <
typename T>
3640 size_t run = 0,
size_t event_number = 0,
size_t evt_time = 0,
T B = -0.5,
bool round =
false)
3642 std::stringstream ofs;
3644 <<
"\"R\": " << run <<
", "
3645 <<
"\"Evt\": " << event_number <<
", "
3646 <<
"\"B\": " <<
B <<
","
3647 <<
"\"tm\": " << evt_time <<
", "
3650 for (
size_t i = 0; i < trigger_ids.size(); i++)
3656 ofs << trigger_ids[i];
3660 <<
"\"tracks\": [\n";
3662 for (
int i = 0, ilen = candidates.size(); i < ilen; i++)
3664 std::vector<T> hit = candidates[i]->getPosForHit(0);
3665 std::vector<T>
mom = candidates[i]->getMomForHit(0);
3666 size_t nhits = candidates[i]->nhits();
3667 T pt = candidates[i]->Pt();
3668 T sign = candidates[i]->sign();
3669 T length = candidates[i]->approxLength();
3670 size_t color = get_track_color<T>(
pt);
3674 hit[0] = std::floor(hit[0] * 10) / 10;
3675 hit[1] = std::floor(hit[0] * 10) / 10;
3676 hit[2] = std::floor(hit[0] * 10) / 10;
3677 mom[0] = std::floor(mom[0] * 1000) / 1000;
3678 mom[1] = std::floor(mom[1] * 1000) / 1000;
3679 mom[2] = std::floor(mom[2] * 1000) / 1000;
3680 length = std::floor(length * 100) / 100;
3683 ofs <<
"{ \"color\": " << color <<
", \"pt\": " << pt <<
", \"xyz\":[" << hit[0] <<
"," << hit[1] <<
"," << hit[2] <<
"], \"pxyz\":[" << mom[0] <<
"," << mom[1] <<
"," << mom[2] <<
"],\"l\":" << length <<
",\"nh\":" << nhits <<
",\"q\":" << sign <<
"}";
3684 if (i != (ilen - 1))