12#include "TDecompChol.h" 
   13#include "Math/Vector3D.h" 
   14#include "Math/Point3D.h" 
   19  for (
const auto &p : scifi_planes)
 
   23      return p.GetStation();
 
   32  for (
auto p = scifi_planes.rbegin(); 
p != scifi_planes.rend(); 
p++) {
 
   35      return p->GetStation();
 
   44  for (
const auto &p : us_planes)
 
   48      return p.GetStation();
 
   57  for (
auto p = us_planes.rbegin(); 
p != us_planes.rend(); 
p++) {
 
   60      return p->GetStation();
 
   68  std::vector<double> positions_x;
 
   69  std::vector<double> positions_y;
 
   70  std::vector<double> positions_z;
 
   71  std::vector<double> err_positions_x;
 
   72  std::vector<double> err_positions_y;
 
   73  std::vector<double> err_positions_z;
 
   75  auto collect_centroids = [&](
const auto &planes) {
 
   76    for (
const auto &p : planes) {
 
   77      auto centroid = 
p.GetCentroid();
 
   78      auto centroid_error = 
p.GetCentroidError();
 
   80      if (!(std::isnan(centroid.X()) || std::isnan(centroid.Y()) || std::isnan(centroid.Z()))) {
 
   81        positions_x.push_back(centroid.X());
 
   82        positions_y.push_back(centroid.Y());
 
   83        positions_z.push_back(centroid.Z());
 
   84        err_positions_x.push_back(centroid_error.X());
 
   85        err_positions_y.push_back(centroid_error.Y());
 
   86        err_positions_z.push_back(centroid_error.Z());
 
   91  collect_centroids(scifi_planes);
 
   92  collect_centroids(us_planes);
 
   95    return std::make_pair(ROOT::Math::XYZPoint(std::nan(
""), std::nan(
""), std::nan(
"")), ROOT::Math::XYZVector(std::nan(
""), std::nan(
""), std::nan(
"")));
 
   98  auto weighted_linear_fit = [](
const std::vector<double> &
z, 
const std::vector<double> &
val, 
const std::vector<double> &err)
 
  100    const int n_points = 
z.size();
 
  101    const int n_variables = 2; 
 
  105    v_z.Use(n_points, 
const_cast<double*
>(
z.data()));
 
  107    v_y.Use(n_points, 
const_cast<double*
>(
val.data()));
 
  109    v_e.Use(n_points, 
const_cast<double*
>(err.data()));
 
  111    TMatrixD matrix(n_points, n_variables);
 
  112    TMatrixDColumn(matrix,0) = 1.0;
 
  113    TMatrixDColumn(matrix,1) = v_z;
 
  116    TVectorD coeffs = NormalEqn(matrix, v_y, v_e);
 
  118    return std::make_pair(coeffs[0], coeffs[1]); 
 
  121  auto [intercept_x, slope_x] = weighted_linear_fit(positions_z, positions_x, err_positions_x);
 
  122  auto [intercept_y, slope_y] = weighted_linear_fit(positions_z, positions_y, err_positions_y);
 
  124  ROOT::Math::XYZPoint shower_intercept(intercept_x, intercept_y, 0.0);
 
  125  ROOT::Math::XYZVector shower_direction(slope_x, slope_y, 1.0);
 
  127  return std::make_pair(shower_intercept, shower_direction.Unit());
 
  130std::pair<std::vector<snd::analysis_tools::ScifiPlane>, std::vector<snd::analysis_tools::USPlane>> 
snd::analysis_tools::GetShoweringPlanes(
const std::vector<snd::analysis_tools::ScifiPlane> &scifi_planes, 
const std::vector<snd::analysis_tools::USPlane> &us_planes)
 
  132  std::vector<snd::analysis_tools::ScifiPlane> sh_scifi_planes;
 
  133  std::vector<snd::analysis_tools::USPlane> sh_us_planes;
 
  136  std::copy_if(scifi_planes.begin(), scifi_planes.end(), std::back_inserter(sh_scifi_planes), [](
const snd::analysis_tools::ScifiPlane& p) { return p.HasShower(); });
 
  138  std::copy_if(us_planes.begin(), us_planes.end(), std::back_inserter(sh_us_planes), [](
const snd::analysis_tools::USPlane& p) { return p.HasShower(); });
 
  140  for (
auto &p: sh_scifi_planes) {
 
  143  for (
auto &p: sh_us_planes) {
 
  147  return std::make_pair(sh_scifi_planes, sh_us_planes);
 
int centroid_min_valid_station