R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
R3BNeulandApp.h
Go to the documentation of this file.
1#pragma once
2
4#include <TStopwatch.h>
5#include <algorithm>
6#include <fmt/core.h>
7#include <fstream>
8#include <functional>
9#include <ios>
10#include <iterator>
11#include <memory>
12#include <nlohmann/json.hpp>
13#include <nlohmann/json_fwd.hpp>
14#include <string>
15#include <string_view>
16#include <utility>
17#include <vector>
18
19class FairRun;
20class R3BFileSource2;
21
22namespace CLI
23{
24 class App;
25}
26
27namespace R3B::Neuland
28{
29 constexpr auto DEFAULT_EVENT_NUM = 100;
30 constexpr auto DEFAULT_RUN_ID = 999;
31 const auto DEFAULT_JSON_FILENAME = "config.json";
33 {
34 public:
35 struct Options
36 {
39 bool enable_mpi = false;
40 std::string log_level = "error";
41 std::string verbose_level = "user1";
42 struct Input
43 {
44 std::string working_dir;
45 std::vector<std::string> data;
46 std::vector<std::string> tree_data;
47 std::vector<std::string> par;
49 struct Output
50 {
51 std::string working_dir;
52 std::string data = "output.root";
53 std::string par = "output.par.root";
54 std::string mode = "update";
56 };
57
58 explicit CLIApplication(std::string_view name,
59 std::unique_ptr<FairRun> run,
60 std::reference_wrapper<Options> option);
63 auto operator=(const CLIApplication&) -> CLIApplication& = delete;
65 ~CLIApplication() override;
66
67 // common APIs:
68
69 template <typename CLIAPP, typename OptionType>
70 void setup_common_options(CLIAPP& program_options, OptionType& options);
71
72 template <typename OptionType>
73 void print_json_options(const OptionType& options);
74
75 template <typename OptionType>
76 void dump_json_options(const OptionType& options, const std::string& filename);
77
78 // setters:
79
80 void set_log_level(std::string_view log_level) { option_.get().log_level = log_level; }
81 void set_run_id(int run_id) { option_.get().run_id = run_id; }
82 void set_output_filename(std::string_view output_filename) { option_.get().output.data = output_filename; }
83 void add_inputpar_filename(std::string_view inputpar_filename)
84 {
85 option_.get().input.par.emplace_back(inputpar_filename);
86 }
87 void set_outputpar_filename(std::string_view outputpar_filename)
88 {
89 option_.get().output.par = outputpar_filename;
90 }
91 void set_event_num(int val) { option_.get().event_num = val; }
92 void set_input_filename(const std::vector<std::string>& input_filename)
93 {
94 std::copy(input_filename.begin(), input_filename.end(), std::back_inserter(option_.get().input.data));
95 }
96 void set_tree_input_filename(const std::vector<std::string>& input_filename)
97 {
98 std::copy(input_filename.begin(), input_filename.end(), std::back_inserter(option_.get().input.tree_data));
99 }
100
101 // Getters:
102
103 auto get_run() -> FairRun* { return run_.get(); }
104 auto has_mpi() -> bool { return option_.get().enable_mpi; }
105
106 protected:
107 template <typename OptionType>
108 void ParseApplicationOptionImp(const std::vector<std::string>& filename, OptionType& options);
109
110 private:
111 bool is_already_parsed_ = false; // guards for callbacks.
112 bool is_dump_ = false; // guards for callbacks.
115 int rank_num_ = 0;
116 std::string app_name_;
118 std::unique_ptr<FairRun> run_;
119 std::reference_wrapper<Options> option_;
120 TStopwatch timer_;
121 std::vector<std::pair<std::string, bool>> input_files_;
122
123 // private overriden virtual function:
124 void set_num_of_procs(int val) override { num_of_procs_ = val; }
125 void set_rank_num(int val) override { rank_num_ = val; }
127 void init() override;
128 void run() override;
129 void print_options() override { print_json_options(); }
130 [[nodiscard]] auto has_print_default_options() const -> bool override { return has_print_default_options_; }
131 [[nodiscard]] auto has_dump() const -> bool override { return is_dump_; }
132 void setup_options(CLI::App& program_options) override;
133 void post_parse() override;
134
135 // private virtual methods:
136 virtual void pre_init(FairRun* run) = 0;
137 virtual void ParseApplicationOption(const std::vector<std::string>& filename_or_option) = 0;
138 virtual void post_init(FairRun* run) {}
139 void add_input_filename(R3BFileSource2* filesource);
140 virtual void print_json_options() {}
141 virtual void dump_json_options(const std::string& filename) {}
142 virtual void run_action(FairRun* run, int num_of_events);
143 virtual void setup_application_options(CLI::App& program_options) {}
144
145 // private non-virtual methods:
146 void setup_common_options(CLI::App& program_options);
147 void add_inout_files();
148 void add_inout_pars();
149 void extract_input_files();
150 static void setup_logger();
151 static void patch_files_or_strings(nlohmann::ordered_json& json_obj,
152 const std::vector<std::string>& filenames_or_options);
153 };
154
155 template <typename OptionType>
156 void CLIApplication::print_json_options(const OptionType& options)
157 {
158 using json = nlohmann::ordered_json;
159 auto json_obj = json{ options };
160 if (json_obj.is_array())
161 {
162 fmt::print("{}\n", json_obj.front().dump(4));
163 }
164 else
165 {
166 fmt::print("{}\n", json_obj.dump(4));
167 }
168 }
169
170 template <typename OptionType>
171 void CLIApplication::dump_json_options(const OptionType& options, const std::string& filename)
172 {
173 using json = nlohmann::ordered_json;
174 auto file = std::ofstream{ filename, std::ios::trunc };
175 auto json_obj = json{ options };
176 if (json_obj.is_array())
177 {
178 file << json_obj.front().dump(4);
179 }
180 else
181 {
182 file << json_obj.dump(4);
183 }
184 fmt::println("Configuration of {} is saved into the file {:?}", app_name_, filename);
185 }
186
187 template <typename OptionType>
188 void CLIApplication::ParseApplicationOptionImp(const std::vector<std::string>& filenames_or_options,
189 OptionType& options)
190 {
191 auto json_obj = [&options]()
192 {
193 auto json_obj_tmp = nlohmann::ordered_json{ options };
194 return json_obj_tmp.is_array() ? json_obj_tmp.front() : json_obj_tmp;
195 }();
196 patch_files_or_strings(json_obj, filenames_or_options);
197 json_obj.get_to(options);
198 }
199} // namespace R3B::Neuland
CLIAbstract()=default
Default constructor.
void post_parse() override
Action done after the option parsing.
static void patch_files_or_strings(nlohmann::ordered_json &json_obj, const std::vector< std::string > &filenames_or_options)
auto operator=(const CLIApplication &) -> CLIApplication &=delete
void set_rank_num(int val) override
void set_input_filename(const std::vector< std::string > &input_filename)
virtual void setup_application_options(CLI::App &program_options)
std::vector< std::pair< std::string, bool > > input_files_
CLIApplication(const CLIApplication &)=delete
virtual void post_init(FairRun *run)
void set_outputpar_filename(std::string_view outputpar_filename)
void set_log_level(std::string_view log_level)
auto operator=(CLIApplication &&) -> CLIApplication &=delete
void run() override
Run the CLI program.
std::reference_wrapper< Options > option_
void ParseApplicationOptionImp(const std::vector< std::string > &filename, OptionType &options)
void add_input_filename(R3BFileSource2 *filesource)
CLIApplication(std::string_view name, std::unique_ptr< FairRun > run, std::reference_wrapper< Options > option)
auto has_dump() const -> bool override
Check whether the options should be dump to a JSON file.
auto has_print_default_options() const -> bool override
Check the flag whether the default options should be printed in JSON strings.
void set_output_filename(std::string_view output_filename)
void dump_json_options(const OptionType &options, const std::string &filename)
virtual void ParseApplicationOption(const std::vector< std::string > &filename_or_option)=0
void setup_options(CLI::App &program_options) override
Setup the CLI options given to the program.
virtual void pre_init(FairRun *run)=0
void add_inputpar_filename(std::string_view inputpar_filename)
virtual void run_action(FairRun *run, int num_of_events)
CLIApplication(CLIApplication &&)=delete
void init() override
Initialization of a CLI program.
auto get_run() -> FairRun *
void set_num_of_procs(int val) override
std::unique_ptr< FairRun > run_
void setup_common_options(CLIAPP &program_options, OptionType &options)
virtual void dump_json_options(const std::string &filename)
void set_tree_input_filename(const std::vector< std::string > &input_filename)
Simulation of NeuLAND Bar/Paddle.
constexpr auto DEFAULT_EVENT_NUM
const auto DEFAULT_JSON_FILENAME
constexpr auto DEFAULT_RUN_ID
nlohmann::ordered_json json
struct R3B::Neuland::CLIApplication::Options::Input input
struct R3B::Neuland::CLIApplication::Options::Output output