VIPRA Documentation
Loading...
Searching...
No Matches
output.hpp
1#pragma once
2
3#include <algorithm>
4#include <filesystem>
5#include <memory>
6
7#include "vipra/macros/module.hpp"
8#include "vipra/macros/parameters.hpp"
9
10#include "vipra/modules/module.hpp"
11#include "vipra/modules/output.hpp"
12
13#include "vipra/random/random.hpp"
14
15#include "vipra/special_modules/parameters.hpp"
16#include "vipra/types/idx.hpp"
17
18// TODO(rolland): add a write to module method, that writes to a module if loaded, does nothing if not
19
20namespace VIPRA::CoordModules {
21
22class OutputCoordinator : public Modules::Module<OutputCoordinator> {
23 // TODO(rolland): need to figure out how to get paths for each output
24 // - if multiple output modules use the same parameter, how do we split them up
25 // - maybe require a path parameter for each output module, in their constructor?
26 // - this would require a recompile for changing paths
27
28 public:
29 VIPRA_MODULE_NAME("coordinator");
30 VIPRA_MODULE_TYPE(Output);
31
32 VIPRA_REGISTER_PARAMS(VIPRA_PARAM("output_dir", _base_output_dir))
33
34 void reset_modules()
35 {
36 for ( auto& output : _outputs ) {
37 output->reset_module();
38 }
39 }
40
41 void add_output(
42 std::unique_ptr<Modules::Output>&& module,
43 std::function<void(void*, Parameters&, VIPRA::Random::Engine&)>&& config)
44 {
45 _outputs.emplace_back(std::move(module));
46 _configs.emplace_back(std::move(config));
47 }
48
49 void config(Parameters& paramIn, VIPRA::Random::Engine& engine)
50 {
51 paramIn.register_param(module_type(), module_name(), "output_dir");
52 _base_output_dir = paramIn.get_param<std::string>(module_type(), module_name(),
53 "output_dir", engine);
54
55 _current_output_dir = _base_output_dir;
56 create_output_directory(_current_output_dir);
57
58 for ( size_t i = 0; i < _outputs.size(); ++i ) {
59 _configs[i](_outputs[i].get(), paramIn, engine);
60 }
61 }
62
68 void new_run(VIPRA::idx runIdx)
69 {
70 _current_output_dir = _base_output_dir / std::to_string(runIdx);
71 create_output_directory(_current_output_dir);
72 }
73
79 void write()
80 {
81 std::for_each(_outputs.begin(), _outputs.end(),
82 [&](auto& output) { output->write(_current_output_dir); });
83 }
84
85 void timestep_update(VIPRA::timestep timestep, VIPRA::delta_t timestepSize,
86 VIPRA::State const& state)
87 {
88 std::for_each(_outputs.begin(), _outputs.end(), [&](auto& output) {
89 output->timestep_update(timestep, timestepSize, state);
90 });
91 }
92
99 void write_to_file(std::string const& filename, std::string const& value)
100 {
101 std::filesystem::path filepath = _current_output_dir / filename;
102 std::ofstream file(filepath);
103
104 if ( ! file.is_open() ) {
105 VIPRA_MODULE_ERROR("Could not open file for writing: {}", filepath.string());
106 }
107
108 file << value;
109
110 file.close();
111 }
112
113 private:
114 std::vector<std::unique_ptr<VIPRA::Modules::Output>> _outputs;
115 std::vector<std::function<void(void*, Parameters&, VIPRA::Random::Engine&)>> _configs;
116
117 std::filesystem::path _base_output_dir;
118 std::filesystem::path _current_output_dir;
119
120 void create_output_directory(std::filesystem::path const& directory) const
121 {
122 if ( std::filesystem::exists(directory) ) {
123 if ( std::filesystem::is_directory(directory) ) {
124 // directory exists and is actually a directory, all is good
125 return;
126 }
127
128 // exists but isn't a directory, error
129 VIPRA_MODULE_ERROR("Output directory already exists and is not a directory: {}",
130 directory.string());
131 }
132
133 // create and check it was actually created
134 if ( ! std::filesystem::create_directory(directory) ) {
135 if ( ! std::filesystem::exists(directory) )
136 VIPRA_MODULE_ERROR("Could not create output directory: {}", directory.string());
137 }
138 }
139};
140} // namespace VIPRA::CoordModules
void write()
Calls write on all outputs, returning a tuple of the results or VOID.
Definition output.hpp:79
void write_to_file(std::string const &filename, std::string const &value)
Writes a string to a file in the current output directory.
Definition output.hpp:99
void new_run(VIPRA::idx runIdx)
Creates a new output directory for the current simulation run.
Definition output.hpp:68
VIPRA Module Base CRTP Class.
Definition module.hpp:36
Definition parameters.hpp:20
auto get_param(Modules::Type module, std::string const &moduleName, std::string const &paramName, Random::Engine &engine) const -> std::remove_cvref_t< data_t >
Returns the value of the parameter if it exists, otherwise throws an error.
Definition parameters.hpp:87
void register_param(Modules::Type module, std::string const &moduleName, std::string const &paramName)
Registers a parameter for a module.
Definition parameters.cpp:28
Psuedo Random number engine.
Definition random.hpp:22
Struct that holds the updated positions and velocities of all pedestrians.
Definition state.hpp:12