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