6#include <Fit/BinData.h>
7#include <Math/WrappedMultiTF1.h>
10#include <fairlogger/Logger.h>
15#include <unordered_map>
19#ifdef HAS_CPP_STANDARD_23
22namespace stdrng = std::ranges;
24#include <range/v3/algorithm/find_if.hpp>
25#include <range/v3/algorithm/min_element.hpp>
26using namespace stdrng = ranges
38 config.weight.init = 1.;
40 config.bias.init = 0.;
41 config.bias.learning_rate = 10.;
46 const auto num_of_planes = num_of_modules /
BarsPerPlane;
47 for (
int plane_id{}; plane_id < num_of_planes; ++plane_id)
49 auto data_iter =
data_buffers_.insert_or_assign(plane_id, std::vector<MilleCalData>{}).first;
70 for (
const auto& signal : signals)
72 if (signal.left.size() == 1 && signal.right.size() == 1)
74 const auto module_num =
static_cast<int>(signal.module_num);
89 if (bar_data.size() < 2)
94 const auto& bar_signals = bar_data;
95 auto check_if_isolated = [&bar_signals](
const auto& signal) ->
bool
97 const auto module_num =
static_cast<int>(signal.module_num);
98 return (stdrng::find_if(bar_signals,
99 [module_num](
const auto& bar_signal) ->
auto
100 {
return bar_signal.module_num == module_num - 1; }) == bar_signals.end()) and
101 (stdrng::find_if(bar_signals,
102 [module_num](
const auto& bar_signal) ->
auto
103 {
return bar_signal.module_num == module_num + 1; }) == bar_signals.end());
107 bar_data.erase(std::remove_if(bar_data.begin(), bar_data.end(), check_if_isolated), bar_data.end());
109 std::erase_if(bar_data, check_if_isolated);
118 constexpr auto calculate_diff(
const TrackFitPar& fit_result,
double val,
int module_num) ->
float
121 return static_cast<float>(val - (fit_result.slope * z_val) - fit_result.offset);
124 constexpr auto calculate_residual(
const TrackFitPar& fit_result,
double val,
int module_num) ->
float
126 const auto diff = calculate_diff(fit_result, val, module_num);
127 return static_cast<float>(diff * diff);
130 constexpr auto check_outlier_exist(
const DataBufferType& data_buffer) ->
bool
132 for (
const auto& [plane_num, bars_data] : data_buffer)
144 for (
auto& [plane_num, bars_data] : data_buffer)
146 std::erase_if(bars_data, [](
const auto& bar_data) ->
bool {
return bar_data.is_outlier; });
156 LOGP(debug,
"Fitting the data of bar displacements ... ");
157 while (not std::ranges::all_of(
data_buffers_ | std::views::values,
158 [](
const auto& bars) ->
bool {
return bars.empty(); }))
175 LOGP(debug,
"Fitting the data of time-derived positions ... ");
176 if (fair::Logger::GetConsoleSeverity() <= fair::Severity::debug)
191 return huber_regressor_.check_outlier(pos_z, pos_disp, std::make_pair(fit_par.slope, fit_par.offset)).first;
197 "Bar data size: {{x_z: {}, y_z: {}}}, track data size: {{x_z: {}, y_z: {}}}",
205 "bar displacements: {}\n"
206 "positions: slope: {}",
212 LOGP(debug,
"x_z plane fit result doesn't match!");
214 LOGP(debug,
"x_z plane time fit data:\n{}",
track_fit_data_.time_data_x_z);
219 LOGP(debug,
"y_z plane fit result doesn't match!");
221 LOGP(debug,
"y_z plane time fit data:\n{}",
track_fit_data_.time_data_y_z);
229 if (plane_data.empty())
237 const auto bar_disp =
238 std::accumulate(plane_data.begin(),
242 { return sum + GetBarVerticalDisplacement(static_cast<int>(signal.module_num)); }) /
243 static_cast<double>(plane_data.size());
244 bar_disp_fit_data.z_vals.push_back(bar_z_val);
245 bar_disp_fit_data.z_errs.push_back(
BarSize_Z / 2.);
246 bar_disp_fit_data.errs.push_back(
BarSize_XY / 2.);
247 bar_disp_fit_data.vals.push_back(bar_disp);
255 if (plane_data.empty())
264 if (iter == plane_data.end())
269 bar_time_data.z_vals.push_back(bar_z_val);
270 bar_time_data.z_errs.push_back(
BarSize_Z / 2.);
271 bar_time_data.errs.push_back(iter->position.error);
272 bar_time_data.vals.push_back(iter->position.value);
280 for (
auto& [plane_id, plane_data] : data_buffers)
282 for (
auto& signal : plane_data)
284 const auto t_diff = (signal.right.leading_time - signal.right.trigger_time) -
285 (signal.left.leading_time - signal.left.trigger_time);
286 const auto& module_par = hit_par.
GetModuleParAt(signal.module_num);
287 const auto position_along_bar = (-t_diff + module_par.t_diff) / 2 * module_par.effective_speed;
289 signal.position = position_along_bar;
293 ? std::tie(bar_disp_info.x_z, bar_disp_info.y_z)
294 : std::tie(bar_disp_info.y_z, bar_disp_info.x_z);
295 signal.fit_diff = calculate_diff(fit_result, position_along_bar.value, signal.module_num);
296 signal.residual = calculate_residual(fit_result, position_along_bar.value, signal.module_num);
297 signal.residual_bar_pos = calculate_residual(fit_result_bar, position_vert_bar, signal.module_num);
306 double p_value_cut) ->
bool
316 huber_regressor.reset_parameters();
318 LOGP(debug,
"fitting the data with x: {} and y: {}", data.z_vals, data.vals);
319 auto is_ok = huber_regressor.train_from_data(data.z_vals, data.vals);
321 const auto& result = huber_regressor.get_result();
322 LOGP(debug,
"Fitting result: {}", result);
326 LOGP(debug,
"Huber regression minimization failed!");
331 fit_par.p_value = huber_regressor.calculate_p_value(data.errs, 2.);
332 fit_par.slope = result.weight.value;
333 fit_par.offset = result.bias.value;
334 if (fit_par.p_value < p_value_cut)
337 debug,
"p-value ({}) is too small from the fit. Must be larger than {}.", fit_par.p_value, p_value_cut);
338 LOGP(debug,
"fit data: \n {}", data);
0.1 DEFAULT_LEARNING_RATE
auto GetModuleParAt(int module_num) const -> const ::R3B::Neuland::HitModulePar &
void remove_isolated_bar_signal()
Remove signals that are isolated in the plane.
auto process(const std::vector< BarCalData > &signals, const Cal2HitPar &hit_par) -> bool
Process the cal level data.
MilleDataProcessor(int num_of_modules)
static auto linear_fit(const NeulandTrackDataSet &data, FitPar &fit_par, HuberRegressor &huber_regressor, double p_value_cut) -> bool
auto check_is_outlier(int module_num) const -> bool
HuberRegressor huber_regressor_
void init_data_registers(int num_of_modules)
void set_data_buffers(DataBufferType &data_buffers, const TrackInfo &track_info, const Cal2HitPar &hit_par) const
NeulandTrackInfo TrackInfo
void fill_bar_disp_dataset()
auto fit_planes(const Cal2HitPar &hit_par) -> bool
std::unordered_map< int, std::vector< MilleCalData > > data_buffers_
TrackFitDataSet track_fit_data_
std::unordered_map< int, std::vector< MilleCalData > > DataBufferType
Data buffer for the event data.
static constexpr auto GetBarVerticalDisplacement(int module_num) -> double
std::unordered_map< int, std::vector< MilleCalData > > DataBufferType
constexpr auto BarsPerPlane
constexpr auto ModuleID2PlaneID(int moduleID) -> int
constexpr auto GetBarVerticalDisplacement(int module_num) -> double
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
Data structure to store the cal level data for the data preprocessing.
bool is_outlier
check if outlier
float residual
residual value against the fitted line
TrackFitResult bar_disp_data