R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
R3BNeulandHitCosmicMonitorTask.cxx
Go to the documentation of this file.
2#include "R3BDataMonitor.h"
4#include "R3BNeulandCommon.h"
8#include <FairRootManager.h>
9#include <TH1.h>
10#include <TH2.h>
11#include <algorithm>
12#include <chrono>
13#include <fmt/format.h>
14#include <limits>
15#include <string_view>
16#include <tuple>
17
19{
21 : CalibrationTask(config.name, 1)
22 , config_{ config }
23 , hit_data_{ get_from_sep_string(0, config.read) }
24 {
26 }
27
29 {
30 const auto module_size = GetBasePar()->get_num_of_planes() * BarsPerPlane;
31 static constexpr auto RESIDUAL_BIN_NUM = 500;
32 static constexpr auto PAR_BIN_NUM = 400;
33
34 static constexpr auto MAX_TIME_SEC = 800;
35 static constexpr auto TIME_BIN_NUM = 800;
36 static constexpr auto TIME_US_MAX = 100.;
37 static constexpr auto ITER_BIN_NUM = 200;
38 static constexpr auto ITER_MAX = 200.;
39
40 static const auto SLOPE_MAX = 10.;
41 static const auto OFFSET_MAX = 200.;
42 static constexpr auto residual_bin_num = 1000;
43 static constexpr auto max_residual = 300.;
44 static constexpr auto max_diff = 50;
45
46 auto set_x_title = [](auto* hist, std::string_view title) -> void { hist->GetXaxis()->SetTitle(title.data()); };
47 auto set_y_title = [](auto* hist, std::string_view title) -> void { hist->GetYaxis()->SetTitle(title.data()); };
48
49 hist_fit_time_duration_us_ = histograms.add_hist<TH1D>(
50 "fit_time_duration", "Time spent to fit the tracks", TIME_BIN_NUM, 0., TIME_US_MAX);
51 set_x_title(hist_fit_time_duration_us_, "Fit time (us)");
52 set_y_title(hist_fit_time_duration_us_, fmt::format("Entries per {} us", TIME_US_MAX / TIME_BIN_NUM));
53
54 hist_fit_iterations_ = histograms.add_hist<TH1D>(
55 "fit_iterations", "Iterations used to fit the tracks", ITER_BIN_NUM, 0., ITER_MAX);
56 set_y_title(hist_fit_iterations_, fmt::format("Entries per {} iteration", ITER_MAX / ITER_BIN_NUM));
57 set_x_title(hist_fit_iterations_, "Iterations");
58
59 hist_a_xz_ = histograms.add_hist<TH1D>("a_xz", "slope of the xz plane", PAR_BIN_NUM, 0., SLOPE_MAX);
60 set_x_title(hist_a_xz_, "abs(a_xz)");
61 set_y_title(hist_a_xz_, fmt::format("counts per {}", SLOPE_MAX / PAR_BIN_NUM));
62
63 hist_b_xz_ = histograms.add_hist<TH1D>("b_xz", "offset of the xz plane", PAR_BIN_NUM, 0., OFFSET_MAX);
64 set_x_title(hist_b_xz_, "abs(b_xz)");
65 set_y_title(hist_b_xz_, fmt::format("counts per {}", OFFSET_MAX / PAR_BIN_NUM));
66
67 hist_a_yz_ = histograms.add_hist<TH1D>("a_yz", "slope of the yz plane", PAR_BIN_NUM, 0., SLOPE_MAX);
68 set_x_title(hist_a_yz_, "abs(a_yz)");
69 set_y_title(hist_a_yz_, fmt::format("counts per {}", SLOPE_MAX / PAR_BIN_NUM));
70
71 hist_b_yz_ = histograms.add_hist<TH1D>("b_yz", "offset of the yz plane", PAR_BIN_NUM, 0., OFFSET_MAX);
72 set_x_title(hist_b_yz_, "abs(b_yz)");
73 set_y_title(hist_b_yz_, fmt::format("counts per {}", OFFSET_MAX / PAR_BIN_NUM));
74
75 hist_t_diff_module_counts_ = histograms.add_hist<TH1D>("t_diff_module_counts",
76 "counts of each module used for t_diff relation",
77 module_size,
78 0.5,
79 0.5 + module_size);
80 set_x_title(hist_t_diff_module_counts_, "Module number");
81 set_y_title(hist_t_diff_module_counts_, "Counts");
82
83 hist_fit_diff_time_ = histograms.add_hist<TH2D>("fit_diff_time",
84 "difference between the fitted line and time values",
85 module_size,
86 0.5,
87 0.5 + module_size,
88 residual_bin_num,
89 -max_diff,
90 max_diff);
91 set_x_title(hist_fit_diff_time_, "Module number");
92 set_y_title(hist_fit_diff_time_, "diff value (cm)");
93
94 hist_fit_diff_bar_pos_ = histograms.add_hist<TH2D>("fit_diff_bar_pos",
95 "difference between the fitted line and bar positions",
96 module_size,
97 0.5,
98 0.5 + module_size,
99 residual_bin_num,
100 -max_diff,
101 max_diff);
102 set_x_title(hist_fit_diff_bar_pos_, "Module number");
103 set_y_title(hist_fit_diff_bar_pos_, "diff value (cm)");
104 }
105
106 void CosmicMonitorTask::ExtraInit([[maybe_unused]] FairRootManager* rootMan)
107 {
108 hit_data_.init();
109 plane_counter_.resize(GetBasePar()->get_num_of_planes());
110 }
111
113 {
114 track_info_.clear();
115 track_dataset_xz_.clear();
116 track_dataset_yz_.clear();
117 std::ranges::fill(plane_counter_, 0);
118 for (const auto& hit : hit_data_)
119 {
120 const auto plane_id = ModuleID2PlaneID(hit.module_id);
121 ++(plane_counter_.at(plane_id));
122 }
123 fit_duration_ms_ = std::chrono::microseconds{ 0 };
124 }
125
127 {
128 for (const auto& hit : hit_data_)
129 {
130 track_dataset_xz_.z_vals.push_back(hit.position.Z().value);
131 track_dataset_xz_.z_errs.push_back(hit.position.Z().error);
132 track_dataset_xz_.vals.push_back(hit.position.X().value);
133
134 track_dataset_yz_.z_vals.push_back(hit.position.Z().value);
135 track_dataset_yz_.z_errs.push_back(hit.position.Z().error);
136 track_dataset_yz_.vals.push_back(hit.position.Y().value);
137 }
138 auto before_fit = std::chrono::steady_clock::now();
140 track_dataset_xz_, track_info_.x_z, huber_regressor_, std::numeric_limits<double>::max());
141 hist_fit_iterations_->Fill(huber_regressor_.get_result().iteration);
143 track_dataset_yz_, track_info_.y_z, huber_regressor_, std::numeric_limits<double>::max());
144 hist_fit_iterations_->Fill(huber_regressor_.get_result().iteration);
145
146 auto is_ok = true;
147 if (config_.max_abs_a_xz > 0 and config_.max_abs_a_xz < track_info_.x_z.slope)
148 {
149 ConditionFillToHist("xz_slope_too_large");
150 is_ok = false;
151 }
152 if (config_.max_abs_a_yz > 0 and config_.max_abs_a_yz < track_info_.y_z.slope)
153 {
154 ConditionFillToHist("yz_slope_too_large");
155 is_ok = false;
156 }
157 if (not is_ok)
158 {
159 return;
160 }
161
163 std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - before_fit);
164 hist_fit_time_duration_us_->Fill(static_cast<double>(fit_duration_ms_.count()));
166
167 ConditionFillToHist("passed");
168 }
169
171 {
172 if (track_info_.x_z.slope != 0 and track_info_.x_z.offset != 0)
173 {
174 hist_a_xz_->Fill(track_info_.x_z.slope);
175 hist_b_xz_->Fill(track_info_.x_z.offset);
176 }
177 if (track_info_.y_z.slope != 0 and track_info_.y_z.offset != 0)
178 {
179 hist_a_yz_->Fill(track_info_.y_z.slope);
180 hist_b_yz_->Fill(track_info_.y_z.offset);
181 }
182
183 auto predict = [](const TrackFitPar& par, double val) -> double { return (par.slope * val) + par.offset; };
184
185 for (const auto& hit : hit_data_)
186 {
187 const auto z_pos = hit.position.Z().value;
188 const auto x_pos = hit.position.X().value;
189 const auto y_pos = hit.position.Y().value;
190 const auto module_num = hit.module_id + 1;
191 const auto is_horizontal = IsModuleNumHorizontal(module_num);
192
193 const auto [time_diff_pos, bar_diff_pos] =
194 is_horizontal ? std::tuple{ x_pos, y_pos } : std::tuple{ y_pos, x_pos };
195 const auto [time_diff_par, bar_diff_par] =
196 is_horizontal ? std::tie(track_info_.x_z, track_info_.y_z) : std::tie(track_info_.y_z, track_info_.x_z);
197 const auto time_diff_val = predict(time_diff_par, z_pos) - time_diff_pos;
198 const auto bar_diff_val = predict(bar_diff_par, z_pos) - bar_diff_pos;
199 hist_fit_diff_time_->Fill(module_num, time_diff_val);
200 hist_fit_diff_bar_pos_->Fill(module_num, bar_diff_val);
201 }
202 }
203
204 auto CosmicMonitorTask::CheckConditions([[maybe_unused]] TH1L* hist_condition) const -> bool
205 {
206 auto res = true;
207 if (hit_data_.get().size() < config_.n_hit_min)
208 {
209 ConditionFillToHist(hist_condition, "undersized");
210 res = false;
211 }
212 auto n_plane = std::ranges::count_if(plane_counter_, [](auto val) -> bool { return val > 0; });
213 if (n_plane <= config_.n_plane_min)
214 {
215 ConditionFillToHist(hist_condition, "too_few_planes");
216 res = false;
217 }
218 return res;
219 }
220} // namespace R3B::Neuland::Calibration
auto add_hist(std::unique_ptr< TH1 > hist) -> TH1 *
auto CheckConditions(TH1L *hist_condition) const -> bool override
static auto linear_fit(const NeulandTrackDataSet &data, FitPar &fit_par, HuberRegressor &huber_regressor, double p_value_cut) -> bool
static void ConditionFillToHist(TH1L *hist_condition, std::string_view condition)
constexpr auto BarsPerPlane
constexpr auto ModuleID2PlaneID(int moduleID) -> int
constexpr auto IsModuleNumHorizontal(int module_num) -> bool