4#include <FairParRootFileIo.h>
5#include <FairRootFileSink.h>
7#include <FairRuntimeDb.h>
8#include <TGeoManager.h>
10#include <fmt/format.h>
19 namespace fs = std::filesystem;
21 auto get_partition_from(
const std::vector<T>& elements,
int num_of_partitions,
int partition_num) -> span<const T>
23 const auto total_size = elements.size();
25 static_cast<int>(std::ceil(
static_cast<float>(total_size) /
static_cast<float>(num_of_partitions)));
26 if (step * partition_num >= total_size)
30 const auto span_size = step * (partition_num + 1) < total_size ? step : total_size - (step * partition_num);
31 return span<const T>{ &(elements.at(step * partition_num)), span_size };
37 using json = nlohmann::ordered_json;
39 std::unique_ptr<FairRun>
run,
40 std::reference_wrapper<Options> option)
43 , run_(std::move(
run))
53 R3BLOG(info,
"Writting all parameters to files");
54 run_->GetRuntimeDb()->writeContainers();
55 run_->GetSink()->Close();
64 fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
65 "\nNeuland Application finished with a failure!\n\n");
69 fmt::print(fmt::emphasis::bold | fg(fmt::color::green),
70 "\nNeuland Application finished successfully!\n\n");
72 fmt::print(
"Real time: {}s, cpu time: {}s\n", timer_.RealTime(), timer_.CpuTime());
78 R3BLOG(info,
"Initializaing application ...");
80 FairLogger::GetLogger()->SetLogScreenLevel(option_.get().log_level.c_str());
86 R3BLOG(info,
"Application is initialized.");
97 auto dump_config_callback = [
this](
const std::string& filename)
100 dump_json_filename_ = filename;
103 auto use_config_callback = [
this](
const std::vector<std::string>& filename)
105 if (not is_already_parsed_)
108 is_already_parsed_ =
true;
112 auto& options = option_.get();
114 .add_option_function<std::vector<std::string>>(
115 "-c, --config-file", use_config_callback,
"Set the json config file")
117 ->run_callback_for_default()
118 ->trigger_on_parse();
119 program_options.add_flag(
"--print-config", has_print_default_options_,
"Print default option value");
121 .add_option_function<std::string>(
"--dump-config", dump_config_callback,
"Dump the config into a json file")
122 ->default_val(dump_json_filename_)
123 ->run_callback_for_default()
125 program_options.add_option(
"-v, --verbose", options.log_level,
"Set the verbose level");
126 program_options.add_option(
"-n, --event-num", options.event_num,
"Set the event number")->capture_default_str();
127 program_options.add_option(
"--run-id", options.run_id,
"Set the run id")->capture_default_str();
129 program_options.add_option(
"-i, --input-file", options.input.data,
"Set the input filenames (regex)")
130 ->capture_default_str()
131 ->group(
"Input options");
133 .add_option(
"--input-tree-file",
134 options.input.tree_data,
135 "Set the input filenames (regex) containing only root tree")
136 ->group(
"Input options");
137 program_options.add_option(
"--par-in", options.input.par,
"Set the filename of the input parameter root file")
138 ->capture_default_str()
139 ->group(
"Input options");
142 "--par-in-second", options.input.par_2,
"Set the filename of the second input parameter root file")
143 ->group(
"Input options");
145 program_options.add_option(
"-o, --output-file", options.output.data,
"Set the output filename")
146 ->capture_default_str()
147 ->group(
"Output options");
149 .add_option(
"--par-out", options.output.par,
"Set the filename of the output parameter root file")
150 ->capture_default_str()
151 ->group(
"Output options");
154 void Application::add_inout_files()
156 const auto& option = option_.get();
159 const auto output_name =
160 option.enable_mpi ? fmt::format(
"{}.{}", option.output.data, rank_num_) : option.output.data;
161 if (not option_.get().output.data.empty())
164 auto file_path = option.output.working_dir.empty()
165 ? fs::path{ output_name }
166 : fs::path{ option.output.working_dir } / fs::path{ output_name };
167 auto file_sink = std::make_unique<FairRootFileSink>(file_path.c_str());
168 run_->SetSink(file_sink.release());
172 auto file_source = std::make_unique<R3BFileSource2>();
173 if (option_.get().run_id >= 0)
175 file_source->SetInitRunID(option_.get().run_id);
176 run_->SetRunId(option_.get().run_id);
177 R3BLOG(info, fmt::format(
"Filesource2: Set to run id {}", option_.get().run_id));
179 add_input_filename(file_source.get());
180 if (not file_source->IsEmpty())
182 run_->SetSource(file_source.release());
186 void Application::add_inout_pars()
188 auto file_path = fs::path{};
189 const auto& input_option = option_.get().input;
190 const auto& output_option = option_.get().output;
191 const auto& input_wd = input_option.working_dir;
192 const auto& output_wd = output_option.working_dir;
194 if (not input_option.par.empty())
197 input_wd.empty() ? fs::path{ input_option.par } : fs::path{ input_wd } / fs::path{ input_option.par };
198 auto fileio = std::make_unique<FairParRootFileIo>();
199 R3BLOG(info, fmt::format(
"Input first parameter file is {:?}", file_path.string()));
200 fileio->open(file_path.c_str(),
"READ");
201 run_->GetRuntimeDb()->setFirstInput(fileio.release());
204 if (not input_option.par_2.empty())
206 file_path = input_wd.empty() ? fs::path{ input_option.par_2 }
207 : fs::path{ input_wd } / fs::path{ input_option.par_2 };
208 auto fileio = std::make_unique<FairParRootFileIo>();
209 R3BLOG(info, fmt::format(
"Input second parameter file is {:?}", file_path.string()));
210 fileio->open(file_path.c_str(),
"READ");
211 run_->GetRuntimeDb()->setSecondInput(fileio.release());
214 if (not output_option.par.empty())
216 const auto& option = option_.get();
217 const auto output_name =
218 option.enable_mpi ? fmt::format(
"{}.{}", output_option.par, rank_num_) : output_option.par;
219 file_path = output_wd.empty() ? fs::path{ output_name } : fs::path{ output_wd } / fs::path{ output_name };
220 R3BLOG(info, fmt::format(
"Ouptut parameter file is {:?}", file_path.string()));
221 auto fileio = std::make_unique<FairParRootFileIo>(
true);
222 fileio->open(file_path.c_str(),
"RECREATE");
223 auto* rtdb = run_->GetRuntimeDb();
224 rtdb->setOutput(fileio.release());
230 auto max_event = option_.get().event_num;
231 max_event = max_event > 0 ? max_event : 0;
234 R3BLOG(info, fmt::format(
"{} is set to run with {} events", app_name_, max_event));
243 extract_input_files();
244 auto input_span = option_.get().enable_mpi ? get_partition_from(input_files_, num_of_procs_, rank_num_)
245 : span{ input_files_ };
246 for (
const auto& [filename, is_tree] : input_span)
248 filesource->
AddFile(filename, is_tree);
252 void Application::extract_input_files()
254 auto file_path = fs::path{};
255 const auto& working_dir = option_.get().input.working_dir;
256 for (
const auto& filename : option_.get().input.data)
259 file_path = working_dir.empty() ? fs::path{ filename } : fs::path{ working_dir } / fs::path{ filename };
261 for (
const auto& fairroot_input_file : fairroot_input_files)
263 input_files_.emplace_back(fairroot_input_file,
false);
266 for (
const auto& filename : option_.get().input.tree_data)
269 for (
const auto& tree_input_file : tree_input_files)
271 input_files_.emplace_back(tree_input_file,
true);
#define R3BLOG(severity, x)
virtual void run_action(FairRun *run, int num_of_events)
virtual void pre_init(FairRun *run)=0
Application(std::string_view name, std::unique_ptr< FairRun > run, std::reference_wrapper< Options > option)
void setup_options(CLI::App &program_options)
virtual void post_init(FairRun *run)
virtual void setup_application_options(CLI::App &program_options)
void setup_common_options(CLIAPP &program_options, OptionType &options)
virtual void ParseApplicationOption(const std::vector< std::string > &filename)=0
void AddFile(std::string file_name, bool is_tree_file=false)
Simulation of NeuLAND Bar/Paddle.
const auto DEFAULT_JSON_FILENAME
nlohmann::ordered_json json
auto GetFilesFromRegex(std::string_view filename_regex) -> std::vector< std::string >