R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
R3BTrigIDMappingFinder.cxx
Go to the documentation of this file.
2#include "R3BException.h"
3#include "R3BShared.h"
4#include <R3BLogger.h>
5#include <algorithm>
6#include <filesystem>
7#include <fmt/core.h>
8#include <fstream>
9#include <iomanip>
10#include <ios>
11#include <nlohmann/json_fwd.hpp>
12#include <optional>
13#include <utility>
14#define JSON_USE_IMPLICIT_CONVERSIONS 0 // NOLINT
15#include <nlohmann/json.hpp>
16
17namespace nlh = nlohmann;
18
19namespace R3B::Neuland
20{
21 void TrigIDMappingRecorder::add(unsigned int trigID, R3B::Side side, unsigned int counts)
22 {
23 auto& record = (side == R3B::Side::left) ? left : right;
24 auto counter = record.find(trigID);
25 if (counter == record.end())
26 {
27 counter = record.insert({ trigID, 0 }).first;
28 }
29 (counter->second) += counts;
30 }
31
32 auto TrigIDMappingRecorder::findID(R3B::Side side) const -> std::optional<unsigned int>
33 {
34 const auto& record = (side == R3B::Side::left) ? left : right;
35 auto criteria = [](auto pre, auto post) { return pre.second < post.second; };
36 auto result = std::max_element(record.begin(), record.end(), criteria);
37 return (result != record.end()) ? result->first : std::optional<unsigned int>{};
38 }
39
40 void TrigIDMappingFinder::add_id_pair(std::pair<unsigned int, unsigned int> pair,
41 R3B::Side side,
42 unsigned int counts)
43 {
44 auto [moduleID, trigID] = pair;
45 auto record = records_.find(moduleID);
46 if (record == records_.end())
47 {
48 record = records_.insert({ moduleID, TrigIDMappingRecorder{} }).first;
49 }
50 record->second.add(trigID, side, counts);
51 }
52
54 {
55 for (auto& [moduleID, trigIDs] : trigIDMap)
56 {
57 if (trigIDs.first == 0)
58 {
59 auto pre = trigIDMap.find(moduleID - 1);
60 auto post = trigIDMap.find(moduleID + 1);
61 auto is_existed = (pre != trigIDMap.end() and post != trigIDMap.end());
62 auto is_same_left = (pre->second.first == post->second.first);
63 auto is_same_right = (pre->second.second == post->second.second);
64 if (is_existed and is_same_left and is_same_right)
65 {
66 trigIDs = { pre->second.first, pre->second.second };
67 continue;
68 }
69 R3BLOG(warn,
70 fmt::format("trigID can't be auto-resolved for moduleID: {}! Increase the event numbers to make "
71 "trigIDs on the two sides different.",
72 moduleID));
73 }
74 }
75 }
76
78 {
79 if (force_find or idMap_.empty())
80 {
82 }
83 return std::move(idMap_);
84 }
85
86 // Precondition: the trigIDs on two sides must be different!
88 {
89 idMap_.clear();
90 for (const auto& [moduleID, record] : records_)
91 {
92 auto trigID_left = record.findID(Side::left);
93 auto trigID_right = record.findID(Side::right);
94 if (trigID_left.has_value() and trigID_right.has_value())
95 {
96 if (trigID_left.value() != trigID_right.value())
97 {
98 idMap_.insert({ moduleID, { trigID_left.value(), trigID_right.value() } });
99 }
100 else
101 {
102 idMap_.insert({ moduleID, { 0, 0 } });
103 }
104 }
105 else
106 {
107 R3BLOG(error, fmt::format("Empty record for moduleID {}", moduleID));
108 }
109 }
111 }
112
114 {
115 switch (format_)
116 {
118 break;
120 Print_screen(trigMap);
121 break;
122 default:
123 throw R3B::logic_error("unrecognized TrigMappingPrinter option");
124 break;
125 }
126 }
127
129 {
130 fmt::print("==============TrigIDMapping=================\n");
131 fmt::print("{0:^18s}|{1:^18s}|{2:^18s}\n", "barID", "trigID_l", "trigID_r");
132 for (unsigned int moduleID{ 1 }; moduleID <= numOfModule_; ++moduleID)
133 {
134 if (auto trigID = trigMap.find(moduleID); trigID == trigMap.end())
135 {
136 fmt::print("{0:^18d}|{1:^18s}|{2:^18s}\n", moduleID, "NAN", "NAN");
137 }
138 else
139 {
140 fmt::print("{0:^18d}|{1:^18d}|{2:^18d}\n", moduleID, trigID->second.first, trigID->second.second);
141 }
142 }
143 fmt::print("============================================\n");
144 }
145
147 {
148 const auto filepath = fs::path{ fileDir_ } / fs::path{ filename_ };
149 fmt::print("Writing trigIDMap to JSON file {} ...\n", filepath);
150 auto ostream = std::ofstream(filepath, std::ios_base::out | std::ios_base::trunc);
151 auto jsonData = nlh::json::array();
152 auto jsonEntry = nlh::json::object();
153 for (const auto& [moduleID, id_pair] : trigMap)
154 {
155 jsonEntry["barID"] = moduleID;
156 jsonEntry["trigID_left"] = id_pair.first;
157 jsonEntry["trigID_right"] = id_pair.second;
158 jsonData.push_back(jsonEntry);
159 }
160 std::sort(jsonData.begin(),
161 jsonData.end(),
162 [](const auto& left, const auto& right) { return left.at("barID") < right.at("barID"); });
163 ostream << std::setw(4) << jsonData << "\n";
164 // ostream << jsonData.dump(4) << std::endl;
165 }
166
168 {
169 const auto filepath = fs::path{ fileDir_ } / fs::path{ filename_ };
170 // fmt::print("Reading trigIDMap from file {} ...\n", filepath);
171 auto istream = std::ifstream(filepath);
172 if (not istream.is_open())
173 {
174 throw R3B::runtime_error(fmt::format("Cannot open JSON file {}", filepath));
175 }
176 auto trigMap = TrigIDMappingFinder::TrigIDMap{};
177 auto jsonData = nlh::json::parse(istream);
178 for (const auto& jsonEntry : jsonData)
179 {
180 const auto moduleID = jsonEntry.at("barID").template get<int>();
181 const auto trigID_left = jsonEntry.at("trigID_left").template get<int>();
182 const auto trigID_right = jsonEntry.at("trigID_right").template get<int>();
183 trigMap.insert({ moduleID, std::make_pair(trigID_left, trigID_right) });
184 }
185 return trigMap;
186 }
187} // namespace R3B::Neuland
#define R3BLOG(severity, x)
Definition R3BLogger.h:32
std::unordered_map< unsigned int, TrigIDMappingRecorder > records_
void add_id_pair(std::pair< unsigned int, unsigned int > pair, R3B::Side side, unsigned int counts=1)
auto extract_trigIDMap(bool force_find=false) -> TrigIDMap
std::unordered_map< unsigned int, std::pair< unsigned int, unsigned int > > TrigIDMap
static void AutoResolve(TrigIDMap &trigIDMap)
TrigIDMappingPrintFormat format_
void Save_json(const TrigIDMappingFinder::TrigIDMap &trigMap) const
auto Read_json() const -> TrigIDMappingFinder::TrigIDMap
void Print_screen(const TrigIDMappingFinder::TrigIDMap &trigMap) const
void Print(const TrigIDMappingFinder::TrigIDMap &trigMap) const
STL class.
Simulation of NeuLAND Bar/Paddle.
void add(unsigned int trigID, R3B::Side side, unsigned int counts=1)
auto findID(R3B::Side side) const -> std::optional< unsigned int >