From 956934e5f58138a54c7ac29ba3b2da36c40001a6 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de> Date: Sun, 27 Jun 2021 23:01:46 +0200 Subject: [PATCH] several namespaces -> under BaseUtils:: --- Base/Py/PyFmt.cpp | 6 +- Base/Py/PyUtils.cpp | 36 +- Base/Py/PyUtils.h | 4 +- Base/Utils/FileSystemUtils.cpp | 33 +- Base/Utils/FileSystemUtils.h | 4 +- Base/Utils/StringUtils.cpp | 27 +- Base/Utils/StringUtils.h | 6 +- Base/Utils/SysUtils.cpp | 12 +- Base/Utils/SysUtils.h | 4 +- Core/Fitting/FitObjective.h | 4 +- Core/Fitting/FitPrintService.cpp | 2 +- Core/Simulation/ISimulation.cpp | 2 +- Device/Data/ArrayUtils.h | 8 +- Device/Data/DataUtils.cpp | 13 +- Device/Histo/HistoUtils.cpp | 14 +- Device/Histo/Histogram1D.cpp | 6 +- Device/Histo/IntensityDataIOFactory.cpp | 6 +- Device/InputOutput/DataFormatUtils.cpp | 11 +- .../OutputDataReadReflectometry.cpp | 2 +- Device/InputOutput/OutputDataReadWriteINT.cpp | 2 +- .../InputOutput/OutputDataReadWriteNicos.cpp | 26 +- .../OutputDataReadWriteNumpyTXT.cpp | 2 +- .../InputOutput/OutputDataReadWriteTiff.cpp | 2 +- GUI/Models/RealDataItem.cpp | 3 +- GUI/Models/SaveLoadInterface.cpp | 2 +- .../FitWidgets/FitComparisonController.cpp | 4 +- .../FitComparisonViewController.cpp | 4 +- GUI/mainwindow/PyImportAssistant.cpp | 2 +- GUI/mainwindow/actionmanager.cpp | 2 +- Sample/Multilayer/PyImport.cpp | 8 +- Sample/Scattering/IFormFactor.cpp | 2 +- .../Core/Consistence/CompareTwoReferences.cpp | 2 +- .../Core/CoreSpecial/CoreIOPathTest.cpp | 4 +- .../CoreSpecial/FourierTransformationTest.cpp | 14 +- Tests/Functional/Core/Std/Check.cpp | 6 +- Tests/Functional/PyEmbedded/Tests.cpp | 810 +++++++++--------- Tests/Functional/PyStd/Check.cpp | 4 +- .../Core/Basics/FileSystemUtilsTest.cpp | 150 ++-- .../UnitTests/Core/Basics/StringUtilsTest.cpp | 76 +- auto/Wrap/doxygenBase.i | 287 ++++--- 40 files changed, 813 insertions(+), 799 deletions(-) diff --git a/Base/Py/PyFmt.cpp b/Base/Py/PyFmt.cpp index cc4b2dce8fc..932aff1cb09 100644 --- a/Base/Py/PyFmt.cpp +++ b/Base/Py/PyFmt.cpp @@ -30,7 +30,7 @@ std::string printImportedSymbols(const std::string& code) for (const std::string& key : {"kvector_t"}) if (code.find(key) != std::string::npos) to_declare.push_back(key); - return "from bornagain import " + StringUtils::join(to_declare, ", ") + "\n"; + return "from bornagain import " + BaseUtils::String::join(to_declare, ", ") + "\n"; } std::string printInt(int value) @@ -154,7 +154,7 @@ std::string printArguments(const std::vector<std::pair<double, std::string>>& ar std::vector<std::string> args; for (const auto& argument : arguments) args.push_back(pyfmt::printValue(argument.first, argument.second)); - return StringUtils::join(args, ", "); + return BaseUtils::String::join(args, ", "); } std::string @@ -163,7 +163,7 @@ printArguments(const std::vector<std::pair<std::variant<double, int>, std::strin std::vector<std::string> args; for (const auto& argument : arguments) args.push_back(pyfmt::printValue(argument.first, argument.second)); - return StringUtils::join(args, ", "); + return BaseUtils::String::join(args, ", "); } std::string printFunction(const std::string& name, diff --git a/Base/Py/PyUtils.cpp b/Base/Py/PyUtils.cpp index 49ef9191302..4683ca2aaa9 100644 --- a/Base/Py/PyUtils.cpp +++ b/Base/Py/PyUtils.cpp @@ -21,7 +21,7 @@ #include <sstream> #include <stdexcept> -std::string PyUtils::toString(PyObject* obj) +std::string BaseUtils::Python::toString(PyObject* obj) { std::string result; PyObject* pyStr = PyUnicode_AsEncodedString(obj, "utf-8", "Error ~"); @@ -30,7 +30,7 @@ std::string PyUtils::toString(PyObject* obj) return result; } -std::vector<std::string> PyUtils::toVectorString(PyObject* obj) +std::vector<std::string> BaseUtils::Python::toVectorString(PyObject* obj) { std::vector<std::string> result; @@ -47,12 +47,13 @@ std::vector<std::string> PyUtils::toVectorString(PyObject* obj) } } else - throw std::runtime_error("PyUtils::toVectorString() -> Error. Unexpected object."); + throw std::runtime_error( + "BaseUtils::Python::toVectorString() -> Error. Unexpected object."); return result; } -std::string PyUtils::toString(char* c) +std::string BaseUtils::Python::toString(char* c) { if (c) return c; @@ -60,7 +61,7 @@ std::string PyUtils::toString(char* c) return ""; } -std::string PyUtils::toString(wchar_t* c) +std::string BaseUtils::Python::toString(wchar_t* c) { if (!c) return ""; @@ -68,7 +69,7 @@ std::string PyUtils::toString(wchar_t* c) return std::string(wstr.begin(), wstr.end()); } -void PyUtils::import_bornagain(const std::string& path) +void BaseUtils::Python::import_bornagain(const std::string& path) { if (!Py_IsInitialized()) { Py_InitializeEx(0); @@ -97,7 +98,7 @@ void PyUtils::import_bornagain(const std::string& path) } } -std::string PyUtils::pythonRuntimeInfo() +std::string BaseUtils::Python::pythonRuntimeInfo() { Py_InitializeEx(0); @@ -105,19 +106,20 @@ std::string PyUtils::pythonRuntimeInfo() // Runtime environment result << std::string(60, '=') << "\n"; - result << "PATH: " << SysUtils::getenv("PATH") << "\n"; - result << "PYTHONPATH: " << SysUtils::getenv("PYTHONPATH") << "\n"; - result << "PYTHONHOME: " << SysUtils::getenv("PYTHONHOME") << "\n"; + result << "PATH: " << BaseUtils::System::getenv("PATH") << "\n"; + result << "PYTHONPATH: " << BaseUtils::System::getenv("PYTHONPATH") << "\n"; + result << "PYTHONHOME: " << BaseUtils::System::getenv("PYTHONHOME") << "\n"; // Embedded Python details - result << "Py_GetProgramName(): " << PyUtils::toString(Py_GetProgramName()) << "\n"; - result << "Py_GetProgramFullPath(): " << PyUtils::toString(Py_GetProgramFullPath()) << "\n"; - result << "Py_GetPath(): " << PyUtils::toString(Py_GetPath()) << "\n"; - result << "Py_GetPythonHome(): " << PyUtils::toString(Py_GetPythonHome()) << "\n"; + result << "Py_GetProgramName(): " << BaseUtils::Python::toString(Py_GetProgramName()) << "\n"; + result << "Py_GetProgramFullPath(): " << BaseUtils::Python::toString(Py_GetProgramFullPath()) + << "\n"; + result << "Py_GetPath(): " << BaseUtils::Python::toString(Py_GetPath()) << "\n"; + result << "Py_GetPythonHome(): " << BaseUtils::Python::toString(Py_GetPythonHome()) << "\n"; // Runtime Python's sys.path PyObject* sysPath = PySys_GetObject((char*)"path"); - auto content = PyUtils::toVectorString(sysPath); + auto content = BaseUtils::Python::toVectorString(sysPath); result << "sys.path: "; for (auto s : content) result << s << ","; @@ -129,7 +131,7 @@ std::string PyUtils::pythonRuntimeInfo() // Attempt to retrieve Python stack trace // https://stackoverflow.com/questions/1796510/accessing-a-python-traceback-from-the-c-api -std::string PyUtils::pythonStackTrace() +std::string BaseUtils::Python::pythonStackTrace() { std::stringstream result; @@ -169,7 +171,7 @@ std::string PyUtils::pythonStackTrace() return result.str(); } -PyObject* PyUtils::createNumpyArray(const std::vector<double>& data) +PyObject* BaseUtils::Python::createNumpyArray(const std::vector<double>& data) { const size_t ndim(1); npy_int ndim_numpy = ndim; diff --git a/Base/Py/PyUtils.h b/Base/Py/PyUtils.h index 05c3e1f147d..37ba01f8621 100644 --- a/Base/Py/PyUtils.h +++ b/Base/Py/PyUtils.h @@ -29,7 +29,7 @@ class MultiLayer; -namespace PyUtils { +namespace BaseUtils::Python { //! Converts PyObject into string, if possible, or throws exception. std::string toString(PyObject* obj); @@ -52,7 +52,7 @@ std::string pythonStackTrace(); PyObject* createNumpyArray(const std::vector<double>& data); -} // namespace PyUtils +} // namespace BaseUtils::Python #endif // BORNAGAIN_PYTHON diff --git a/Base/Utils/FileSystemUtils.cpp b/Base/Utils/FileSystemUtils.cpp index 7b502099ae9..bd21b00378e 100644 --- a/Base/Utils/FileSystemUtils.cpp +++ b/Base/Utils/FileSystemUtils.cpp @@ -3,7 +3,7 @@ // BornAgain: simulate and fit reflection and scattering // //! @file Base/Utils/FileSystemUtils.cpp -//! @brief Implements namespace FileSystemUtils +//! @brief Implements namespace BaseUtils::Filesystem //! //! @homepage http://www.bornagainproject.org //! @license GNU General Public License v3 or higher (see COPYING) @@ -22,14 +22,14 @@ namespace fs = std::filesystem; // make the code more readable -std::string FileSystemUtils::extension(const std::string& path) +std::string BaseUtils::Filesystem::extension(const std::string& path) { return fs::path(path).extension().string(); } -std::string FileSystemUtils::extensions(const std::string& path) +std::string BaseUtils::Filesystem::extensions(const std::string& path) { - const auto name = FileSystemUtils::filename(path); + const auto name = BaseUtils::Filesystem::filename(path); if (name == "..") return {}; @@ -37,7 +37,7 @@ std::string FileSystemUtils::extensions(const std::string& path) return pos != std::string::npos ? name.substr(pos, name.size() - pos) : ""; } -bool FileSystemUtils::createDirectory(const std::string& dir_name) +bool BaseUtils::Filesystem::createDirectory(const std::string& dir_name) { #ifdef _WIN32 return fs::create_directory(convert_utf8_to_utf16(dir_name)); @@ -46,7 +46,7 @@ bool FileSystemUtils::createDirectory(const std::string& dir_name) #endif } -bool FileSystemUtils::createDirectories(const std::string& dir_name) +bool BaseUtils::Filesystem::createDirectories(const std::string& dir_name) { #ifdef _WIN32 return fs::create_directories(convert_utf8_to_utf16(dir_name)); @@ -55,11 +55,11 @@ bool FileSystemUtils::createDirectories(const std::string& dir_name) #endif } -std::vector<std::string> FileSystemUtils::filesInDirectory(const std::string& dir_name) +std::vector<std::string> BaseUtils::Filesystem::filesInDirectory(const std::string& dir_name) { std::vector<std::string> ret; if (!fs::exists(dir_name)) - throw std::runtime_error("FileSystemUtils::filesInDirectory '" + dir_name + throw std::runtime_error("BaseUtils::Filesystem::filesInDirectory '" + dir_name + "' does not exist"); for (const auto& entry : fs::directory_iterator(dir_name)) @@ -69,7 +69,7 @@ std::vector<std::string> FileSystemUtils::filesInDirectory(const std::string& di return ret; } -std::string FileSystemUtils::jointPath(const std::string& path1, const std::string& path2) +std::string BaseUtils::Filesystem::jointPath(const std::string& path1, const std::string& path2) { ASSERT(path2 != ""); @@ -79,12 +79,13 @@ std::string FileSystemUtils::jointPath(const std::string& path1, const std::stri return (fs::path(path1) / fs::path(path2)).string(); } -std::string FileSystemUtils::filename(const std::string& path) +std::string BaseUtils::Filesystem::filename(const std::string& path) { return fs::path(path).filename().string(); } -std::vector<std::string> FileSystemUtils::glob(const std::string& dir, const std::string& pattern) +std::vector<std::string> BaseUtils::Filesystem::glob(const std::string& dir, + const std::string& pattern) { std::vector<std::string> ret; for (const std::string& fname : filesInDirectory(dir)) @@ -93,14 +94,14 @@ std::vector<std::string> FileSystemUtils::glob(const std::string& dir, const std return ret; } -std::string FileSystemUtils::stem(const std::string& path) +std::string BaseUtils::Filesystem::stem(const std::string& path) { return fs::path(path).stem().string(); } -std::string FileSystemUtils::stem_ext(const std::string& path) +std::string BaseUtils::Filesystem::stem_ext(const std::string& path) { - const auto name = FileSystemUtils::filename(path); + const auto name = BaseUtils::Filesystem::filename(path); if (name == "..") return name; @@ -108,13 +109,13 @@ std::string FileSystemUtils::stem_ext(const std::string& path) return pos != std::string::npos ? name.substr(0, pos) : name; } -std::wstring FileSystemUtils::convert_utf8_to_utf16(const std::string& str) +std::wstring BaseUtils::Filesystem::convert_utf8_to_utf16(const std::string& str) { std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; return converter.from_bytes(str); } -bool FileSystemUtils::IsFileExists(const std::string& path) +bool BaseUtils::Filesystem::IsFileExists(const std::string& path) { #ifdef _WIN32 return fs::exists(convert_utf8_to_utf16(path)); diff --git a/Base/Utils/FileSystemUtils.h b/Base/Utils/FileSystemUtils.h index 832b6629484..5283d652cd5 100644 --- a/Base/Utils/FileSystemUtils.h +++ b/Base/Utils/FileSystemUtils.h @@ -25,7 +25,7 @@ //! Utility functions to deal with file system. -namespace FileSystemUtils { +namespace BaseUtils::Filesystem { //! Returns extension of given filename. //! "/home/user/filename.int" -> ".int", "/home/user/filename.int.gz" -> ".gz" @@ -67,7 +67,7 @@ std::wstring convert_utf8_to_utf16(const std::string& str); //! Returns true if file with given name exists on disk. bool IsFileExists(const std::string& path); -} // namespace FileSystemUtils +} // namespace BaseUtils::Filesystem #endif // BORNAGAIN_BASE_UTILS_FILESYSTEMUTILS_H #endif // USER_API diff --git a/Base/Utils/StringUtils.cpp b/Base/Utils/StringUtils.cpp index 1c3b76d699e..ad3a9ae4d99 100644 --- a/Base/Utils/StringUtils.cpp +++ b/Base/Utils/StringUtils.cpp @@ -18,7 +18,7 @@ #include <regex> //! Returns true if text matches pattern with wildcards '*' and '?'. -bool StringUtils::matchesPattern(const std::string& text, const std::string& wildcardPattern) +bool BaseUtils::String::matchesPattern(const std::string& text, const std::string& wildcardPattern) { // escape all regex special characters, except '?' and '*' std::string mywildcardPattern = wildcardPattern; @@ -47,7 +47,7 @@ bool StringUtils::matchesPattern(const std::string& text, const std::string& wil } //! Returns string right-padded with blanks. -std::string StringUtils::padRight(const std::string& name, size_t length) +std::string BaseUtils::String::padRight(const std::string& name, size_t length) { std::string result = name; result.resize(length, ' '); @@ -55,21 +55,24 @@ std::string StringUtils::padRight(const std::string& name, size_t length) } //! Returns token vector obtained by splitting string at delimiters. -std::vector<std::string> StringUtils::split(const std::string& text, const std::string& delimiter) +std::vector<std::string> BaseUtils::String::split(const std::string& text, + const std::string& delimiter) { std::vector<std::string> tokens; boost::split(tokens, text, boost::is_any_of(delimiter)); return tokens; } -void StringUtils::replaceItemsFromString(std::string& text, const std::vector<std::string>& items, - const std::string& replacement) +void BaseUtils::String::replaceItemsFromString(std::string& text, + const std::vector<std::string>& items, + const std::string& replacement) { for (size_t i = 0; i < items.size(); ++i) boost::replace_all(text, items[i], replacement); } -std::string StringUtils::join(const std::vector<std::string>& joinable, const std::string& joint) +std::string BaseUtils::String::join(const std::vector<std::string>& joinable, + const std::string& joint) { std::string result; size_t n = joinable.size(); @@ -81,7 +84,7 @@ std::string StringUtils::join(const std::vector<std::string>& joinable, const st return result; } -std::string StringUtils::removeSubstring(const std::string& text, const std::string& substr) +std::string BaseUtils::String::removeSubstring(const std::string& text, const std::string& substr) { std::string result = text; for (std::string::size_type i = result.find(substr); i != std::string::npos; @@ -90,13 +93,13 @@ std::string StringUtils::removeSubstring(const std::string& text, const std::str return result; } -std::string StringUtils::to_lower(std::string text) +std::string BaseUtils::String::to_lower(std::string text) { boost::to_lower(text); return text; } -bool StringUtils::to_int(const std::string& str, int* result) +bool BaseUtils::String::to_int(const std::string& str, int* result) { const char* first = str.data() + str.find_first_not_of(' '); const char* last = str.data() + str.size(); @@ -119,7 +122,7 @@ bool StringUtils::to_int(const std::string& str, int* result) return true; } -std::string StringUtils::trim(const std::string& str, const std::string& whitespace) +std::string BaseUtils::String::trim(const std::string& str, const std::string& whitespace) { const auto strBegin = str.find_first_not_of(whitespace); @@ -132,7 +135,7 @@ std::string StringUtils::trim(const std::string& str, const std::string& whitesp return str.substr(strBegin, strRange); } -std::string StringUtils::trimFront(const std::string& str, const std::string& whitespace) +std::string BaseUtils::String::trimFront(const std::string& str, const std::string& whitespace) { const auto strBegin = str.find_first_not_of(whitespace); @@ -142,7 +145,7 @@ std::string StringUtils::trimFront(const std::string& str, const std::string& wh return str.substr(strBegin); } -bool StringUtils::startsWith(const std::string& str, const std::string& substr) +bool BaseUtils::String::startsWith(const std::string& str, const std::string& substr) { return str.rfind(substr, 0) == 0; } diff --git a/Base/Utils/StringUtils.h b/Base/Utils/StringUtils.h index e8cf327a64c..1df5265e0a5 100644 --- a/Base/Utils/StringUtils.h +++ b/Base/Utils/StringUtils.h @@ -27,7 +27,7 @@ //! Utility functions to analyze or modify strings. -namespace StringUtils { +namespace BaseUtils::String { //! Returns true if text matches pattern with wildcards '*' and '?'. bool matchesPattern(const std::string& text, const std::string& wildcardPattern); @@ -74,9 +74,9 @@ std::string trimFront(const std::string& str, const std::string& whitespace = " //! True if the string starts with substr. The comparison is case sensitive bool startsWith(const std::string& str, const std::string& substr); -} // namespace StringUtils +} // namespace BaseUtils::String -template <typename T> std::string StringUtils::scientific(const T value, int n) +template <typename T> std::string BaseUtils::String::scientific(const T value, int n) { std::ostringstream out; out << std::scientific << std::setprecision(n) << value; diff --git a/Base/Utils/SysUtils.cpp b/Base/Utils/SysUtils.cpp index bbdd40e019e..abfae700f1a 100644 --- a/Base/Utils/SysUtils.cpp +++ b/Base/Utils/SysUtils.cpp @@ -19,7 +19,7 @@ #include <sstream> #include <stdexcept> -std::string SysUtils::getCurrentDateAndTime() +std::string BaseUtils::System::getCurrentDateAndTime() { using clock = std::chrono::system_clock; @@ -30,22 +30,22 @@ std::string SysUtils::getCurrentDateAndTime() } //! enables exception throw in the case of NaN, Inf -void SysUtils::enableFloatingPointExceptions() +void BaseUtils::System::enableFloatingPointExceptions() { #ifdef DEBUG_FPE #ifndef _WIN32 - std::cout << "SysUtils::EnableFloatingPointExceptions() -> " + std::cout << "BaseUtils::System::EnableFloatingPointExceptions() -> " "Enabling floating point exception debugging\n"; feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); // feenableexcept(-1); #endif // _WIN32 #else - std::cout << "SysUtils::EnableFloatingPointExceptions() -> " + std::cout << "BaseUtils::System::EnableFloatingPointExceptions() -> " "Can't enable floating point exceptions. Available in debug mode only.\n"; #endif } -std::string SysUtils::getenv(const std::string& name) +std::string BaseUtils::System::getenv(const std::string& name) { if (char* c = std::getenv(name.c_str())) return c; @@ -53,7 +53,7 @@ std::string SysUtils::getenv(const std::string& name) return ""; } -bool SysUtils::isWindowsHost() +bool BaseUtils::System::isWindowsHost() { #ifdef _WIN32 return true; diff --git a/Base/Utils/SysUtils.h b/Base/Utils/SysUtils.h index 9579f16ddba..5a7541a1184 100644 --- a/Base/Utils/SysUtils.h +++ b/Base/Utils/SysUtils.h @@ -24,7 +24,7 @@ //! Utility functions getCurrentDateAndTime, enableFloatingPointExceptions. -namespace SysUtils { +namespace BaseUtils::System { std::string getCurrentDateAndTime(); @@ -37,7 +37,7 @@ std::string getenv(const std::string& name); //! Returns true if operation system is Windows. bool isWindowsHost(); -} // namespace SysUtils +} // namespace BaseUtils::System #endif // BORNAGAIN_BASE_UTILS_SYSUTILS_H #endif // USER_API diff --git a/Core/Fitting/FitObjective.h b/Core/Fitting/FitObjective.h index 3adfc3c1eee..2f8ea35ef18 100644 --- a/Core/Fitting/FitObjective.h +++ b/Core/Fitting/FitObjective.h @@ -51,8 +51,8 @@ public: template <class T> void addSimulationAndData(PyBuilderCallback& callback, const T& data, double weight = 1.0) { - addSimulationAndData(simulationBuilder(callback), *DataUtils::Array::createData(data), nullptr, - weight); + addSimulationAndData(simulationBuilder(callback), *DataUtils::Array::createData(data), + nullptr, weight); } //! Constructs simulation/data pair for later fit. diff --git a/Core/Fitting/FitPrintService.cpp b/Core/Fitting/FitPrintService.cpp index 119ba2724bf..576d7006e11 100644 --- a/Core/Fitting/FitPrintService.cpp +++ b/Core/Fitting/FitPrintService.cpp @@ -85,7 +85,7 @@ std::string FitPrintService::parameterString(const FitObjective& objective) const auto length = length_of_longest_name(params); for (const auto& par : params) { - result << StringUtils::padRight(par.name(), length) << std::scientific + result << BaseUtils::String::padRight(par.name(), length) << std::scientific << std::setprecision(6) << " " << par.startValue() << " " << par.limits().toString() << " " << par.value() << "\n"; } diff --git a/Core/Simulation/ISimulation.cpp b/Core/Simulation/ISimulation.cpp index 3d55e024b64..3223a744373 100644 --- a/Core/Simulation/ISimulation.cpp +++ b/Core/Simulation/ISimulation.cpp @@ -90,7 +90,7 @@ void runComputations(std::vector<std::unique_ptr<IComputation>>& computations) throw std::runtime_error("Error in runComputations: " "At least one simulation thread has terminated unexpectedly.\n" "Messages: " - + StringUtils::join(failure_messages, " --- ")); + + BaseUtils::String::join(failure_messages, " --- ")); } } // namespace diff --git a/Device/Data/ArrayUtils.h b/Device/Data/ArrayUtils.h index 3738e839d3f..d264cc4d09f 100644 --- a/Device/Data/ArrayUtils.h +++ b/Device/Data/ArrayUtils.h @@ -65,9 +65,8 @@ class CreateDataImpl { template <class T> CreateDataImpl::ReturnType<T> createData(const T& vec) { constexpr const int size = CreateDataImpl::nDim<T>::value; - static_assert( - size == 1 || size == 2, - "Error in DataUtils::Array::createData: invalid dimensionality or type of the input argument"); + static_assert(size == 1 || size == 2, "Error in DataUtils::Array::createData: invalid " + "dimensionality or type of the input argument"); static_assert(std::is_same<CreateDataImpl::ReturnType<T>, decltype(CreateDataImpl::createDataImpl(vec))>::value, "Error in DataUtils::Array::createData: invalid return type."); @@ -87,7 +86,8 @@ template <class T> decltype(auto) createVector2D(const T& data); // ************************************************************************************************ template <class T> -std::unique_ptr<OutputData<T>> DataUtils::Array::CreateDataImpl::createDataImpl(const std::vector<T>& vec) +std::unique_ptr<OutputData<T>> +DataUtils::Array::CreateDataImpl::createDataImpl(const std::vector<T>& vec) { auto result = std::make_unique<OutputData<T>>(); const size_t length = vec.size(); diff --git a/Device/Data/DataUtils.cpp b/Device/Data/DataUtils.cpp index 0dbba36c468..a18ad1c6b0b 100644 --- a/Device/Data/DataUtils.cpp +++ b/Device/Data/DataUtils.cpp @@ -33,7 +33,7 @@ std::vector<std::vector<double>> FT2DArray(const std::vector<std::vector<double> //! Returns relative difference between two data sets sum(dat[i] - ref[i])/ref[i]). double DataUtils::Data::relativeDataDifference(const OutputData<double>& dat, - const OutputData<double>& ref) + const OutputData<double>& ref) { if (!dat.hasSameDimensions(ref)) throw std::runtime_error("OutputData dimension differs from reference"); @@ -49,7 +49,7 @@ double DataUtils::Data::relativeDataDifference(const OutputData<double>& dat, //! Returns true is relative difference is below threshold; prints informative output bool DataUtils::Data::checkRelativeDifference(const OutputData<double>& dat, - const OutputData<double>& ref, const double threshold) + const OutputData<double>& ref, const double threshold) { const double diff = relativeDataDifference(dat, ref); if (diff > threshold) { @@ -67,7 +67,7 @@ bool DataUtils::Data::checkRelativeDifference(const OutputData<double>& dat, std::unique_ptr<OutputData<double>> DataUtils::Data::createRelativeDifferenceData(const OutputData<double>& data, - const OutputData<double>& reference) + const OutputData<double>& reference) { if (!data.hasSameDimensions(reference)) throw std::runtime_error("DataUtils::Data::createRelativeDifferenceData() -> " @@ -125,8 +125,8 @@ DataUtils::Data::createRearrangedDataSet(const OutputData<double>& data, int n) } std::unique_ptr<OutputData<double>> -DataUtils::Data::createClippedDataSet(const OutputData<double>& origin, double x1, double y1, double x2, - double y2) +DataUtils::Data::createClippedDataSet(const OutputData<double>& origin, double x1, double y1, + double x2, double y2) { if (origin.rank() != 2) throw std::runtime_error("DataUtils::Data::createClippedData()" @@ -265,7 +265,8 @@ OutputData<double>* DataUtils::Data::importArrayToOutputData(const std::vector<d return DataUtils::Array::createData(vec).release(); } -OutputData<double>* DataUtils::Data::importArrayToOutputData(const std::vector<std::vector<double>>& vec) +OutputData<double>* +DataUtils::Data::importArrayToOutputData(const std::vector<std::vector<double>>& vec) { return DataUtils::Array::createData(vec).release(); } diff --git a/Device/Histo/HistoUtils.cpp b/Device/Histo/HistoUtils.cpp index 48cf92dd639..d434470f7dd 100644 --- a/Device/Histo/HistoUtils.cpp +++ b/Device/Histo/HistoUtils.cpp @@ -22,9 +22,10 @@ #include <iostream> #include <tspectrum.h> // third-party code, extracted from CERN ROOT (class TSpectrum2) -std::vector<std::pair<double, double>> DataUtils::Histo::FindPeaks(const Histogram2D& hist, double sigma, - const std::string& option, - double threshold) +std::vector<std::pair<double, double>> DataUtils::Histo::FindPeaks(const Histogram2D& hist, + double sigma, + const std::string& option, + double threshold) { std::unique_ptr<OutputData<double>> data(hist.createOutputData()); std::vector<std::vector<double>> arr = DataUtils::Array::createVector2D(*data); @@ -57,7 +58,8 @@ std::vector<std::pair<double, double>> DataUtils::Histo::FindPeaks(const Histogr //! Returns sum of relative differences between each pair of elements: //! (a, b) -> 2*abs(a - b)/(|a| + |b|) ( and zero if a=b=0 within epsilon ) -double DataUtils::Histo::RelativeDifference(const SimulationResult& dat, const SimulationResult& ref) +double DataUtils::Histo::RelativeDifference(const SimulationResult& dat, + const SimulationResult& ref) { if (dat.size() != ref.size()) throw std::runtime_error("Error in DataUtils::Histo::RelativeDifference: " @@ -77,8 +79,8 @@ double DataUtils::Histo::getRelativeDifference(const IHistogram& dat, const IHis *std::unique_ptr<OutputData<double>>(ref.getData().meanValues())); } -bool DataUtils::Histo::agreesWithReference(const SimulationResult& dat, const std::string& refFileName, - double tol) +bool DataUtils::Histo::agreesWithReference(const SimulationResult& dat, + const std::string& refFileName, double tol) { std::unique_ptr<OutputData<double>> refDat{IntensityDataIOFactory::readOutputData(refFileName)}; if (!refDat) { diff --git a/Device/Histo/Histogram1D.cpp b/Device/Histo/Histogram1D.cpp index 91c734a9d6e..c4862452a50 100644 --- a/Device/Histo/Histogram1D.cpp +++ b/Device/Histo/Histogram1D.cpp @@ -68,17 +68,17 @@ std::vector<double> Histogram1D::binErrors() const PyObject* Histogram1D::binCentersNumpy() const { - return PyUtils::createNumpyArray(binCenters()); + return BaseUtils::Python::createNumpyArray(binCenters()); } PyObject* Histogram1D::binValuesNumpy() const { - return PyUtils::createNumpyArray(binValues()); + return BaseUtils::Python::createNumpyArray(binValues()); } PyObject* Histogram1D::binErrorsNumpy() const { - return PyUtils::createNumpyArray(binErrors()); + return BaseUtils::Python::createNumpyArray(binErrors()); } #endif // BORNAGAIN_PYTHON diff --git a/Device/Histo/IntensityDataIOFactory.cpp b/Device/Histo/IntensityDataIOFactory.cpp index 4de9e9f6445..dee5b4934e9 100644 --- a/Device/Histo/IntensityDataIOFactory.cpp +++ b/Device/Histo/IntensityDataIOFactory.cpp @@ -109,7 +109,7 @@ void IntensityDataIOFactory::writeOutputData(const std::string& file_name, openmode = std::ios::out | std::ios_base::binary; #ifdef _WIN32 - fout.open(FileSystemUtils::convert_utf8_to_utf16(file_name), openmode); + fout.open(BaseUtils::Filesystem::convert_utf8_to_utf16(file_name), openmode); #else fout.open(file_name, openmode); #endif @@ -172,7 +172,7 @@ IntensityDataIOFactory::readOutputData(const std::string& file_name, std::function<OutputData<double>*(std::istream&)> readData) { - if (!FileSystemUtils::IsFileExists(file_name)) + if (!BaseUtils::Filesystem::IsFileExists(file_name)) return nullptr; using namespace DataUtils::Format; @@ -182,7 +182,7 @@ IntensityDataIOFactory::readOutputData(const std::string& file_name, openmode = std::ios::in | std::ios_base::binary; #ifdef _WIN32 - input_stream.open(FileSystemUtils::convert_utf8_to_utf16(file_name), openmode); + input_stream.open(BaseUtils::Filesystem::convert_utf8_to_utf16(file_name), openmode); #else input_stream.open(file_name, openmode); #endif diff --git a/Device/InputOutput/DataFormatUtils.cpp b/Device/InputOutput/DataFormatUtils.cpp index 37661f98b5b..d6b62164a04 100644 --- a/Device/InputOutput/DataFormatUtils.cpp +++ b/Device/InputOutput/DataFormatUtils.cpp @@ -37,7 +37,7 @@ std::istringstream getAxisStringRepresentation(std::istream& input_stream) std::string line; std::getline(input_stream, line); const std::vector<std::string> to_replace = {",", "\"", "(", ")", "[", "]"}; - StringUtils::replaceItemsFromString(line, to_replace, " "); + BaseUtils::String::replaceItemsFromString(line, to_replace, " "); return std::istringstream(line); } @@ -112,12 +112,12 @@ bool DataUtils::Format::isCompressed(const std::string& name) bool DataUtils::Format::isGZipped(const std::string& name) { - return FileSystemUtils::extension(name) == GzipExtension; + return BaseUtils::Filesystem::extension(name) == GzipExtension; } bool DataUtils::Format::isBZipped(const std::string& name) { - return FileSystemUtils::extension(name) == BzipExtension; + return BaseUtils::Filesystem::extension(name) == BzipExtension; } //! Returns file main extension (without .gz). @@ -130,7 +130,7 @@ std::string DataUtils::Format::GetFileMainExtension(const std::string& name) } else if (isBZipped(name)) { stripped_name = name.substr(0, name.size() - BzipExtension.size()); } - return FileSystemUtils::extension(stripped_name); + return BaseUtils::Filesystem::extension(stripped_name); } bool DataUtils::Format::isIntFile(const std::string& file_name) @@ -185,7 +185,8 @@ void DataUtils::Format::fillOutputData(OutputData<double>* data, std::istream& i } } if (it != data->end()) - throw std::runtime_error("DataUtils::Format::fillOutputData() -> Error while parsing data."); + throw std::runtime_error( + "DataUtils::Format::fillOutputData() -> Error while parsing data."); } //! Parse double values from string to vector of double diff --git a/Device/InputOutput/OutputDataReadReflectometry.cpp b/Device/InputOutput/OutputDataReadReflectometry.cpp index 626f9de9f7d..2c71acfea03 100644 --- a/Device/InputOutput/OutputDataReadReflectometry.cpp +++ b/Device/InputOutput/OutputDataReadReflectometry.cpp @@ -32,7 +32,7 @@ OutputData<double>* OutputDataReadReflectometry::readOutputData(std::istream& fi // Read numbers from file: while (std::getline(fin, line)) { - line = StringUtils::trim(line); + line = BaseUtils::String::trim(line); try { // #bamigration +++ this works only if separator is space or tab; it does not // work e.g. with comma or semicolon diff --git a/Device/InputOutput/OutputDataReadWriteINT.cpp b/Device/InputOutput/OutputDataReadWriteINT.cpp index 08a032c6fab..d873061a1df 100644 --- a/Device/InputOutput/OutputDataReadWriteINT.cpp +++ b/Device/InputOutput/OutputDataReadWriteINT.cpp @@ -23,7 +23,7 @@ OutputData<double>* OutputDataReadWriteINT::readOutputData(std::istream& input_s std::string line; while (std::getline(input_stream, line)) { - line = StringUtils::trim(line); + line = BaseUtils::String::trim(line); if (line.find("axis") != std::string::npos) { std::unique_ptr<IAxis> axis = DataUtils::Format::createAxis(input_stream); result->addAxis(*axis); diff --git a/Device/InputOutput/OutputDataReadWriteNicos.cpp b/Device/InputOutput/OutputDataReadWriteNicos.cpp index 6f81ea01955..9740638fd5d 100644 --- a/Device/InputOutput/OutputDataReadWriteNicos.cpp +++ b/Device/InputOutput/OutputDataReadWriteNicos.cpp @@ -29,8 +29,8 @@ OutputData<double>* OutputDataReadWriteNicos::readOutputData(std::istream& input bool fileSectionFound = false; while (std::getline(input_stream, line)) { m_currentLineNr++; - line = StringUtils::trimFront(line, " "); - if (!inFileSection && StringUtils::startsWith(line, "%File")) { + line = BaseUtils::String::trimFront(line, " "); + if (!inFileSection && BaseUtils::String::startsWith(line, "%File")) { inFileSection = true; fileSectionFound = true; continue; @@ -39,14 +39,14 @@ OutputData<double>* OutputDataReadWriteNicos::readOutputData(std::istream& input if (!inFileSection) continue; - if (StringUtils::startsWith(line, "%")) { + if (BaseUtils::String::startsWith(line, "%")) { inFileSection = false; break; } - if (StringUtils::startsWith(line, "DataSizeX")) + if (BaseUtils::String::startsWith(line, "DataSizeX")) width = readAssignedPositiveIntValue(line); - else if (StringUtils::startsWith(line, "DataSizeY")) + else if (BaseUtils::String::startsWith(line, "DataSizeY")) height = readAssignedPositiveIntValue(line); if (width != 0 && height != 0) @@ -70,8 +70,8 @@ OutputData<double>* OutputDataReadWriteNicos::readOutputData(std::istream& input while (std::getline(input_stream, line)) { m_currentLineNr++; - line = StringUtils::trimFront(line, " "); - if (!inCountSection && StringUtils::startsWith(line, "%Counts")) { + line = BaseUtils::String::trimFront(line, " "); + if (!inCountSection && BaseUtils::String::startsWith(line, "%Counts")) { inCountSection = true; countSectionFound = true; continue; @@ -80,17 +80,17 @@ OutputData<double>* OutputDataReadWriteNicos::readOutputData(std::istream& input if (!inCountSection) continue; - if (StringUtils::startsWith(line, "%")) { + if (BaseUtils::String::startsWith(line, "%")) { inCountSection = false; break; } // line is a data line - line = StringUtils::trim(line, " "); + line = BaseUtils::String::trim(line, " "); if (line.empty()) continue; - const auto valuesAsString = StringUtils::split(line, ","); + const auto valuesAsString = BaseUtils::String::split(line, ","); if (valuesAsString.size() != width) throw std::runtime_error( lineRelatedError("Number of found values (" + std::to_string(valuesAsString.size()) @@ -102,7 +102,7 @@ OutputData<double>* OutputDataReadWriteNicos::readOutputData(std::istream& input // to show first line at top of image int value = 0; - if (!StringUtils::to_int(valuesAsString[col], &value)) + if (!BaseUtils::String::to_int(valuesAsString[col], &value)) throw std::runtime_error(lineRelatedError( "Value '" + valuesAsString[col] + "' could not be converted to integer.")); @@ -125,12 +125,12 @@ OutputData<double>* OutputDataReadWriteNicos::readOutputData(std::istream& input unsigned int OutputDataReadWriteNicos::readAssignedPositiveIntValue(const std::string& line) const { - const auto parts = StringUtils::split(line, "="); + const auto parts = BaseUtils::String::split(line, "="); if (parts.size() != 2) throw std::runtime_error(lineRelatedError("Missing assigned value.")); int value = 0; - if (!StringUtils::to_int(parts[1], &value)) + if (!BaseUtils::String::to_int(parts[1], &value)) throw std::runtime_error( lineRelatedError("Can't parse assigned value '" + parts[1] + "'.")); diff --git a/Device/InputOutput/OutputDataReadWriteNumpyTXT.cpp b/Device/InputOutput/OutputDataReadWriteNumpyTXT.cpp index 4c060477bb0..87b6f35c9a5 100644 --- a/Device/InputOutput/OutputDataReadWriteNumpyTXT.cpp +++ b/Device/InputOutput/OutputDataReadWriteNumpyTXT.cpp @@ -33,7 +33,7 @@ OutputData<double>* OutputDataReadWriteNumpyTXT::readOutputData(std::istream& in // Read numbers from input stream: while (std::getline(input_stream, line)) { - line = StringUtils::trim(line); + line = BaseUtils::String::trim(line); if (line.empty() || !isDoubleStartChar(line[0])) continue; diff --git a/Device/InputOutput/OutputDataReadWriteTiff.cpp b/Device/InputOutput/OutputDataReadWriteTiff.cpp index a9900b32229..c5423f80e56 100644 --- a/Device/InputOutput/OutputDataReadWriteTiff.cpp +++ b/Device/InputOutput/OutputDataReadWriteTiff.cpp @@ -205,7 +205,7 @@ void OutputDataReadWriteTiff::write_header() { ASSERT(m_tiff); TIFFSetField(m_tiff, TIFFTAG_ARTIST, "BornAgain.IOFactory"); - TIFFSetField(m_tiff, TIFFTAG_DATETIME, SysUtils::getCurrentDateAndTime().c_str()); + TIFFSetField(m_tiff, TIFFTAG_DATETIME, BaseUtils::System::getCurrentDateAndTime().c_str()); TIFFSetField(m_tiff, TIFFTAG_IMAGEDESCRIPTION, "Image converted from BornAgain intensity file."); TIFFSetField(m_tiff, TIFFTAG_SOFTWARE, "BornAgain"); diff --git a/GUI/Models/RealDataItem.cpp b/GUI/Models/RealDataItem.cpp index 58ef4051b73..97f7026651b 100644 --- a/GUI/Models/RealDataItem.cpp +++ b/GUI/Models/RealDataItem.cpp @@ -416,7 +416,8 @@ void RealDataItem::rotateData() // -- now rotate data const auto input = intensityDataItem()->getOutputData(); - intensityDataItem()->setOutputData(DataUtils::Data::createRearrangedDataSet(*input, 1).release()); + intensityDataItem()->setOutputData( + DataUtils::Data::createRearrangedDataSet(*input, 1).release()); intensityDataItem()->setAxesRangeToData(); } diff --git a/GUI/Models/SaveLoadInterface.cpp b/GUI/Models/SaveLoadInterface.cpp index a123a54346c..4433e370be9 100644 --- a/GUI/Models/SaveLoadInterface.cpp +++ b/GUI/Models/SaveLoadInterface.cpp @@ -18,5 +18,5 @@ QString SaveLoadInterface::fileName(const QString& projectDir) const { return QString::fromStdString( - FileSystemUtils::jointPath(projectDir.toStdString(), fileName().toStdString())); + BaseUtils::Filesystem::jointPath(projectDir.toStdString(), fileName().toStdString())); } diff --git a/GUI/Views/FitWidgets/FitComparisonController.cpp b/GUI/Views/FitWidgets/FitComparisonController.cpp index 986c245ce35..34954732dcf 100644 --- a/GUI/Views/FitWidgets/FitComparisonController.cpp +++ b/GUI/Views/FitWidgets/FitComparisonController.cpp @@ -154,8 +154,8 @@ void DiffItemController::updateDiffData() if (!sim_data->getOutputData()) // job failed return; - m_diff_item->setOutputData(DataUtils::Data::createRelativeDifferenceData(*sim_data->getOutputData(), - *real_data->getOutputData()) + m_diff_item->setOutputData(DataUtils::Data::createRelativeDifferenceData( + *sim_data->getOutputData(), *real_data->getOutputData()) .release()); } diff --git a/GUI/Views/FitWidgets/FitComparisonViewController.cpp b/GUI/Views/FitWidgets/FitComparisonViewController.cpp index e563112f56a..c9b40f47d7d 100644 --- a/GUI/Views/FitWidgets/FitComparisonViewController.cpp +++ b/GUI/Views/FitWidgets/FitComparisonViewController.cpp @@ -145,8 +145,8 @@ void DiffItemController::updateDiffData() if (!sim_data->getOutputData()) // job failed return; - m_diff_item->setOutputData(DataUtils::Data::createRelativeDifferenceData(*sim_data->getOutputData(), - *real_data->getOutputData()) + m_diff_item->setOutputData(DataUtils::Data::createRelativeDifferenceData( + *sim_data->getOutputData(), *real_data->getOutputData()) .release()); } diff --git a/GUI/mainwindow/PyImportAssistant.cpp b/GUI/mainwindow/PyImportAssistant.cpp index aed988c2d62..4564e4b731b 100644 --- a/GUI/mainwindow/PyImportAssistant.cpp +++ b/GUI/mainwindow/PyImportAssistant.cpp @@ -41,7 +41,7 @@ namespace { std::string bornagainDir() { - std::string pythonPath = SysUtils::getenv("PYTHONPATH"); + std::string pythonPath = BaseUtils::System::getenv("PYTHONPATH"); return pythonPath.empty() ? BABuild::buildLibDir() : ""; } diff --git a/GUI/mainwindow/actionmanager.cpp b/GUI/mainwindow/actionmanager.cpp index b31cd307530..5b2ec755c5d 100644 --- a/GUI/mainwindow/actionmanager.cpp +++ b/GUI/mainwindow/actionmanager.cpp @@ -137,7 +137,7 @@ void ActionManager::createMenus() #ifdef BORNAGAIN_PYTHON connect(action, &QAction::triggered, this, &ActionManager::onImportFromPythonScript); if (GUI::Utils::OS::HostOsInfo::isMacHost()) - if (SysUtils::getenv("PYTHONHOME").empty()) + if (BaseUtils::System::getenv("PYTHONHOME").empty()) action->setEnabled(false); #endif // BORNAGAIN_PYTHON diff --git a/Sample/Multilayer/PyImport.cpp b/Sample/Multilayer/PyImport.cpp index 0e396b3ed2f..23367a2a8a3 100644 --- a/Sample/Multilayer/PyImport.cpp +++ b/Sample/Multilayer/PyImport.cpp @@ -25,7 +25,7 @@ std::string error_description(const std::string& title) { std::stringstream buf; buf << title << "\n"; - buf << PyUtils::pythonStackTrace() << "\n"; + buf << BaseUtils::Python::pythonStackTrace() << "\n"; return buf.str(); } @@ -35,7 +35,7 @@ std::unique_ptr<MultiLayer> PyImport::createFromPython(const std::string& script const std::string& functionName, const std::string& path) { - PyUtils::import_bornagain(path); + BaseUtils::Python::import_bornagain(path); PyObject* pCompiledFn = Py_CompileString(script.c_str(), "", Py_file_input); if (!pCompiledFn) @@ -86,7 +86,7 @@ std::unique_ptr<MultiLayer> PyImport::createFromPython(const std::string& script std::vector<std::string> PyImport::listOfFunctions(const std::string& script, const std::string& path) { - PyUtils::import_bornagain(path); + BaseUtils::Python::import_bornagain(path); PyObject* pCompiledFn = Py_CompileString(script.c_str(), "", Py_file_input); if (!pCompiledFn) @@ -108,7 +108,7 @@ std::vector<std::string> PyImport::listOfFunctions(const std::string& script, Py_ssize_t pos = 0; while (PyDict_Next(dict, &pos, &key, &value)) { if (PyCallable_Check(value)) { - std::string func_name = PyUtils::toString(key); + std::string func_name = BaseUtils::Python::toString(key); if (func_name.find("__") == std::string::npos) result.push_back(func_name); } diff --git a/Sample/Scattering/IFormFactor.cpp b/Sample/Scattering/IFormFactor.cpp index 28ccefa1966..583b6ca4918 100644 --- a/Sample/Scattering/IFormFactor.cpp +++ b/Sample/Scattering/IFormFactor.cpp @@ -78,7 +78,7 @@ std::string IFormFactor::pythonConstructor() const // are prepended by "FormFactor", the others aren't. const std::string ctorName = - (StringUtils::startsWith(m_nodeMeta.className, "FormFactor") ? "" : "FormFactor") + (BaseUtils::String::startsWith(m_nodeMeta.className, "FormFactor") ? "" : "FormFactor") + m_nodeMeta.className; diff --git a/Tests/Functional/Core/Consistence/CompareTwoReferences.cpp b/Tests/Functional/Core/Consistence/CompareTwoReferences.cpp index 8a3e97550e8..93019389b02 100644 --- a/Tests/Functional/Core/Consistence/CompareTwoReferences.cpp +++ b/Tests/Functional/Core/Consistence/CompareTwoReferences.cpp @@ -24,7 +24,7 @@ std::unique_ptr<OutputData<double>> load(const std::string& name) { ASSERT(name != ""); const std::string path = - FileSystemUtils::jointPath(BATesting::ReferenceDir_Std(), name + ".int.gz"); + BaseUtils::Filesystem::jointPath(BATesting::ReferenceDir_Std(), name + ".int.gz"); std::unique_ptr<OutputData<double>> data; try { data.reset(IntensityDataIOFactory::readOutputData(path)); diff --git a/Tests/Functional/Core/CoreSpecial/CoreIOPathTest.cpp b/Tests/Functional/Core/CoreSpecial/CoreIOPathTest.cpp index 7809f62ff7d..26daae04f70 100644 --- a/Tests/Functional/Core/CoreSpecial/CoreIOPathTest.cpp +++ b/Tests/Functional/Core/CoreSpecial/CoreIOPathTest.cpp @@ -52,7 +52,7 @@ TEST_F(CoreIOPathTest, CoreIOPath) const std::filesystem::path test_dir(BATesting::TestOutDir_Core()); - FileSystemUtils::createDirectories(test_dir.string()); + BaseUtils::Filesystem::createDirectories(test_dir.string()); // tests file writing when file name contains cyrillic characters std::filesystem::path test_file(filename_rus); @@ -60,6 +60,6 @@ TEST_F(CoreIOPathTest, CoreIOPath) // tests file writing and directory creation when dirname contains cyrillic characters std::filesystem::path test_subdir_rus(dirname_rus); - FileSystemUtils::createDirectories((test_dir / test_subdir_rus).string()); + BaseUtils::Filesystem::createDirectories((test_dir / test_subdir_rus).string()); EXPECT_TRUE(test_io(data.get(), (test_dir / test_subdir_rus / test_file).string())); } diff --git a/Tests/Functional/Core/CoreSpecial/FourierTransformationTest.cpp b/Tests/Functional/Core/CoreSpecial/FourierTransformationTest.cpp index 18195a7b016..f6cd9aff762 100644 --- a/Tests/Functional/Core/CoreSpecial/FourierTransformationTest.cpp +++ b/Tests/Functional/Core/CoreSpecial/FourierTransformationTest.cpp @@ -28,9 +28,9 @@ const double threshold = 1e-10; //! Returns name of fft image based on given image name. std::string fftReferenceImage(const std::string& input_image) { - auto filename = FileSystemUtils::filename(input_image); - return FileSystemUtils::jointPath(BATesting::ReferenceDir_Core(), - "FourierTransformation_" + filename); + auto filename = BaseUtils::Filesystem::filename(input_image); + return BaseUtils::Filesystem::jointPath(BATesting::ReferenceDir_Core(), + "FourierTransformation_" + filename); } //! Runs test over one image. Returns true upon success. @@ -43,7 +43,7 @@ bool test_fft(const std::string& input_image_name, const std::string& reference_ std::unique_ptr<OutputData<double>> input_image; try { const auto filename = - FileSystemUtils::jointPath(BATesting::ReferenceDir_Std(), input_image_name); + BaseUtils::Filesystem::jointPath(BATesting::ReferenceDir_Std(), input_image_name); input_image.reset(IntensityDataIOFactory::readOutputData(filename)); } catch (const std::exception&) { std::cout << "Error: no input image.\n"; @@ -67,9 +67,9 @@ bool test_fft(const std::string& input_image_name, const std::string& reference_ success = DataUtils::Data::relativeDataDifference(*fft, *reference_fft) <= threshold; if (!success) { - FileSystemUtils::createDirectory(BATesting::TestOutDir_Core()); - std::string out_fname = FileSystemUtils::jointPath( - BATesting::TestOutDir_Core(), FileSystemUtils::filename(reference_fft_name)); + BaseUtils::Filesystem::createDirectory(BATesting::TestOutDir_Core()); + std::string out_fname = BaseUtils::Filesystem::jointPath( + BATesting::TestOutDir_Core(), BaseUtils::Filesystem::filename(reference_fft_name)); IntensityDataIOFactory::writeOutputData(*fft, out_fname); std::cout << "New fft image stored in " << out_fname << std::endl; } diff --git a/Tests/Functional/Core/Std/Check.cpp b/Tests/Functional/Core/Std/Check.cpp index 20432b7fe28..33e792409c5 100644 --- a/Tests/Functional/Core/Std/Check.cpp +++ b/Tests/Functional/Core/Std/Check.cpp @@ -37,7 +37,7 @@ bool checkSimulation(const std::string& name, const ISimulation& direct_simulati ASSERT(name != ""); try { const std::string refPath = - FileSystemUtils::jointPath(BATesting::ReferenceDir_Std(), name + ".int.gz"); + BaseUtils::Filesystem::jointPath(BATesting::ReferenceDir_Std(), name + ".int.gz"); std::cout << "- reference: " << refPath << "\n"; reference.reset(IntensityDataIOFactory::readOutputData(refPath)); } catch (const std::exception&) { @@ -56,9 +56,9 @@ bool checkSimulation(const std::string& name, const ISimulation& direct_simulati } // Save simulation, as it differs from reference. - FileSystemUtils::createDirectories(BATesting::TestOutDir_Std()); + BaseUtils::Filesystem::createDirectories(BATesting::TestOutDir_Std()); std::string out_fname = - FileSystemUtils::jointPath(BATesting::TestOutDir_Std(), name + ".int.gz"); + BaseUtils::Filesystem::jointPath(BATesting::TestOutDir_Std(), name + ".int.gz"); IntensityDataIOFactory::writeOutputData(*result_data, out_fname); std::cout << "Notes:\n- to visualize an intensity map, use " << "devtools/view/plot_int.py\n" diff --git a/Tests/Functional/PyEmbedded/Tests.cpp b/Tests/Functional/PyEmbedded/Tests.cpp index af9716faa2c..bc7d1dd3307 100644 --- a/Tests/Functional/PyEmbedded/Tests.cpp +++ b/Tests/Functional/PyEmbedded/Tests.cpp @@ -1,405 +1,405 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file Tests/Functional/PyEmbedded/Tests.cpp -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2018 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "BABuild.h" -#include "BAVersion.h" -#include "Base/Py/PyCore.h" -#include "Base/Py/PyFmt.h" -#include "Base/Py/PyUtils.h" -#include "Base/Utils/SysUtils.h" -#include "Core/Export/ExportToPython.h" -#include "Sample/Multilayer/MultiLayer.h" -#include "Sample/Multilayer/PyImport.h" -#include "Sample/StandardSamples/SampleBuilderFactory.h" -#include "Tests/GTestWrapper/google_test.h" -#include <iostream> -#include <sstream> - -class PyEmbedded : public ::testing::Test { -}; - -//! Accessing to the information about Python used during the build, content of path.sys variable. - -TEST_F(PyEmbedded, SysPath) -{ - // Python build info - std::cout << "pythonExecutable(): " << BABuild::pythonExecutable() << std::endl; - std::cout << "pythonInterpreterID(): " << BABuild::pythonInterpreterID() << std::endl; - std::cout << "pythonVersionString(): " << BABuild::pythonVersionString() << std::endl; - std::cout << "pythonLibraries(): " << BABuild::pythonLibraries() << std::endl; - std::cout << "pythonIncludeDirs(): " << BABuild::pythonIncludeDirs() << std::endl; - std::cout << "pythonSiteLib(): " << BABuild::pythonSiteLib() << std::endl; - std::cout << "numpyIncludeDir(): " << BABuild::numpyIncludeDir() << std::endl; - std::cout << "numpyVersionString(): " << BABuild::numpyVersionString() << std::endl; - - // BornAgain build - std::cout << "buildLibDir(): " << BABuild::buildLibDir() << std::endl; - - // Runtime info - auto content = PyUtils::pythonRuntimeInfo(); - - EXPECT_TRUE(!content.empty()); -} - -//! Importing numpy and accessing its version string. - -TEST_F(PyEmbedded, ImportNumpy) -{ - Py_Initialize(); - - PyObject* pmod = PyImport_ImportModule("numpy"); - if (!pmod) - throw std::runtime_error("Can't load numpy"); - - PyObject* pvar = PyObject_GetAttrString(pmod, "__version__"); - Py_DecRef(pmod); - if (!pvar) - throw std::runtime_error("Can't get a variable"); - - auto version_string = PyUtils::toString(pvar); - Py_DecRef(pvar); - std::cout << "numpy_version_string=" << version_string << std::endl; - - Py_Finalize(); - - EXPECT_TRUE(!version_string.empty()); -} - -//! Comparing results of GetVersionNumber() function obtained in "embedded" and "native C++" ways. - -TEST_F(PyEmbedded, FunctionCall) -{ - Py_Initialize(); - - PyObject* sysPath = PySys_GetObject((char*)"path"); - PyList_Append(sysPath, PyString_FromString(".")); - PyList_Append(sysPath, PyString_FromString(BABuild::buildLibDir().c_str())); - - PyObject* pmod = PyImport_ImportModule("bornagain"); - if (!pmod) - throw std::runtime_error("Can't load module"); - - PyObject* pfun = PyObject_GetAttrString(pmod, "GetVersionNumber"); - Py_DecRef(pmod); - if (!pfun) - throw std::runtime_error("Can't get a function"); - - PyObject* pargs = Py_BuildValue("()"); - if (!pargs) { - Py_DecRef(pfun); - throw std::runtime_error("Can't build arguments list"); - } - - PyObject* result = PyObject_Call(pfun, pargs, nullptr); - Py_DecRef(pfun); - Py_DecRef(pargs); - if (!result) - throw std::runtime_error("Error while calling function"); - - auto str = PyUtils::toString(result); - Py_DecRef(result); - - Py_Finalize(); - - std::cout << "BornAgain version via Python: '" << str << "'\n"; - std::cout << "BornAgain version from Core: '" << BornAgain::GetVersionNumber() << "'\n"; - if (str != BornAgain::GetVersionNumber()) { - std::cout << "Version numbers disagree, test will fail.\n" - << "Possible reasons:\n" - << "- Python bindings not regenerated\n" - << "- Python module load from wrong location\n"; - EXPECT_TRUE(false); - } - EXPECT_TRUE(true); -} - -//! Creating instance of FormFactorCylinder and calling its method in embedded Python. - -TEST_F(PyEmbedded, MethodCall) -{ - const double radius(5.0), height(6.0); - Py_Initialize(); - - PyObject* sysPath = PySys_GetObject((char*)"path"); - PyList_Append(sysPath, PyString_FromString(".")); - PyList_Append(sysPath, PyString_FromString(BABuild::buildLibDir().c_str())); - - PyObject* pmod = PyImport_ImportModule("bornagain"); - if (!pmod) - throw std::runtime_error("Can't load module"); - - PyObject* pclass = PyObject_GetAttrString(pmod, "FormFactorCylinder"); - Py_DecRef(pmod); - if (!pclass) - throw std::runtime_error("Can't get a class"); - - PyObject* pargs = Py_BuildValue("(dd)", radius, height); - if (!pargs) { - Py_DecRef(pclass); - throw std::runtime_error("Can't build arguments list"); - } - - PyObject* pinst = PyObject_Call(pclass, pargs, nullptr); - Py_DecRef(pclass); - Py_DecRef(pargs); - - if (!pinst) - throw std::runtime_error("Error while creating object"); - - // result of FormFactorCylinder - PyObject* pmeth = PyObject_GetAttrString(pinst, "getHeight"); - Py_DecRef(pinst); - if (!pmeth) - throw std::runtime_error("Can't fetch FormFactorCylinder.getHeight"); - - PyObject* pargs2 = Py_BuildValue("()"); - if (!pargs2) { - Py_DECREF(pmeth); - throw std::runtime_error("Can't build arguments list"); - } - - PyObject* pres = PyObject_Call(pmeth, pargs2, nullptr); - Py_DecRef(pmeth); - Py_DecRef(pargs); - - if (!pres) - throw std::runtime_error("Error calling FormFactorCylinder.getHeight()"); - - double value(0); - if (!PyArg_Parse(pres, "d", &value)) - throw std::runtime_error("Can't convert class method result"); - - Py_DecRef(pres); - - Py_Finalize(); - - EXPECT_TRUE(value == height); -} - -//! From https://www.awasu.com/weblog/embedding-python/calling-python-code-from-your-program/ - -TEST_F(PyEmbedded, CompiledFunction) -{ - Py_Initialize(); - - // compile our function - std::stringstream buf; - buf << "def add( n1 , n2 ) :" << std::endl << " return n1+n2" << std::endl; - - PyObject* pCompiledFn = Py_CompileString(buf.str().c_str(), "", Py_file_input); - if (!pCompiledFn) - throw std::runtime_error("Can't compile a function"); - - // create a module - PyObject* pModule = PyImport_ExecCodeModule((char*)"test", pCompiledFn); - if (!pModule) - throw std::runtime_error("Can't exec module"); - - // locate the "add" function (it's an attribute of the module) - PyObject* pAddFn = PyObject_GetAttrString(pModule, "add"); - if (!pAddFn) - throw std::runtime_error("Can't locate compiled functione"); - - // clean up - Py_DecRef(pAddFn); - Py_DecRef(pModule); - Py_DecRef(pCompiledFn); - - // ------------------------ - // using compiled function - // ------------------------ - - // create a new tuple with 2 elements - PyObject* pPosArgs = PyTuple_New(2); - - PyObject* pVal1 = PyInt_FromLong(10); - if (!pVal1) - throw std::runtime_error("Can't create PyInt"); - int rc = PyTuple_SetItem(pPosArgs, 0, pVal1); // nb: tuple position 0 - if (rc != 0) - throw std::runtime_error("Can't add to tuple"); - - PyObject* pVal2 = PyInt_FromLong(20); - if (!pVal2) - throw std::runtime_error("Can't create PyInt"); - rc = PyTuple_SetItem(pPosArgs, 1, pVal2); // nb: tuple position 0 - if (rc != 0) - throw std::runtime_error("Can't add to tuple"); - - // create a new dictionary - PyObject* pKywdArgs = PyDict_New(); - if (!pKywdArgs) - throw std::runtime_error("Can't create dictionary"); - - // call our function - PyObject* pResult = PyObject_Call(pAddFn, pPosArgs, pKywdArgs); - if (!pResult) - throw std::runtime_error("Can't get result out of function"); - - // convert the result to a string - PyObject* pResultRepr = PyObject_Repr(pResult); - std::string result = PyUtils::toString(pResultRepr); - Py_DecRef(pResultRepr); - - Py_Finalize(); - - EXPECT_TRUE(result == "30"); -} - -//! Creating MultiLayer in Python and extracting object to C++. -//! https://stackoverflow.com/questions/9040669/how-can-i-implement-a-c-class-in-python-to-be-called-by-c/ - -TEST_F(PyEmbedded, ObjectExtract) -{ - Py_Initialize(); - - PyObject* sysPath = PySys_GetObject((char*)"path"); - PyList_Append(sysPath, PyString_FromString(BABuild::buildLibDir().c_str())); - - PyObject* pmod = PyImport_ImportModule("bornagain"); - if (!pmod) - throw std::runtime_error("Can't load bornagain"); - - PyObject* ml = PyObject_GetAttrString(pmod, "MultiLayer"); - Py_DecRef(pmod); - if (!ml) - throw std::runtime_error("Can't get MultiLayer attribute."); - - PyObject* instance = PyObject_CallFunctionObjArgs(ml, NULL); - - void* argp1 = 0; - swig_type_info* pTypeInfo = SWIG_TypeQuery("MultiLayer *"); - - const int res = SWIG_ConvertPtr(instance, &argp1, pTypeInfo, 0); - if (!SWIG_IsOK(res)) - throw std::runtime_error("SWIG failed extract object"); - - MultiLayer* multilayer = reinterpret_cast<MultiLayer*>(argp1); - std::string name = multilayer->getName(); - - Py_DecRef(instance); - Py_DecRef(ml); - - Py_Finalize(); - - EXPECT_TRUE(name == "MultiLayer"); -} - -//! Running Python snippet which creates a multilayer in embedded way. -//! Casting resulting PyObject to C++ MultiLayer. - -TEST_F(PyEmbedded, EmbeddedMultiLayer) -{ - Py_Initialize(); - - PyObject* sysPath = PySys_GetObject((char*)"path"); - PyList_Append(sysPath, PyString_FromString(BABuild::buildLibDir().c_str())); - - PyObject* pmod = PyImport_ImportModule("bornagain"); - if (!pmod) - throw std::runtime_error("Can't load bornagain"); - - // compile our function - std::stringstream buf; - buf << "import bornagain as ba \n"; - buf << " \n"; - buf << "def get_simulation(): \n"; - buf << " m_vacuum = ba.HomogeneousMaterial(\"Vacuum\", 0.0, 0.0) \n"; - buf << " vacuum_layer = ba.Layer(m_vacuum) \n"; - buf << " multilayer = ba.MultiLayer() \n"; - buf << " multilayer.addLayer(vacuum_layer) \n"; - buf << " return multilayer \n"; - - PyObject* pCompiledFn = Py_CompileString(buf.str().c_str(), "", Py_file_input); - if (!pCompiledFn) - throw std::runtime_error("Can't compile a function"); - - // create a module - PyObject* pModule = PyImport_ExecCodeModule((char*)"test", pCompiledFn); - if (!pModule) - throw std::runtime_error("Can't exec module"); - - // locate the "get_simulation" function (it's an attribute of the module) - PyObject* pAddFn = PyObject_GetAttrString(pModule, "get_simulation"); - if (!pAddFn) - throw std::runtime_error("Can't locate compiled functione"); - - PyObject* instance = PyObject_CallFunctionObjArgs(pAddFn, NULL); - if (!instance) - throw std::runtime_error("Can't call function"); - - // clean up - Py_DecRef(pAddFn); - Py_DecRef(pModule); - Py_DecRef(pCompiledFn); - - void* argp1 = 0; - swig_type_info* pTypeInfo = SWIG_TypeQuery("MultiLayer *"); - - const int res = SWIG_ConvertPtr(instance, &argp1, pTypeInfo, 0); - if (!SWIG_IsOK(res)) - throw std::runtime_error("SWIG failed extract object"); - - MultiLayer* multilayer = reinterpret_cast<MultiLayer*>(argp1); - size_t n_layers = multilayer->numberOfLayers(); - - Py_DecRef(instance); - - Py_Finalize(); - - EXPECT_TRUE(n_layers == 1); -} - -//! We use one of our standard sample builders to build a sample, then generate Python snippet -//! using our standard ExportToPython machinery. -//! Given snippet is compiled and executed in embedded interpretor. Resulting multi layer -//! is casted back to C++ object and used again, to generate code snippet. -//! Two code snippets must be identical. - -TEST_F(PyEmbedded, ExportToPythonAndBack) -{ - SampleBuilderFactory factory; - std::unique_ptr<MultiLayer> sample(factory.createSampleByName("CylindersAndPrismsBuilder")); - - const std::string code = ExportToPython::sampleCode(*sample); - const std::string snippet = - "import bornagain as ba\n" + pyfmt::printImportedSymbols(code) + "\n\n" + code; - - const auto multilayer = - PyImport::createFromPython(snippet, "get_sample", BABuild::buildLibDir()); - const std::string new_code = ExportToPython::sampleCode(*multilayer); - - EXPECT_TRUE(code == new_code); -} - -//! Retrieves list of functions from the imported script and checks, that there is -//! one function in a dictionary with name "get_simulation". - -TEST_F(PyEmbedded, ModuleFunctionsList) -{ - // compile our function - std::stringstream buf; - buf << "import bornagain as ba \n"; - buf << " \n"; - buf << "def get_simulation(): \n"; - buf << " m_vacuum = ba.HomogeneousMaterial(\"Vacuum\", 0.0, 0.0) \n"; - buf << " vacuum_layer = ba.Layer(m_vacuum) \n"; - buf << " multilayer = ba.MultiLayer() \n"; - buf << " multilayer.addLayer(vacuum_layer) \n"; - buf << " return multilayer \n"; - - auto listOfFunc = PyImport::listOfFunctions(buf.str(), BABuild::buildLibDir()); - for (auto s : listOfFunc) - std::cout << "AAA" << s << std::endl; - EXPECT_TRUE(listOfFunc.size() == 1 && listOfFunc.at(0) == "get_simulation"); -} +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file Tests/Functional/PyEmbedded/Tests.cpp +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2018 +//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) +// +// ************************************************************************************************ + +#include "BABuild.h" +#include "BAVersion.h" +#include "Base/Py/PyCore.h" +#include "Base/Py/PyFmt.h" +#include "Base/Py/PyUtils.h" +#include "Base/Utils/SysUtils.h" +#include "Core/Export/ExportToPython.h" +#include "Sample/Multilayer/MultiLayer.h" +#include "Sample/Multilayer/PyImport.h" +#include "Sample/StandardSamples/SampleBuilderFactory.h" +#include "Tests/GTestWrapper/google_test.h" +#include <iostream> +#include <sstream> + +class PyEmbedded : public ::testing::Test { +}; + +//! Accessing to the information about Python used during the build, content of path.sys variable. + +TEST_F(PyEmbedded, SysPath) +{ + // Python build info + std::cout << "pythonExecutable(): " << BABuild::pythonExecutable() << std::endl; + std::cout << "pythonInterpreterID(): " << BABuild::pythonInterpreterID() << std::endl; + std::cout << "pythonVersionString(): " << BABuild::pythonVersionString() << std::endl; + std::cout << "pythonLibraries(): " << BABuild::pythonLibraries() << std::endl; + std::cout << "pythonIncludeDirs(): " << BABuild::pythonIncludeDirs() << std::endl; + std::cout << "pythonSiteLib(): " << BABuild::pythonSiteLib() << std::endl; + std::cout << "numpyIncludeDir(): " << BABuild::numpyIncludeDir() << std::endl; + std::cout << "numpyVersionString(): " << BABuild::numpyVersionString() << std::endl; + + // BornAgain build + std::cout << "buildLibDir(): " << BABuild::buildLibDir() << std::endl; + + // Runtime info + auto content = BaseUtils::Python::pythonRuntimeInfo(); + + EXPECT_TRUE(!content.empty()); +} + +//! Importing numpy and accessing its version string. + +TEST_F(PyEmbedded, ImportNumpy) +{ + Py_Initialize(); + + PyObject* pmod = PyImport_ImportModule("numpy"); + if (!pmod) + throw std::runtime_error("Can't load numpy"); + + PyObject* pvar = PyObject_GetAttrString(pmod, "__version__"); + Py_DecRef(pmod); + if (!pvar) + throw std::runtime_error("Can't get a variable"); + + auto version_string = BaseUtils::Python::toString(pvar); + Py_DecRef(pvar); + std::cout << "numpy_version_string=" << version_string << std::endl; + + Py_Finalize(); + + EXPECT_TRUE(!version_string.empty()); +} + +//! Comparing results of GetVersionNumber() function obtained in "embedded" and "native C++" ways. + +TEST_F(PyEmbedded, FunctionCall) +{ + Py_Initialize(); + + PyObject* sysPath = PySys_GetObject((char*)"path"); + PyList_Append(sysPath, PyString_FromString(".")); + PyList_Append(sysPath, PyString_FromString(BABuild::buildLibDir().c_str())); + + PyObject* pmod = PyImport_ImportModule("bornagain"); + if (!pmod) + throw std::runtime_error("Can't load module"); + + PyObject* pfun = PyObject_GetAttrString(pmod, "GetVersionNumber"); + Py_DecRef(pmod); + if (!pfun) + throw std::runtime_error("Can't get a function"); + + PyObject* pargs = Py_BuildValue("()"); + if (!pargs) { + Py_DecRef(pfun); + throw std::runtime_error("Can't build arguments list"); + } + + PyObject* result = PyObject_Call(pfun, pargs, nullptr); + Py_DecRef(pfun); + Py_DecRef(pargs); + if (!result) + throw std::runtime_error("Error while calling function"); + + auto str = BaseUtils::Python::toString(result); + Py_DecRef(result); + + Py_Finalize(); + + std::cout << "BornAgain version via Python: '" << str << "'\n"; + std::cout << "BornAgain version from Core: '" << BornAgain::GetVersionNumber() << "'\n"; + if (str != BornAgain::GetVersionNumber()) { + std::cout << "Version numbers disagree, test will fail.\n" + << "Possible reasons:\n" + << "- Python bindings not regenerated\n" + << "- Python module load from wrong location\n"; + EXPECT_TRUE(false); + } + EXPECT_TRUE(true); +} + +//! Creating instance of FormFactorCylinder and calling its method in embedded Python. + +TEST_F(PyEmbedded, MethodCall) +{ + const double radius(5.0), height(6.0); + Py_Initialize(); + + PyObject* sysPath = PySys_GetObject((char*)"path"); + PyList_Append(sysPath, PyString_FromString(".")); + PyList_Append(sysPath, PyString_FromString(BABuild::buildLibDir().c_str())); + + PyObject* pmod = PyImport_ImportModule("bornagain"); + if (!pmod) + throw std::runtime_error("Can't load module"); + + PyObject* pclass = PyObject_GetAttrString(pmod, "FormFactorCylinder"); + Py_DecRef(pmod); + if (!pclass) + throw std::runtime_error("Can't get a class"); + + PyObject* pargs = Py_BuildValue("(dd)", radius, height); + if (!pargs) { + Py_DecRef(pclass); + throw std::runtime_error("Can't build arguments list"); + } + + PyObject* pinst = PyObject_Call(pclass, pargs, nullptr); + Py_DecRef(pclass); + Py_DecRef(pargs); + + if (!pinst) + throw std::runtime_error("Error while creating object"); + + // result of FormFactorCylinder + PyObject* pmeth = PyObject_GetAttrString(pinst, "getHeight"); + Py_DecRef(pinst); + if (!pmeth) + throw std::runtime_error("Can't fetch FormFactorCylinder.getHeight"); + + PyObject* pargs2 = Py_BuildValue("()"); + if (!pargs2) { + Py_DECREF(pmeth); + throw std::runtime_error("Can't build arguments list"); + } + + PyObject* pres = PyObject_Call(pmeth, pargs2, nullptr); + Py_DecRef(pmeth); + Py_DecRef(pargs); + + if (!pres) + throw std::runtime_error("Error calling FormFactorCylinder.getHeight()"); + + double value(0); + if (!PyArg_Parse(pres, "d", &value)) + throw std::runtime_error("Can't convert class method result"); + + Py_DecRef(pres); + + Py_Finalize(); + + EXPECT_TRUE(value == height); +} + +//! From https://www.awasu.com/weblog/embedding-python/calling-python-code-from-your-program/ + +TEST_F(PyEmbedded, CompiledFunction) +{ + Py_Initialize(); + + // compile our function + std::stringstream buf; + buf << "def add( n1 , n2 ) :" << std::endl << " return n1+n2" << std::endl; + + PyObject* pCompiledFn = Py_CompileString(buf.str().c_str(), "", Py_file_input); + if (!pCompiledFn) + throw std::runtime_error("Can't compile a function"); + + // create a module + PyObject* pModule = PyImport_ExecCodeModule((char*)"test", pCompiledFn); + if (!pModule) + throw std::runtime_error("Can't exec module"); + + // locate the "add" function (it's an attribute of the module) + PyObject* pAddFn = PyObject_GetAttrString(pModule, "add"); + if (!pAddFn) + throw std::runtime_error("Can't locate compiled functione"); + + // clean up + Py_DecRef(pAddFn); + Py_DecRef(pModule); + Py_DecRef(pCompiledFn); + + // ------------------------ + // using compiled function + // ------------------------ + + // create a new tuple with 2 elements + PyObject* pPosArgs = PyTuple_New(2); + + PyObject* pVal1 = PyInt_FromLong(10); + if (!pVal1) + throw std::runtime_error("Can't create PyInt"); + int rc = PyTuple_SetItem(pPosArgs, 0, pVal1); // nb: tuple position 0 + if (rc != 0) + throw std::runtime_error("Can't add to tuple"); + + PyObject* pVal2 = PyInt_FromLong(20); + if (!pVal2) + throw std::runtime_error("Can't create PyInt"); + rc = PyTuple_SetItem(pPosArgs, 1, pVal2); // nb: tuple position 0 + if (rc != 0) + throw std::runtime_error("Can't add to tuple"); + + // create a new dictionary + PyObject* pKywdArgs = PyDict_New(); + if (!pKywdArgs) + throw std::runtime_error("Can't create dictionary"); + + // call our function + PyObject* pResult = PyObject_Call(pAddFn, pPosArgs, pKywdArgs); + if (!pResult) + throw std::runtime_error("Can't get result out of function"); + + // convert the result to a string + PyObject* pResultRepr = PyObject_Repr(pResult); + std::string result = BaseUtils::Python::toString(pResultRepr); + Py_DecRef(pResultRepr); + + Py_Finalize(); + + EXPECT_TRUE(result == "30"); +} + +//! Creating MultiLayer in Python and extracting object to C++. +//! https://stackoverflow.com/questions/9040669/how-can-i-implement-a-c-class-in-python-to-be-called-by-c/ + +TEST_F(PyEmbedded, ObjectExtract) +{ + Py_Initialize(); + + PyObject* sysPath = PySys_GetObject((char*)"path"); + PyList_Append(sysPath, PyString_FromString(BABuild::buildLibDir().c_str())); + + PyObject* pmod = PyImport_ImportModule("bornagain"); + if (!pmod) + throw std::runtime_error("Can't load bornagain"); + + PyObject* ml = PyObject_GetAttrString(pmod, "MultiLayer"); + Py_DecRef(pmod); + if (!ml) + throw std::runtime_error("Can't get MultiLayer attribute."); + + PyObject* instance = PyObject_CallFunctionObjArgs(ml, NULL); + + void* argp1 = 0; + swig_type_info* pTypeInfo = SWIG_TypeQuery("MultiLayer *"); + + const int res = SWIG_ConvertPtr(instance, &argp1, pTypeInfo, 0); + if (!SWIG_IsOK(res)) + throw std::runtime_error("SWIG failed extract object"); + + MultiLayer* multilayer = reinterpret_cast<MultiLayer*>(argp1); + std::string name = multilayer->getName(); + + Py_DecRef(instance); + Py_DecRef(ml); + + Py_Finalize(); + + EXPECT_TRUE(name == "MultiLayer"); +} + +//! Running Python snippet which creates a multilayer in embedded way. +//! Casting resulting PyObject to C++ MultiLayer. + +TEST_F(PyEmbedded, EmbeddedMultiLayer) +{ + Py_Initialize(); + + PyObject* sysPath = PySys_GetObject((char*)"path"); + PyList_Append(sysPath, PyString_FromString(BABuild::buildLibDir().c_str())); + + PyObject* pmod = PyImport_ImportModule("bornagain"); + if (!pmod) + throw std::runtime_error("Can't load bornagain"); + + // compile our function + std::stringstream buf; + buf << "import bornagain as ba \n"; + buf << " \n"; + buf << "def get_simulation(): \n"; + buf << " m_vacuum = ba.HomogeneousMaterial(\"Vacuum\", 0.0, 0.0) \n"; + buf << " vacuum_layer = ba.Layer(m_vacuum) \n"; + buf << " multilayer = ba.MultiLayer() \n"; + buf << " multilayer.addLayer(vacuum_layer) \n"; + buf << " return multilayer \n"; + + PyObject* pCompiledFn = Py_CompileString(buf.str().c_str(), "", Py_file_input); + if (!pCompiledFn) + throw std::runtime_error("Can't compile a function"); + + // create a module + PyObject* pModule = PyImport_ExecCodeModule((char*)"test", pCompiledFn); + if (!pModule) + throw std::runtime_error("Can't exec module"); + + // locate the "get_simulation" function (it's an attribute of the module) + PyObject* pAddFn = PyObject_GetAttrString(pModule, "get_simulation"); + if (!pAddFn) + throw std::runtime_error("Can't locate compiled functione"); + + PyObject* instance = PyObject_CallFunctionObjArgs(pAddFn, NULL); + if (!instance) + throw std::runtime_error("Can't call function"); + + // clean up + Py_DecRef(pAddFn); + Py_DecRef(pModule); + Py_DecRef(pCompiledFn); + + void* argp1 = 0; + swig_type_info* pTypeInfo = SWIG_TypeQuery("MultiLayer *"); + + const int res = SWIG_ConvertPtr(instance, &argp1, pTypeInfo, 0); + if (!SWIG_IsOK(res)) + throw std::runtime_error("SWIG failed extract object"); + + MultiLayer* multilayer = reinterpret_cast<MultiLayer*>(argp1); + size_t n_layers = multilayer->numberOfLayers(); + + Py_DecRef(instance); + + Py_Finalize(); + + EXPECT_TRUE(n_layers == 1); +} + +//! We use one of our standard sample builders to build a sample, then generate Python snippet +//! using our standard ExportToPython machinery. +//! Given snippet is compiled and executed in embedded interpretor. Resulting multi layer +//! is casted back to C++ object and used again, to generate code snippet. +//! Two code snippets must be identical. + +TEST_F(PyEmbedded, ExportToPythonAndBack) +{ + SampleBuilderFactory factory; + std::unique_ptr<MultiLayer> sample(factory.createSampleByName("CylindersAndPrismsBuilder")); + + const std::string code = ExportToPython::sampleCode(*sample); + const std::string snippet = + "import bornagain as ba\n" + pyfmt::printImportedSymbols(code) + "\n\n" + code; + + const auto multilayer = + PyImport::createFromPython(snippet, "get_sample", BABuild::buildLibDir()); + const std::string new_code = ExportToPython::sampleCode(*multilayer); + + EXPECT_TRUE(code == new_code); +} + +//! Retrieves list of functions from the imported script and checks, that there is +//! one function in a dictionary with name "get_simulation". + +TEST_F(PyEmbedded, ModuleFunctionsList) +{ + // compile our function + std::stringstream buf; + buf << "import bornagain as ba \n"; + buf << " \n"; + buf << "def get_simulation(): \n"; + buf << " m_vacuum = ba.HomogeneousMaterial(\"Vacuum\", 0.0, 0.0) \n"; + buf << " vacuum_layer = ba.Layer(m_vacuum) \n"; + buf << " multilayer = ba.MultiLayer() \n"; + buf << " multilayer.addLayer(vacuum_layer) \n"; + buf << " return multilayer \n"; + + auto listOfFunc = PyImport::listOfFunctions(buf.str(), BABuild::buildLibDir()); + for (auto s : listOfFunc) + std::cout << "AAA" << s << std::endl; + EXPECT_TRUE(listOfFunc.size() == 1 && listOfFunc.at(0) == "get_simulation"); +} diff --git a/Tests/Functional/PyStd/Check.cpp b/Tests/Functional/PyStd/Check.cpp index fdbcd5e1aa6..0c0c041cc20 100644 --- a/Tests/Functional/PyStd/Check.cpp +++ b/Tests/Functional/PyStd/Check.cpp @@ -28,14 +28,14 @@ std::unique_ptr<OutputData<double>> domainData(const std::string& test_name, const ISimulation& direct_simulation) { const std::string output_name = - FileSystemUtils::jointPath(BATesting::TestOutDir_PyStd(), test_name); + BaseUtils::Filesystem::jointPath(BATesting::TestOutDir_PyStd(), test_name); const std::string output_path = output_name + ".ref.int.gz"; std::remove(output_path.c_str()); std::cout << "- removed old output " << output_path << std::endl; // Generate Python script const std::string pyscript = - FileSystemUtils::jointPath(BATesting::TestOutDir_PyStd(), test_name + ".py"); + BaseUtils::Filesystem::jointPath(BATesting::TestOutDir_PyStd(), test_name + ".py"); std::ofstream f(pyscript); f << ExportToPython::simulationSaveCode(direct_simulation, output_path); f.close(); diff --git a/Tests/UnitTests/Core/Basics/FileSystemUtilsTest.cpp b/Tests/UnitTests/Core/Basics/FileSystemUtilsTest.cpp index 8b78a3b5690..c8f392c6339 100644 --- a/Tests/UnitTests/Core/Basics/FileSystemUtilsTest.cpp +++ b/Tests/UnitTests/Core/Basics/FileSystemUtilsTest.cpp @@ -8,7 +8,7 @@ class FileSystemUtilsTest : public ::testing::Test { protected: void SetUp() override { - FileSystemUtils::createDirectories(BATesting::TestOutDir_Core()); + BaseUtils::Filesystem::createDirectories(BATesting::TestOutDir_Core()); ASSERT_TRUE(std::filesystem::exists(BATesting::TestOutDir_Core())); ASSERT_TRUE(assureNonExistingTestCasePath()); } @@ -28,7 +28,7 @@ protected: std::string testCasePath() const { - return FileSystemUtils::jointPath(BATesting::TestOutDir_Core(), testCaseFolderName()); + return BaseUtils::Filesystem::jointPath(BATesting::TestOutDir_Core(), testCaseFolderName()); } //! Assures the test case specific path is not existent. Removes it if necessary. @@ -43,92 +43,92 @@ protected: TEST_F(FileSystemUtilsTest, extension) { - EXPECT_EQ(FileSystemUtils::extension(""), ""); - EXPECT_EQ(FileSystemUtils::extension("/home/james/"), ""); - EXPECT_EQ(FileSystemUtils::extension("/home/james/."), ""); - EXPECT_EQ(FileSystemUtils::extension("/home/james/.."), ""); - EXPECT_EQ(FileSystemUtils::extension("/home/james/.hidden"), ""); - EXPECT_EQ(FileSystemUtils::extension("/home/james/.hidden.txt"), ".txt"); - EXPECT_EQ(FileSystemUtils::extension("/home/james/file.txt"), ".txt"); - EXPECT_EQ(FileSystemUtils::extension("/home/james/file.txt.gz"), ".gz"); - EXPECT_EQ(FileSystemUtils::extension("/home/james/file.txt.GZ"), ".GZ"); + EXPECT_EQ(BaseUtils::Filesystem::extension(""), ""); + EXPECT_EQ(BaseUtils::Filesystem::extension("/home/james/"), ""); + EXPECT_EQ(BaseUtils::Filesystem::extension("/home/james/."), ""); + EXPECT_EQ(BaseUtils::Filesystem::extension("/home/james/.."), ""); + EXPECT_EQ(BaseUtils::Filesystem::extension("/home/james/.hidden"), ""); + EXPECT_EQ(BaseUtils::Filesystem::extension("/home/james/.hidden.txt"), ".txt"); + EXPECT_EQ(BaseUtils::Filesystem::extension("/home/james/file.txt"), ".txt"); + EXPECT_EQ(BaseUtils::Filesystem::extension("/home/james/file.txt.gz"), ".gz"); + EXPECT_EQ(BaseUtils::Filesystem::extension("/home/james/file.txt.GZ"), ".GZ"); } TEST_F(FileSystemUtilsTest, extensions) { - EXPECT_EQ(FileSystemUtils::extensions(""), ""); - EXPECT_EQ(FileSystemUtils::extensions("/home/james/"), ""); - EXPECT_EQ(FileSystemUtils::extensions("/home/james/."), ""); - EXPECT_EQ(FileSystemUtils::extensions("/home/james/.."), ""); - EXPECT_EQ(FileSystemUtils::extensions("/home/james/.hidden"), ""); - EXPECT_EQ(FileSystemUtils::extensions("/home/james/.hidden.txt"), ".txt"); - EXPECT_EQ(FileSystemUtils::extensions("/home/james/.hidden.txt.gz"), ".txt.gz"); - EXPECT_EQ(FileSystemUtils::extensions("/home/james/f"), ""); - EXPECT_EQ(FileSystemUtils::extensions("/home/james/f.txt"), ".txt"); - EXPECT_EQ(FileSystemUtils::extensions("/home/james/file.txt"), ".txt"); - EXPECT_EQ(FileSystemUtils::extensions("/home/james/file.txt.gz"), ".txt.gz"); + EXPECT_EQ(BaseUtils::Filesystem::extensions(""), ""); + EXPECT_EQ(BaseUtils::Filesystem::extensions("/home/james/"), ""); + EXPECT_EQ(BaseUtils::Filesystem::extensions("/home/james/."), ""); + EXPECT_EQ(BaseUtils::Filesystem::extensions("/home/james/.."), ""); + EXPECT_EQ(BaseUtils::Filesystem::extensions("/home/james/.hidden"), ""); + EXPECT_EQ(BaseUtils::Filesystem::extensions("/home/james/.hidden.txt"), ".txt"); + EXPECT_EQ(BaseUtils::Filesystem::extensions("/home/james/.hidden.txt.gz"), ".txt.gz"); + EXPECT_EQ(BaseUtils::Filesystem::extensions("/home/james/f"), ""); + EXPECT_EQ(BaseUtils::Filesystem::extensions("/home/james/f.txt"), ".txt"); + EXPECT_EQ(BaseUtils::Filesystem::extensions("/home/james/file.txt"), ".txt"); + EXPECT_EQ(BaseUtils::Filesystem::extensions("/home/james/file.txt.gz"), ".txt.gz"); } TEST_F(FileSystemUtilsTest, filename) { - EXPECT_EQ(FileSystemUtils::filename(""), ""); - EXPECT_EQ(FileSystemUtils::filename("/home/james/"), ""); - EXPECT_EQ(FileSystemUtils::filename("/home/james/."), "."); // sic! according to C++17 - EXPECT_EQ(FileSystemUtils::filename("/home/james/.."), ".."); // sic! according to C++17 - EXPECT_EQ(FileSystemUtils::filename("/home/james/.hidden"), ".hidden"); - EXPECT_EQ(FileSystemUtils::filename("/home/james/file.txt"), "file.txt"); - EXPECT_EQ(FileSystemUtils::filename("/home/james/file"), "file"); + EXPECT_EQ(BaseUtils::Filesystem::filename(""), ""); + EXPECT_EQ(BaseUtils::Filesystem::filename("/home/james/"), ""); + EXPECT_EQ(BaseUtils::Filesystem::filename("/home/james/."), "."); // sic! according to C++17 + EXPECT_EQ(BaseUtils::Filesystem::filename("/home/james/.."), ".."); // sic! according to C++17 + EXPECT_EQ(BaseUtils::Filesystem::filename("/home/james/.hidden"), ".hidden"); + EXPECT_EQ(BaseUtils::Filesystem::filename("/home/james/file.txt"), "file.txt"); + EXPECT_EQ(BaseUtils::Filesystem::filename("/home/james/file"), "file"); } TEST_F(FileSystemUtilsTest, stem) { - EXPECT_EQ(FileSystemUtils::stem(""), ""); - EXPECT_EQ(FileSystemUtils::stem("/home/james/"), ""); - EXPECT_EQ(FileSystemUtils::stem("/home/james/."), "."); - EXPECT_EQ(FileSystemUtils::stem("/home/james/.."), ".."); - EXPECT_EQ(FileSystemUtils::stem("/home/james/.hidden"), ".hidden"); - EXPECT_EQ(FileSystemUtils::stem("/home/james/.hidden.txt"), ".hidden"); - EXPECT_EQ(FileSystemUtils::stem("/home/james/.hidden.txt.gz"), ".hidden.txt"); - EXPECT_EQ(FileSystemUtils::stem("/home/james/filename.txt"), "filename"); - EXPECT_EQ(FileSystemUtils::stem("/home/james/filename.txt.gz"), "filename.txt"); + EXPECT_EQ(BaseUtils::Filesystem::stem(""), ""); + EXPECT_EQ(BaseUtils::Filesystem::stem("/home/james/"), ""); + EXPECT_EQ(BaseUtils::Filesystem::stem("/home/james/."), "."); + EXPECT_EQ(BaseUtils::Filesystem::stem("/home/james/.."), ".."); + EXPECT_EQ(BaseUtils::Filesystem::stem("/home/james/.hidden"), ".hidden"); + EXPECT_EQ(BaseUtils::Filesystem::stem("/home/james/.hidden.txt"), ".hidden"); + EXPECT_EQ(BaseUtils::Filesystem::stem("/home/james/.hidden.txt.gz"), ".hidden.txt"); + EXPECT_EQ(BaseUtils::Filesystem::stem("/home/james/filename.txt"), "filename"); + EXPECT_EQ(BaseUtils::Filesystem::stem("/home/james/filename.txt.gz"), "filename.txt"); } TEST_F(FileSystemUtilsTest, stem_ext) { - EXPECT_EQ(FileSystemUtils::stem_ext(""), ""); - EXPECT_EQ(FileSystemUtils::stem_ext("/home/james/"), ""); - EXPECT_EQ(FileSystemUtils::stem_ext("/home/james/."), "."); - EXPECT_EQ(FileSystemUtils::stem_ext("/home/james/.."), ".."); - EXPECT_EQ(FileSystemUtils::stem_ext("/home/james/.hidden"), ".hidden"); - EXPECT_EQ(FileSystemUtils::stem_ext("/home/james/.hidden.txt"), ".hidden"); - EXPECT_EQ(FileSystemUtils::stem_ext("/home/james/.hidden.txt.gz"), ".hidden"); - EXPECT_EQ(FileSystemUtils::stem_ext("/home/james/filename"), "filename"); - EXPECT_EQ(FileSystemUtils::stem_ext("/home/james/filename.txt"), "filename"); - EXPECT_EQ(FileSystemUtils::stem_ext("/home/james/filename.txt.gz"), "filename"); + EXPECT_EQ(BaseUtils::Filesystem::stem_ext(""), ""); + EXPECT_EQ(BaseUtils::Filesystem::stem_ext("/home/james/"), ""); + EXPECT_EQ(BaseUtils::Filesystem::stem_ext("/home/james/."), "."); + EXPECT_EQ(BaseUtils::Filesystem::stem_ext("/home/james/.."), ".."); + EXPECT_EQ(BaseUtils::Filesystem::stem_ext("/home/james/.hidden"), ".hidden"); + EXPECT_EQ(BaseUtils::Filesystem::stem_ext("/home/james/.hidden.txt"), ".hidden"); + EXPECT_EQ(BaseUtils::Filesystem::stem_ext("/home/james/.hidden.txt.gz"), ".hidden"); + EXPECT_EQ(BaseUtils::Filesystem::stem_ext("/home/james/filename"), "filename"); + EXPECT_EQ(BaseUtils::Filesystem::stem_ext("/home/james/filename.txt"), "filename"); + EXPECT_EQ(BaseUtils::Filesystem::stem_ext("/home/james/filename.txt.gz"), "filename"); } TEST_F(FileSystemUtilsTest, createDirectory) { // with absolute path - EXPECT_TRUE(FileSystemUtils::createDirectory(testCasePath())); - EXPECT_FALSE(FileSystemUtils::createDirectory(testCasePath())); + EXPECT_TRUE(BaseUtils::Filesystem::createDirectory(testCasePath())); + EXPECT_FALSE(BaseUtils::Filesystem::createDirectory(testCasePath())); // with relative path std::filesystem::current_path(testCasePath()); - EXPECT_TRUE(FileSystemUtils::createDirectory("sub")); - EXPECT_FALSE(FileSystemUtils::createDirectory("sub")); + EXPECT_TRUE(BaseUtils::Filesystem::createDirectory("sub")); + EXPECT_FALSE(BaseUtils::Filesystem::createDirectory("sub")); EXPECT_TRUE(std::filesystem::exists("sub")); - EXPECT_TRUE(std::filesystem::exists(FileSystemUtils::jointPath(testCasePath(), "sub"))); + EXPECT_TRUE(std::filesystem::exists(BaseUtils::Filesystem::jointPath(testCasePath(), "sub"))); } TEST_F(FileSystemUtilsTest, createDirectories) { // with absolute path - const auto sub1 = FileSystemUtils::jointPath(testCasePath(), "sub1"); - const auto sub2 = FileSystemUtils::jointPath(sub1, "sub2"); + const auto sub1 = BaseUtils::Filesystem::jointPath(testCasePath(), "sub1"); + const auto sub2 = BaseUtils::Filesystem::jointPath(sub1, "sub2"); - EXPECT_TRUE(FileSystemUtils::createDirectories(sub2)); - EXPECT_FALSE(FileSystemUtils::createDirectories(sub2)); + EXPECT_TRUE(BaseUtils::Filesystem::createDirectories(sub2)); + EXPECT_FALSE(BaseUtils::Filesystem::createDirectories(sub2)); EXPECT_TRUE(std::filesystem::exists(testCasePath())); EXPECT_TRUE(std::filesystem::exists(sub1)); EXPECT_TRUE(std::filesystem::exists(sub2)); @@ -136,33 +136,33 @@ TEST_F(FileSystemUtilsTest, createDirectories) // with relative path const auto sub4 = "sub3/sub4"; std::filesystem::current_path(sub2); - EXPECT_TRUE(FileSystemUtils::createDirectories(sub4)); - EXPECT_FALSE(FileSystemUtils::createDirectories(sub4)); + EXPECT_TRUE(BaseUtils::Filesystem::createDirectories(sub4)); + EXPECT_FALSE(BaseUtils::Filesystem::createDirectories(sub4)); EXPECT_TRUE(std::filesystem::exists("sub3")); EXPECT_TRUE(std::filesystem::exists("sub3/sub4")); - EXPECT_TRUE(std::filesystem::exists(FileSystemUtils::jointPath(sub2, sub4))); + EXPECT_TRUE(std::filesystem::exists(BaseUtils::Filesystem::jointPath(sub2, sub4))); } TEST_F(FileSystemUtilsTest, jointPath) { #ifdef _WIN32 - EXPECT_EQ(FileSystemUtils::jointPath("a", "b"), "a\\b"); + EXPECT_EQ(BaseUtils::Filesystem::jointPath("a", "b"), "a\\b"); #else - EXPECT_EQ(FileSystemUtils::jointPath("a", "b"), "a/b"); + EXPECT_EQ(BaseUtils::Filesystem::jointPath("a", "b"), "a/b"); #endif - EXPECT_ANY_THROW(FileSystemUtils::jointPath("", "")); - EXPECT_ANY_THROW(FileSystemUtils::jointPath("a", "")); - EXPECT_EQ(FileSystemUtils::jointPath("", "b"), "b"); + EXPECT_ANY_THROW(BaseUtils::Filesystem::jointPath("", "")); + EXPECT_ANY_THROW(BaseUtils::Filesystem::jointPath("a", "")); + EXPECT_EQ(BaseUtils::Filesystem::jointPath("", "b"), "b"); } TEST_F(FileSystemUtilsTest, filesInDirectory_IsFileExists) { - EXPECT_ANY_THROW(FileSystemUtils::filesInDirectory("non-existent/directory")); + EXPECT_ANY_THROW(BaseUtils::Filesystem::filesInDirectory("non-existent/directory")); // assure clean preconditions - ASSERT_TRUE(FileSystemUtils::createDirectories(testCasePath())); - EXPECT_TRUE(FileSystemUtils::filesInDirectory(testCasePath()).empty()); + ASSERT_TRUE(BaseUtils::Filesystem::createDirectories(testCasePath())); + EXPECT_TRUE(BaseUtils::Filesystem::filesInDirectory(testCasePath()).empty()); // create a few files std::filesystem::current_path(testCasePath()); @@ -170,16 +170,16 @@ TEST_F(FileSystemUtilsTest, filesInDirectory_IsFileExists) std::ofstream("file2.txt"); std::ofstream("file3.txt"); - EXPECT_EQ(FileSystemUtils::filesInDirectory(testCasePath()).size(), 3); // abs - EXPECT_EQ(FileSystemUtils::filesInDirectory(".").size(), 3); // rel - const auto files = FileSystemUtils::filesInDirectory("."); + EXPECT_EQ(BaseUtils::Filesystem::filesInDirectory(testCasePath()).size(), 3); // abs + EXPECT_EQ(BaseUtils::Filesystem::filesInDirectory(".").size(), 3); // rel + const auto files = BaseUtils::Filesystem::filesInDirectory("."); EXPECT_TRUE(std::find(files.begin(), files.end(), "file1.txt") != files.end()); EXPECT_TRUE(std::find(files.begin(), files.end(), "file2.txt") != files.end()); EXPECT_TRUE(std::find(files.begin(), files.end(), "file3.txt") != files.end()); // tests for IsFileExists - EXPECT_TRUE(FileSystemUtils::IsFileExists("file1.txt")); - EXPECT_TRUE(FileSystemUtils::IsFileExists("file2.txt")); - EXPECT_TRUE(FileSystemUtils::IsFileExists("file3.txt")); - EXPECT_FALSE(FileSystemUtils::IsFileExists("nonexisting.txt")); + EXPECT_TRUE(BaseUtils::Filesystem::IsFileExists("file1.txt")); + EXPECT_TRUE(BaseUtils::Filesystem::IsFileExists("file2.txt")); + EXPECT_TRUE(BaseUtils::Filesystem::IsFileExists("file3.txt")); + EXPECT_FALSE(BaseUtils::Filesystem::IsFileExists("nonexisting.txt")); } diff --git a/Tests/UnitTests/Core/Basics/StringUtilsTest.cpp b/Tests/UnitTests/Core/Basics/StringUtilsTest.cpp index 3929b879c0b..4ac0eb1fb2d 100644 --- a/Tests/UnitTests/Core/Basics/StringUtilsTest.cpp +++ b/Tests/UnitTests/Core/Basics/StringUtilsTest.cpp @@ -7,91 +7,91 @@ class StringUtilsTest : public ::testing::Test { TEST_F(StringUtilsTest, to_int) { - EXPECT_TRUE(StringUtils::to_int("1", nullptr)); - EXPECT_FALSE(StringUtils::to_int("a", nullptr)); + EXPECT_TRUE(BaseUtils::String::to_int("1", nullptr)); + EXPECT_FALSE(BaseUtils::String::to_int("a", nullptr)); int v = 2; - EXPECT_FALSE(StringUtils::to_int("", &v)); + EXPECT_FALSE(BaseUtils::String::to_int("", &v)); EXPECT_EQ(v, 2); - EXPECT_FALSE(StringUtils::to_int(" ", &v)); + EXPECT_FALSE(BaseUtils::String::to_int(" ", &v)); EXPECT_EQ(v, 2); - EXPECT_FALSE(StringUtils::to_int("r", &v)); + EXPECT_FALSE(BaseUtils::String::to_int("r", &v)); EXPECT_EQ(v, 2); - EXPECT_FALSE(StringUtils::to_int("1r", &v)); + EXPECT_FALSE(BaseUtils::String::to_int("1r", &v)); EXPECT_EQ(v, 2); - EXPECT_FALSE(StringUtils::to_int("1r ", &v)); + EXPECT_FALSE(BaseUtils::String::to_int("1r ", &v)); EXPECT_EQ(v, 2); - EXPECT_FALSE(StringUtils::to_int("r1", &v)); + EXPECT_FALSE(BaseUtils::String::to_int("r1", &v)); EXPECT_EQ(v, 2); - EXPECT_FALSE(StringUtils::to_int("1 r", &v)); + EXPECT_FALSE(BaseUtils::String::to_int("1 r", &v)); EXPECT_EQ(v, 2); - EXPECT_FALSE(StringUtils::to_int("r 1", &v)); + EXPECT_FALSE(BaseUtils::String::to_int("r 1", &v)); EXPECT_EQ(v, 2); - EXPECT_FALSE(StringUtils::to_int("111111111111111111111111111111111", &v)); + EXPECT_FALSE(BaseUtils::String::to_int("111111111111111111111111111111111", &v)); EXPECT_EQ(v, 2); - EXPECT_FALSE(StringUtils::to_int("1\t", &v)); + EXPECT_FALSE(BaseUtils::String::to_int("1\t", &v)); EXPECT_EQ(v, 2); - EXPECT_FALSE(StringUtils::to_int("\t1", &v)); + EXPECT_FALSE(BaseUtils::String::to_int("\t1", &v)); EXPECT_EQ(v, 2); - EXPECT_TRUE(StringUtils::to_int("1", &v)); + EXPECT_TRUE(BaseUtils::String::to_int("1", &v)); EXPECT_EQ(v, 1); - EXPECT_TRUE(StringUtils::to_int(" 2", &v)); + EXPECT_TRUE(BaseUtils::String::to_int(" 2", &v)); EXPECT_EQ(v, 2); - EXPECT_TRUE(StringUtils::to_int(" 3 ", &v)); + EXPECT_TRUE(BaseUtils::String::to_int(" 3 ", &v)); EXPECT_EQ(v, 3); - EXPECT_TRUE(StringUtils::to_int("4 ", &v)); + EXPECT_TRUE(BaseUtils::String::to_int("4 ", &v)); EXPECT_EQ(v, 4); - EXPECT_TRUE(StringUtils::to_int("01", &v)); + EXPECT_TRUE(BaseUtils::String::to_int("01", &v)); EXPECT_EQ(v, 1); - EXPECT_TRUE(StringUtils::to_int("0000", &v)); + EXPECT_TRUE(BaseUtils::String::to_int("0000", &v)); EXPECT_EQ(v, 0); - EXPECT_TRUE(StringUtils::to_int("65535", &v)); + EXPECT_TRUE(BaseUtils::String::to_int("65535", &v)); EXPECT_EQ(v, 65535); - EXPECT_TRUE(StringUtils::to_int("-10", &v)); + EXPECT_TRUE(BaseUtils::String::to_int("-10", &v)); EXPECT_EQ(v, -10); - EXPECT_TRUE(StringUtils::to_int(" -20 ", &v)); + EXPECT_TRUE(BaseUtils::String::to_int(" -20 ", &v)); EXPECT_EQ(v, -20); } TEST_F(StringUtilsTest, trimFront) { - EXPECT_EQ(StringUtils::trimFront(" "), ""); - EXPECT_EQ(StringUtils::trimFront(" a"), "a"); - EXPECT_EQ(StringUtils::trimFront("\t a"), "a"); - EXPECT_EQ(StringUtils::trimFront("\t a", " "), "\t a"); - EXPECT_EQ(StringUtils::trimFront("\t\ta"), "a"); - EXPECT_EQ(StringUtils::trimFront("a "), "a "); + EXPECT_EQ(BaseUtils::String::trimFront(" "), ""); + EXPECT_EQ(BaseUtils::String::trimFront(" a"), "a"); + EXPECT_EQ(BaseUtils::String::trimFront("\t a"), "a"); + EXPECT_EQ(BaseUtils::String::trimFront("\t a", " "), "\t a"); + EXPECT_EQ(BaseUtils::String::trimFront("\t\ta"), "a"); + EXPECT_EQ(BaseUtils::String::trimFront("a "), "a "); } TEST_F(StringUtilsTest, startsWith) { - EXPECT_TRUE(StringUtils::startsWith("a", "a")); - EXPECT_TRUE(StringUtils::startsWith("ab", "a")); - EXPECT_TRUE(StringUtils::startsWith(" a", " a")); - EXPECT_TRUE(StringUtils::startsWith("abc", "ab")); - EXPECT_TRUE(StringUtils::startsWith("\tabc", "\t")); - EXPECT_TRUE(StringUtils::startsWith("abc", "")); - - EXPECT_FALSE(StringUtils::startsWith("ab", "abc")); - EXPECT_FALSE(StringUtils::startsWith("abc", "A")); - EXPECT_FALSE(StringUtils::startsWith(" a", "a")); + EXPECT_TRUE(BaseUtils::String::startsWith("a", "a")); + EXPECT_TRUE(BaseUtils::String::startsWith("ab", "a")); + EXPECT_TRUE(BaseUtils::String::startsWith(" a", " a")); + EXPECT_TRUE(BaseUtils::String::startsWith("abc", "ab")); + EXPECT_TRUE(BaseUtils::String::startsWith("\tabc", "\t")); + EXPECT_TRUE(BaseUtils::String::startsWith("abc", "")); + + EXPECT_FALSE(BaseUtils::String::startsWith("ab", "abc")); + EXPECT_FALSE(BaseUtils::String::startsWith("abc", "A")); + EXPECT_FALSE(BaseUtils::String::startsWith(" a", "a")); } \ No newline at end of file diff --git a/auto/Wrap/doxygenBase.i b/auto/Wrap/doxygenBase.i index 11855d416e5..7ac162b5353 100644 --- a/auto/Wrap/doxygenBase.i +++ b/auto/Wrap/doxygenBase.i @@ -1314,68 +1314,200 @@ Returns the concatenation of two std::vectors. "; -// File: namespaceFileSystemUtils.xml -%feature("docstring") FileSystemUtils::extension "std::string FileSystemUtils::extension(const std::string &path) +// File: namespaceBaseUtils.xml + + +// File: namespaceBaseUtils_1_1Filesystem.xml +%feature("docstring") BaseUtils::Filesystem::extension "std::string BaseUtils::Filesystem::extension(const std::string &path) Returns extension of given filename. \"/home/user/filename.int\" -> \".int\", \"/home/user/filename.int.gz\" -> \".gz\" "; -%feature("docstring") FileSystemUtils::extensions "std::string FileSystemUtils::extensions(const std::string &path) +%feature("docstring") BaseUtils::Filesystem::extensions "std::string BaseUtils::Filesystem::extensions(const std::string &path) Returns extension(s) of given filename. \"/home/user/filename.int\" -> \".int\", \"/home/user/filename.int.gz\" -> \".int.gz\" "; -%feature("docstring") FileSystemUtils::createDirectory "bool FileSystemUtils::createDirectory(const std::string &dir_name) +%feature("docstring") BaseUtils::Filesystem::createDirectory "bool BaseUtils::Filesystem::createDirectory(const std::string &dir_name) Creates directory in current directory. "; -%feature("docstring") FileSystemUtils::createDirectories "bool FileSystemUtils::createDirectories(const std::string &dir_name) +%feature("docstring") BaseUtils::Filesystem::createDirectories "bool BaseUtils::Filesystem::createDirectories(const std::string &dir_name) Creates directories in current directory for any element of dir_name which doesn't exist. "; -%feature("docstring") FileSystemUtils::filesInDirectory "std::vector< std::string > FileSystemUtils::filesInDirectory(const std::string &dir_name) +%feature("docstring") BaseUtils::Filesystem::filesInDirectory "std::vector< std::string > BaseUtils::Filesystem::filesInDirectory(const std::string &dir_name) Returns filenames of files in directory. "; -%feature("docstring") FileSystemUtils::jointPath "std::string FileSystemUtils::jointPath(const std::string &path1, const std::string &path2) +%feature("docstring") BaseUtils::Filesystem::jointPath "std::string BaseUtils::Filesystem::jointPath(const std::string &path1, const std::string &path2) Returns joint path name. Argument path1 may be empty, argument path2 not. "; -%feature("docstring") FileSystemUtils::filename "std::string FileSystemUtils::filename(const std::string &path) +%feature("docstring") BaseUtils::Filesystem::filename "std::string BaseUtils::Filesystem::filename(const std::string &path) Returns path without directory part (\"Foo/Bar/Doz.int.gz\" -> \"Doz.int.gz\") "; -%feature("docstring") FileSystemUtils::stem "std::string FileSystemUtils::stem(const std::string &path) +%feature("docstring") BaseUtils::Filesystem::stem "std::string BaseUtils::Filesystem::stem(const std::string &path) Returns filename without (last) extension. \"/home/user/filename.int\" -> \"filename\", \"/home/user/filename.int.gz\" -> \"filename.int\" "; -%feature("docstring") FileSystemUtils::stem_ext "std::string FileSystemUtils::stem_ext(const std::string &path) +%feature("docstring") BaseUtils::Filesystem::stem_ext "std::string BaseUtils::Filesystem::stem_ext(const std::string &path) Returns filename without extension(s). \"/home/user/filename.int\" -> \"filename\", \"/home/user/filename.int.gz\" -> \"filename\" "; -%feature("docstring") FileSystemUtils::glob "std::vector< std::string > FileSystemUtils::glob(const std::string &dir, const std::string &pattern) +%feature("docstring") BaseUtils::Filesystem::glob "std::vector< std::string > BaseUtils::Filesystem::glob(const std::string &dir, const std::string &pattern) Returns file names that agree with a regex glob pattern. "; -%feature("docstring") FileSystemUtils::convert_utf8_to_utf16 "std::wstring FileSystemUtils::convert_utf8_to_utf16(const std::string &str) +%feature("docstring") BaseUtils::Filesystem::convert_utf8_to_utf16 "std::wstring BaseUtils::Filesystem::convert_utf8_to_utf16(const std::string &str) Converts utf8 string represented by std::string to utf16 string represented by std::wstring. "; -%feature("docstring") FileSystemUtils::IsFileExists "bool FileSystemUtils::IsFileExists(const std::string &path) +%feature("docstring") BaseUtils::Filesystem::IsFileExists "bool BaseUtils::Filesystem::IsFileExists(const std::string &path) Returns true if file with given name exists on disk. "; +// File: namespaceBaseUtils_1_1Python.xml +%feature("docstring") BaseUtils::Python::toString "std::string BaseUtils::Python::toString(PyObject *obj) + +Converts PyObject into string, if possible, or throws exception. +"; + +%feature("docstring") BaseUtils::Python::toVectorString "std::vector< std::string > BaseUtils::Python::toVectorString(PyObject *obj) + +Converts PyObject into vector of strings, if possible, or throws exception. +"; + +%feature("docstring") BaseUtils::Python::toString "std::string BaseUtils::Python::toString(char *c) + +Converts char to string. In the case of nullptr will return an empty string. +"; + +%feature("docstring") BaseUtils::Python::toString "std::string BaseUtils::Python::toString(wchar_t *c) +"; + +%feature("docstring") BaseUtils::Python::import_bornagain "void BaseUtils::Python::import_bornagain(const std::string &path=\"\") + +Imports BornAgain from given location. If path is empty, tries to rely on PYTHONPATH. +"; + +%feature("docstring") BaseUtils::Python::pythonRuntimeInfo "std::string BaseUtils::Python::pythonRuntimeInfo() + +Returns multi-line string representing PATH, PYTHONPATH, sys.path and other info. +"; + +%feature("docstring") BaseUtils::Python::pythonStackTrace "std::string BaseUtils::Python::pythonStackTrace() + +Returns string representing python stack trace. +"; + +%feature("docstring") BaseUtils::Python::createNumpyArray "PyObject * BaseUtils::Python::createNumpyArray(const std::vector< double > &data) +"; + + +// File: namespaceBaseUtils_1_1String.xml +%feature("docstring") BaseUtils::String::matchesPattern "bool BaseUtils::String::matchesPattern(const std::string &text, const std::string &wildcardPattern) + +Returns true if text matches pattern with wildcards '*' and '?'. +"; + +%feature("docstring") BaseUtils::String::padRight "std::string BaseUtils::String::padRight(const std::string &name, size_t length) + +Returns string right-padded with blanks. +"; + +%feature("docstring") BaseUtils::String::split "std::vector< std::string > BaseUtils::String::split(const std::string &text, const std::string &delimiter) + +Split string into vector of string using delimiter. + +Returns token vector obtained by splitting string at delimiters. +"; + +%feature("docstring") BaseUtils::String::replaceItemsFromString "void BaseUtils::String::replaceItemsFromString(std::string &text, const std::vector< std::string > &items, const std::string &replacement=\"\") + +Replaces all occurrences of items from string text with delimiter. +"; + +%feature("docstring") BaseUtils::String::join "std::string BaseUtils::String::join(const std::vector< std::string > &joinable, const std::string &joint) + +Returns string obtain by joining vector elements. +"; + +%feature("docstring") BaseUtils::String::removeSubstring "std::string BaseUtils::String::removeSubstring(const std::string &text, const std::string &substr) + +Removes multiple occurrences of given substring from a string and returns result. +"; + +%feature("docstring") BaseUtils::String::scientific "std::string BaseUtils::String::scientific(const T value, int n=10) + +Returns scientific string representing given value of any numeric type. +"; + +%feature("docstring") BaseUtils::String::to_lower "std::string BaseUtils::String::to_lower(std::string text) + +Returns new string which is lower case of text. +"; + +%feature("docstring") BaseUtils::String::to_int "bool BaseUtils::String::to_int(const std::string &str, int *result) + +Interprets the contained text as an integer and returns it in result. Space chars at its begin and end will be ignored. If the conversion result is of no interest, but only the convertibility, then you can set result to nullptr. The conversion is assumed to be successful if: +every character was consumed by the conversion + +the value is not too big for int + +the text is not empty Returns true if successful. If not successful, the value in result is not changed. Does not throw anything. +"; + +%feature("docstring") BaseUtils::String::trim "std::string BaseUtils::String::trim(const std::string &str, const std::string &whitespace=\" \\\\t\") + +Cuts any of the chars given in whitespace from start and end of str. +"; + +%feature("docstring") BaseUtils::String::trimFront "std::string BaseUtils::String::trimFront(const std::string &str, const std::string &whitespace=\" \\\\t\") + +Cuts any of the chars given in whitespace from start. +"; + +%feature("docstring") BaseUtils::String::startsWith "bool BaseUtils::String::startsWith(const std::string &str, const std::string &substr) + +True if the string starts with substr. The comparison is case sensitive. +"; + + +// File: namespaceBaseUtils_1_1System.xml +%feature("docstring") BaseUtils::System::getCurrentDateAndTime "std::string BaseUtils::System::getCurrentDateAndTime() +"; + +%feature("docstring") BaseUtils::System::enableFloatingPointExceptions "void BaseUtils::System::enableFloatingPointExceptions() + +Enables exception throw in the case of NaN, Inf. + +enables exception throw in the case of NaN, Inf +"; + +%feature("docstring") BaseUtils::System::getenv "std::string BaseUtils::System::getenv(const std::string &name) + +Returns environment variable. +"; + +%feature("docstring") BaseUtils::System::isWindowsHost "bool BaseUtils::System::isWindowsHost() + +Returns true if operation system is Windows. +"; + + // File: namespaceMath.xml %feature("docstring") Math::Bessel::StandardNormal "double Math::StandardNormal(double x) "; @@ -1566,138 +1698,9 @@ Returns a string of blanks with given width. By default the width equals standar "; -// File: namespacePyUtils.xml -%feature("docstring") PyUtils::toString "std::string PyUtils::toString(PyObject *obj) - -Converts PyObject into string, if possible, or throws exception. -"; - -%feature("docstring") PyUtils::toVectorString "std::vector< std::string > PyUtils::toVectorString(PyObject *obj) - -Converts PyObject into vector of strings, if possible, or throws exception. -"; - -%feature("docstring") PyUtils::toString "std::string PyUtils::toString(char *c) - -Converts char to string. In the case of nullptr will return an empty string. -"; - -%feature("docstring") PyUtils::toString "std::string PyUtils::toString(wchar_t *c) -"; - -%feature("docstring") PyUtils::import_bornagain "void PyUtils::import_bornagain(const std::string &path=\"\") - -Imports BornAgain from given location. If path is empty, tries to rely on PYTHONPATH. -"; - -%feature("docstring") PyUtils::pythonRuntimeInfo "std::string PyUtils::pythonRuntimeInfo() - -Returns multi-line string representing PATH, PYTHONPATH, sys.path and other info. -"; - -%feature("docstring") PyUtils::pythonStackTrace "std::string PyUtils::pythonStackTrace() - -Returns string representing python stack trace. -"; - -%feature("docstring") PyUtils::createNumpyArray "PyObject * PyUtils::createNumpyArray(const std::vector< double > &data) -"; - - // File: namespacestd.xml -// File: namespaceStringUtils.xml -%feature("docstring") StringUtils::matchesPattern "bool StringUtils::matchesPattern(const std::string &text, const std::string &wildcardPattern) - -Returns true if text matches pattern with wildcards '*' and '?'. -"; - -%feature("docstring") StringUtils::padRight "std::string StringUtils::padRight(const std::string &name, size_t length) - -Returns string right-padded with blanks. -"; - -%feature("docstring") StringUtils::split "std::vector< std::string > StringUtils::split(const std::string &text, const std::string &delimiter) - -Split string into vector of string using delimiter. - -Returns token vector obtained by splitting string at delimiters. -"; - -%feature("docstring") StringUtils::replaceItemsFromString "void StringUtils::replaceItemsFromString(std::string &text, const std::vector< std::string > &items, const std::string &replacement=\"\") - -Replaces all occurrences of items from string text with delimiter. -"; - -%feature("docstring") StringUtils::join "std::string StringUtils::join(const std::vector< std::string > &joinable, const std::string &joint) - -Returns string obtain by joining vector elements. -"; - -%feature("docstring") StringUtils::removeSubstring "std::string StringUtils::removeSubstring(const std::string &text, const std::string &substr) - -Removes multiple occurrences of given substring from a string and returns result. -"; - -%feature("docstring") StringUtils::scientific "std::string StringUtils::scientific(const T value, int n=10) - -Returns scientific string representing given value of any numeric type. -"; - -%feature("docstring") StringUtils::to_lower "std::string StringUtils::to_lower(std::string text) - -Returns new string which is lower case of text. -"; - -%feature("docstring") StringUtils::to_int "bool StringUtils::to_int(const std::string &str, int *result) - -Interprets the contained text as an integer and returns it in result. Space chars at its begin and end will be ignored. If the conversion result is of no interest, but only the convertibility, then you can set result to nullptr. The conversion is assumed to be successful if: -every character was consumed by the conversion - -the value is not too big for int - -the text is not empty Returns true if successful. If not successful, the value in result is not changed. Does not throw anything. -"; - -%feature("docstring") StringUtils::trim "std::string StringUtils::trim(const std::string &str, const std::string &whitespace=\" \\\\t\") - -Cuts any of the chars given in whitespace from start and end of str. -"; - -%feature("docstring") StringUtils::trimFront "std::string StringUtils::trimFront(const std::string &str, const std::string &whitespace=\" \\\\t\") - -Cuts any of the chars given in whitespace from start. -"; - -%feature("docstring") StringUtils::startsWith "bool StringUtils::startsWith(const std::string &str, const std::string &substr) - -True if the string starts with substr. The comparison is case sensitive. -"; - - -// File: namespaceSysUtils.xml -%feature("docstring") SysUtils::getCurrentDateAndTime "std::string SysUtils::getCurrentDateAndTime() -"; - -%feature("docstring") SysUtils::enableFloatingPointExceptions "void SysUtils::enableFloatingPointExceptions() - -Enables exception throw in the case of NaN, Inf. - -enables exception throw in the case of NaN, Inf -"; - -%feature("docstring") SysUtils::getenv "std::string SysUtils::getenv(const std::string &name) - -Returns environment variable. -"; - -%feature("docstring") SysUtils::isWindowsHost "bool SysUtils::isWindowsHost() - -Returns true if operation system is Windows. -"; - - // File: namespaceUnits.xml %feature("docstring") Units::rad2deg "double Units::rad2deg(double angle) "; -- GitLab