From ae7aac3929dd1c201f086f2e4bc5c933a317cf45 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de> Date: Wed, 10 May 2023 17:22:40 +0200 Subject: [PATCH] read|writeNumpyTxt in ns IO --- Device/IO/IOFactory.cpp | 6 ++---- Device/IO/ReadWriteNumpyTXT.cpp | 25 +++++++++--------------- Device/IO/ReadWriteNumpyTXT.h | 16 +++++++-------- Tests/Unit/Device/IOReaderWriterTest.cpp | 6 ++---- 4 files changed, 21 insertions(+), 32 deletions(-) diff --git a/Device/IO/IOFactory.cpp b/Device/IO/IOFactory.cpp index ca0c08528e5..baae6e36a28 100644 --- a/Device/IO/IOFactory.cpp +++ b/Device/IO/IOFactory.cpp @@ -65,8 +65,7 @@ Datafield* IOFactory::readDatafield(const std::string& file_name, LoaderSelector // Try to read ASCII by default. Binary maps to ASCII. // If the file is not actually a matrix of numbers, // the error will be thrown during the reading. - result = functional_read( - file_name, [](std::istream& s) { return ReadWriteNumpyTXT().readDatafield(s); }); + result = functional_read(file_name, [](std::istream& s) { return IO::readNumpyTxt(s); }); ASSERT(result); return result; @@ -89,8 +88,7 @@ void IOFactory::writeDatafield(const Datafield& data, const std::string& file_na functional_write(file_name, [&](std::ostream& s) { IO::writeTiff(data, s); }); #endif else - functional_write(file_name, - [&](std::ostream& s) { ReadWriteNumpyTXT().writeDatafield(data, s); }); + functional_write(file_name, [&](std::ostream& s) { IO::writeNumpyTxt(data, s); }); } catch (const std::exception& ex) { throw std::runtime_error("Failed writing to " + file_name + ": " + ex.what()); } diff --git a/Device/IO/ReadWriteNumpyTXT.cpp b/Device/IO/ReadWriteNumpyTXT.cpp index 5dd36fe0361..15dbd006c30 100644 --- a/Device/IO/ReadWriteNumpyTXT.cpp +++ b/Device/IO/ReadWriteNumpyTXT.cpp @@ -14,6 +14,7 @@ #include "Device/IO/ReadWriteNumpyTXT.h" #include "Base/Axis/Scale.h" +#include "Base/Util/Assert.h" #include "Base/Util/StringUtil.h" #include "Device/Data/ArrayUtil.h" #include "Device/Data/Datafield.h" @@ -69,7 +70,7 @@ void write2DRepresentation(const Datafield& data, std::ostream& output_stream) } // namespace -Datafield* ReadWriteNumpyTXT::readDatafield(std::istream& input_stream) +Datafield* IO::readNumpyTxt(std::istream& input_stream) { std::string line; std::vector<std::vector<double>> data; @@ -79,13 +80,8 @@ Datafield* ReadWriteNumpyTXT::readDatafield(std::istream& input_stream) line = BaseUtil::String::trim(line); if (line.empty() || !isDoubleStartChar(line[0])) continue; - - try { - std::vector<double> dataInRow = DataUtil::Format::parse_doubles(line); - data.push_back(dataInRow); - } catch (...) { - continue; - } + std::vector<double> dataInRow = DataUtil::Format::parse_doubles(line); + data.push_back(dataInRow); } // validating @@ -95,14 +91,12 @@ Datafield* ReadWriteNumpyTXT::readDatafield(std::istream& input_stream) ncols = data[0].size(); if (ncols == 0) - throw std::runtime_error("ReadNumpyTXTStrategy::readDatafield -> Error. " - "Cannot parse file"); + throw std::runtime_error("Numpy txt file has invalid content"); - for (size_t row = 0; row < nrows; row++) { + for (size_t row = 0; row < nrows; row++) if (data[row].size() != ncols) - throw std::runtime_error("ReadNumpyTXTStrategy::readDatafield -> Error. " + throw std::runtime_error("Error in Numpy txt file: " "Number of elements is different from row to row."); - } if (nrows < 2) return DataUtil::Array::createPField1D(data[0]).release(); @@ -118,7 +112,7 @@ Datafield* ReadWriteNumpyTXT::readDatafield(std::istream& input_stream) return DataUtil::Array::createPField2D(data).release(); } -void ReadWriteNumpyTXT::writeDatafield(const Datafield& data, std::ostream& output_stream) +void IO::writeNumpyTxt(const Datafield& data, std::ostream& output_stream) { output_stream << "# BornAgain Intensity Data" << std::endl; output_stream << "# Simple array suitable for numpy, matlab etc." << std::endl; @@ -132,7 +126,6 @@ void ReadWriteNumpyTXT::writeDatafield(const Datafield& data, std::ostream& outp write2DRepresentation(data, output_stream); break; default: - throw std::runtime_error("Error in DatafieldWriteNumpyTXTStrategy::writeDatafield: data " - "of unsupported dimensions"); + ASSERT(false); } } diff --git a/Device/IO/ReadWriteNumpyTXT.h b/Device/IO/ReadWriteNumpyTXT.h index 6492610f0b8..f56b3f96b45 100644 --- a/Device/IO/ReadWriteNumpyTXT.h +++ b/Device/IO/ReadWriteNumpyTXT.h @@ -3,7 +3,7 @@ // BornAgain: simulate and fit reflection and scattering // //! @file Device/IO/ReadWriteNumpyTXT.h -//! @brief Defines ReadWriteNumpyTXT +//! @brief Declares functions read|writeNumpyTxt //! //! @homepage http://www.bornagainproject.org //! @license GNU General Public License v3 or higher (see COPYING) @@ -22,13 +22,13 @@ class Datafield; -//! Class for reading and writing Datafield from simple ASCII file with the layout as in -//! numpy.savetxt. +namespace IO { -class ReadWriteNumpyTXT { -public: - static Datafield* readDatafield(std::istream& input_stream); - static void writeDatafield(const Datafield& data, std::ostream& output_stream); -}; +//! Reads Datafield from simple ASCII file with layout as in numpy.savetxt. +Datafield* readNumpyTxt(std::istream& input_stream); +//! Writes Datafield to simple ASCII file with layout as in numpy.savetxt. +void writeNumpyTxt(const Datafield& data, std::ostream& output_stream); + +}; // namespace IO #endif // BORNAGAIN_DEVICE_IO_READWRITENUMPYTXT_H diff --git a/Tests/Unit/Device/IOReaderWriterTest.cpp b/Tests/Unit/Device/IOReaderWriterTest.cpp index 60d69021671..5ec6931efea 100644 --- a/Tests/Unit/Device/IOReaderWriterTest.cpp +++ b/Tests/Unit/Device/IOReaderWriterTest.cpp @@ -42,11 +42,9 @@ TEST_F(IOReaderWriterTest, TestRWINT) TEST_F(IOReaderWriterTest, TestRWNumpyTXT) { std::stringstream ss; - ReadWriteNumpyTXT write_txt; - write_txt.writeDatafield(m_model_data, ss); + IO::writeNumpyTxt(m_model_data, ss); - ReadWriteNumpyTXT read_txt; - auto result = std::unique_ptr<Datafield>(read_txt.readDatafield(ss)); + auto result = std::unique_ptr<Datafield>(IO::readNumpyTxt(ss)); EXPECT_EQ(m_model_data.rank(), result->rank()); for (size_t i = 0, size = m_model_data.size(); i < size; ++i) EXPECT_EQ(m_model_data[i], (*result)[i]); -- GitLab