R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
R3BFTCalEngine.cxx
Go to the documentation of this file.
1#include "R3BFTCalEngine.h"
2#include "R3BException.h"
3#include "R3BNeulandCommon.h"
5#include "R3BShared.h"
6#include "R3BValueError.h"
7#include <TH1.h>
8#include <TH2.h>
9#include <cmath>
10#include <cstddef>
11#include <numbers>
12#include <range/v3/algorithm/for_each.hpp>
13#include <string_view>
14#include <utility>
15
17{
18 auto FTType2Str(FTType type) -> std::string_view
19 {
20 switch (type)
21 {
23 return "left_leading";
25 return "right_leading";
27 return "left_trailing";
29 return "right_trailing";
30 case FTType::trigger:
31 return "trigger";
32 default:
33 throw R3B::logic_error("unresolvable types");
34 }
35 }
36
37 ModuleCal::ModuleCal(std::string_view hist_name, int mID)
38 : FTBaseCal{ hist_name, mID, { FTType::trigger } }
39 {
40 auto initHist = R3B::make_hist<TH1I>(hist_name.data(), hist_name.data(), MaxFTValue, 0.5, MaxFTValue + 0.5);
41 InitAllDistributions(initHist.get());
42 }
43
44 PlaneCal::PlaneCal(std::string_view hist_name, int mID)
45 : FTBaseCal{ hist_name,
46 mID,
48 {
49 auto initHist = R3B::make_hist<TH2I>(hist_name.data(),
50 hist_name.data(),
52 +0.5,
53 BarsPerPlane + 0.5,
55 +0.5,
56 MaxFTValue + 0.5);
57 InitAllDistributions(initHist.get());
58 }
59
60 namespace
61 {
62 using ValueErrors = FTCalStrategy::ValueErrors;
63 constexpr int uniform_err_divider = 12;
64 constexpr auto uniform_err_divider_sqrt = SQRT_12;
65 const auto sqrt_3 = std::numbers::sqrt3;
66
67 struct InputInfo
68 {
69 double previous_sum;
70 double bin_entry;
71 double total_entry;
72 };
73
74 auto calculate_meanerror_exact(const InputInfo& input) -> ValueError<double>
75 {
76 const auto base_variance = input.bin_entry * input.bin_entry / uniform_err_divider;
77 const auto sum_term = input.previous_sum + (input.bin_entry / 3);
78 const auto bin_prob = input.bin_entry / input.total_entry;
79 const auto pre_prob = input.previous_sum / input.total_entry;
80 const auto residual = ((1 - bin_prob) * sum_term) - (input.previous_sum * pre_prob);
81
82 const auto mean = input.previous_sum + (input.bin_entry / 2);
83 return ValueError<double>{ mean, std::sqrt(base_variance + residual) };
84 }
85
86 auto calculate_meanerror_approx(const InputInfo& input) -> ValueError<double>
87 {
88 const auto mean = input.previous_sum + (input.bin_entry / 2);
89
90 const auto base_error = input.bin_entry / uniform_err_divider_sqrt;
91 const auto bin_prob = input.bin_entry / input.total_entry;
92 const auto pre_prob = input.previous_sum / input.total_entry;
93 const auto residual_main = (-(pre_prob - 0.5) * (pre_prob - 0.5)) + 0.25;
94 const auto residual_factor = (bin_prob == 0.) ? 0. : sqrt_3 / bin_prob;
95
96 return ValueError<double>{ mean, base_error + (residual_main * residual_factor) };
97 }
98
99 auto calculate_meanerror_uniform_only(const InputInfo& input) -> ValueError<double>
100 {
101 const auto mean = input.previous_sum + (input.bin_entry / 2);
102 const auto base_error = input.bin_entry / uniform_err_divider_sqrt;
103 return ValueError<double>{ mean, base_error };
104 }
105
106 auto calculate_meanerror_none(const InputInfo& input) -> ValueError<double>
107 {
108 const auto mean = input.previous_sum + (input.bin_entry / 2);
109 return ValueError<double>{ mean, 0. };
110 }
111
112 auto use_method(FTCalErrorMethod methodtype)
113 {
114 switch (methodtype)
115 {
117 return +[](const InputInfo& input) -> ValueError<double>
118 { return calculate_meanerror_exact(input); };
120 return +[](const InputInfo& input) -> ValueError<double>
121 { return calculate_meanerror_approx(input); };
123 return +[](const InputInfo& input) -> ValueError<double>
124 { return calculate_meanerror_uniform_only(input); };
126 return +[](const InputInfo& input) -> ValueError<double>
127 { return calculate_meanerror_none(input); };
128 default:
129 throw R3B::logic_error("undefined enumerator for method type!");
130 }
131 }
132
133 auto extract_bin_data(TH1* hist, int max_bin) -> ValueErrors
134 {
135 auto output = ValueErrors{};
136 output.reserve(max_bin);
137 // root histogram starts from index 1
138 for (size_t index{ 1 }; index < max_bin + 1; ++index)
139 {
140 output.emplace_back(hist->GetBinContent(static_cast<int>(index)), 0.);
141 }
142 return output;
143 }
144
145 void scale_to_real_ns(ValueErrors& value_errors, double period, double total_entry)
146 {
147 ranges::for_each(value_errors,
148 [&](ValueError<double>& value_error) -> void
149 {
150 value_error.value = value_error.value / total_entry * period;
151 value_error.error = value_error.error / total_entry * period;
152 });
153 }
154
155 auto calculate_value_errors(TH1* hist, int max_bin, double total_entry, FTCalErrorMethod methodtype)
156 -> std::pair<ValueErrors, int>
157 {
158 auto output = extract_bin_data(hist, max_bin);
159
160 auto method = use_method(methodtype);
161 auto previous_sum = 0.;
162 for (auto& value_error : output)
163 {
164 auto& value = value_error.value;
165 auto& error = value_error.error;
166 const auto inputInfo =
167 InputInfo{ .previous_sum = previous_sum, .bin_entry = value, .total_entry = total_entry };
168 previous_sum += value;
169 auto new_value_error = method(inputInfo);
170 value = new_value_error.value;
171 error = new_value_error.error;
172 }
173 const auto overflow = total_entry - previous_sum;
174 return std::make_pair(output, overflow);
175 }
176 } // namespace
177
179 {
180 const auto total_entry = hist->GetEntries();
181
182 auto bin_num = hist->GetNbinsX();
183 auto max_bin = (max_bin_number_ == 0) ? bin_num : max_bin_number_;
184 max_bin = (bin_num > max_bin) ? max_bin : bin_num;
185
186 auto [value_errors, overflow] = calculate_value_errors(hist, max_bin, total_entry, error_method_);
187
188 scale_to_real_ns(value_errors, cycle_period_, total_entry);
189
190 auto calRelation = FTChannel2TimeRelation{};
191 calRelation.value_error = std::move(value_errors);
192 calRelation.hist_overflow = overflow;
193 return calRelation;
194 }
195} // namespace R3B::Neuland::calibration
FTBaseCal(std::string_view hist_name, int moduleNum, const std::vector< FTType > &types)
TCalVFTXModulePar::ValueErrors ValueErrors
auto GetChannel2Time(TH1 *hist) const -> FTChannel2TimeRelation
PlaneCal(std::string_view hist_name, int mID)
auto FTType2Str(FTType type) -> std::string_view
constexpr auto BarsPerPlane
constexpr auto SQRT_12
constexpr auto MaxFTValue
auto make_hist(Args &&... args)
Definition R3BShared.h:69
std::vector< ValueError< double > > value_error