26#include <TGraphErrors.h>
34#include <range/v3/algorithm/all_of.hpp>
35#include <range/v3/iterator/operations.hpp>
36#include <range/v3/numeric/accumulate.hpp>
37#include <range/v3/view.hpp>
41#include <range/v3/view/all.hpp>
42#include <range/v3/view/filter.hpp>
43#include <range/v3/view/sliding.hpp>
44#include <range/v3/view/transform.hpp>
50namespace rng = ranges;
63 for (
auto& [module_num, module_par] : module_pars)
65 if (module_par.effective_speed.value != 0)
67 module_par.t_diff = module_par.t_diff / module_par.effective_speed;
75 for (
auto& [module_num, module_par] : module_pars)
77 module_par.t_diff = module_par.t_diff * module_par.effective_speed;
86 cal_to_hit_par_ =
GetTask()->GetCal2HitPar();
89 pede_launcher_.set_steer_filename(pede_steer_filename_);
90 pede_launcher_.set_parameter_filename(parameter_filename_);
91 if (
const auto* r3b_dir = std::getenv(
"R3BROOTPATH"); r3b_dir !=
nullptr)
93 pede_launcher_.set_binary_dir(fmt::format(
"{}/bin", r3b_dir));
98 "Environment variable R3BROOTPATH is not defined! Did you forget to source the \"config.sh\" file?");
101 data_preprocessor_ = std::make_unique<MilleDataProcessor>(
GetModuleSize());
102 data_preprocessor_->set_p_value_cut(p_value_cut_);
109 inline auto MillepedeEngine::to_module_num_label(
int par_num) -> std::pair<int, GlobalLabel>
111 const auto num_of_module = GetModuleSize();
112 auto res = std::pair<int, GlobalLabel>{};
113 const auto factor = (par_num - 1) / num_of_module;
114 res.first = (par_num - 1) % num_of_module + 1;
134 throw R3B::logic_error(fmt::format(
"An error occured with unrecognized global par id: {}", par_num));
140 inline auto MillepedeEngine::get_global_label_id(
int module_num,
GlobalLabel label) ->
int
142 const auto num_of_module = GetModuleSize();
154 return module_num + num_of_module;
160 void MillepedeEngine::fill_module_parameters(
const Millepede::ResultReader& result,
161 Neuland::Cal2HitPar& cal_to_hit_par)
163 change_time_offset(cal_to_hit_par);
164 const auto& pars = result.get_pars();
165 for (
const auto& [par_id, par] : pars)
167 const auto [module_num, global_label] = to_module_num_label(par_id);
170 auto& par_ref = module_pars.emplace(module_num, HitModulePar{}).first->second;
171 switch (global_label)
183 par_ref.effective_speed.value += par.value;
184 par_ref.effective_speed.error += par.error;
187 throw std::runtime_error(
"An error occured with unrecognized global tag");
191 calculate_time_offset(cal_to_hit_par);
194 auto MillepedeEngine::set_minimum_values(
const std::vector<R3B::Neuland::BarCalData>& signals) ->
bool
197 auto filtered_signals = rng::filter_view(
198 signals | rng::views::all,
199 [](
const auto& bar_signal) {
return bar_signal.left.size() == 1 and bar_signal.right.size() == 1; });
200 if (filtered_signals.empty())
205 if (not average_t_sum_.has_value())
207 auto t_sum_view = filtered_signals | rng::views::transform(
208 [](
const auto& bar_signal)
210 const auto& left_signal = bar_signal.left.front();
211 const auto& right_signal = bar_signal.right.front();
212 return (left_signal.leading_time - left_signal.trigger_time +
213 right_signal.leading_time - right_signal.trigger_time)
216 auto sum = rng::accumulate(t_sum_view, 0.F);
217 average_t_sum_ = sum /
static_cast<float>(rng::distance(t_sum_view.begin(), t_sum_view.end()));
218 R3BLOG(info, fmt::format(
"Average t_sum is calculated to be {}", average_t_sum_.value()));
226 if (signals.size() < minimum_hit_)
232 if (rng::all_of(signals |
233 rng::views::transform([](
const auto& bar_signal)
235 rng::views::sliding(2),
236 [](
const auto&
pair) {
return pair.front() ==
pair.back(); }))
241 if (not set_minimum_values(signals))
249 void MillepedeEngine::add_signal_t_sum(
const MilleCalData& signal)
252 const auto module_num =
static_cast<int>(signal.
module_num);
255 auto init_effective_c = cal_to_hit_par_->
GetModuleParAt(module_num).effective_speed.value;
257 const auto& left_signal = signal.
left;
258 const auto& right_signal = signal.
right;
259 const auto t_sum = (left_signal.leading_time - left_signal.trigger_time) +
260 (right_signal.leading_time - right_signal.trigger_time) - average_t_sum_.value_or(0.F);
264 input_data_buffer_.
sigma =
static_cast<float>(t_sum.error /
SCALE_FACTOR / 2. * error_scale_factor_);
266 const auto local_derivs_t = std::array{ 0.F, 0.F, pos_z /
SCALE_FACTOR, 0.F, 0.F, 1.F };
267 std::copy(local_derivs_t.begin(), local_derivs_t.end(), std::back_inserter(input_data_buffer_.
locals));
275 void MillepedeEngine::add_spacial_local_constraint(
int plane_id,
const std::vector<MilleCalData>& plane_signals)
281 const auto pos_bar_vert_disp = std::accumulate(plane_signals.begin(),
284 [](
double sum,
const auto& signal) {
285 return sum + GetBarVerticalDisplacement(signal.module_num);
287 static_cast<double>(plane_signals.size());
288 const auto local_derivs = is_horizontal ? std::array{ 0.F, pos_z /
SCALE_FACTOR, 0.F, 1.F }
293 input_data_buffer_.measurement =
static_cast<float>(pos_bar_vert_disp /
SCALE_FACTOR);
303 std::copy(local_derivs.begin(), local_derivs.end(), std::back_inserter(input_data_buffer_.locals));
307 void MillepedeEngine::add_signal_t_diff(
const MilleCalData& signal)
310 const auto module_num =
static_cast<int>(signal.module_num);
313 const auto& module_par = cal_to_hit_par_->GetModuleParAt(module_num);
314 auto init_effective_c = module_par.effective_speed.value;
315 auto init_t_offset = module_par.t_diff.value;
316 const auto pos_z =
static_cast<float>(
PlaneID2ZPos(plane_id));
318 const auto& left_signal = signal.left;
319 const auto& right_signal = signal.right;
320 const auto t_diff = (right_signal.leading_time - right_signal.trigger_time) -
321 (left_signal.leading_time - left_signal.trigger_time);
323 const auto t_error = t_diff.error == 0 ?
DEFAULT_T_ERROR : t_diff.error;
324 input_data_buffer_.measurement =
static_cast<float>((init_effective_c * init_t_offset / 2. /
SCALE_FACTOR) -
326 input_data_buffer_.sigma =
327 static_cast<float>(t_error /
SCALE_FACTOR / 2. * std::abs(init_effective_c) * error_scale_factor_);
328 const auto local_derivs = is_horizontal ? std::array{ pos_z /
SCALE_FACTOR, 0.F, 1.F, 0.F }
332 std::copy(local_derivs.begin(), local_derivs.end(), std::back_inserter(input_data_buffer_.locals));
350 "Writting Mille data to binary file with meas = {} and z = {}", input_data_buffer_.measurement, pos_z));
353 auto MillepedeEngine::select_t_diff_signal(
const std::vector<MilleCalData>& plane_data)
355 if (plane_data.empty())
357 return plane_data.end();
359 auto calculate_residual = [
this](
const MilleCalData& signal) ->
double
361 const auto t_diff = (signal.right.leading_time - signal.right.trigger_time) -
362 (signal.left.leading_time - signal.left.trigger_time);
363 const auto& module_par = cal_to_hit_par_->GetModuleParAt(signal.module_num);
364 const auto position = (-t_diff + module_par.t_diff) / 2 * module_par.effective_speed;
366 data_preprocessor_->calculate_residual(position.value,
static_cast<int>(signal.module_num));
369 auto iter = std::min_element(plane_data.begin(),
371 [calculate_residual](
const auto& first,
const auto& second)
372 { return calculate_residual(first) < calculate_residual(second); });
373 if (iter != plane_data.end())
375 auto residual = calculate_residual(*iter);
376 hist_t_offset_residual_->Fill(residual);
377 if (residual > t_diff_residual_cut_)
379 return plane_data.end();
390 if (not data_preprocessor_->filter(signals))
394 const auto& processed_data = data_preprocessor_->get_data();
395 for (
const auto& [plane_id, plane_signals] :
397 rng::views::filter([](
const auto& planeid_signals) {
return not planeid_signals.second.empty(); }))
400 auto iter = select_t_diff_signal(plane_signals);
401 if (iter == plane_signals.end())
409 add_signal_t_diff(*iter);
410 add_spacial_local_constraint(plane_id, plane_signals);
417 binary_data_writer_.close();
418 R3BLOG(info,
"Launching pede algorithm..");
419 pede_launcher_.launch();
420 pede_launcher_.end();
423 fill_module_parameters(par_result_, hit_par);
424 fill_data_to_figure(hit_par);
427 void MillepedeEngine::fill_data_to_figure(
Cal2HitPar& hit_par)
430 for (
const auto& [module_num, par] : pars)
432 graph_time_offset_->SetPoint(
static_cast<int>(module_num), module_num, par.t_diff.value);
433 graph_time_offset_->SetPointError(
static_cast<int>(module_num), 0., par.t_diff.error);
434 graph_time_sync_->SetPoint(
static_cast<int>(module_num), module_num, par.t_sync.value);
435 graph_time_sync_->SetPointError(
static_cast<int>(module_num), 0., par.t_sync.error);
436 graph_effective_c_->SetPoint(
static_cast<int>(module_num), module_num, par.effective_speed.value);
437 graph_effective_c_->SetPointError(
static_cast<int>(module_num), 0., par.effective_speed.error);
444 binary_data_writer_.end();
445 data_preprocessor_->reset();
454 graph_time_offset_ = histograms.
add_graph(
"time_offset", std::make_unique<TGraphErrors>(module_size));
455 graph_time_offset_->SetTitle(
"Time offset vs BarNum");
457 graph_time_sync_ = histograms.
add_graph(
"time_sync", std::make_unique<TGraphErrors>(module_size));
458 graph_time_sync_->SetTitle(
"Time sync vs BarNum");
460 graph_effective_c_ = histograms.
add_graph(
"effective_c", std::make_unique<TGraphErrors>(module_size));
461 graph_effective_c_->SetTitle(
"Effective c vs BarNum");
463 static constexpr auto RESIDUAL_BIN_NUM = 500;
464 hist_t_offset_residual_ = histograms.
add_hist<TH1D>(
465 "t_diff_residual",
"Residual values of the positios calculated from t_dff", RESIDUAL_BIN_NUM, 0., 1000.);
468 void MillepedeEngine::buffer_clear()
470 input_data_buffer_.
locals.clear();
471 input_data_buffer_.
globals.clear();
473 input_data_buffer_.
sigma = 0.F;
476 void MillepedeEngine::write_to_buffer() { binary_data_writer_.
mille(input_data_buffer_); }
480 average_t_sum_.reset();
484 void MillepedeEngine::init_parameter()
486 if (cal_to_hit_par_ ==
nullptr)
492 void MillepedeEngine::init_steer_writer()
496 steer_writer.set_parameter_file(parameter_filename_);
497 steer_writer.set_data_filepath(input_data_filename_);
498 static constexpr auto NUMBER_OF_ITERARTION = 3.F;
499 static constexpr auto CONVERGENCE_RECOGNITION = 0.001F;
501 std::make_pair(NUMBER_OF_ITERARTION, CONVERGENCE_RECOGNITION));
502 steer_writer.add_other_options(std::vector<std::string>{
"hugecut",
"50000" });
503 steer_writer.add_other_options(std::vector<std::string>{
"outlierdownweighting",
"4" });
521 steer_writer.write();
#define R3BLOG(severity, x)
constexpr auto SCALE_FACTOR
constexpr auto DEFAULT_T_ERROR
constexpr auto DEFAULT_RES_FILENAME
constexpr auto MILLE_BUFFER_SIZE
auto add_hist(std::unique_ptr< TH1 > hist) -> TH1 *
auto add_graph(std::string_view graph_name, std::unique_ptr< GraphType > graph) -> GraphType *
void mille(const MilleDataPoint &data_point)
auto GetListOfModuleParRef() -> auto &
auto GetModuleParAt(unsigned int module_num) const -> const ::R3B::Neuland::HitModulePar &
auto GetListOfModulePar() const -> const std::unordered_map< unsigned int, ::R3B::Neuland::HitModulePar > &
auto GetTask() -> Cal2HitParTask *
auto GetModuleSize() const -> auto
void Calibrate(Cal2HitPar &hit_par) override
void EndOfEvent(unsigned int event_num=0) override
void EndOfTask() override
auto SignalFilter(const std::vector< BarCalData > &signals) -> bool override
void AddSignals(const std::vector< BarCalData > &signals) override
void EventReset() override
void HistInit(DataMonitor &histograms) override
void set_filepath(std::string_view filepath)
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
std::vector< std::pair< int, float > > globals
std::vector< float > locals