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::string par;
48 std::string par_2;
50 struct Output
51 {
52 std::string working_dir;
53 std::string data = "output.root";
54 std::string par = "output.par.root";
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 set_inputpar_filename(std::string_view inputpar_filename) { option_.get().input.par = inputpar_filename; }
84 void set_second_inputpar_filename(std::string_view inputpar_filename)
85 {
86 option_.get().input.par_2 = inputpar_filename;
87 }
88 void set_outputpar_filename(std::string_view outputpar_filename)
89 {
90 option_.get().output.par = outputpar_filename;
91 }
92 void set_event_num(int val) { option_.get().event_num = val; }
93 void set_input_filename(const std::vector<std::string>& input_filename)
94 {
95 std::copy(input_filename.begin(), input_filename.end(), std::back_inserter(option_.get().input.data));
96 }
97 void set_tree_input_filename(const std::vector<std::string>& input_filename)
98 {
99 std::copy(input_filename.begin(), input_filename.end(), std::back_inserter(option_.get().input.tree_data));
100 }
101
102 // Getters:
103
104 auto get_run() -> FairRun* { return run_.get(); }
105 auto has_mpi() -> bool { return option_.get().enable_mpi; }
106
107 protected:
108 template <typename OptionType>
109 void ParseApplicationOptionImp(const std::vector<std::string>& filename, OptionType& options);
110
111 private:
112 bool is_already_parsed_ = false; // guards for callbacks.
113 bool is_dump_ = false; // guards for callbacks.
116 int rank_num_ = 0;
117 std::string app_name_;
119 std::unique_ptr<FairRun> run_;
120 std::reference_wrapper<Options> option_;
121 TStopwatch timer_;
122 std::vector<std::pair<std::string, bool>> input_files_;
123
124 // private overriden virtual function:
125 void set_num_of_procs(int val) override { num_of_procs_ = val; }
126 void set_rank_num(int val) override { rank_num_ = val; }
128 void init() override;
129 void run() override;
130 void print_options() override { print_json_options(); }
131 [[nodiscard]] auto has_print_default_options() const -> bool override { return has_print_default_options_; }
132 [[nodiscard]] auto has_dump() const -> bool override { return is_dump_; }
133 void setup_options(CLI::App& program_options) override;
134 void post_parse() override;
135
136 // private virtual methods:
137 virtual void pre_init(FairRun* run) = 0;
138 virtual void ParseApplicationOption(const std::vector<std::string>& filename_or_option) = 0;
139 virtual void post_init(FairRun* run) {}
140 void add_input_filename(R3BFileSource2* filesource);
141 virtual void print_json_options() {}
142 virtual void dump_json_options(const std::string& filename) {}
143 virtual void run_action(FairRun* run, int num_of_events);
144 virtual void setup_application_options(CLI::App& program_options) {}
145
146 // private non-virtual methods:
147 void setup_common_options(CLI::App& program_options);
148 void add_inout_files();
149 void add_inout_pars();
150 void extract_input_files();
151 static void setup_logger();
152 static void patch_files_or_strings(nlohmann::ordered_json& json_obj,
153 const std::vector<std::string>& filenames_or_options);
154 };
155
156 template <typename OptionType>
157 void CLIApplication::print_json_options(const OptionType& options)
158 {
159 using json = nlohmann::ordered_json;
160 auto json_obj = json{ options };
161 if (json_obj.is_array())
162 {
163 fmt::print("{}\n", json_obj.front().dump(4));
164 }
165 else
166 {
167 fmt::print("{}\n", json_obj.dump(4));
168 }
169 }
170
171 template <typename OptionType>
172 void CLIApplication::dump_json_options(const OptionType& options, const std::string& filename)
173 {
174 using json = nlohmann::ordered_json;
175 auto file = std::ofstream{ filename, std::ios::trunc };
176 auto json_obj = json{ options };
177 if (json_obj.is_array())
178 {
179 file << json_obj.front().dump(4);
180 }
181 else
182 {
183 file << json_obj.dump(4);
184 }
185 fmt::println("Configuration of {} is saved into the file {:?}", app_name_, filename);
186 }
187
188 template <typename OptionType>
189 void CLIApplication::ParseApplicationOptionImp(const std::vector<std::string>& filenames_or_options,
190 OptionType& options)
191 {
192 auto json_obj = [&options]()
193 {
194 auto json_obj_tmp = nlohmann::ordered_json{ options };
195 return json_obj_tmp.is_array() ? json_obj_tmp.front() : json_obj_tmp;
196 }();
197 patch_files_or_strings(json_obj, filenames_or_options);
198 json_obj.get_to(options);
199 }
200} // 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)
void set_second_inputpar_filename(std::string_view inputpar_filename)
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)
void set_inputpar_filename(std::string_view inputpar_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
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