From 40a02a725da2b60d19c22f51f82e60ad939c7587 Mon Sep 17 00:00:00 2001 From: program-- Date: Mon, 28 Aug 2023 11:20:34 -0700 Subject: [PATCH] fix: update output format again after discussion --- include/utilities/nexus_writer.hpp | 33 ++++++++++++++------------ src/NGen.cpp | 8 ++----- test/utils/nexus_writer_Test.cpp | 37 +++++++++++------------------- 3 files changed, 33 insertions(+), 45 deletions(-) diff --git a/include/utilities/nexus_writer.hpp b/include/utilities/nexus_writer.hpp index 45a9656db5..285714608b 100644 --- a/include/utilities/nexus_writer.hpp +++ b/include/utilities/nexus_writer.hpp @@ -15,7 +15,7 @@ // Changing these will affect both NetCDF and CSV outputs #define NGEN_VARIABLE_NEXUS_ID "feature_id" -#define NGEN_VARIABLE_SEGMENT_ID "segment_id" +#define NGEN_VARIABLE_TIME "time" #define NGEN_VARIABLE_Q_LATERAL "q_lateral" namespace ngen { @@ -44,17 +44,17 @@ struct nexus_writer * * @param file_name File path to create * @param num_nexuses Number of nexuses contained in this output + * @param timestamp String timestamp for the timestep these values occur at */ - virtual void next(const std::string& file_name, size_type num_nexuses) = 0; + virtual void next(const std::string& file_name, size_type num_nexuses, const std::string& timestamp) = 0; /** * @brief Write a line to the current file. * - * @param segment_id Flowpath/segment ID * @param nexus_id Nexus ID * @param qlat Lateral streamflow */ - virtual void write(const std::string& segment_id, const std::string& nexus_id, double qlat) = 0; + virtual void write(const std::string& nexus_id, double qlat) = 0; /** * @brief Flush current output @@ -82,16 +82,16 @@ struct nexus_csv_writer : public nexus_writer it_--; } - void next(const std::string& file_name, size_type num_nexuses) override + void next(const std::string& file_name, size_type num_nexuses, const std::string& timestamp) override { it_++; it_->open(file_name + ".csv"); - (*it_) << NGEN_VARIABLE_NEXUS_ID "," NGEN_VARIABLE_SEGMENT_ID "," NGEN_VARIABLE_Q_LATERAL "\n"; + (*it_) << NGEN_VARIABLE_NEXUS_ID "," << timestamp << "\n"; } - void write(const std::string& segment_id, const std::string& nexus_id, double contribution) override + void write(const std::string& nexus_id, double contribution) override { - (*it_) << nexus_id << ',' << segment_id << ',' << std::setprecision(14) << contribution << '\n'; + (*it_) << nexus_id << ',' << std::setprecision(14) << contribution << '\n'; } void flush() override @@ -127,7 +127,7 @@ struct nexus_netcdf_writer : public nexus_writer #endif } - void next(const std::string& file_name, size_type num_nexuses) override + void next(const std::string& file_name, size_type num_nexuses, const std::string& timestamp) override { #ifndef NETCDF_ACTIVE NGEN_NETCDF_ERROR; @@ -140,25 +140,28 @@ struct nexus_netcdf_writer : public nexus_writer const auto& var_nexus_id = out->addVar(NGEN_VARIABLE_NEXUS_ID, netCDF::ncString, dim_fid); var_nexus_id.putAtt("description", "Contributing Nexus ID"); - - const auto& var_segment_id = out->addVar(NGEN_VARIABLE_SEGMENT_ID, netCDF::ncString, dim_fid); - var_segment_id.putAtt("description", "Flowpath ID downstream from the corresponding nexus"); const auto& var_qlat = out->addVar(NGEN_VARIABLE_Q_LATERAL, netCDF::ncDouble, dim_fid); var_qlat.putAtt("description", "Runoff into channel reach"); var_qlat.putAtt("units", "m3 s-1"); + + // TODO: Should be minutes since epoch? (aka netCDF::ncInt) + const auto& var_time = out->addVar(NGEN_VARIABLE_TIME, netCDF::ncString); + var_time.putAtt("description", "Output timestamp for this contribution"); + var_time.putAtt("standard_name", "time"); + var_time.putAtt("format", "%Y%m%s%H%M"); + var_time.putVar({0}, timestamp); index_ = 0; #endif } - void write(const std::string& segment_id, const std::string& nexus_id, double contribution) override + void write(const std::string& nexus_id, double contribution) override { #ifndef NETCDF_ACTIVE NGEN_NETCDF_ERROR; #else it_->get()->getVar(NGEN_VARIABLE_NEXUS_ID).putVar({ index_ }, nexus_id); - it_->get()->getVar(NGEN_VARIABLE_SEGMENT_ID).putVar({ index_ }, segment_id); it_->get()->getVar(NGEN_VARIABLE_Q_LATERAL).putVar({ index_ }, contribution); index_++; #endif @@ -188,5 +191,5 @@ struct nexus_netcdf_writer : public nexus_writer #undef NGEN_NETCDF_ERROR #undef NGEN_VARIABLE_NEXUS_ID -#undef NGEN_VARIABLE_SEGMENT_ID +#undef NGEN_VARIABLE_TIME #undef NGEN_VARIABLE_Q_LATERAL diff --git a/src/NGen.cpp b/src/NGen.cpp index 660f1c1b17..09c711297b 100644 --- a/src/NGen.cpp +++ b/src/NGen.cpp @@ -398,7 +398,7 @@ int main(int argc, char *argv[]) { boost::algorithm::erase_all(output_timestamp, ":"); // Remove Seconds output_timestamp = output_timestamp.substr(0, output_timestamp.size() - 2); - nexus_output->next(manager->get_output_root() + output_timestamp + "NEXOUT", num_nexuses); + nexus_output->next(manager->get_output_root() + output_timestamp + "NEXOUT", num_nexuses, output_timestamp); for(const auto& id : features.nexuses()) { #ifdef NGEN_MPI_ACTIVE @@ -420,11 +420,7 @@ int main(int argc, char *argv[]) { double contribution_at_t = features.nexus_at(id)->get_downstream_flow(cat_id, output_time_index, 100.0); - nexus_output->write( - nexus_collection->get_feature(id)->get_property("toid").as_string(), - id, - contribution_at_t - ); + nexus_output->write(id, contribution_at_t); #ifdef NGEN_MPI_ACTIVE } diff --git a/test/utils/nexus_writer_Test.cpp b/test/utils/nexus_writer_Test.cpp index e332d7ff68..f1bcabd645 100644 --- a/test/utils/nexus_writer_Test.cpp +++ b/test/utils/nexus_writer_Test.cpp @@ -21,11 +21,11 @@ class nexus_writer_Test : public ::testing::Test std::string write_to_file() { std::unique_ptr writer = std::make_unique(); - + writer->init(1); - writer->next(tempfile, 2); - writer->write("wb-1", "nex-1", 5); - writer->write("wb-2", "nex-2", 10); + writer->next(tempfile, 2, timestamp_); + writer->write("nex-1", 5); + writer->write("nex-2", 10); writer->flush(); return tempfile + ( @@ -35,6 +35,8 @@ class nexus_writer_Test : public ::testing::Test ); } + const std::string timestamp_ = "202308250000"; + private: std::string tempfile = testing::TempDir() + "/ngen_nexus_writer__test"; }; @@ -49,11 +51,11 @@ TEST_F(nexus_writer_Test, csv_writer) std::string line; stream >> line; - ASSERT_EQ(line, "feature_id,segment_id,q_lateral"); + ASSERT_EQ(line, "feature_id," + timestamp_); stream >> line; - ASSERT_EQ(line, "nex-1,wb-1,5"); + ASSERT_EQ(line, "nex-1,5"); stream >> line; - ASSERT_EQ(line, "nex-2,wb-2,10"); + ASSERT_EQ(line, "nex-2,10"); stream.close(); } @@ -75,25 +77,12 @@ TEST_F(nexus_writer_Test, netcdf_writer) const auto& var_nexus_id = stream.getVar("feature_id"); ASSERT_FALSE(var_nexus_id.isNull()); - char* nex_id_1 = nullptr; + std::string nex_id_1(5, ' '); var_nexus_id.getVar({ 0 }, &nex_id_1); - char* nex_id_2 = nullptr; + std::string nex_id_2(5, ' '); var_nexus_id.getVar({ 1 }, &nex_id_2); - ASSERT_STREQ(nex_id_1, "nex-1"); - ASSERT_STREQ(nex_id_2, "nex-2"); - delete nex_id_1; - delete nex_id_2; - - const auto& var_segment_id = stream.getVar("segment_id"); - ASSERT_FALSE(var_segment_id.isNull()); - char* seg_id_1 = nullptr; - var_segment_id.getVar({ 0 }, &seg_id_1); - char* seg_id_2 = nullptr; - var_segment_id.getVar({ 1 }, &seg_id_2); - ASSERT_STREQ(seg_id_1, "wb-1"); - ASSERT_STREQ(seg_id_2, "wb-2"); - delete seg_id_1; - delete seg_id_2; + ASSERT_EQ(nex_id_1, "nex-1"); + ASSERT_EQ(nex_id_2, "nex-2"); const auto& var_qlat = stream.getVar("q_lateral"); ASSERT_FALSE(var_qlat.isNull());