R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
R3BParRootFileIo.cxx
Go to the documentation of this file.
1#include "R3BParRootFileIo.h"
3#include "R3BException.h"
4#include <FairParIo.h>
5#include <FairParSet.h>
6#include <FairRtdbRun.h>
7#include <TError.h>
8#include <TFile.h>
9#include <TObject.h>
10#include <fairlogger/Logger.h>
11#include <fmt/core.h>
12#include <memory>
13#include <root/TKey.h>
14#include <string>
15#include <string_view>
16#include <utility>
17#include <vector>
18
19namespace R3B
20{
21 namespace
22 {
23 auto get_cycle_number(TFile* root_file, TObject* obj) -> int
24 {
25 if (auto* key = root_file->GetKey(obj->GetName()); key != nullptr)
26 {
27 return key->GetCycle();
28 }
29 LOGP(error,
30 "Failed to get the key with the name {:?} after it's written to the file {:?}",
31 obj->GetName(),
32 root_file->GetName());
33 return -1;
34 }
35
36 } // namespace
37
40 : is_input_{ is_input }
41 {
42 auto par_det_io = std::make_unique<DetParRootFileIo>(this);
43 setDetParIo(par_det_io.release());
44 }
45
46 void ParRootFileIo::open(std::unique_ptr<TFile> root_file)
47 {
48 if (root_file == nullptr)
49 {
50 throw R3B::runtime_error("Root file is nullptr!");
51 }
52 if (not root_file->IsOpen())
53 {
54 throw R3B::logic_error(fmt::format("Cannot open the root file {:?}", root_file->GetName()));
55 }
56 if (is_input_)
57 {
58 auto option = std::string_view{ root_file->GetOption() };
59 if (option != "read" and option != "READ")
60 {
61 LOGP(warn, "Input parameter file {:?} should have read only permision", root_file->GetName());
62 }
63 }
64 else
65 {
66 if (not root_file->IsWritable())
67 {
68 throw R3B::logic_error(fmt::format("Cannot write the root file {:?}", root_file->GetName()));
69 }
70 }
71 root_files_.push_back(std::move(root_file));
72 }
73
74 void ParRootFileIo::open(std::string_view file_name, std::string_view file_option)
75 {
76 open(std::make_unique<TFile>(file_name.data(), file_option.data()));
77 LOGP(debug, "Open root file {:?}", file_name);
78 }
79
80 void ParRootFileIo::open(const std::vector<std::string>& filenames, std::string_view file_option)
81 {
82 for (const auto& file_name : filenames)
83 {
84 open(file_name, file_option);
85 }
86 }
87
88 bool ParRootFileIo::read_parameter(FairParSet* par)
89 {
90 auto is_ok = read_parameter_from_run(par, false);
91 if (not is_ok)
92 {
93 is_ok = read_parameter_from_run(par, true);
94 }
95 return is_ok;
96 }
97
98 int ParRootFileIo::write_parameter(FairParSet* par)
99 {
100
101 if (par == nullptr)
102 {
103 throw R3B::runtime_error("Cannot write parameter which is nuulptr!");
104 }
105 auto* root_file = root_files_.front().get();
106
107 auto ret_val = root_file->WriteObject(par, par->GetName());
108
109 if (ret_val <= 0)
110 {
111 LOGP(error,
112 "Failed to write the parameter {:?} to the file {:?} with the return value: {}",
113 par->GetName(),
114 root_file->GetName(),
115 ret_val);
116 return -1;
117 }
118 return get_cycle_number(root_file, par);
119 }
120
121 auto ParRootFileIo::read_parameter_from_run(FairParSet* par, bool is_ignored) -> bool
122 {
123 auto old_log = gErrorIgnoreLevel;
124 gErrorIgnoreLevel = 1001; // NOLINT
125 const auto* par_name = par->GetName();
126 for (auto& root_file : root_files_)
127 {
128 if (not is_ignored)
129 {
130 auto* par_run = root_file->GetKey(run_name_.data());
131 if (par_run == nullptr)
132 {
133 continue;
134 }
135 }
136
137 auto ret_val = root_file->ReadTObject(par, par_name);
138 if (ret_val == 0)
139 {
140 continue;
141 }
142
143 LOGP(info, "Read parameter {:?} in the file {:?}", par_name, root_file->GetName());
144 gErrorIgnoreLevel = old_log;
145 return true;
146 }
147 gErrorIgnoreLevel = old_log;
148 return false;
149 }
150
151 void ParRootFileIo::readVersions(FairRtdbRun* current_par_run) { run_name_ = current_par_run->GetName(); }
152
154 {
155 if (not is_input_)
156 {
157 root_files_.front()->cd();
158 }
159 }
160
161 auto ParRootFileIo::check() -> bool
162 {
163 if (root_files_.empty())
164 {
165 if (is_input_)
166 {
167 LOGP(error, "Input parameter IO has no files to read!");
168 }
169 else
170 {
171 LOGP(error, "Output parameter IO has no file to write!");
172 }
173 return false;
174 }
175
176 if (not is_input_ and root_files_.size() > 1)
177 {
178 if (root_files_.size() > 1)
179 {
180 LOGP(warn, "Output parameter IO has more than one files (choosing the first)!");
181 for (auto& root_file : root_files_)
182 {
183 LOGP(warn, "\t{}", root_file->GetName());
184 }
185 }
186 }
187 return true;
188 }
189
191 {
192 for (const auto& root_file : root_files_)
193 {
194 LOGP(debug, "closing the par IO file {}", root_file->GetName());
195 root_file->Close();
196 }
197 FairParIo::close();
198 }
199} // namespace R3B
auto check() -> bool override
~ParRootFileIo() override
bool read_parameter(FairParSet *par)
Read a parameter from the input root file.
std::vector< std::unique_ptr< TFile > > root_files_
void open(std::string_view file_name, std::string_view file_option)
auto read_parameter_from_run(FairParSet *par, bool is_ignored) -> bool
void readVersions(FairRtdbRun *current_par_run) override
int write_parameter(FairParSet *par)
Write the parameter to the output root file.
ParRootFileIo(bool is_input)