Skip to content
Snippets Groups Projects
Commit 0325614b authored by w-klijn's avatar w-klijn Committed by GitHub
Browse files

Merge pull request #80 from eth-cscs/exporter_fixes

Exporter fixes
parents 319b7802 c19bca56
No related branches found
No related tags found
No related merge requests found
...@@ -65,6 +65,7 @@ external/tmp ...@@ -65,6 +65,7 @@ external/tmp
mechanisms/*.hpp mechanisms/*.hpp
# build path # build path
build build*
commit.msg commit.msg
...@@ -181,6 +181,8 @@ cl_options read_options(int argc, char** argv) { ...@@ -181,6 +181,8 @@ cl_options read_options(int argc, char** argv) {
TCLAP::ValueArg<util::optional<unsigned>> trace_max_gid_arg( TCLAP::ValueArg<util::optional<unsigned>> trace_max_gid_arg(
"T", "trace-max-gid", "only trace probes on cells up to and including <gid>", "T", "trace-max-gid", "only trace probes on cells up to and including <gid>",
false, defopts.trace_max_gid, "gid", cmd); false, defopts.trace_max_gid, "gid", cmd);
TCLAP::SwitchArg spike_output_arg(
"f","spike_file_output","save spikes to file", cmd, false);
cmd.reorder_arguments(); cmd.reorder_arguments();
cmd.parse(argc, argv); cmd.parse(argc, argv);
...@@ -241,6 +243,7 @@ cl_options read_options(int argc, char** argv) { ...@@ -241,6 +243,7 @@ cl_options read_options(int argc, char** argv) {
update_option(options.probe_soma_only, probe_soma_only_arg); update_option(options.probe_soma_only, probe_soma_only_arg);
update_option(options.trace_prefix, trace_prefix_arg); update_option(options.trace_prefix, trace_prefix_arg);
update_option(options.trace_max_gid, trace_max_gid_arg); update_option(options.trace_max_gid, trace_max_gid_arg);
update_option(options.spike_file_output, spike_output_arg);
save_file = ofile_arg.getValue(); save_file = ofile_arg.getValue();
} }
......
...@@ -21,7 +21,6 @@ namespace io { ...@@ -21,7 +21,6 @@ namespace io {
template <typename Time, typename CommunicationPolicy> template <typename Time, typename CommunicationPolicy>
class exporter_spike_file : public exporter<Time, CommunicationPolicy> { class exporter_spike_file : public exporter<Time, CommunicationPolicy> {
public: public:
using time_type = Time; using time_type = Time;
using spike_type = spike<cell_member_type, time_type>; using spike_type = spike<cell_member_type, time_type>;
...@@ -31,64 +30,69 @@ public: ...@@ -31,64 +30,69 @@ public:
// over_write if true will overwrite the specified output file (default = true) // over_write if true will overwrite the specified output file (default = true)
// output_path relative or absolute path // output_path relative or absolute path
// file_name will be appended with "_x" with x the rank number // file_name will be appended with "_x" with x the rank number
// file_extention a seperator will be added automatically // file_extension a seperator will be added automatically
exporter_spike_file( exporter_spike_file(
const std::string& file_name, const std::string& path, const std::string& file_name,
const std::string& file_extention, bool over_write=true) const std::string& path,
const std::string& file_extension,
bool over_write=true)
{ {
auto file_path = file_path_ =
create_output_file_path(file_name, path, file_extention, create_output_file_path(
communication_policy_.id()); file_name, path, file_extension, communication_policy_.id());
//test if the file exist and depending on over_write throw or delete //test if the file exist and depending on over_write throw or delete
if (!over_write && file_exists(file_path)) { if (!over_write && file_exists(file_path_)) {
throw std::runtime_error("Tried opening file for writing but it exists and over_write is false: " + throw std::runtime_error(
file_path); "Tried opening file for writing but it exists and over_write is false: " + file_path_);
} }
file_handle_.open(file_path); file_handle_.open(file_path_);
} }
// Performs the a export of the spikes to file // Performs the a export of the spikes to file
// one id and spike time with 4 decimals after the comma on a // one id and spike time with 4 decimals after the comma on a
// line space separated // line space separated
void output(const std::vector<spike_type>& spikes) override { void output(const std::vector<spike_type>& spikes) override {
for (auto spike : spikes) { for (auto spike : spikes) {
char linebuf[45]; char linebuf[45];
auto n = std::snprintf(linebuf, sizeof(linebuf), "%u %.4f\n", auto n =
unsigned{spike.source.gid}, float(spike.time)); std::snprintf(
linebuf, sizeof(linebuf), "%u %.4f\n",
unsigned{spike.source.gid}, float(spike.time));
file_handle_.write(linebuf, n); file_handle_.write(linebuf, n);
} }
} }
bool good() const override { bool good() const override {
return file_handle_.good(); return file_handle_.good();
} }
// Creates an indexed filename // Creates an indexed filename
static std::string create_output_file_path( static std::string create_output_file_path(
const std::string& file_name, const std::string& path, const std::string& file_name,
const std::string& file_extention, unsigned index) const std::string& path,
const std::string& file_extension,
unsigned index)
{ {
// Nest does not produce the indexing for nrank == 0 return path + file_name + "_" + std::to_string(index) + "." + file_extension;
// I have the feeling this disrupts consistent output. Id rather }
// always put the zero in. it allows a simpler regex when opening
// files // The name of the output path and file name.
return path + file_name + "_" + std::to_string(index) + "." + // May be either relative or absolute path.
file_extention; const std::string& file_path() const {
return file_path_;
} }
private: private:
bool file_exists(const std::string& file_path) { bool file_exists(const std::string& file_path) {
std::ifstream fid(file_path); std::ifstream fid(file_path);
return fid.good(); return fid.good();
} }
// Handle to opened file handle // Handle to opened file handle
std::ofstream file_handle_; std::ofstream file_handle_;
std::string file_path_;
communication_policy_type communication_policy_; communication_policy_type communication_policy_;
}; };
......
...@@ -19,21 +19,20 @@ protected: ...@@ -19,21 +19,20 @@ protected:
nest::mc::io::exporter_spike_file<time_type, communicator_type>; nest::mc::io::exporter_spike_file<time_type, communicator_type>;
using spike_type = exporter_type::spike_type; using spike_type = exporter_type::spike_type;
std::string file_name; std::string file_name_;
std::string path; std::string path_;
std::string extention; std::string extension_;
unsigned index; unsigned index_;
exporter_spike_file_fixture() : exporter_spike_file_fixture() :
file_name("spikes_exporter_spike_file_fixture"), file_name_("spikes_exporter_spike_file_fixture"),
path("./"), path_("./"),
extention("gdf"), extension_("gdf"),
index(0) index_(communicator_type::id())
{} {}
std::string get_standard_file_name() { std::string get_standard_file_name() {
return exporter_type::create_output_file_path( return exporter_type::create_output_file_path(file_name_, path_, extension_, index_);
file_name, path, extention, 0);
} }
void SetUp() { void SetUp() {
...@@ -50,7 +49,7 @@ protected: ...@@ -50,7 +49,7 @@ protected:
}; };
TEST_F(exporter_spike_file_fixture, constructor) { TEST_F(exporter_spike_file_fixture, constructor) {
exporter_type exporter(file_name, path, extention, true); exporter_type exporter(file_name_, path_, extension_, true);
//test if the file exist and depending on over_write throw or delete //test if the file exist and depending on over_write throw or delete
std::ifstream f(get_standard_file_name()); std::ifstream f(get_standard_file_name());
...@@ -58,14 +57,14 @@ TEST_F(exporter_spike_file_fixture, constructor) { ...@@ -58,14 +57,14 @@ TEST_F(exporter_spike_file_fixture, constructor) {
// We now know the file exists, so create a new exporter with overwrite false // We now know the file exists, so create a new exporter with overwrite false
try { try {
exporter_type exporter1(file_name, path, extention, false); exporter_type exporter1(file_name_, path_, extension_, false);
FAIL() << "expected a file already exists error"; FAIL() << "expected a file already exists error";
} }
catch (std::runtime_error const & err) { catch (const std::runtime_error& err) {
EXPECT_EQ( EXPECT_EQ(
err.what(), err.what(),
std::string("Tried opening file for writing but it exists and over_write is false: " + "Tried opening file for writing but it exists and over_write is false: " +
get_standard_file_name()) get_standard_file_name()
); );
} }
catch (...) { catch (...) {
...@@ -86,7 +85,7 @@ TEST_F(exporter_spike_file_fixture, create_output_file_path) { ...@@ -86,7 +85,7 @@ TEST_F(exporter_spike_file_fixture, create_output_file_path) {
TEST_F(exporter_spike_file_fixture, do_export) { TEST_F(exporter_spike_file_fixture, do_export) {
{ {
exporter_type exporter(file_name, path, extention); exporter_type exporter(file_name_, path_, extension_);
// Create some spikes // Create some spikes
std::vector<spike_type> spikes; std::vector<spike_type> spikes;
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment