5 #include "cetlib/pow.h" 17 constexpr
auto range_gramper_cm()
19 std::array<float, 29> Range_grampercm{{
20 9.833E-1, 1.786E0, 3.321E0, 6.598E0, 1.058E1, 3.084E1, 4.250E1, 6.732E1,
21 1.063E2, 1.725E2, 2.385E2, 4.934E2, 6.163E2, 8.552E2, 1.202E3, 1.758E3,
22 2.297E3, 4.359E3, 5.354E3, 7.298E3, 1.013E4, 1.469E4, 1.910E4, 3.558E4,
23 4.326E4, 5.768E4, 7.734E4, 1.060E5, 1.307E5}};
24 for (
float&
value : Range_grampercm) {
27 return Range_grampercm;
30 constexpr
auto Range_grampercm = range_gramper_cm();
31 constexpr std::array<float, 29> KE_MeV{{
32 10, 14, 20, 30, 40, 80, 100, 140, 200, 300,
33 400, 800, 1000, 1400, 2000, 3000, 4000, 8000, 10000, 14000,
34 20000, 30000, 40000, 80000, 100000, 140000, 200000, 300000, 400000}};
35 TGraph
const KEvsR{29, Range_grampercm.data(), KE_MeV.data()};
36 TSpline3
const KEvsR_spline3{
"KEvsRS", &KEvsR};
39 TVector3
const basex{1, 0, 0};
40 TVector3
const basey{0, 1, 0};
41 TVector3
const basez{0, 0, 1};
42 constexpr
float kcal{0.0024};
46 explicit FcnWrapper(std::vector<double>&& xmeas,
47 std::vector<double>&& ymeas,
48 std::vector<double>&& eymeas)
55 my_mcs_chi2(
double const*
x)
const 62 auto const n = xmeas_.size();
63 assert(
n == ymeas_.size());
64 assert(
n == eymeas_.size());
66 for (std::size_t i = 0; i <
n; ++i) {
67 double const xx = xmeas_[i];
68 double const yy = ymeas_[i];
69 double const ey = eymeas_[i];
71 if (std::abs(ey) < std::numeric_limits<double>::epsilon()) {
72 std::cout <<
" Zero denominator in my_mcs_chi2 ! " << std::endl;
76 constexpr
double rad_length{14.0};
77 double const l0 = xx / rad_length;
81 res1 = (13.6 / p) * std::sqrt(l0) * (1.0 + 0.038 * std::log(l0));
83 res1 = std::sqrt(res1 * res1 + theta0 * theta0);
85 double const diff = yy - res1;
86 result += cet::square(diff / ey);
89 result += 2.0 / (4.6) * theta0;
91 if (std::isnan(result) || std::isinf(result)) {
92 LOG_DEBUG(
"TrackMomentumCalculator") <<
" Is nan in my_mcs_chi2 ! ";
100 std::vector<double>
const xmeas_;
101 std::vector<double>
const ymeas_;
102 std::vector<double>
const eymeas_;
109 TrackMomentumCalculator::TrackMomentumCalculator(
double const min,
114 for (
int i = 1; i <=
n_steps; i++) {
183 if (trkrange < 0 || std::isnan(trkrange)) {
185 <<
"Invalid track range " << trkrange <<
" return -1";
189 double KE, Momentum, M;
190 constexpr
double Muon_M = 105.7, Proton_M = 938.272;
192 if (abs(pdg) == 13) {
194 KE = KEvsR_spline3.Eval(trkrange);
195 }
else if (abs(pdg) == 2212) {
197 if (trkrange > 0 && trkrange <= 80)
198 KE = 29.9317 * std::pow(trkrange, 0.586304);
199 else if (trkrange > 80 && trkrange <= 3.022E3)
201 149.904 + (3.34146 * trkrange) + (-0.00318856 * trkrange * trkrange) +
202 (4.34587E-6 * trkrange * trkrange * trkrange) +
203 (-3.18146
E-9 * trkrange * trkrange * trkrange * trkrange) +
204 (1.17854E-12 * trkrange * trkrange * trkrange * trkrange * trkrange) +
205 (-1.71763
E-16 * trkrange * trkrange * trkrange * trkrange * trkrange *
215 Momentum = std::sqrt((KE * KE) + (2 * M * KE));
217 Momentum = Momentum / 1000;
232 std::vector<float> recoX;
233 std::vector<float> recoY;
234 std::vector<float> recoZ;
238 for (
int i = 0; i < n_points; i++) {
240 recoX.push_back(pos.X());
241 recoY.push_back(pos.Y());
242 recoZ.push_back(pos.Z());
245 if (recoX.size() < 2)
251 constexpr
double seg_size{10.};
253 auto const segments =
getSegTracks_(recoX, recoY, recoZ, seg_size);
254 if (!segments.has_value())
257 auto const seg_steps = segments->x.size();
261 double const recoL = segments->L.at(seg_steps - 1);
262 if (recoL < minLength || recoL >
maxLength)
265 std::vector<float> dEi;
266 std::vector<float> dEj;
267 std::vector<float> dthij;
268 std::vector<float> ind;
280 for (
int k = start1; k <= end1; ++k) {
281 double const p_test = 0.001 + k * 0.01;
283 for (
int l = start2; l <= end2; ++l) {
284 double const res_test = 2.0;
285 double const fv =
my_mcs_llhd(dEi, dEj, dthij, ind, p_test, res_test);
304 if (LLHDp != -1 && LLHDm != -1 && LLHDp > LLHDm) {
320 std::vector<float> recoX;
321 std::vector<float> recoY;
322 std::vector<float> recoZ;
325 for (
int i = 0; i < n_points; ++i) {
326 auto const index = dir ? i : n_points - 1 - i;
328 recoX.push_back(pos.X());
329 recoY.push_back(pos.Y());
330 recoZ.push_back(pos.Z());
333 if (recoX.size() < 2)
339 constexpr
double seg_size{5.0};
340 auto const segments =
getSegTracks_(recoX, recoY, recoZ, seg_size);
341 if (!segments.has_value())
344 auto const seg_steps = segments->x.size();
348 double const recoL = segments->L.at(seg_steps - 1);
352 std::vector<float> dEi;
353 std::vector<float> dEj;
354 std::vector<float> dthij;
355 std::vector<float> ind;
359 double const p_range = recoL * kcal;
360 double const logL =
my_mcs_llhd(dEi, dEj, dthij, ind, p_range, 5.65);
367 std::vector<float>& ej,
368 std::vector<float>& th,
369 std::vector<float>& ind,
371 double const thick)
const 373 int const a1 = segments.
x.size();
374 int const a2 = segments.
y.size();
375 int const a3 = segments.
z.size();
377 if (a1 != a2 || a1 != a3) {
378 std::cout <<
" ( Get thij ) Error ! " << std::endl;
382 auto const& segnx = segments.
nx;
383 auto const& segny = segments.
ny;
384 auto const& segnz = segments.
nz;
385 auto const& segL = segments.
L;
388 double thick1 = thick + 0.13;
390 for (
int i = 0; i < tot; i++) {
391 double const dx = segnx.at(i);
392 double const dy = segny.at(i);
393 double const dz = segnz.at(i);
395 TVector3
const vec_z{dx, dy, dz};
399 double const switcher = basex.Dot(vec_z);
400 if (std::abs(switcher) <= 0.995) {
401 vec_y = vec_z.Cross(basex).Unit();
402 vec_x = vec_y.Cross(vec_z);
406 vec_y = basez.Cross(vec_z).Unit();
407 vec_x = vec_y.Cross(vec_z);
410 TVector3
const Rx{vec_x.Dot(basex), vec_x.Dot(basey), vec_x.Dot(basez)};
411 TVector3
const Ry{vec_y.Dot(basex), vec_y.Dot(basey), vec_y.Dot(basez)};
412 TVector3
const Rz{vec_z.Dot(basex), vec_z.Dot(basey), vec_z.Dot(basez)};
414 double const refL = segL.at(i);
416 for (
int j = i; j < tot; j++) {
417 double const L1 = segL.at(j);
418 double const L2 = segL.at(j + 1);
420 double const dz1 = L1 - refL;
421 double const dz2 = L2 - refL;
423 if (dz1 <= thick1 && dz2 > thick1) {
424 double const here_dx = segnx.at(j);
425 double const here_dy = segny.at(j);
426 double const here_dz = segnz.at(j);
428 TVector3
const here_vec{here_dx, here_dy, here_dz};
429 TVector3
const rot_here{
430 Rx.Dot(here_vec), Ry.Dot(here_vec), Rz.Dot(here_vec)};
432 double const scx = rot_here.X();
433 double const scy = rot_here.Y();
434 double const scz = rot_here.Z();
439 constexpr
double ULim = 10000.0;
440 constexpr
double LLim = -10000.0;
442 double const cL = kcal;
443 double const Li = segL.at(i);
444 double const Lj = segL.at(j);
446 if (azy <= ULim && azy >= LLim) {
447 ei.push_back(Li * cL);
448 ej.push_back(Lj * cL);
453 if (azx <= ULim && azx >= LLim) {
454 ei.push_back(Li * cL);
455 ej.push_back(Lj * cL);
472 std::vector<float> recoX;
473 std::vector<float> recoY;
474 std::vector<float> recoZ;
478 for (
int i = 0; i < n_points; i++) {
480 recoX.push_back(pos.X());
481 recoY.push_back(pos.Y());
482 recoZ.push_back(pos.Z());
485 if (recoX.size() < 2)
492 auto const segments =
getSegTracks_(recoX, recoY, recoZ, seg_size);
493 if (!segments.has_value())
496 auto const seg_steps = segments->x.size();
500 double const recoL = segments->L.at(seg_steps - 1);
501 if (recoL < minLength || recoL >
maxLength)
504 double ymax = -999.0;
505 double ymin = +999.0;
507 std::vector<double> xmeas;
508 std::vector<double> ymeas;
509 std::vector<double> eymeas;
513 for (
int j = 0; j <
n_steps; j++) {
514 double const trial =
steps.at(j);
517 if (std::isnan(
mean) || std::isinf(
mean)) {
518 mf::LogDebug(
"TrackMomentumCalculator") <<
"Returned mean is either nan or infinity.";
521 if (std::isnan(rms) || std::isinf(rms)) {
522 mf::LogDebug(
"TrackMomentumCalculator") <<
"Returned rms is either nan or infinity.";
525 if (std::isnan(rmse) || std::isinf(rmse)) {
526 mf::LogDebug(
"TrackMomentumCalculator") <<
"Returned rmse is either nan or infinity.";
530 xmeas.push_back(trial);
531 ymeas.push_back(rms);
532 eymeas.push_back(std::sqrt(cet::sum_of_squares(rmse, 0.05 * rms)));
540 assert(xmeas.size() == ymeas.size());
541 assert(xmeas.size() == eymeas.size());
546 TGraphErrors gr_meas{
n_steps, xmeas.data(), ymeas.data(),
nullptr, eymeas.data()};
548 gr_meas.SetTitle(
"(#Delta#theta)_{rms} versus material thickness; Material " 549 "thickness in cm; (#Delta#theta)_{rms} in mrad");
551 gr_meas.SetLineColor(kBlack);
552 gr_meas.SetMarkerColor(kBlack);
553 gr_meas.SetMarkerStyle(20);
554 gr_meas.SetMarkerSize(1.2);
556 gr_meas.GetXaxis()->SetLimits(
steps.at(0) -
steps.at(0),
558 gr_meas.SetMinimum(0.0);
559 gr_meas.SetMaximum(1.80 * ymax);
561 ROOT::Minuit2::Minuit2Minimizer mP{};
562 FcnWrapper
const wrapper{move(xmeas), move(ymeas), move(eymeas)};
563 ROOT::Math::Functor FCA([&wrapper](
double const* xs) {
return wrapper.my_mcs_chi2(xs); }, 2);
566 mP.SetLimitedVariable(0,
"p_{MCS}", 1.0, 0.01, 0.001, 7.5);
567 mP.SetLimitedVariable(1,
"#delta#theta", 0.0, 1.0, 0.0, 45.0);
568 mP.SetMaxFunctionCalls(1.E9);
569 mP.SetMaxIterations(1.E9);
570 mP.SetTolerance(0.01);
574 bool const mstatus = mP.Minimize();
578 const double* pars = mP.X();
579 const double* erpars = mP.Errors();
581 double const deltap = (recoL * kcal) / 2.0;
583 double const p_mcs = pars[0] + deltap;
584 double const p_mcs_e [[maybe_unused]] = erpars[0];
585 return mstatus ? p_mcs : -1.0;
590 std::vector<float>
const& yyy,
591 std::vector<float>
const& zzz)
593 auto const n = xxx.size();
594 auto const y_size = yyy.size();
595 auto const z_size = zzz.size();
597 if (n != y_size || n != z_size) {
598 cout <<
" ( Get reco tacks ) Error ! " << endl;
605 auto xs =
const_cast<float*
>(xxx.data());
606 auto ys =
const_cast<float*
>(yyy.data());
607 auto zs =
const_cast<float*
>(zzz.data());
609 auto const narrowed_size =
612 gr_reco_xyz =
new TPolyLine3D{narrowed_size, zs, xs, ys};
613 gr_reco_yz = TGraph{narrowed_size, zzz.data(), yyy.data()};
614 gr_reco_xz = TGraph{narrowed_size, zzz.data(), xxx.data()};
615 gr_reco_xy = TGraph{narrowed_size, xxx.data(), yyy.data()};
620 std::optional<TrackMomentumCalculator::Segments>
622 std::vector<float>
const& yyy,
623 std::vector<float>
const& zzz,
624 double const seg_size)
632 if ((a1 != a2) || (a1 != a3) || (a2 != a3)) {
633 cout <<
" ( Digitize reco tacks ) Error ! " << endl;
637 int const stopper =
seg_stop / seg_size;
639 std::vector<float> segx, segnx;
640 std::vector<float> segy, segny;
641 std::vector<float> segz, segnz;
642 std::vector<float> segL;
652 double x00 = xxx.at(0);
653 double y00 = yyy.at(0);
654 double z00 = zzz.at(0);
658 std::vector<float> vx;
659 std::vector<float> vy;
660 std::vector<float> vz;
662 for (
int i = 0; i <
a1; i++) {
668 std::sqrt(cet::sum_of_squares(x00 - x0, y00 - y0, z00 - z0));
675 segL.push_back(stag);
695 for (
int i = indC; i < a1 - 1; i++) {
696 double const x1 = xxx.at(i);
697 double const y1 = yyy.at(i);
698 double const z1 = zzz.at(i);
700 double const dr1 = std::sqrt(cet::sum_of_squares(x1 - x0, y1 - y0, z1 - z0));
702 double const x2 = xxx.at(i + 1);
703 double const y2 = yyy.at(i + 1);
704 double const z2 = zzz.at(i + 1);
706 double const dr2 = std::sqrt(cet::sum_of_squares(x2 - x0, y2 - y0, z2 - z0));
708 if (dr1 < seg_size) {
716 if (dr1 <= seg_size && dr2 > seg_size) {
717 double const dx = x2 -
x1;
718 double const dy = y2 -
y1;
719 double const dz = z2 - z1;
720 double const dr = std::sqrt(dx * dx + dy * dy + dz * dz);
723 cout <<
" ( Zero ) Error ! " << endl;
728 2.0 * ((x1 - x0) * dx + (y1 - y0) * dy + (z1 - z0) * dz) / (dr * dr);
730 double const gamma = (dr1 * dr1 - seg_size * seg_size) / (dr * dr);
731 double const delta = beta * beta - 4.0 * gamma;
734 cout <<
" ( Discriminant ) Error ! " << endl;
738 double const lysi1 = (-beta + std::sqrt(delta)) / 2.0;
739 double const t = lysi1;
741 double const xp = x1 + t * dx;
742 double const yp = y1 + t * dy;
743 double const zp = z1 + t * dz;
749 segL.push_back(1.0 *
n_seg * 1.0 * seg_size + stag);
766 auto const na = vx.size();
771 for (std::size_t i = 0; i < na; ++i) {
781 std::vector<double> mx;
782 std::vector<double> my;
783 std::vector<double> mz;
787 for (std::size_t i = 0; i < na; ++i) {
788 double const xxw1 = vx.at(i);
789 double const yyw1 = vy.at(i);
790 double const zzw1 = vz.at(i);
792 mx.push_back(xxw1 - sumx);
793 my.push_back(yyw1 - sumy);
794 mz.push_back(zzw1 - sumz);
796 double const xxw0 = mx.at(i);
797 double const yyw0 = my.at(i);
798 double const zzw0 = mz.at(i);
800 m(0, 0) += xxw0 * xxw0 / na;
801 m(0, 1) += xxw0 * yyw0 / na;
802 m(0, 2) += xxw0 * zzw0 / na;
804 m(1, 0) += yyw0 * xxw0 / na;
805 m(1, 1) += yyw0 * yyw0 / na;
806 m(1, 2) += yyw0 * zzw0 / na;
808 m(2, 0) += zzw0 * xxw0 / na;
809 m(2, 1) += zzw0 * yyw0 / na;
810 m(2, 2) += zzw0 * zzw0 / na;
813 TMatrixDSymEigen me(m);
815 TVectorD eigenval = me.GetEigenValues();
816 TMatrixD eigenvec = me.GetEigenVectors();
818 double max1 = -666.0;
822 for (
int i = 0; i < 3; ++i) {
823 double const p1 = eigenval(i);
831 double ax = eigenvec(0, ind1);
832 double ay = eigenvec(1, ind1);
833 double az = eigenvec(2, ind1);
836 if (segx.at(
n_seg - 1) - segx.at(
n_seg - 2) > 0)
839 ax = -1.0 * std::abs(ax);
841 if (segy.at(
n_seg - 1) - segy.at(
n_seg - 2) > 0)
844 ay = -1.0 * std::abs(ay);
846 if (segz.at(
n_seg - 1) - segz.at(
n_seg - 2) > 0)
849 az = -1.0 * std::abs(az);
870 else if (dr1 > seg_size) {
871 double const dx = x1 - x0;
872 double const dy = y1 - y0;
873 double const dz = z1 - z0;
874 double const dr = std::sqrt(cet::sum_of_squares(dx, dy, dz));
877 cout <<
" ( Zero ) Error ! " << endl;
881 double const t = seg_size / dr;
882 double const xp = x0 + t * dx;
883 double const yp = y0 + t * dy;
884 double const zp = z0 + t * dz;
889 segL.push_back(1.0 *
n_seg * 1.0 * seg_size + stag);
908 double na = vx.size();
914 for (std::size_t i = 0; i < na; ++i) {
924 std::vector<double> mx;
925 std::vector<double> my;
926 std::vector<double> mz;
930 for (
int i = 0; i < na; ++i) {
931 double const xxw1 = vx.at(i);
932 double const yyw1 = vy.at(i);
933 double const zzw1 = vz.at(i);
935 mx.push_back(xxw1 - sumx);
936 my.push_back(yyw1 - sumy);
937 mz.push_back(zzw1 - sumz);
939 double const xxw0 = mx.at(i);
940 double const yyw0 = my.at(i);
941 double const zzw0 = mz.at(i);
943 m(0, 0) += xxw0 * xxw0 / na;
944 m(0, 1) += xxw0 * yyw0 / na;
945 m(0, 2) += xxw0 * zzw0 / na;
947 m(1, 0) += yyw0 * xxw0 / na;
948 m(1, 1) += yyw0 * yyw0 / na;
949 m(1, 2) += yyw0 * zzw0 / na;
951 m(2, 0) += zzw0 * xxw0 / na;
952 m(2, 1) += zzw0 * yyw0 / na;
953 m(2, 2) += zzw0 * zzw0 / na;
956 TMatrixDSymEigen me(m);
958 TVectorD eigenval = me.GetEigenValues();
959 TMatrixD eigenvec = me.GetEigenVectors();
961 double max1 = -666.0;
964 for (
int i = 0; i < 3; ++i) {
965 double const p1 = eigenval(i);
973 double ax = eigenvec(0, ind1);
974 double ay = eigenvec(1, ind1);
975 double az = eigenvec(2, ind1);
978 if (segx.at(
n_seg - 1) - segx.at(
n_seg - 2) > 0)
981 ax = -1.0 * std::abs(ax);
983 if (segy.at(
n_seg - 1) - segy.at(
n_seg - 2) > 0)
986 ay = -1.0 * std::abs(ay);
988 if (segz.at(
n_seg - 1) - segz.at(
n_seg - 2) > 0)
991 az = -1.0 * std::abs(az);
1024 return std::make_optional<Segments>(
Segments{segx, segnx, segy, segny, segz, segnz, segL});
1027 std::tuple<double, double, double>
1029 double const thick)
const 1031 auto const& segnx = segments.
nx;
1032 auto const& segny = segments.
ny;
1033 auto const& segnz = segments.
nz;
1034 auto const& segL = segments.
L;
1036 int const a1 = segnx.size();
1037 int const a2 = segny.size();
1038 int const a3 = segnz.size();
1040 if (a1 != a2 || a1 != a3) {
1041 cout <<
" ( Get RMS ) Error ! " << endl;
1042 return std::make_tuple(0., 0., 0.);
1045 int const tot = a1 - 1;
1047 double const thick1 = thick + 0.13;
1049 std::vector<float> buf0;
1051 for (
int i = 0; i < tot; i++) {
1052 double const dx = segnx.at(i);
1053 double const dy = segny.at(i);
1054 double const dz = segnz.at(i);
1056 TVector3
const vec_z{dx, dy, dz};
1060 double const switcher = basex.Dot(vec_z);
1062 if (switcher <= 0.995) {
1063 vec_y = vec_z.Cross(basex).Unit();
1064 vec_x = vec_y.Cross(vec_z);
1068 vec_y = basez.Cross(vec_z).Unit();
1069 vec_x = vec_y.Cross(vec_z);
1072 TVector3
const Rx{vec_x.Dot(basex), vec_x.Dot(basey), vec_x.Dot(basez)};
1073 TVector3
const Ry{vec_y.Dot(basex), vec_y.Dot(basey), vec_y.Dot(basez)};
1074 TVector3
const Rz{vec_z.Dot(basex), vec_z.Dot(basey), vec_z.Dot(basez)};
1076 double const refL = segL.at(i);
1078 for (
int j = i; j < tot; j++) {
1079 double const L1 = segL.at(j);
1080 double const L2 = segL.at(j + 1);
1082 double const dz1 = L1 - refL;
1083 double const dz2 = L2 - refL;
1085 if (dz1 <= thick1 && dz2 > thick1) {
1086 double const here_dx = segnx.at(j);
1087 double const here_dy = segny.at(j);
1088 double const here_dz = segnz.at(j);
1090 TVector3
const here_vec{here_dx, here_dy, here_dz};
1091 TVector3
const rot_here{Rx.Dot(here_vec), Ry.Dot(here_vec), Rz.Dot(here_vec)};
1093 double const scx = rot_here.X();
1094 double const scy = rot_here.Y();
1095 double const scz = rot_here.Z();
1102 double const ULim = 10000.0;
1103 double const LLim = -10000.0;
1105 if (azx <= ULim && azx >= LLim) {
1106 buf0.push_back(azx);
1114 int const nmeas = buf0.size();
1121 for (
int i = 0; i < nmeas; i++) {
1127 for (
int i = 0; i < nmeas; i++)
1128 rms += ((buf0.at(i)) * (buf0.at(i)));
1131 rms = std::sqrt(rms);
1132 rmse = rms / std::sqrt(2.0 * tot);
1139 double const lev1 = 2.50;
1141 for (
int i = 0; i < nmeas; i++) {
1142 double const amp = buf0.at(i);
1143 if (amp < (mean + lev1 * rms1) && amp > (mean - lev1 * rms1)) {
1149 rms = rms / (ntot1);
1150 rms = std::sqrt(rms);
1151 rmse = rms / std::sqrt(2.0 * ntot1);
1152 return std::make_tuple(mean, rms, rmse);
1158 double thetayz = -999.0;
1160 if (vz > 0 && vy > 0) {
1161 double ratio = std::abs(vy / vz);
1162 thetayz = std::atan(ratio);
1165 else if (vz < 0 && vy > 0) {
1166 double ratio = std::abs(vy / vz);
1167 thetayz = std::atan(ratio);
1168 thetayz = TMath::Pi() - thetayz;
1171 else if (vz < 0 && vy < 0) {
1172 double ratio = std::abs(vy / vz);
1173 thetayz = std::atan(ratio);
1174 thetayz = thetayz + TMath::Pi();
1177 else if (vz > 0 && vy < 0) {
1178 double ratio = std::abs(vy / vz);
1179 thetayz = std::atan(ratio);
1180 thetayz = 2.0 * TMath::Pi() - thetayz;
1183 else if (vz == 0 && vy > 0) {
1184 thetayz = TMath::Pi() / 2.0;
1187 else if (vz == 0 && vy < 0) {
1188 thetayz = 3.0 * TMath::Pi() / 2.0;
1191 if (thetayz > TMath::Pi()) {
1192 thetayz = thetayz - 2.0 * TMath::Pi();
1195 return 1000.0 * thetayz;
1202 cout <<
" Error : The code tries to divide by zero ! " << endl;
1206 double const arg = (xx - Q) / s;
1207 double const result =
1208 -0.5 * std::log(2.0 * TMath::Pi()) - std::log(s) - 0.5 * arg * arg;
1210 if (std::isnan(result) || std::isinf(result)) {
1211 cout <<
" Is nan ! my_g ! " << -std::log(s) <<
", " << s << endl;
1219 std::vector<float>
const& dEj,
1220 std::vector<float>
const& dthij,
1221 std::vector<float>
const& ind,
1223 double const x1)
const 1226 double theta0x =
x1;
1228 double result = 0.0;
1229 double nnn1 = dEi.size();
1231 double red_length = (10.0) / 14.0;
1234 for (
int i = 0; i < nnn1; i++) {
1235 double Ei = p - dEi.at(i);
1236 double Ej = p - dEj.at(i);
1238 if (Ei > 0 && Ej < 0)
1239 addth = 3.14 * 1000.0;
1244 double tH0 = (13.6 / std::sqrt(Ei * Ej)) *
1245 (1.0 + 0.038 * std::log(red_length)) * std::sqrt(red_length);
1249 if (ind.at(i) == 1) {
1250 rms = std::sqrt(tH0 * tH0 + pow(theta0x, 2.0));
1252 double const DT = dthij.at(i) + addth;
1253 double const prob =
my_g(DT, 0.0, rms);
1255 result = result - 2.0 * prob;
1259 if (std::isnan(result) || std::isinf(result)) {
1260 std::cout <<
" Is nan ! my_mcs_llhd ( 1 ) ! " << std::endl;
double my_g(double xx, double Q, double s) const
Float_t y1[n_points_granero]
double GetMomentumMultiScatterChi2(art::Ptr< recob::Track > const &trk)
int getDeltaThetaij_(std::vector< float > &ei, std::vector< float > &ej, std::vector< float > &th, std::vector< float > &ind, Segments const &segments, double thick) const
Float_t x1[n_points_granero]
Point_t const & LocationAtPoint(size_t i) const
Access to track position at different points.
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
std::optional< Segments > getSegTracks_(std::vector< float > const &xxx, std::vector< float > const &yyy, std::vector< float > const &zzz, double seg_size)
Float_t y2[n_points_geant4]
double find_angle(double vz, double vy) const
std::tuple< double, double, double > getDeltaThetaRMS_(Segments const &segments, double thick) const
std::vector< float > steps
double mean(const std::vector< short > &wf, size_t start, size_t nsample)
std::string value(boost::any const &)
double GetMuMultiScatterLLHD3(art::Ptr< recob::Track > const &trk, bool dir)
double my_mcs_llhd(std::vector< float > const &dEi, std::vector< float > const &dEj, std::vector< float > const &dthij, std::vector< float > const &ind, double x0, double x1) const
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
TVector3 GetMultiScatterStartingPoint(art::Ptr< recob::Track > const &trk)
Float_t x2[n_points_geant4]
double GetMomentumMultiScatterLLHD(art::Ptr< recob::Track > const &trk)
TPolyLine3D * gr_reco_xyz
double GetTrackMomentum(double trkrange, int pdg) const
bool plotRecoTracks_(std::vector< float > const &xxx, std::vector< float > const &yyy, std::vector< float > const &zzz)