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 <FairParSet.h>
15#include <FairRtdbRun.h>
16#include <R3BException.h>
17#include <R3BLogger.h>
18#include <R3BProgramOptions.h>
19#include <TFile.h>
20#include <TKey.h>
21#include <fmt/format.h>
22#include <string>
23
24auto filenames_split(std::string_view namelist, std::string_view delimeter = ";") -> std::vector<std::string>
25{
26 auto filenames = std::vector<std::string>{};
27 auto filename_begin = std::string::size_type{ 0 };
28 for (auto filename_end = std::string::size_type{ 0 }; filename_end != std::string::npos;
29 filename_begin = filename_end + 1)
30 {
31 filename_end = namelist.find(delimeter, filename_begin);
32 auto filename = namelist.substr(filename_begin, filename_end - filename_begin);
33 filenames.emplace_back(filename);
34 }
35 return filenames;
36}
37
38void fill_pars(std::vector<FairParSet*>& pars, TDirectory* input)
39{
40 auto* keys = input->GetListOfKeys();
41 for (auto* key : TRangeDynCast<TKey>(keys))
42 {
43 auto* obj = key->ReadObj();
44 if (auto* dir = dynamic_cast<TDirectory*>(obj); dir != nullptr)
45 {
46 fill_pars(pars, dir);
47 }
48 else if (auto* par = dynamic_cast<FairParSet*>(obj); par != nullptr)
49 {
50 pars.push_back(par);
51 }
52 }
53}
54
55auto get_par_run(TFile* root_file) -> FairRtdbRun*
56{
57 auto* keys = root_file->GetListOfKeys();
58 for (auto* key : TRangeDynCast<TKey>(keys))
59 {
60 if (auto* par_run = dynamic_cast<FairRtdbRun*>(key->ReadObj()); par_run != nullptr)
61 {
62 return par_run;
63 }
64 }
65 return nullptr;
66}
67
68auto make_default_par_version(FairParSet* par) -> std::unique_ptr<FairParVersion>
69{
70 auto version = std::make_unique<FairParVersion>(par->GetName());
71 version->setRootVersion(1);
72 version->resetInputVersions();
73 return version;
74}
75
76void copy_par_version(FairRtdbRun* output_run, FairRtdbRun* input_run, FairParSet* par)
77{
78 if (input_run != nullptr)
79 {
80 if (auto* par_version = input_run->getParVersion(par->GetName()); par_version != nullptr)
81 {
82 output_run->addParVersion(par_version);
83 return;
84 }
85 }
86 output_run->addParVersion(make_default_par_version(par).release());
87}
88
89void write_parameters(TFile* output, TFile* input)
90{
91 auto pars = std::vector<FairParSet*>{};
92 fill_pars(pars, input);
93
94 auto* output_par_run = get_par_run(output);
95 auto* input_par_run = get_par_run(input);
96 if (output_par_run == nullptr)
97 {
98 throw R3B::runtime_error("Cannot get the FairRtdbRun from the output root file!");
99 }
100
101 for (auto* par : pars)
102 {
103 R3BLOG(info, fmt::format(R"(parameter "{}" is written to {}.)", par->GetName(), output->GetName()));
104 output->WriteObject<FairParSet>(par, par->GetName(), "overwrite");
105 copy_par_version(output_par_run, input_par_run, par);
106 }
107 // overwrite or writedelete
108 output->WriteObject<FairRtdbRun>(output_par_run, output_par_run->GetName(), "overwrite");
109}
110
111void merge_into_rootfile(TFile* output, const std::vector<std::string>& filenames)
112{
113 for (const auto& filename : filenames)
114 {
115 auto inputfile = std::make_unique<TFile>(filename.c_str(), "READ");
116 write_parameters(output, inputfile.get());
117 }
118}
119
120void initialize_output_file(TFile* output, std::string_view base)
121{
122 auto base_file = std::make_unique<TFile>(base.data(), "READ");
123 auto* par_run = get_par_run(base_file.get());
124 if (par_run == nullptr)
125 {
126 throw R3B::runtime_error(fmt::format(R"(Base file {} doesn't contain any FairRtdbRun!)", base));
127 }
128 output->WriteObject<FairRtdbRun>(par_run, par_run->GetName(), "overwrite");
129}
130
131auto main(int argc, char** argv) -> int
132{
133
134 using namespace std::string_literals;
135 //====================================================================================
136 // Program options:
137 auto programOptions = R3B::ProgramOptions("Parameter merge");
138 auto help = programOptions.create_option<bool>("help,h", "help message", false);
139 auto logLevel = programOptions.create_option<std::string>("logLevel,v", "set log level of fairlog", "info");
140 auto parameter_out = programOptions.create_option<std::string>(
141 "par-out", "set the path of the parameter file to merge into (only one allowed)");
142 auto parameter_in = programOptions.create_option<std::string>(
143 "par-in", "set the path of the parameter files to merge from (semicolon seperated)");
144 if (!programOptions.verify(argc, argv))
145 {
146 return EXIT_FAILURE;
147 }
148
149 FairLogger::GetLogger()->SetLogScreenLevel(logLevel().c_str());
150
151 const auto input_files = filenames_split(parameter_in());
152 const auto output_file = parameter_out();
153
154 if (input_files.empty())
155 {
156 R3BLOG(error, "empty input parameter file!");
157 }
158
159 auto output_rootfile = std::make_unique<TFile>(output_file.c_str(), "RECREATE");
160
161 try
162 {
163 initialize_output_file(output_rootfile.get(), input_files.front());
164 merge_into_rootfile(output_rootfile.get(), input_files);
165 }
166 catch (const std::exception& ex)
167 {
168 fmt::print("An exception has occurred: {}\n", ex.what());
169 }
170 catch (...)
171 {
172 fmt::print("An unrecgonised exception has occurred!\n");
173 }
174
175 return 0;
176}
#define R3BLOG(severity, x)
Definition R3BLogger.h:35
auto main() -> int
Definition ex_test.cxx:109
auto filenames_split(std::string_view namelist, std::string_view delimeter=";") -> std::vector< std::string >
void write_parameters(TFile *output, TFile *input)
void copy_par_version(FairRtdbRun *output_run, FairRtdbRun *input_run, FairParSet *par)
void fill_pars(std::vector< FairParSet * > &pars, TDirectory *input)
void initialize_output_file(TFile *output, std::string_view base)
void merge_into_rootfile(TFile *output, const std::vector< std::string > &filenames)
auto get_par_run(TFile *root_file) -> FairRtdbRun *
auto make_default_par_version(FairParSet *par) -> std::unique_ptr< FairParVersion >