diff --git a/Device/IO/IOFactory.cpp b/Device/IO/IOFactory.cpp index ca0c08528e5910896d034c081e2dc3f135d05f36..baae6e36a28e904bb250da2e166d0a451e0c43cf 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 5dd36fe0361e1ee5468861266f40ddcac245544d..15dbd006c30344e3803f9fcf32e0a4c986082946 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 6492610f0b83128d92ca474dced85f365ae20d92..f56b3f96b45319c9690645c4ac779ae16b586259 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 60d69021671eafbe8884f57574e2111dd7429319..5ec6931efea1073d8fe3862e320784173f378f81 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]);