diff --git a/.env.dev b/.env.dev new file mode 100644 index 0000000..eb19e75 --- /dev/null +++ b/.env.dev @@ -0,0 +1 @@ +export PROJECT_ROOT_DIR=/home/l_bechir/github/aare diff --git a/CMakeLists.txt b/CMakeLists.txt index e17c311..59a3c34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ include(FetchContent) include(cmake/helpers.cmake) default_build_type("Release") -option(AARE_USE_WARNINGS "Eable warnings" OFF) +option(AARE_USE_WARNINGS "Eable warnings" ON) option(AARE_PYTHON_BINDINGS "Build python bindings" ON) option(AARE_TESTS "Build tests" ON) option(AARE_EXAMPLES "Build examples" ON) @@ -86,4 +86,6 @@ target_link_libraries(example PUBLIC aare) if(AARE_PYTHON_BINDINGS) add_subdirectory(python) -endif() \ No newline at end of file +endif() + +set(ENV{PROJECT_ROOT_DIR} ${PROJECT_SOURCE_DIR}) diff --git a/examples/main.cpp b/examples/main.cpp index 66d8af5..a1464e0 100644 --- a/examples/main.cpp +++ b/examples/main.cpp @@ -2,6 +2,8 @@ #include "aare/FileHandler.hpp" #include +#define AARE_ROOT_DIR_VAR "PROJECT_ROOT_DIR" + using JFileHandler = FileHandler; using JFile = File; using JFrame = Frame; @@ -18,8 +20,11 @@ void test(JFileHandler *f, int frame_number) { } int main() { + auto PROJECT_ROOT_DIR = std::filesystem::path(getenv(AARE_ROOT_DIR_VAR)); // std::filesystem::path fpath("/home/bb/github/aare/data/jungfrau_single_master_0.json"); - std::filesystem::path fpath("/home/bb/github/aare/data/test_numpy_file.npy"); + std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "test_numpy_file.npy"); + std::cout< -#include -#include #include -#include -#include -#include -#include + + template class NumpyFileFactory : public FileFactory { private: diff --git a/file_io/include/aare/NumpyHelpers.hpp b/file_io/include/aare/NumpyHelpers.hpp new file mode 100644 index 0000000..21b08d4 --- /dev/null +++ b/file_io/include/aare/NumpyHelpers.hpp @@ -0,0 +1,146 @@ + +#include +#include +#include +#include +#include +#include +#include +#include + +inline std::string parse_str(const std::string &in) { + if ((in.front() == '\'') && (in.back() == '\'')) + return in.substr(1, in.length() - 2); + + throw std::runtime_error("Invalid python string."); +} +/** + Removes leading and trailing whitespaces + */ +inline std::string trim(const std::string &str) { + const std::string whitespace = " \t\n"; + auto begin = str.find_first_not_of(whitespace); + + if (begin == std::string::npos) + return ""; + + auto end = str.find_last_not_of(whitespace); + + return str.substr(begin, end - begin + 1); +} +inline std::vector parse_tuple(std::string in) { + std::vector v; + const char seperator = ','; + + in = trim(in); + + if ((in.front() == '(') && (in.back() == ')')) + in = in.substr(1, in.length() - 2); + else + throw std::runtime_error("Invalid Python tuple."); + + std::istringstream iss(in); + + for (std::string token; std::getline(iss, token, seperator);) { + v.push_back(token); + } + + return v; +} +inline bool parse_bool(const std::string &in) { + if (in == "True") + return true; + if (in == "False") + return false; + + throw std::runtime_error("Invalid python boolan."); +} + +inline std::string get_value_from_map(const std::string &mapstr) { + size_t sep_pos = mapstr.find_first_of(":"); + if (sep_pos == std::string::npos) + return ""; + + std::string tmp = mapstr.substr(sep_pos + 1); + return trim(tmp); +} +std::unordered_map parse_dict(std::string in, const std::vector &keys) { + std::unordered_map map; + if (keys.size() == 0) + return map; + + in = trim(in); + + // unwrap dictionary + if ((in.front() == '{') && (in.back() == '}')) + in = in.substr(1, in.length() - 2); + else + throw std::runtime_error("Not a Python dictionary."); + + std::vector> positions; + + for (auto const &value : keys) { + size_t pos = in.find("'" + value + "'"); + + if (pos == std::string::npos) + throw std::runtime_error("Missing '" + value + "' key."); + + std::pair position_pair{pos, value}; + positions.push_back(position_pair); + } + + // sort by position in dict + std::sort(positions.begin(), positions.end()); + + for (size_t i = 0; i < positions.size(); ++i) { + std::string raw_value; + size_t begin{positions[i].first}; + size_t end{std::string::npos}; + + std::string key = positions[i].second; + + if (i + 1 < positions.size()) + end = positions[i + 1].first; + + raw_value = in.substr(begin, end - begin); + + raw_value = trim(raw_value); + + if (raw_value.back() == ',') + raw_value.pop_back(); + + map[key] = get_value_from_map(raw_value); + } + + return map; +} + +template inline bool in_array(T val, const std::array &arr) { + return std::find(std::begin(arr), std::end(arr), val) != std::end(arr); +} +inline bool is_digits(const std::string &str) { return std::all_of(str.begin(), str.end(), ::isdigit); } + +inline dtype_t parse_descr(std::string typestring) { + if (typestring.length() < 3) { + throw std::runtime_error("invalid typestring (length)"); + } + + char byteorder_c = typestring.at(0); + char kind_c = typestring.at(1); + std::string itemsize_s = typestring.substr(2); + + if (!in_array(byteorder_c, endian_chars)) { + throw std::runtime_error("invalid typestring (byteorder)"); + } + + if (!in_array(kind_c, numtype_chars)) { + throw std::runtime_error("invalid typestring (kind)"); + } + + if (!is_digits(itemsize_s)) { + throw std::runtime_error("invalid typestring (itemsize)"); + } + unsigned int itemsize = std::stoul(itemsize_s); + + return {byteorder_c, kind_c, itemsize}; +} diff --git a/file_io/src/NumpyFileFactory.cpp b/file_io/src/NumpyFileFactory.cpp index 0f90a7d..42e2056 100644 --- a/file_io/src/NumpyFileFactory.cpp +++ b/file_io/src/NumpyFileFactory.cpp @@ -1,146 +1,9 @@ #include "aare/NumpyFileFactory.hpp" - +#include "aare/NumpyHelpers.hpp" template NumpyFileFactory::NumpyFileFactory(std::filesystem::path fpath) { this->m_fpath = fpath; } -inline std::string parse_str(const std::string &in) { - if ((in.front() == '\'') && (in.back() == '\'')) - return in.substr(1, in.length() - 2); - - throw std::runtime_error("Invalid python string."); -} -/** - Removes leading and trailing whitespaces - */ -inline std::string trim(const std::string &str) { - const std::string whitespace = " \t\n"; - auto begin = str.find_first_not_of(whitespace); - - if (begin == std::string::npos) - return ""; - - auto end = str.find_last_not_of(whitespace); - - return str.substr(begin, end - begin + 1); -} -inline std::vector parse_tuple(std::string in) { - std::vector v; - const char seperator = ','; - - in = trim(in); - - if ((in.front() == '(') && (in.back() == ')')) - in = in.substr(1, in.length() - 2); - else - throw std::runtime_error("Invalid Python tuple."); - - std::istringstream iss(in); - - for (std::string token; std::getline(iss, token, seperator);) { - v.push_back(token); - } - - return v; -} -inline bool parse_bool(const std::string &in) { - if (in == "True") - return true; - if (in == "False") - return false; - - throw std::runtime_error("Invalid python boolan."); -} - -inline std::string get_value_from_map(const std::string &mapstr) { - size_t sep_pos = mapstr.find_first_of(":"); - if (sep_pos == std::string::npos) - return ""; - - std::string tmp = mapstr.substr(sep_pos + 1); - return trim(tmp); -} -std::unordered_map parse_dict(std::string in, const std::vector &keys) { - std::unordered_map map; - if (keys.size() == 0) - return map; - - in = trim(in); - - // unwrap dictionary - if ((in.front() == '{') && (in.back() == '}')) - in = in.substr(1, in.length() - 2); - else - throw std::runtime_error("Not a Python dictionary."); - - std::vector> positions; - - for (auto const &value : keys) { - size_t pos = in.find("'" + value + "'"); - - if (pos == std::string::npos) - throw std::runtime_error("Missing '" + value + "' key."); - - std::pair position_pair{pos, value}; - positions.push_back(position_pair); - } - - // sort by position in dict - std::sort(positions.begin(), positions.end()); - - for (size_t i = 0; i < positions.size(); ++i) { - std::string raw_value; - size_t begin{positions[i].first}; - size_t end{std::string::npos}; - - std::string key = positions[i].second; - - if (i + 1 < positions.size()) - end = positions[i + 1].first; - - raw_value = in.substr(begin, end - begin); - - raw_value = trim(raw_value); - - if (raw_value.back() == ',') - raw_value.pop_back(); - - map[key] = get_value_from_map(raw_value); - } - - return map; -} - -template inline bool in_array(T val, const std::array &arr) { - return std::find(std::begin(arr), std::end(arr), val) != std::end(arr); -} -inline bool is_digits(const std::string &str) { return std::all_of(str.begin(), str.end(), ::isdigit); } - -inline dtype_t parse_descr(std::string typestring) { - if (typestring.length() < 3) { - throw std::runtime_error("invalid typestring (length)"); - } - - char byteorder_c = typestring.at(0); - char kind_c = typestring.at(1); - std::string itemsize_s = typestring.substr(2); - - if (!in_array(byteorder_c, endian_chars)) { - throw std::runtime_error("invalid typestring (byteorder)"); - } - - if (!in_array(kind_c, numtype_chars)) { - throw std::runtime_error("invalid typestring (kind)"); - } - - if (!is_digits(itemsize_s)) { - throw std::runtime_error("invalid typestring (itemsize)"); - } - unsigned int itemsize = std::stoul(itemsize_s); - - return {byteorder_c, kind_c, itemsize}; -} - template void NumpyFileFactory::parse_metadata(File *_file) { auto file = dynamic_cast *>(_file); diff --git a/python/example/read_frame.py b/python/example/read_frame.py index 457a4ef..293ac45 100644 --- a/python/example/read_frame.py +++ b/python/example/read_frame.py @@ -1,7 +1,13 @@ +import os +from pathlib import Path from aare import File, Frame if __name__ == "__main__": - file = File("/home/bb/github/aare/data/jungfrau_single_master_0.json") + #get env variable + root_dir = Path(os.environ.get("PROJECT_ROOT_DIR")) + data_path = str(root_dir / "data"/"jungfrau_single_master_0.json") + + file = File(data_path) frame = file.get_frame(0) print(frame.rows, frame.cols) print(frame.get(0,0)) \ No newline at end of file