6 #include "cetlib/pow.h" 17 #include "Math/Functor.h" 18 #include "Math/GenVector/PositionVector3D.h" 19 #include "Minuit2/Minuit2Minimizer.h" 22 #include "TGraphErrors.h" 24 #include "TMatrixDSymEigen.h" 25 #include "TMatrixDSymfwd.h" 26 #include "TMatrixDfwd.h" 28 #include "TMatrixTSym.h" 29 #include "TPolyLine3D.h" 31 #include "TVectorDfwd.h" 41 constexpr
auto range_gramper_cm()
43 std::array<float, 29> Range_grampercm{
44 {9.833E-1, 1.786E0, 3.321E0, 6.598E0, 1.058E1, 3.084E1, 4.250E1, 6.732E1, 1.063E2, 1.725E2,
45 2.385E2, 4.934E2, 6.163E2, 8.552E2, 1.202E3, 1.758E3, 2.297E3, 4.359E3, 5.354E3, 7.298E3,
46 1.013E4, 1.469E4, 1.910E4, 3.558E4, 4.326E4, 5.768E4, 7.734E4, 1.060E5, 1.307E5}};
47 for (
float&
value : Range_grampercm) {
50 return Range_grampercm;
53 constexpr
auto Range_grampercm = range_gramper_cm();
54 constexpr std::array<float, 29> KE_MeV{
55 {10, 14, 20, 30, 40, 80, 100, 140, 200, 300,
56 400, 800, 1000, 1400, 2000, 3000, 4000, 8000, 10000, 14000,
57 20000, 30000, 40000, 80000, 100000, 140000, 200000, 300000, 400000}};
58 TGraph
const KEvsR{29, Range_grampercm.data(), KE_MeV.data()};
59 TSpline3
const KEvsR_spline3{
"KEvsRS", &KEvsR};
61 TVector3
const basex{1, 0, 0};
62 TVector3
const basey{0, 1, 0};
63 TVector3
const basez{0, 0, 1};
64 constexpr
float kcal{0.0024};
68 explicit FcnWrapper(std::vector<double>&& xmeas,
69 std::vector<double>&& ymeas,
70 std::vector<double>&& eymeas)
71 : xmeas_{xmeas}, ymeas_{ymeas}, eymeas_{eymeas}
74 double my_mcs_chi2(
double const*
x)
const 81 auto const n = xmeas_.size();
82 assert(
n == ymeas_.size());
83 assert(
n == eymeas_.size());
85 for (std::size_t i = 0; i <
n; ++i) {
86 double const xx = xmeas_[i];
87 double const yy = ymeas_[i];
88 double const ey = eymeas_[i];
90 if (
std::abs(ey) < std::numeric_limits<double>::epsilon()) {
91 std::cout <<
" Zero denominator in my_mcs_chi2 ! " << std::endl;
95 constexpr
double rad_length{14.0};
96 double const l0 = xx / rad_length;
100 if (xx > 0 && p > 0) res1 = (13.6 / p) * std::sqrt(l0) * (1.0 + 0.038 * std::log(l0));
102 res1 = std::sqrt(res1 * res1 + theta0 * theta0);
104 double const diff = yy - res1;
105 result += cet::square(diff / ey);
109 result += 2.0 / (4.6) * theta0;
111 if (std::isnan(result) || std::isinf(result)) {
112 MF_LOG_DEBUG(
"TrackMomentumCalculator") <<
" Is nan in my_mcs_chi2 ! ";
120 std::vector<double>
const xmeas_;
121 std::vector<double>
const ymeas_;
122 std::vector<double>
const eymeas_;
129 TrackMomentumCalculator::TrackMomentumCalculator(
double const min,
131 double const stepsize)
134 for (
int i = 1; i <=
n_steps; i++) {
202 if (trkrange < 0 || std::isnan(trkrange)) {
203 mf::LogError(
"TrackMomentumCalculator") <<
"Invalid track range " << trkrange <<
" return -1";
207 double KE, Momentum, M;
208 constexpr
double Muon_M = 105.7, Proton_M = 938.272;
210 if (
abs(pdg) == 13) {
212 KE = KEvsR_spline3.Eval(trkrange);
214 else if (
abs(pdg) == 2212) {
216 if (trkrange > 0 && trkrange <= 80)
217 KE = 29.9317 * std::pow(trkrange, 0.586304);
218 else if (trkrange > 80 && trkrange <= 3.022E3)
219 KE = 149.904 + (3.34146 * trkrange) + (-0.00318856 * trkrange * trkrange) +
220 (4.34587E-6 * trkrange * trkrange * trkrange) +
221 (-3.18146
E-9 * trkrange * trkrange * trkrange * trkrange) +
222 (1.17854E-12 * trkrange * trkrange * trkrange * trkrange * trkrange) +
223 (-1.71763
E-16 * trkrange * trkrange * trkrange * trkrange * trkrange * trkrange);
233 Momentum = std::sqrt((KE * KE) + (2 * M * KE));
235 Momentum = Momentum / 1000;
247 const bool checkValidPoints,
248 const int maxMomentum_MeV,
249 const int MomentumStep_MeV,
250 const int max_resolution)
252 std::vector<float> recoX;
253 std::vector<float> recoY;
254 std::vector<float> recoZ;
258 for (
int i = 0; i < n_points; i++) {
261 recoX.push_back(pos.X());
262 recoY.push_back(pos.Y());
263 recoZ.push_back(pos.Z());
266 if (recoX.size() < 2)
return -1.0;
272 auto const segments =
getSegTracks_(recoX, recoY, recoZ, seg_size);
273 if (!segments.has_value())
return -1.0;
275 auto const seg_steps = segments->x.size();
276 if (seg_steps < 2)
return -1;
278 double const recoL = segments->L.at(seg_steps - 1);
279 if (recoL < minLength || recoL >
maxLength)
return -1;
281 std::vector<float> dEi;
282 std::vector<float> dEj;
283 std::vector<float> dthij;
284 std::vector<float> ind;
285 if (
getDeltaThetaij_(dEi, dEj, dthij, ind, *segments, seg_size) != 0)
return -1.0;
291 int const end1{
static_cast<int>(maxMomentum_MeV / MomentumStep_MeV)};
293 int const end2{max_resolution};
295 for (
int k = start1; k <= end1; ++k) {
296 double const p_test = 0.001 + k * 0.01;
298 for (
int l = start2; l <= end2; ++l) {
299 double const res_test = (start2 == end2) ? 2.0 : 0.001 + l * 1.0;
300 double const fv =
my_mcs_llhd(dEi, dEj, dthij, ind, p_test, res_test);
317 if (LLHDp != -1 && LLHDm != -1 && LLHDp > LLHDm) {
332 std::vector<float> recoX;
333 std::vector<float> recoY;
334 std::vector<float> recoZ;
337 for (
int i = 0; i < n_points; ++i) {
338 auto const index = dir ? i : n_points - 1 - i;
340 recoX.push_back(pos.X());
341 recoY.push_back(pos.Y());
342 recoZ.push_back(pos.Z());
345 if (recoX.size() < 2)
return -1.0;
349 constexpr
double seg_size{5.0};
350 auto const segments =
getSegTracks_(recoX, recoY, recoZ, seg_size);
351 if (!segments.has_value())
return -1.0;
353 auto const seg_steps = segments->x.size();
354 if (seg_steps < 2)
return -1;
356 double const recoL = segments->L.at(seg_steps - 1);
357 if (recoL < 15.0 || recoL >
maxLength)
return -1;
359 std::vector<float> dEi;
360 std::vector<float> dEj;
361 std::vector<float> dthij;
362 std::vector<float> ind;
363 if (
getDeltaThetaij_(dEi, dEj, dthij, ind, *segments, seg_size) != 0)
return -1.0;
365 double const p_range = recoL * kcal;
366 double const logL =
my_mcs_llhd(dEi, dEj, dthij, ind, p_range, 5.65);
372 std::vector<float>& ej,
373 std::vector<float>& th,
374 std::vector<float>& ind,
376 double const thick)
const 378 int const a1 = segments.
x.size();
379 int const a2 = segments.
y.size();
380 int const a3 = segments.
z.size();
382 if (a1 != a2 || a1 != a3) {
383 std::cout <<
" ( Get thij ) Error ! " << std::endl;
387 auto const& segnx = segments.
nx;
388 auto const& segny = segments.
ny;
389 auto const& segnz = segments.
nz;
390 auto const& segL = segments.
L;
393 double thick1 = thick + 0.13;
395 for (
int i = 0; i < tot; i++) {
396 double const dx = segnx.at(i);
397 double const dy = segny.at(i);
398 double const dz = segnz.at(i);
401 TVector3
const vec_z{dx, dy, dz};
405 double const switcher = basex.Dot(vec_z);
407 vec_y = vec_z.Cross(basex).Unit();
408 vec_x = vec_y.Cross(vec_z);
412 vec_y = basez.Cross(vec_z).Unit();
413 vec_x = vec_y.Cross(vec_z);
416 TVector3
const Rx{vec_x.Dot(basex), vec_x.Dot(basey), vec_x.Dot(basez)};
417 TVector3
const Ry{vec_y.Dot(basex), vec_y.Dot(basey), vec_y.Dot(basez)};
418 TVector3
const Rz{vec_z.Dot(basex), vec_z.Dot(basey), vec_z.Dot(basez)};
420 double const refL = segL.at(i);
423 for (
int j = i; j < tot; j++) {
424 double const L1 = segL.at(j);
425 double const L2 = segL.at(j + 1);
427 double const dz1 = L1 - refL;
428 double const dz2 = L2 - refL;
430 if (dz1 <= thick1 && dz2 > thick1) {
431 double const here_dx = segnx.at(j);
432 double const here_dy = segny.at(j);
433 double const here_dz = segnz.at(j);
435 TVector3
const here_vec{here_dx, here_dy, here_dz};
436 TVector3
const rot_here{Rx.Dot(here_vec), Ry.Dot(here_vec), Rz.Dot(here_vec)};
438 double const scx = rot_here.X();
439 double const scy = rot_here.Y();
440 double const scz = rot_here.Z();
445 constexpr
double ULim = 10000.0;
446 constexpr
double LLim = -10000.0;
448 double const cL = kcal;
449 double const Li = segL.at(i);
450 double const Lj = segL.at(j);
452 if (azy <= ULim && azy >= LLim) {
453 ei.push_back(Li * cL);
454 ej.push_back(Lj * cL);
459 if (azx <= ULim && azx >= LLim) {
460 ei.push_back(Li * cL);
461 ej.push_back(Lj * cL);
475 const bool checkValidPoints,
476 const int maxMomentum_MeV)
478 std::vector<float> recoX;
479 std::vector<float> recoY;
480 std::vector<float> recoZ;
484 for (
int i = 0; i < n_points; i++) {
487 recoX.push_back(pos.X());
488 recoY.push_back(pos.Y());
489 recoZ.push_back(pos.Z());
492 if (recoX.size() < 2)
return -1.0;
497 auto const segments =
getSegTracks_(recoX, recoY, recoZ, seg_size);
498 if (!segments.has_value())
return -1.0;
500 auto const seg_steps = segments->x.size();
501 if (seg_steps < 2)
return -1;
503 double const recoL = segments->L.at(seg_steps - 1);
504 if (recoL < minLength || recoL >
maxLength)
return -1;
506 double ymax = -999.0;
507 double ymin = +999.0;
509 std::vector<double> xmeas;
510 std::vector<double> ymeas;
511 std::vector<double> eymeas;
515 for (
int j = 0; j <
n_steps; j++) {
516 double const trial =
steps.at(j);
519 if (std::isnan(
mean) || std::isinf(
mean)) {
520 mf::LogDebug(
"TrackMomentumCalculator") <<
"Returned mean is either nan or infinity.";
523 if (std::isnan(rms) || std::isinf(rms)) {
524 mf::LogDebug(
"TrackMomentumCalculator") <<
"Returned rms is either nan or infinity.";
527 if (std::isnan(rmse) || std::isinf(rmse)) {
528 mf::LogDebug(
"TrackMomentumCalculator") <<
"Returned rmse is either nan or infinity.";
532 xmeas.push_back(trial);
533 ymeas.push_back(rms);
534 eymeas.push_back(std::sqrt(cet::sum_of_squares(
537 if (ymin > rms) ymin = rms;
538 if (ymax < rms) ymax = rms;
541 assert(xmeas.size() == ymeas.size());
542 assert(xmeas.size() == eymeas.size());
543 if (xmeas.empty()) {
return -1.0; }
545 TGraphErrors gr_meas{
n_steps, xmeas.data(), ymeas.data(),
nullptr, eymeas.data()};
547 gr_meas.SetTitle(
"(#Delta#theta)_{rms} versus material thickness; Material " 548 "thickness in cm; (#Delta#theta)_{rms} in mrad");
550 gr_meas.SetLineColor(kBlack);
551 gr_meas.SetMarkerColor(kBlack);
552 gr_meas.SetMarkerStyle(20);
553 gr_meas.SetMarkerSize(1.2);
556 gr_meas.SetMinimum(0.0);
557 gr_meas.SetMaximum(1.80 * ymax);
559 ROOT::Minuit2::Minuit2Minimizer mP{};
560 FcnWrapper
const wrapper{move(xmeas), move(ymeas), move(eymeas)};
561 ROOT::Math::Functor FCA([&wrapper](
double const* xs) {
return wrapper.my_mcs_chi2(xs); }, 2);
564 mP.SetLimitedVariable(0,
"p_{MCS}", 1.0, 0.01, 0.001, maxMomentum_MeV / 1.e3);
565 mP.SetLimitedVariable(1,
"#delta#theta", 0.0, 1.0, 0.0, 45.0);
566 mP.SetMaxFunctionCalls(1.E9);
567 mP.SetMaxIterations(1.E9);
568 mP.SetTolerance(0.01);
572 bool const mstatus = mP.Minimize();
576 const double* pars = mP.X();
577 const double* erpars = mP.Errors();
579 double const deltap = (recoL * kcal) / 2.0;
581 double const p_mcs = pars[0] + deltap;
582 double const p_mcs_e [[maybe_unused]] = erpars[0];
583 return mstatus ? p_mcs : -1.0;
587 std::vector<float>
const& yyy,
588 std::vector<float>
const& zzz)
590 auto const n = xxx.size();
591 auto const y_size = yyy.size();
592 auto const z_size = zzz.size();
594 if (n != y_size || n != z_size) {
595 cout <<
" ( Get reco tacks ) Error ! " << endl;
602 auto xs =
const_cast<float*
>(xxx.data());
603 auto ys =
const_cast<float*
>(yyy.data());
604 auto zs =
const_cast<float*
>(zzz.data());
606 auto const narrowed_size =
static_cast<int>(
n);
608 gr_reco_xyz =
new TPolyLine3D{narrowed_size, zs, xs, ys};
609 gr_reco_yz = TGraph{narrowed_size, zzz.data(), yyy.data()};
610 gr_reco_xz = TGraph{narrowed_size, zzz.data(), xxx.data()};
611 gr_reco_xy = TGraph{narrowed_size, xxx.data(), yyy.data()};
617 const std::vector<float> segy,
618 const std::vector<float> segz,
619 std::vector<float>& segnx,
620 std::vector<float>& segny,
621 std::vector<float>& segnz,
622 std::vector<float>& vx,
623 std::vector<float>& vy,
624 std::vector<float>& vz)
626 auto const na = vx.size();
632 for (std::size_t i = 0; i < na; ++i) {
642 std::vector<double> mx;
643 std::vector<double> my;
644 std::vector<double> mz;
648 for (std::size_t i = 0; i < na; ++i) {
649 double const xxw1 = vx.at(i);
650 double const yyw1 = vy.at(i);
651 double const zzw1 = vz.at(i);
653 mx.push_back(xxw1 - sumx);
654 my.push_back(yyw1 - sumy);
655 mz.push_back(zzw1 - sumz);
657 double const xxw0 = mx.at(i);
658 double const yyw0 = my.at(i);
659 double const zzw0 = mz.at(i);
661 m(0, 0) += xxw0 * xxw0 / na;
662 m(0, 1) += xxw0 * yyw0 / na;
663 m(0, 2) += xxw0 * zzw0 / na;
665 m(1, 0) += yyw0 * xxw0 / na;
666 m(1, 1) += yyw0 * yyw0 / na;
667 m(1, 2) += yyw0 * zzw0 / na;
669 m(2, 0) += zzw0 * xxw0 / na;
670 m(2, 1) += zzw0 * yyw0 / na;
671 m(2, 2) += zzw0 * zzw0 / na;
674 TMatrixDSymEigen me(m);
676 TVectorD eigenval = me.GetEigenValues();
677 TMatrixD eigenvec = me.GetEigenVectors();
679 double max1 = -666.0;
683 for (
int i = 0; i < 3; ++i) {
684 double const p1 = eigenval(i);
692 double ax = eigenvec(0, ind1);
693 double ay = eigenvec(1, ind1);
694 double az = eigenvec(2, ind1);
697 if (segx.at(
n_seg - 1) - segx.at(
n_seg - 2) > 0)
702 if (segy.at(
n_seg - 1) - segy.at(
n_seg - 2) > 0)
707 if (segz.at(
n_seg - 1) - segz.at(
n_seg - 2) > 0)
722 std::vector<float>
const& xxx,
723 std::vector<float>
const& yyy,
724 std::vector<float>
const& zzz,
725 double const seg_size)
733 if ((a1 != a2) || (a1 != a3) || (a2 != a3)) {
734 cout <<
" ( Digitize reco tacks ) Error ! " << endl;
738 int const stopper =
seg_stop / seg_size;
740 std::vector<float> segx, segnx;
741 std::vector<float> segy, segny;
742 std::vector<float> segz, segnz;
743 std::vector<float> segL;
753 double x00 = xxx.at(0);
754 double y00 = yyy.at(0);
755 double z00 = zzz.at(0);
759 std::vector<float> vx;
760 std::vector<float> vy;
761 std::vector<float> vz;
763 for (
int i = 0; i <
a1; i++) {
768 double const RR0 = std::sqrt(cet::sum_of_squares(x00 - x0, y00 - y0, z00 - z0));
775 segL.push_back(stag);
795 for (
int i = indC; i < a1 - 1; i++) {
796 double const x1 = xxx.at(i);
797 double const y1 = yyy.at(i);
798 double const z1 = zzz.at(i);
800 double const dr1 = std::sqrt(cet::sum_of_squares(x1 - x0, y1 - y0, z1 - z0));
802 double const x2 = xxx.at(i + 1);
803 double const y2 = yyy.at(i + 1);
804 double const z2 = zzz.at(i + 1);
806 double const dr2 = std::sqrt(cet::sum_of_squares(x2 - x0, y2 - y0, z2 - z0));
808 if (dr1 < seg_size) {
816 if (dr1 <= seg_size && dr2 > seg_size) {
817 double const dx = x2 -
x1;
818 double const dy = y2 -
y1;
819 double const dz = z2 - z1;
820 double const dr = std::sqrt(dx * dx + dy * dy + dz * dz);
823 cout <<
" ( Zero ) Error ! " << endl;
827 double const beta = 2.0 * ((x1 - x0) * dx + (y1 - y0) * dy + (z1 - z0) * dz) / (dr * dr);
829 double const gamma = (dr1 * dr1 - seg_size * seg_size) / (dr * dr);
830 double const delta = beta * beta - 4.0 * gamma;
833 cout <<
" ( Discriminant ) Error ! " << endl;
837 double const lysi1 = (-beta + std::sqrt(delta)) / 2.0;
838 double const t = lysi1;
840 double const xp = x1 + t * dx;
841 double const yp = y1 + t * dy;
842 double const zp = z1 + t * dz;
848 segL.push_back(1.0 *
n_seg * 1.0 * seg_size + stag);
874 else if (dr1 > seg_size) {
877 double const dx = x1 - x0;
878 double const dy = y1 - y0;
879 double const dz = z1 - z0;
880 double const dr = std::sqrt(cet::sum_of_squares(dx, dy, dz));
883 cout <<
" ( Zero ) Error ! " << endl;
887 double const t = seg_size / dr;
888 double const xp = x0 + t * dx;
889 double const yp = y0 + t * dy;
890 double const zp = z0 + t * dz;
895 segL.push_back(1.0 *
n_seg * 1.0 * seg_size + stag);
932 return std::make_optional<Segments>(
Segments{segx, segnx, segy, segny, segz, segnz, segL});
937 double const thick)
const 939 auto const& segnx = segments.
nx;
940 auto const& segny = segments.
ny;
941 auto const& segnz = segments.
nz;
942 auto const& segL = segments.
L;
944 int const a1 = segnx.size();
945 int const a2 = segny.size();
946 int const a3 = segnz.size();
948 if (a1 != a2 || a1 != a3) {
949 cout <<
" ( Get RMS ) Error ! " << endl;
950 return std::make_tuple(0., 0., 0.);
953 int const tot = a1 - 1;
955 double const thick1 = thick + 0.13;
957 std::vector<float> buf0;
959 for (
int i = 0; i < tot; i++) {
960 double const dx = segnx.at(i);
961 double const dy = segny.at(i);
962 double const dz = segnz.at(i);
964 TVector3
const vec_z{dx, dy, dz};
968 double const switcher = basex.Dot(vec_z);
970 if (switcher <= 0.995) {
971 vec_y = vec_z.Cross(basex).Unit();
972 vec_x = vec_y.Cross(vec_z);
976 vec_y = basez.Cross(vec_z).Unit();
977 vec_x = vec_y.Cross(vec_z);
980 TVector3
const Rx{vec_x.Dot(basex), vec_x.Dot(basey), vec_x.Dot(basez)};
981 TVector3
const Ry{vec_y.Dot(basex), vec_y.Dot(basey), vec_y.Dot(basez)};
982 TVector3
const Rz{vec_z.Dot(basex), vec_z.Dot(basey), vec_z.Dot(basez)};
984 double const refL = segL.at(i);
986 for (
int j = i; j < tot; j++) {
987 double const L1 = segL.at(j);
988 double const L2 = segL.at(j + 1);
990 double const dz1 = L1 - refL;
991 double const dz2 = L2 - refL;
993 if (dz1 <= thick1 && dz2 > thick1) {
994 double const here_dx = segnx.at(j);
995 double const here_dy = segny.at(j);
996 double const here_dz = segnz.at(j);
998 TVector3
const here_vec{here_dx, here_dy, here_dz};
999 TVector3
const rot_here{Rx.Dot(here_vec), Ry.Dot(here_vec), Rz.Dot(here_vec)};
1001 double const scx = rot_here.X();
1002 double const scz = rot_here.Z();
1006 double const ULim = 10000.0;
1007 double const LLim = -10000.0;
1009 if (azx <= ULim && azx >= LLim) { buf0.push_back(azx); }
1016 int const nmeas = buf0.size();
1023 for (
int i = 0; i < nmeas; i++) {
1029 for (
int i = 0; i < nmeas; i++)
1030 rms += ((buf0.at(i)) * (buf0.at(i)));
1033 rms = std::sqrt(rms);
1034 rmse = rms / std::sqrt(2.0 * tot);
1041 double const lev1 = 2.50;
1043 for (
int i = 0; i < nmeas; i++) {
1044 double const amp = buf0.at(i);
1045 if (amp < (mean + lev1 * rms1) && amp > (mean - lev1 * rms1)) {
1051 rms = rms / (ntot1);
1052 rms = std::sqrt(rms);
1053 rmse = rms / std::sqrt(2.0 * ntot1);
1054 return std::make_tuple(mean, rms, rmse);
1059 double thetayz = -999.0;
1061 if (vz > 0 && vy > 0) {
1063 thetayz = std::atan(ratio);
1066 else if (vz < 0 && vy > 0) {
1068 thetayz = std::atan(ratio);
1069 thetayz = TMath::Pi() - thetayz;
1072 else if (vz < 0 && vy < 0) {
1074 thetayz = std::atan(ratio);
1075 thetayz = thetayz + TMath::Pi();
1078 else if (vz > 0 && vy < 0) {
1080 thetayz = std::atan(ratio);
1081 thetayz = 2.0 * TMath::Pi() - thetayz;
1084 else if (vz == 0 && vy > 0) {
1085 thetayz = TMath::Pi() / 2.0;
1088 else if (vz == 0 && vy < 0) {
1089 thetayz = 3.0 * TMath::Pi() / 2.0;
1092 if (thetayz > TMath::Pi()) { thetayz = thetayz - 2.0 * TMath::Pi(); }
1094 return 1000.0 * thetayz;
1100 cout <<
" Error : The code tries to divide by zero ! " << endl;
1104 double const arg = (xx - Q) / s;
1105 double const result = -0.5 * std::log(2.0 * TMath::Pi()) - std::log(s) - 0.5 * arg * arg;
1107 if (std::isnan(result) || std::isinf(result)) {
1108 cout <<
" Is nan ! my_g ! " << -std::log(s) <<
", " << s << endl;
1115 std::vector<float>
const& dEj,
1116 std::vector<float>
const& dthij,
1117 std::vector<float>
const& ind,
1119 double const x1)
const 1122 double theta0x =
x1;
1124 double result = 0.0;
1125 double nnn1 = dEi.size();
1130 for (
int i = 0; i < nnn1; i++) {
1131 double Ei = p - dEi.at(i);
1132 double Ej = p - dEj.at(i);
1135 if (Ei > 0 && Ej < 0) addth = 3.14 * 1000.0;
1143 (13.6 / std::sqrt(Ei * Ej)) * (1.0 + 0.038 * std::log(red_length)) * std::sqrt(red_length);
1147 if (ind.at(i) == 1) {
1149 rms = std::sqrt(tH0 * tH0 + cet::square(theta0x));
1151 double const DT = dthij.at(i) + addth;
1152 double const prob =
my_g(DT, 0.0, rms);
1154 result = result - 2.0 * prob;
1158 if (std::isnan(result) || std::isinf(result)) {
1159 std::cout <<
" Is nan ! my_mcs_llhd ( 1 ) ! " << std::endl;
double my_g(double xx, double Q, double s) const
chi square minizer using Minuit2, it will minize (xx-Q)/s
Float_t y1[n_points_granero]
int getDeltaThetaij_(std::vector< float > &ei, std::vector< float > &ej, std::vector< float > &th, std::vector< float > &ind, Segments const &segments, double thick) const
Gets the scatterd angle for all the segments.
Float_t x1[n_points_granero]
Point_t const & LocationAtPoint(size_t i) const
Access to track position at different points.
void compute_max_fluctuation_vector(const std::vector< float > segx, const std::vector< float > segy, const std::vector< float > segz, std::vector< float > &segnx, std::vector< float > &segny, std::vector< float > &segnz, std::vector< float > &vx, std::vector< float > &vy, std::vector< float > &vz)
Computes the vector with most scattering inside a segment with size steps_size.
bool HasValidPoint(size_t i) const
Various functions related to the presence and the number of (valid) points.
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
constexpr auto abs(T v)
Returns the absolute value of the argument.
double GetMomentumMultiScatterLLHD(art::Ptr< recob::Track > const &trk, const bool checkValidPoints=false, const int maxMomentum_MeV=7500, const int MomentumStep_MeV=10, const int max_resolution=0)
Calculate muon momentum (GeV) using multiple coulomb scattering by log likelihood.
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)
Split tracks into segments to calculate the scattered angle later. Check DOI 10.1088/1748-0221/12/10/...
double GetMomentumMultiScatterChi2(art::Ptr< recob::Track > const &trk, const bool checkValidPoints=false, const int maxMomentum_MeV=7500)
Calculate muon momentum (GeV) using multiple coulomb scattering. Chi2 minimization of the Highland fo...
Float_t y2[n_points_geant4]
double find_angle(double vz, double vy) const
Gets angle between two vy and vz.
Struct to store segments. x, y and z are the 3D points of the segment nx, ny, nz forms the vector tha...
Provides recob::Track data product.
std::tuple< double, double, double > getDeltaThetaRMS_(Segments const &segments, double thick) const
Gets the scattered angle RMS for a all segments.
std::vector< float > steps
double mean(const std::vector< short > &wf, size_t start, size_t nsample)
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
Minimizer of log likelihood for scattered angle.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
TVector3 GetMultiScatterStartingPoint(art::Ptr< recob::Track > const &trk)
Float_t x2[n_points_geant4]
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)