R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
neuland_par_merger.cxx
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) 2019 GSI Helmholtzzentrum für Schwerionenforschung GmbH *
3 * Copyright (C) 2019-2023 Members of R3B Collaboration *
4 * *
5 * This software is distributed under the terms of the *
6 * GNU General Public Licence (GPL) version 3, *
7 * copied verbatim in the file "LICENSE". *
8 * *
9 * In applying this license GSI does not waive the privileges and immunities *
10 * granted to it by virtue of its status as an Intergovernmental Organization *
11 * or submit itself to any jurisdiction. *
12 ******************************************************************************/
13
14#include <FairLogger.h>
15#include <FairParSet.h>
16#include <FairRtdbRun.h>
17#include <R3BException.h>
18#include <R3BLogger.h>
19#include <R3BProgramOptions.h>
20#include <TCollection.h>
21#include <TFile.h>
22#include <TKey.h>
23#include <cstdlib>
24#include <exception>
25#include <fmt/core.h>
26#include <memory>
27#include <string>
28#include <string_view>
29#include <vector>
30
31namespace
32{
33 auto filenames_split(std::string_view namelist, std::string_view delimeter = ";") -> std::vector<std::string>
34 {
35 auto filenames = std::vector<std::string>{};
36 auto filename_begin = std::string::size_type{ 0 };
37 for (auto filename_end = std::string::size_type{ 0 }; filename_end != std::string::npos;
38 filename_begin = filename_end + 1)
39 {
40 filename_end = namelist.find(delimeter, filename_begin);
41 auto filename = namelist.substr(filename_begin, filename_end - filename_begin);
42 filenames.emplace_back(filename);
43 }
44 return filenames;
45 }
46
47 void fill_pars(std::vector<FairParSet*>& pars, TDirectory* input)
48 {
49 auto* keys = input->GetListOfKeys();
50 for (auto* key : TRangeDynCast<TKey>(keys))
51 {
52 auto* obj = key->ReadObj();
53 if (auto* dir = dynamic_cast<TDirectory*>(obj); dir != nullptr)
54 {
55 fill_pars(pars, dir);
56 }
57 else if (auto* par = dynamic_cast<FairParSet*>(obj); par != nullptr)
58 {
59 pars.push_back(par);
60 }
61 }
62 }
63
64 auto get_par_run(TFile* root_file) -> FairRtdbRun*
65 {
66 auto* keys = root_file->GetListOfKeys();
67 for (auto* key : TRangeDynCast<TKey>(keys))
68 {
69 if (auto* par_run = dynamic_cast<FairRtdbRun*>(key->ReadObj()); par_run != nullptr)
70 {
71 return par_run;
72 }
73 }
74 return nullptr;
75 }
76
77 auto make_default_par_version(FairParSet* par) -> std::unique_ptr<FairParVersion>
78 {
79 auto version = std::make_unique<FairParVersion>(par->GetName());
80 version->setRootVersion(1);
81 version->resetInputVersions();
82 return version;
83 }
84
85 void copy_par_version(FairRtdbRun* output_run, FairRtdbRun* input_run, FairParSet* par)
86 {
87 if (input_run != nullptr)
88 {
89 if (auto* par_version = input_run->getParVersion(par->GetName()); par_version != nullptr)
90 {
91 output_run->addParVersion(par_version);
92 return;
93 }
94 }
95 output_run->addParVersion(make_default_par_version(par).release());
96 }
97
98 void write_parameters(TFile* output, TFile* input)
99 {
100 auto pars = std::vector<FairParSet*>{};
101 fill_pars(pars, input);
102
103 auto* output_par_run = get_par_run(output);
104 auto* input_par_run = get_par_run(input);
105 if (output_par_run == nullptr)
106 {
107 throw R3B::runtime_error("Cannot get the FairRtdbRun from the output root file!");
108 }
109
110 for (auto* par : pars)
111 {
112 R3BLOG(info, fmt::format(R"(parameter "{}" is written to {}.)", par->GetName(), output->GetName()));
113 output->WriteObject<FairParSet>(par, par->GetName(), "overwrite");
114 copy_par_version(output_par_run, input_par_run, par);
115 }
116 // overwrite or writedelete
117 output->WriteObject<FairRtdbRun>(output_par_run, output_par_run->GetName(), "overwrite");
118 }
119
120 void merge_into_rootfile(TFile* output, const std::vector<std::string>& filenames)
121 {
122 for (const auto& filename : filenames)
123 {
124 auto inputfile = std::make_unique<TFile>(filename.c_str(), "READ");
125 write_parameters(output, inputfile.get());
126 }
127 }
128
129 void initialize_output_file(TFile* output, std::string_view base)
130 {
131 auto base_file = std::make_unique<TFile>(base.data(), "READ");
132 auto* par_run = get_par_run(base_file.get());
133 if (par_run == nullptr)
134 {
135 throw R3B::runtime_error(fmt::format(R"(Base file {} doesn't contain any FairRtdbRun!)", base));
136 }
137 output->WriteObject<FairRtdbRun>(par_run, par_run->GetName(), "overwrite");
138 }
139
140} // namespace
141
142auto main(int argc, char** argv) -> int
143{
144
145 using namespace std::string_literals;
146 //====================================================================================
147 // Program options:
148 auto programOptions = R3B::ProgramOptions("Parameter merge");
149 auto help = programOptions.create_option<bool>("help,h", "help message", false);
150 auto logLevel = programOptions.create_option<std::string>("logLevel,v", "set log level of fairlog", "info");
151 auto parameter_out = programOptions.create_option<std::string>(
152 "par-out", "set the path of the parameter file to merge into (only one allowed)");
153 auto parameter_in = programOptions.create_option<std::string>(
154 "par-in", "set the path of the parameter files to merge from (semicolon seperated)");
155 if (!programOptions.verify(argc, argv))
156 {
157 return EXIT_FAILURE;
158 }
159
160 FairLogger::GetLogger()->SetLogScreenLevel(logLevel().c_str());
161
162 const auto input_files = filenames_split(parameter_in());
163 const auto output_file = parameter_out();
164
165 if (input_files.empty())
166 {
167 R3BLOG(error, "empty input parameter file!");
168 }
169
170 auto output_rootfile = std::make_unique<TFile>(output_file.c_str(), "RECREATE");
171
172 try
173 {
174 initialize_output_file(output_rootfile.get(), input_files.front());
175 merge_into_rootfile(output_rootfile.get(), input_files);
176 }
177 catch (const std::exception& ex)
178 {
179 fmt::print("An exception has occurred: {}\n", ex.what());
180 }
181 catch (...)
182 {
183 fmt::print("An unrecgonised exception has occurred!\n");
184 }
185
186 return 0;
187}
#define R3BLOG(severity, x)
Definition R3BLogger.h:32
auto main(int argc, char **argv) -> int