5 #include "cetlib/pow.h"
7 #include "messagefacility/MessageLogger/MessageLogger.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"
33 #include "canvas/Persistency/Common/Ptr.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,
45 1.063E2, 1.725E2, 2.385E2, 4.934E2, 6.163E2, 8.552E2, 1.202E3, 1.758E3,
46 2.297E3, 4.359E3, 5.354E3, 7.298E3, 1.013E4, 1.469E4, 1.910E4, 3.558E4,
47 4.326E4, 5.768E4, 7.734E4, 1.060E5, 1.307E5}};
48 for (
float&
value : Range_grampercm) {
51 return Range_grampercm;
54 constexpr
auto Range_grampercm = range_gramper_cm();
55 constexpr std::array<float, 29> KE_MeV{{
56 10, 14, 20, 30, 40, 80, 100, 140, 200, 300,
57 400, 800, 1000, 1400, 2000, 3000, 4000, 8000, 10000, 14000,
58 20000, 30000, 40000, 80000, 100000, 140000, 200000, 300000, 400000}};
59 TGraph
const KEvsR{29, Range_grampercm.data(), KE_MeV.data()};
60 TSpline3
const KEvsR_spline3{
"KEvsRS", &KEvsR};
63 TVector3
const basex{1, 0, 0};
64 TVector3
const basey{0, 1, 0};
65 TVector3
const basez{0, 0, 1};
66 constexpr
float kcal{0.0024};
70 explicit FcnWrapper(std::vector<double>&& xmeas,
71 std::vector<double>&& ymeas,
72 std::vector<double>&& eymeas)
79 my_mcs_chi2(
double const*
x)
const
86 auto const n = xmeas_.size();
87 assert(
n == ymeas_.size());
88 assert(
n == eymeas_.size());
90 for (std::size_t i = 0; i <
n; ++i) {
91 double const xx = xmeas_[i];
92 double const yy = ymeas_[i];
93 double const ey = eymeas_[i];
95 if (
std::abs(ey) < std::numeric_limits<double>::epsilon()) {
96 std::cout <<
" Zero denominator in my_mcs_chi2 ! " << std::endl;
100 constexpr
double rad_length{14.0};
101 double const l0 = xx / rad_length;
105 res1 = (13.6 /
p) * std::sqrt(l0) * (1.0 + 0.038 * std::log(l0));
107 res1 = std::sqrt(res1 * res1 + theta0 * theta0);
109 double const diff = yy - res1;
110 result += cet::square(diff / ey);
113 result += 2.0 / (4.6) * theta0;
115 if (std::isnan(result) || std::isinf(result)) {
116 MF_LOG_DEBUG(
"TrackMomentumCalculator") <<
" Is nan in my_mcs_chi2 ! ";
124 std::vector<double>
const xmeas_;
125 std::vector<double>
const ymeas_;
126 std::vector<double>
const eymeas_;
138 for (
int i = 1; i <= n_steps; i++) {
139 steps.push_back(steps_size * i);
207 if (trkrange < 0 || std::isnan(trkrange)) {
208 mf::LogError(
"TrackMomentumCalculator")
209 <<
"Invalid track range " << trkrange <<
" return -1";
213 double KE, Momentum, M;
214 constexpr
double Muon_M = 105.7, Proton_M = 938.272;
216 if (
abs(pdg) == 13) {
218 KE = KEvsR_spline3.Eval(trkrange);
219 }
else if (
abs(pdg) == 2212) {
221 if (trkrange > 0 && trkrange <= 80)
222 KE = 29.9317 * std::pow(trkrange, 0.586304);
223 else if (trkrange > 80 && trkrange <= 3.022E3)
225 149.904 + (3.34146 * trkrange) + (-0.00318856 * trkrange * trkrange) +
226 (4.34587E-6 * trkrange * trkrange * trkrange) +
227 (-3.18146
E-9 * trkrange * trkrange * trkrange * trkrange) +
228 (1.17854E-12 * trkrange * trkrange * trkrange * trkrange * trkrange) +
229 (-1.71763
E-16 * trkrange * trkrange * trkrange * trkrange * trkrange *
239 Momentum = std::sqrt((KE * KE) + (2 * M * KE));
241 Momentum = Momentum / 1000;
254 const art::Ptr<recob::Track>& trk)
256 std::vector<float> recoX;
257 std::vector<float> recoY;
258 std::vector<float> recoZ;
260 int n_points = trk->NumberTrajectoryPoints();
262 for (
int i = 0; i < n_points; i++) {
263 auto const& pos = trk->LocationAtPoint(i);
264 recoX.push_back(pos.X());
265 recoY.push_back(pos.Y());
266 recoZ.push_back(pos.Z());
269 if (recoX.size() < 2)
275 constexpr
double seg_size{10.};
277 auto const segments =
getSegTracks_(recoX, recoY, recoZ, seg_size);
278 if (!segments.has_value())
281 auto const seg_steps = segments->x.size();
285 double const recoL = segments->L.at(seg_steps - 1);
286 if (recoL < minLength || recoL >
maxLength)
289 std::vector<float> dEi;
290 std::vector<float> dEj;
291 std::vector<float> dthij;
292 std::vector<float> ind;
304 for (
int k = start1;
k <= end1; ++
k) {
305 double const p_test = 0.001 +
k * 0.01;
307 for (
int l = start2; l <= end2; ++l) {
308 double const res_test = 2.0;
309 double const fv =
my_mcs_llhd(dEi, dEj, dthij, ind, p_test, res_test);
323 const art::Ptr<recob::Track>& trk)
328 if (LLHDp != -1 && LLHDm != -1 && LLHDp > LLHDm) {
329 int const n_points = trk->NumberTrajectoryPoints();
330 return trk->LocationAtPoint<TVector3>(n_points - 1);
332 return trk->LocationAtPoint<TVector3>(0);
341 art::Ptr<recob::Track>
const& trk,
344 std::vector<float> recoX;
345 std::vector<float> recoY;
346 std::vector<float> recoZ;
348 int const n_points = trk->NumberTrajectoryPoints();
349 for (
int i = 0; i < n_points; ++i) {
350 auto const index = dir ? i : n_points - 1 - i;
351 auto const& pos = trk->LocationAtPoint(index);
352 recoX.push_back(pos.X());
353 recoY.push_back(pos.Y());
354 recoZ.push_back(pos.Z());
357 if (recoX.size() < 2)
363 constexpr
double seg_size{5.0};
364 auto const segments =
getSegTracks_(recoX, recoY, recoZ, seg_size);
365 if (!segments.has_value())
368 auto const seg_steps = segments->x.size();
372 double const recoL = segments->L.at(seg_steps - 1);
376 std::vector<float> dEi;
377 std::vector<float> dEj;
378 std::vector<float> dthij;
379 std::vector<float> ind;
383 double const p_range = recoL * kcal;
384 double const logL =
my_mcs_llhd(dEi, dEj, dthij, ind, p_range, 5.65);
391 std::vector<float>& ej,
392 std::vector<float>& th,
393 std::vector<float>& ind,
395 double const thick)
const
397 int const a1 = segments.
x.size();
398 int const a2 = segments.
y.size();
399 int const a3 = segments.
z.size();
401 if (a1 != a2 || a1 != a3) {
402 std::cout <<
" ( Get thij ) Error ! " << std::endl;
406 auto const& segnx = segments.
nx;
407 auto const& segny = segments.
ny;
408 auto const& segnz = segments.
nz;
409 auto const& segL = segments.
L;
412 double thick1 = thick + 0.13;
414 for (
int i = 0; i < tot; i++) {
415 double const dx = segnx.at(i);
416 double const dy = segny.at(i);
417 double const dz = segnz.at(i);
419 TVector3
const vec_z{dx, dy, dz};
423 double const switcher = basex.Dot(vec_z);
425 vec_y = vec_z.Cross(basex).Unit();
426 vec_x = vec_y.Cross(vec_z);
430 vec_y = basez.Cross(vec_z).Unit();
431 vec_x = vec_y.Cross(vec_z);
434 TVector3
const Rx{vec_x.Dot(basex), vec_x.Dot(basey), vec_x.Dot(basez)};
435 TVector3
const Ry{vec_y.Dot(basex), vec_y.Dot(basey), vec_y.Dot(basez)};
436 TVector3
const Rz{vec_z.Dot(basex), vec_z.Dot(basey), vec_z.Dot(basez)};
438 double const refL = segL.at(i);
440 for (
int j = i; j < tot; j++) {
441 double const L1 = segL.at(j);
442 double const L2 = segL.at(j + 1);
444 double const dz1 = L1 - refL;
445 double const dz2 = L2 - refL;
447 if (dz1 <= thick1 && dz2 > thick1) {
448 double const here_dx = segnx.at(j);
449 double const here_dy = segny.at(j);
450 double const here_dz = segnz.at(j);
452 TVector3
const here_vec{here_dx, here_dy, here_dz};
453 TVector3
const rot_here{
454 Rx.Dot(here_vec), Ry.Dot(here_vec), Rz.Dot(here_vec)};
456 double const scx = rot_here.X();
457 double const scy = rot_here.Y();
458 double const scz = rot_here.Z();
463 constexpr
double ULim = 10000.0;
464 constexpr
double LLim = -10000.0;
466 double const cL = kcal;
467 double const Li = segL.at(i);
468 double const Lj = segL.at(j);
470 if (azy <= ULim && azy >= LLim) {
471 ei.push_back(Li * cL);
472 ej.push_back(Lj * cL);
477 if (azx <= ULim && azx >= LLim) {
478 ei.push_back(Li * cL);
479 ej.push_back(Lj * cL);
494 const art::Ptr<recob::Track>& trk,
const bool checkValidPoints)
496 std::vector<float> recoX;
497 std::vector<float> recoY;
498 std::vector<float> recoZ;
500 int n_points = trk->NumberTrajectoryPoints();
502 for (
int i = 0; i < n_points; i++) {
503 if (checkValidPoints && !trk->HasValidPoint(i))
continue;
504 auto const& pos = trk->LocationAtPoint(i);
505 recoX.push_back(pos.X());
506 recoY.push_back(pos.Y());
507 recoZ.push_back(pos.Z());
510 if (recoX.size() < 2)
517 auto const segments =
getSegTracks_(recoX, recoY, recoZ, seg_size);
518 if (!segments.has_value())
521 auto const seg_steps = segments->x.size();
525 double const recoL = segments->L.at(seg_steps - 1);
526 if (recoL < minLength || recoL >
maxLength)
529 double ymax = -999.0;
530 double ymin = +999.0;
532 std::vector<double> xmeas;
533 std::vector<double> ymeas;
534 std::vector<double> eymeas;
538 for (
int j = 0; j <
n_steps; j++) {
539 double const trial =
steps.at(j);
542 if (std::isnan(
mean) || std::isinf(
mean)) {
543 mf::LogDebug(
"TrackMomentumCalculator") <<
"Returned mean is either nan or infinity.";
546 if (std::isnan(rms) || std::isinf(rms)) {
547 mf::LogDebug(
"TrackMomentumCalculator") <<
"Returned rms is either nan or infinity.";
550 if (std::isnan(rmse) || std::isinf(rmse)) {
551 mf::LogDebug(
"TrackMomentumCalculator") <<
"Returned rmse is either nan or infinity.";
555 xmeas.push_back(trial);
556 ymeas.push_back(rms);
557 eymeas.push_back(std::sqrt(cet::sum_of_squares(rmse, 0.05 * rms)));
565 assert(xmeas.size() == ymeas.size());
566 assert(xmeas.size() == eymeas.size());
571 TGraphErrors gr_meas{
n_steps, xmeas.data(), ymeas.data(),
nullptr, eymeas.data()};
573 gr_meas.SetTitle(
"(#Delta#theta)_{rms} versus material thickness; Material "
574 "thickness in cm; (#Delta#theta)_{rms} in mrad");
576 gr_meas.SetLineColor(kBlack);
577 gr_meas.SetMarkerColor(kBlack);
578 gr_meas.SetMarkerStyle(20);
579 gr_meas.SetMarkerSize(1.2);
581 gr_meas.GetXaxis()->SetLimits(
steps.at(0) -
steps.at(0),
583 gr_meas.SetMinimum(0.0);
584 gr_meas.SetMaximum(1.80 * ymax);
586 ROOT::Minuit2::Minuit2Minimizer mP{};
587 FcnWrapper
const wrapper{move(xmeas), move(ymeas), move(eymeas)};
588 ROOT::Math::Functor FCA([&wrapper](
double const* xs) {
return wrapper.my_mcs_chi2(xs); }, 2);
591 mP.SetLimitedVariable(0,
"p_{MCS}", 1.0, 0.01, 0.001, 7.5);
592 mP.SetLimitedVariable(1,
"#delta#theta", 0.0, 1.0, 0.0, 45.0);
593 mP.SetMaxFunctionCalls(1.E9);
594 mP.SetMaxIterations(1.E9);
595 mP.SetTolerance(0.01);
599 bool const mstatus = mP.Minimize();
603 const double* pars = mP.X();
604 const double* erpars = mP.Errors();
606 double const deltap = (recoL * kcal) / 2.0;
608 double const p_mcs = pars[0] + deltap;
609 double const p_mcs_e [[maybe_unused]] = erpars[0];
610 return mstatus ? p_mcs : -1.0;
615 std::vector<float>
const& yyy,
616 std::vector<float>
const& zzz)
618 auto const n = xxx.size();
619 auto const y_size = yyy.size();
620 auto const z_size = zzz.size();
622 if (n != y_size || n != z_size) {
623 cout <<
" ( Get reco tacks ) Error ! " << endl;
630 auto xs =
const_cast<float*
>(xxx.data());
631 auto ys =
const_cast<float*
>(yyy.data());
632 auto zs =
const_cast<float*
>(zzz.data());
634 auto const narrowed_size =
637 gr_reco_xyz =
new TPolyLine3D{narrowed_size, zs, xs, ys};
638 gr_reco_yz = TGraph{narrowed_size, zzz.data(), yyy.data()};
639 gr_reco_xz = TGraph{narrowed_size, zzz.data(), xxx.data()};
640 gr_reco_xy = TGraph{narrowed_size, xxx.data(), yyy.data()};
645 std::optional<TrackMomentumCalculator::Segments>
647 std::vector<float>
const& yyy,
648 std::vector<float>
const& zzz,
649 double const seg_size)
657 if ((a1 != a2) || (a1 != a3) || (a2 != a3)) {
658 cout <<
" ( Digitize reco tacks ) Error ! " << endl;
662 int const stopper =
seg_stop / seg_size;
664 std::vector<float> segx, segnx;
665 std::vector<float> segy, segny;
666 std::vector<float> segz, segnz;
667 std::vector<float> segL;
677 double x00 = xxx.at(0);
678 double y00 = yyy.at(0);
679 double z00 = zzz.at(0);
683 std::vector<float> vx;
684 std::vector<float> vy;
685 std::vector<float> vz;
687 for (
int i = 0; i <
a1; i++) {
693 std::sqrt(cet::sum_of_squares(x00 - x0, y00 - y0, z00 - z0));
700 segL.push_back(stag);
720 for (
int i = indC; i < a1 - 1; i++) {
721 double const x1 = xxx.at(i);
722 double const y1 = yyy.at(i);
723 double const z1 = zzz.at(i);
725 double const dr1 = std::sqrt(cet::sum_of_squares(x1 - x0, y1 - y0, z1 - z0));
727 double const x2 = xxx.at(i + 1);
728 double const y2 = yyy.at(i + 1);
729 double const z2 = zzz.at(i + 1);
731 double const dr2 = std::sqrt(cet::sum_of_squares(x2 - x0, y2 - y0, z2 - z0));
733 if (dr1 < seg_size) {
741 if (dr1 <= seg_size && dr2 > seg_size) {
742 double const dx = x2 - x1;
743 double const dy = y2 - y1;
744 double const dz = z2 - z1;
745 double const dr = std::sqrt(dx * dx + dy * dy + dz * dz);
748 cout <<
" ( Zero ) Error ! " << endl;
753 2.0 * ((x1 - x0) * dx + (y1 - y0) * dy + (z1 - z0) * dz) / (dr * dr);
755 double const gamma = (dr1 * dr1 - seg_size * seg_size) / (dr * dr);
756 double const delta = beta * beta - 4.0 * gamma;
759 cout <<
" ( Discriminant ) Error ! " << endl;
763 double const lysi1 = (-beta + std::sqrt(delta)) / 2.0;
764 double const t = lysi1;
766 double const xp = x1 + t * dx;
767 double const yp = y1 + t * dy;
768 double const zp = z1 + t * dz;
774 segL.push_back(1.0 *
n_seg * 1.0 * seg_size + stag);
791 auto const na = vx.size();
796 for (std::size_t i = 0; i < na; ++i) {
806 std::vector<double> mx;
807 std::vector<double>
my;
808 std::vector<double> mz;
812 for (std::size_t i = 0; i < na; ++i) {
813 double const xxw1 = vx.at(i);
814 double const yyw1 = vy.at(i);
815 double const zzw1 = vz.at(i);
817 mx.push_back(xxw1 - sumx);
818 my.push_back(yyw1 - sumy);
819 mz.push_back(zzw1 - sumz);
821 double const xxw0 = mx.at(i);
822 double const yyw0 = my.at(i);
823 double const zzw0 = mz.at(i);
825 m(0, 0) += xxw0 * xxw0 / na;
826 m(0, 1) += xxw0 * yyw0 / na;
827 m(0, 2) += xxw0 * zzw0 / na;
829 m(1, 0) += yyw0 * xxw0 / na;
830 m(1, 1) += yyw0 * yyw0 / na;
831 m(1, 2) += yyw0 * zzw0 / na;
833 m(2, 0) += zzw0 * xxw0 / na;
834 m(2, 1) += zzw0 * yyw0 / na;
835 m(2, 2) += zzw0 * zzw0 / na;
838 TMatrixDSymEigen me(m);
840 TVectorD eigenval = me.GetEigenValues();
841 TMatrixD eigenvec = me.GetEigenVectors();
843 double max1 = -666.0;
847 for (
int i = 0; i < 3; ++i) {
848 double const p1 = eigenval(i);
856 double ax = eigenvec(0, ind1);
857 double ay = eigenvec(1, ind1);
858 double az = eigenvec(2, ind1);
861 if (segx.at(
n_seg - 1) - segx.at(
n_seg - 2) > 0)
866 if (segy.at(
n_seg - 1) - segy.at(
n_seg - 2) > 0)
871 if (segz.at(
n_seg - 1) - segz.at(
n_seg - 2) > 0)
895 else if (dr1 > seg_size) {
896 double const dx = x1 - x0;
897 double const dy = y1 - y0;
898 double const dz = z1 - z0;
899 double const dr = std::sqrt(cet::sum_of_squares(dx, dy, dz));
902 cout <<
" ( Zero ) Error ! " << endl;
906 double const t = seg_size / dr;
907 double const xp = x0 + t * dx;
908 double const yp = y0 + t * dy;
909 double const zp = z0 + t * dz;
914 segL.push_back(1.0 *
n_seg * 1.0 * seg_size + stag);
933 double na = vx.size();
939 for (std::size_t i = 0; i < na; ++i) {
949 std::vector<double> mx;
950 std::vector<double>
my;
951 std::vector<double> mz;
955 for (
int i = 0; i < na; ++i) {
956 double const xxw1 = vx.at(i);
957 double const yyw1 = vy.at(i);
958 double const zzw1 = vz.at(i);
960 mx.push_back(xxw1 - sumx);
961 my.push_back(yyw1 - sumy);
962 mz.push_back(zzw1 - sumz);
964 double const xxw0 = mx.at(i);
965 double const yyw0 = my.at(i);
966 double const zzw0 = mz.at(i);
968 m(0, 0) += xxw0 * xxw0 / na;
969 m(0, 1) += xxw0 * yyw0 / na;
970 m(0, 2) += xxw0 * zzw0 / na;
972 m(1, 0) += yyw0 * xxw0 / na;
973 m(1, 1) += yyw0 * yyw0 / na;
974 m(1, 2) += yyw0 * zzw0 / na;
976 m(2, 0) += zzw0 * xxw0 / na;
977 m(2, 1) += zzw0 * yyw0 / na;
978 m(2, 2) += zzw0 * zzw0 / na;
981 TMatrixDSymEigen me(m);
983 TVectorD eigenval = me.GetEigenValues();
984 TMatrixD eigenvec = me.GetEigenVectors();
986 double max1 = -666.0;
989 for (
int i = 0; i < 3; ++i) {
990 double const p1 = eigenval(i);
998 double ax = eigenvec(0, ind1);
999 double ay = eigenvec(1, ind1);
1000 double az = eigenvec(2, ind1);
1003 if (segx.at(
n_seg - 1) - segx.at(
n_seg - 2) > 0)
1008 if (segy.at(
n_seg - 1) - segy.at(
n_seg - 2) > 0)
1013 if (segz.at(
n_seg - 1) - segz.at(
n_seg - 2) > 0)
1018 segnx.push_back(ax);
1019 segny.push_back(ay);
1020 segnz.push_back(az);
1024 return std::nullopt;
1049 return std::make_optional<Segments>(
Segments{segx, segnx, segy, segny, segz, segnz, segL});
1052 std::tuple<double, double, double>
1054 double const thick)
const
1056 auto const& segnx = segments.
nx;
1057 auto const& segny = segments.
ny;
1058 auto const& segnz = segments.
nz;
1059 auto const& segL = segments.
L;
1061 int const a1 = segnx.size();
1062 int const a2 = segny.size();
1063 int const a3 = segnz.size();
1065 if (a1 != a2 || a1 != a3) {
1066 cout <<
" ( Get RMS ) Error ! " << endl;
1067 return std::make_tuple(0., 0., 0.);
1070 int const tot = a1 - 1;
1072 double const thick1 = thick + 0.13;
1074 std::vector<float> buf0;
1076 for (
int i = 0; i < tot; i++) {
1077 double const dx = segnx.at(i);
1078 double const dy = segny.at(i);
1079 double const dz = segnz.at(i);
1081 TVector3
const vec_z{dx, dy, dz};
1085 double const switcher = basex.Dot(vec_z);
1087 if (switcher <= 0.995) {
1088 vec_y = vec_z.Cross(basex).Unit();
1089 vec_x = vec_y.Cross(vec_z);
1093 vec_y = basez.Cross(vec_z).Unit();
1094 vec_x = vec_y.Cross(vec_z);
1097 TVector3
const Rx{vec_x.Dot(basex), vec_x.Dot(basey), vec_x.Dot(basez)};
1098 TVector3
const Ry{vec_y.Dot(basex), vec_y.Dot(basey), vec_y.Dot(basez)};
1099 TVector3
const Rz{vec_z.Dot(basex), vec_z.Dot(basey), vec_z.Dot(basez)};
1101 double const refL = segL.at(i);
1103 for (
int j = i; j < tot; j++) {
1104 double const L1 = segL.at(j);
1105 double const L2 = segL.at(j + 1);
1107 double const dz1 = L1 - refL;
1108 double const dz2 = L2 - refL;
1110 if (dz1 <= thick1 && dz2 > thick1) {
1111 double const here_dx = segnx.at(j);
1112 double const here_dy = segny.at(j);
1113 double const here_dz = segnz.at(j);
1115 TVector3
const here_vec{here_dx, here_dy, here_dz};
1116 TVector3
const rot_here{Rx.Dot(here_vec), Ry.Dot(here_vec), Rz.Dot(here_vec)};
1118 double const scx = rot_here.X();
1119 double const scy = rot_here.Y();
1120 double const scz = rot_here.Z();
1127 double const ULim = 10000.0;
1128 double const LLim = -10000.0;
1130 if (azx <= ULim && azx >= LLim) {
1131 buf0.push_back(azx);
1139 int const nmeas = buf0.size();
1146 for (
int i = 0; i < nmeas; i++) {
1152 for (
int i = 0; i < nmeas; i++)
1153 rms += ((buf0.at(i)) * (buf0.at(i)));
1156 rms = std::sqrt(rms);
1157 rmse = rms / std::sqrt(2.0 * tot);
1164 double const lev1 = 2.50;
1166 for (
int i = 0; i < nmeas; i++) {
1167 double const amp = buf0.at(i);
1168 if (amp < (mean + lev1 * rms1) && amp > (mean - lev1 * rms1)) {
1174 rms = rms / (ntot1);
1175 rms = std::sqrt(rms);
1176 rmse = rms / std::sqrt(2.0 * ntot1);
1177 return std::make_tuple(mean, rms, rmse);
1183 double thetayz = -999.0;
1185 if (vz > 0 && vy > 0) {
1187 thetayz = std::atan(ratio);
1190 else if (vz < 0 && vy > 0) {
1192 thetayz = std::atan(ratio);
1193 thetayz = TMath::Pi() - thetayz;
1196 else if (vz < 0 && vy < 0) {
1198 thetayz = std::atan(ratio);
1199 thetayz = thetayz + TMath::Pi();
1202 else if (vz > 0 && vy < 0) {
1204 thetayz = std::atan(ratio);
1205 thetayz = 2.0 * TMath::Pi() - thetayz;
1208 else if (vz == 0 && vy > 0) {
1209 thetayz = TMath::Pi() / 2.0;
1212 else if (vz == 0 && vy < 0) {
1213 thetayz = 3.0 * TMath::Pi() / 2.0;
1216 if (thetayz > TMath::Pi()) {
1217 thetayz = thetayz - 2.0 * TMath::Pi();
1220 return 1000.0 * thetayz;
1227 cout <<
" Error : The code tries to divide by zero ! " << endl;
1231 double const arg = (xx - Q) / s;
1232 double const result =
1233 -0.5 * std::log(2.0 * TMath::Pi()) - std::log(s) - 0.5 * arg * arg;
1235 if (std::isnan(result) || std::isinf(result)) {
1236 cout <<
" Is nan ! my_g ! " << -std::log(s) <<
", " << s << endl;
1244 std::vector<float>
const& dEj,
1245 std::vector<float>
const& dthij,
1246 std::vector<float>
const& ind,
1248 double const x1)
const
1251 double theta0x = x1;
1253 double result = 0.0;
1254 double nnn1 = dEi.size();
1256 double red_length = (10.0) / 14.0;
1259 for (
int i = 0; i < nnn1; i++) {
1260 double Ei = p - dEi.at(i);
1261 double Ej = p - dEj.at(i);
1263 if (Ei > 0 && Ej < 0)
1264 addth = 3.14 * 1000.0;
1269 double tH0 = (13.6 / std::sqrt(Ei * Ej)) *
1270 (1.0 + 0.038 * std::log(red_length)) * std::sqrt(red_length);
1274 if (ind.at(i) == 1) {
1275 rms = std::sqrt(tH0 * tH0 + pow(theta0x, 2.0));
1277 double const DT = dthij.at(i) + addth;
1278 double const prob =
my_g(DT, 0.0, rms);
1280 result = result - 2.0 * prob;
1284 if (std::isnan(result) || std::isinf(result)) {
1285 std::cout <<
" Is nan ! my_mcs_llhd ( 1 ) ! " << std::endl;
double GetMomentumMultiScatterChi2(art::Ptr< recob::Track > const &trk, const bool checkValidPoints=false)
double my_g(double xx, double Q, double s) const
process_name opflash particleana ie x
int getDeltaThetaij_(std::vector< float > &ei, std::vector< float > &ej, std::vector< float > &th, std::vector< float > &ind, Segments const &segments, double thick) const
tuple m
now if test mode generate materials, CRT shell, world, gdml header else just generate CRT shell for u...
std::optional< Segments > getSegTracks_(std::vector< float > const &xxx, std::vector< float > const &yyy, std::vector< float > const &zzz, double seg_size)
my($xml, $fcl, $workdir, $check, $merge)
double find_angle(double vz, double vy) const
TPolyLine3D * gr_reco_xyz
std::tuple< double, double, double > getDeltaThetaRMS_(Segments const &segments, double thick) const
Provides recob::Track data product.
double mean(const std::vector< short > &wf, size_t start, size_t nsample)
double GetMuMultiScatterLLHD3(art::Ptr< recob::Track > const &trk, bool dir)
std::vector< float > steps
TrackMomentumCalculator(double minLength=100.0, double maxLength=1350.0)
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
then echo File list $list not found else cat $list while read file do echo $file sed s
TVector3 GetMultiScatterStartingPoint(art::Ptr< recob::Track > const &trk)
double GetMomentumMultiScatterLLHD(art::Ptr< recob::Track > const &trk)
physics associatedGroupsWithLeft p1
BEGIN_PROLOG could also be cout
double GetTrackMomentum(double trkrange, int pdg) const
bool plotRecoTracks_(std::vector< float > const &xxx, std::vector< float > const &yyy, std::vector< float > const &zzz)