4#include <Fit/BinData.h>
5#include <Math/WrappedMultiTF1.h>
11#include <range/v3/algorithm/find_if.hpp>
15#include <fmt/ranges.h>
21 init_data_registers(num_of_modules);
23 ROOT::Math::WrappedMultiTF1{ fit_function_,
static_cast<unsigned int>(fit_function_.GetNdim()) },
true);
24 fitter_.Config().SetMinimizer(
"Linear");
27 void MilleDataProcessor::init_data_registers(
int num_of_modules)
29 const auto num_of_planes = num_of_modules /
BarsPerPlane;
30 for (
int plane_id{}; plane_id < num_of_planes; ++plane_id)
32 auto data_iter = data_regsiters_.insert_or_assign(plane_id, std::vector<MilleCalData>{}).first;
37 void MilleDataProcessor::reset_fitpars()
39 fitter_.Config().ParSettings(0).SetValue(0.);
40 fitter_.Config().ParSettings(1).SetValue(0.);
45 for (
auto& [plane_id, bar_data] : data_regsiters_)
49 fit_result_.x_z =
FitPar{};
50 fit_result_.y_z =
FitPar{};
59 for (
const auto& signal : signals)
61 if (signal.left.size() == 1 && signal.right.size() == 1)
63 const auto bar_num =
static_cast<int>(signal.module_num);
65 data_regsiters_[plane_id].emplace_back(signal);
69 remove_isolated_bar_signal();
74 void MilleDataProcessor::remove_isolated_bar_signal()
76 namespace rng = ranges;
77 for (
auto& [plane_id, bar_data] : data_regsiters_)
79 if (bar_data.size() < 2)
84 const auto& bar_signals = bar_data;
85 auto check_if_isolated = [&bar_signals](
const auto& signal) ->
bool
87 const auto module_num =
static_cast<int>(signal.module_num);
88 return (rng::find_if(bar_signals,
89 [module_num](
const auto& bar_signal)
90 {
return bar_signal.module_num == module_num - 1; }) == bar_signals.end()) and
91 (rng::find_if(bar_signals,
92 [module_num](
const auto& bar_signal)
93 {
return bar_signal.module_num == module_num + 1; }) == bar_signals.end());
96 bar_data.erase(std::remove_if(bar_data.begin(), bar_data.end(), check_if_isolated), bar_data.end());
100 auto MilleDataProcessor::fit_planes() ->
bool
104 return fit_plane_data();
107 void MilleDataProcessor::fill_fit_data()
109 for (
auto& [plane_id, bar_data] : data_regsiters_)
111 if (bar_data.empty())
116 auto& fit_data = is_plane_horizontal ? y_z_vals_ : x_z_vals_;
119 const auto displacement =
120 std::accumulate(bar_data.begin(),
123 [](
double sum,
const MilleCalData& signal)
124 { return sum + GetBarVerticalDisplacement(static_cast<int>(signal.module_num)); }) /
125 static_cast<double>(bar_data.size());
126 fit_data.z_vals.push_back(z_val);
127 fit_data.z_errs.push_back(
BarSize_Z / 2.);
129 fit_data.vals.push_back(displacement);
133 auto MilleDataProcessor::fit_plane_data() ->
bool
135 return linear_fit(x_z_vals_, fit_result_.x_z) and linear_fit(y_z_vals_, fit_result_.y_z);
142 const auto& fit_result = is_plane_horizontal ? fit_result_.x_z : fit_result_.y_z;
143 const auto diff = val - (fit_result.slope * z_val) - fit_result.offset;
147 auto MilleDataProcessor::linear_fit(
const FitData& data, FitPar& fit_par) ->
bool
150 const auto bin_data = ROOT::Fit::BinData{
static_cast<unsigned int>(data.size()),
158 auto old_var = gErrorIgnoreLevel;
159 gErrorIgnoreLevel = kFatal;
160 auto res = fitter_.Fit(bin_data);
161 gErrorIgnoreLevel = old_var;
165 R3BLOG(debug,
"Linear fitting on x_z data failed");
168 fit_par.slope = fitter_.Result().Parameter(0);
169 fit_par.offset = fitter_.Result().Parameter(1);
170 if (fitter_.Result().Prob() < p_value_cut_)
173 fmt::format(
"p-value ({}) is too small from the fit.\n\
175 x_err = np.array({}) \n\
177 y_err = np.array({})",
178 fitter_.Result().Prob(),
#define R3BLOG(severity, x)
MilleDataProcessor(int num_of_modules)
auto calculate_residual(double val, int module_num) const -> double
auto filter(const std::vector< BarCalData > &signals) -> bool
constexpr auto BarsPerPlane
constexpr auto ModuleID2PlaneID(int moduleID) -> int
constexpr auto BarSize_XY
constexpr auto ModuleNum2ZPos(int module_num) -> T
constexpr auto IsPlaneIDHorizontal(int plane_id) -> bool
constexpr auto PlaneID2ZPos(int plane_id) -> T