14#include "FairRootManager.h"
21#include "ext_data_struct_info.hh"
22#include "ext_h101_raw_nnp_tamex.h"
29#include <boost/regex/v5/regex.hpp>
30#include <boost/regex/v5/regex_fwd.hpp>
31#include <boost/regex/v5/regex_match.hpp>
32#include <boost/regex/v5/regex_search.hpp>
34#include <fairlogger/Logger.h>
39#include <range/v3/algorithm/equal.hpp>
40#include <range/v3/view/iota.hpp>
41#include <range/v3/view/take.hpp>
42#include <range/v3/view/zip.hpp>
53namespace views = ranges::views;
59 constexpr size_t PRINT_ERROR_MAX = 100000;
60 constexpr auto BarsPerPlane = 50;
61 const auto errorStrings = std::map<Errors, std::string>{
62 { Errors::module_size,
"Incompatible module size" },
63 { Errors::data_size,
"Incompatible signal size" },
64 { Errors::divider,
"Incompatible signal dividers" },
65 { Errors::indices,
"Incompatible module IDs" },
68 const auto SIDES = std::array<Side, 2>{ Side::left, Side::right };
69 template <
typename BinaryOperation,
typename Item0,
typename Item1>
70 constexpr auto CheckAmong(BinaryOperation optn,
const Item0& item0,
const Item1& item1) ->
bool
72 return optn(item0, item1);
75 template <
typename BinaryOperation,
typename Item0,
typename Item1,
typename... Items>
76 constexpr auto CheckAmong(BinaryOperation optn,
const Item0& item0,
const Item1& item1,
const Items&... items)
79 return CheckAmong(optn, item0, item1) && CheckAmong(optn, item1, items...);
82 template <
typename UnaryOperation,
typename... Items>
83 inline auto CheckAny(UnaryOperation optn,
const Items&... items)
85 return (optn(items) || ...);
88 template <
typename UnaryFunction,
typename... Items>
89 inline auto Zip_from(UnaryFunction optn,
const Items&... items)
91 return ranges::zip_view(optn(items)...);
94 template <
typename Signals,
typename ModuleNum_div
ider,
typename UnaryFunction>
95 inline void FillData(
const Signals& signals_view,
96 const ModuleNum_divider& moduleNum_divider_view,
99 auto range_begin = signals_view.begin();
100 auto range_iter = signals_view.begin();
101 for (
const auto& [module_num, divider] : moduleNum_divider_view)
103 for (; !(range_iter == signals_view.end() || range_iter == (range_begin + divider)); ++range_iter)
105 optn(*range_iter, module_num);
120 error_log_.insert_or_assign(Errors::module_size, 0);
121 error_log_.insert_or_assign(Errors::data_size, 0);
122 error_log_.insert_or_assign(Errors::indices, 0);
123 error_log_.insert_or_assign(Errors::divider, 0);
134 R3BLOG(error,
"Failed to setup structure information.");
141 auto* rootMan = FairRootManager::Instance();
159 "bar_FT_l",
"number of hits on left PMTS for each bar", BarBinSize, 0.5, 0.5 + BarBinSize);
161 "bar_FT_r",
"number of hits on right PMTS for each bar", BarBinSize, 0.5, 0.5 + BarBinSize);
166 template <
typename ErrorLog,
typename... Items>
167 auto CheckCondition(ErrorLog& log,
const Items&... items) ->
bool
169 auto ApplyCriterium = [&log, &items...](
Errors error,
auto criterium) ->
bool
171 if (!CheckAmong(criterium, items...))
178 return ApplyCriterium(Errors::module_size,
179 [](
const auto& left,
const auto& right) {
return left.BM ==
right.BM; }) &&
180 ApplyCriterium(Errors::data_size,
181 [](
const auto& left,
const auto& right) {
return left.B ==
right.B; }) &&
184 [](
const auto& left,
const auto& right)
185 {
return ranges::equal(views::take(
left.BMI,
left.BM), views::take(
right.BMI,
right.BM)); }) &&
188 [](
const auto& left,
const auto& right)
189 {
return ranges::equal(views::take(
left.BME,
left.BM), views::take(
right.BME,
right.BM)); });
193template <
typename ViewType>
197 const auto signals_sides_view =
198 ranges::zip_view(signalsPlane.tcl_T, signalsPlane.tfl_T, signalsPlane.tct_T, signalsPlane.tft_T, SIDES);
199 for (
const auto& [coarse_leading, fine_leading, coarse_trailing, fine_trailing, side] : signals_sides_view)
202 if (CheckAny([](
const auto& item) {
return item.BM == 0; },
208 R3BLOG(debug3, fmt::format(
"No signals at the current event from plane {}.", planeNum));
212 if (!CheckCondition(
error_log_, coarse_leading, fine_leading, coarse_trailing, fine_trailing))
218 const auto signal_size = coarse_leading.B;
219 R3BLOG(debug, fmt::format(
"Signals at the current event from plane {}: {}", planeNum, signal_size));
220 const auto barNum_divider_view = ranges::zip_view(span(coarse_leading.BMI), span(coarse_leading.BME));
222 const auto signals_view = Zip_from([](
const auto& item) {
return span(item.Bv); },
229 auto side_temp = side;
231 signals_view | ranges::views::take(signal_size),
232 barNum_divider_view | ranges::views::take(
module_size),
233 [&](
const auto& signals,
const auto& barNum)
235 const auto& [cl_time, fl_time, ct_time, ft_time] = signals;
238 doubleEdgeSignal.leading.coarse = cl_time;
239 doubleEdgeSignal.trailing.fine = ft_time;
240 doubleEdgeSignal.trailing.coarse = ct_time;
242 planeSignals.push_back(side_temp, barNum, doubleEdgeSignal);
246 "Writing a doube edge signal: barNum: {}, fl_time: {}, cl_time: {}, ft_time: {}, ct_time: {}",
260 histograms_.get(
"bar_FT_l")->Fill(barNum + (planeNum - 1) * BarsPerPlane);
264 histograms_.get(
"bar_FT_r")->Fill(barNum + (planeNum - 1) * BarsPerPlane);
273 const auto signalsAllPlanes = span(inputData->NN_P);
276 for (
const auto& [signalsPlane, plane_num] : ranges::zip_view(signalsAllPlanes, ranges::iota_view(1)))
279 if (!planeSignals.empty())
285 mappedData_.try_emplace(plane_num, std::move(planeSignals));
302 template <
typename ErrorLog,
typename... Items>
305 auto ApplyCriterium = [&log](
Errors error,
bool criterium) ->
bool
314 return ApplyCriterium(Errors::module_size, inputData->NN_TRIGCM == inputData->NN_TRIGFM) &&
315 ApplyCriterium(Errors::data_size, inputData->NN_TRIGC == inputData->NN_TRIGF) &&
316 ApplyCriterium(Errors::indices,
317 ranges::equal(views::take(inputData->NN_TRIGCMI, inputData->NN_TRIGCM),
318 views::take(inputData->NN_TRIGFMI, inputData->NN_TRIGFM))) &&
319 ApplyCriterium(Errors::divider,
320 ranges::equal(views::take(inputData->NN_TRIGCME, inputData->NN_TRIGCM),
321 views::take(inputData->NN_TRIGFME, inputData->NN_TRIGFM)));
327 if (!
is_triggered_ || inputData->NN_TRIGCM == 0 || inputData->NN_TRIGFM == 0)
338 const auto signal_size = inputData->NN_TRIGC;
339 auto const trigger_signals_view =
340 Zip_from([](
const auto& item) {
return span(item); }, inputData->NN_TRIGCv, inputData->NN_TRIGFv);
341 auto const moduleNum_divider_view = ranges::zip_view(span(inputData->NN_TRIGCMI), span(inputData->NN_TRIGCME));
342 FillData(ranges::views::take(trigger_signals_view, signal_size),
343 ranges::views::take(moduleNum_divider_view,
module_size),
344 [&](
const auto& signal_pack,
const auto& module_num)
346 const auto& [coarse_time, fine_time] = signal_pack;
348 trigDatum->second.signal.fine = fine_time;
349 trigDatum->second.signal.coarse = coarse_time;
351 fmt::format(
"Writing a trig signal: module ID: {}, fine time: {}, coarse_time: {}",
366 if (fair::Logger::GetConsoleSeverity() <= fair::Severity::info && ++
counter_ ==
max_limit_)
377 const auto neuland_trigger_regex = boost::regex{
"^NN_TRIG(C|F)(v|M)?(I|E)?$" };
378 auto res =
is_triggered_ && boost::regex_match(item_name.data(), neuland_trigger_regex);
384 const auto neuland_bar_regex = boost::regex{ R
"(^NN_P(\d*)t.*$)" };
385 auto result = boost::cmatch{};
386 if (boost::regex_search(item_name.data(), result, neuland_bar_regex))
388 const auto plane_num = std::stoi(result.str(1));
389 if (plane_num != 0 and plane_num <=
numPlanes_)
402 "The plane number of NeuLAND is not set. Please use R3BNeulandTamexReader2::SetMaxNbPalnes to set it.");
416 fmt::print(
"----------Tamex Reader Error Summary:--------------\n");
417 fmt::print(
"{0:^30}|{1:^10}\n",
"Causes",
"Counts");
420 fmt::print(
"{0:<30}|{1:^10}\n", errorStrings.at(key), counts);
422 fmt::print(
"---------------------------------------------------\n");
#define R3BLOG(severity, x)
ClassImp(R3BNeulandTamexReader2)
R3BNeulandTamexReader2::Errors Errors
struct EXT_STR_h101_raw_nnp_tamex_onion_t EXT_STR_h101_raw_nnp_tamex_onion
struct EXT_STR_h101_raw_nnp_tamex_t EXT_STR_h101_raw_nnp_tamex
R3B::PaddleTamexMappedData R3BPaddleTamexMappedData2
R3B::PaddleTamexTrigMappedData R3BPaddleTamexTrigMappedData
auto R3BRead() -> bool override
std::map< std::string, std::function< void(const R3B::PaddleTamexMappedData &, TH1 *)> > hist_actions_
auto ReadSignals(EXT_STR_h101_raw_nnp_tamex_onion *inputData) -> bool
auto check_bar_needed(std::string_view item_name) const -> bool
R3BNeulandTamexReader2(EXT_STR_h101_raw_nnp_tamex_onion *, size_t)
auto Init(ext_data_struct_info *) -> bool override
auto extract_plane_signals(const ViewType &signalsPlane, int planeNum)
R3B::DataMonitor histograms_
TrigMappedDataVector * mappedTrigDataPtr_
auto ReadTriggerSignals(EXT_STR_h101_raw_nnp_tamex_onion *inputData) -> bool
EXT_STR_h101_raw_nnp_tamex_onion * inputData_
auto check_trigger_needed(std::string_view item_name) const -> bool
std::map< Errors, uint > error_log_
MappedDataVector mappedData_
TrigMappedDataVector mappedTrigData_
void histogram_action(const R3B::PaddleTamexMappedData &mappedData)
MappedDataVector * mappedDataPtr_
auto MismappedItemRequired(std::string_view item_name) const -> bool override
R3BReader(TString const &)