diff --git a/core/include/aare/NDView.hpp b/core/include/aare/NDView.hpp index b582613c..9e07d417 100644 --- a/core/include/aare/NDView.hpp +++ b/core/include/aare/NDView.hpp @@ -68,6 +68,16 @@ template class NDView { T &operator()(ssize_t i) { return buffer_[i]; } T &operator[](ssize_t i) { return buffer_[i]; } + bool operator==(const NDView &other) const { + if (size_ != other.size_) + return false; + for (ssize_t i = 0; i != size_; ++i) { + if (buffer_[i] != other.buffer_[i]) + return false; + } + return true; + } + NDView &operator+=(const T val) { return elemenwise(val, std::plus()); } NDView &operator-=(const T val) { return elemenwise(val, std::minus()); } NDView &operator*=(const T val) { return elemenwise(val, std::multiplies()); } diff --git a/core/test/CircularFifo.test.cpp b/core/test/CircularFifo.test.cpp index 973142a9..c3ff995f 100644 --- a/core/test/CircularFifo.test.cpp +++ b/core/test/CircularFifo.test.cpp @@ -1,116 +1,116 @@ -#include - -#include "aare/CircularFifo.hpp" - -using aare::CircularFifo; - -// Only for testing. To make sure we can avoid copy constructor -// and copy assignment - -struct MoveOnlyInt { - int value{}; - - MoveOnlyInt() = default; - MoveOnlyInt(int i) : value(i){}; - MoveOnlyInt(const MoveOnlyInt &) = delete; - MoveOnlyInt &operator=(const MoveOnlyInt &) = delete; - MoveOnlyInt(MoveOnlyInt &&other) { std::swap(value, other.value); } - MoveOnlyInt &operator=(MoveOnlyInt &&other) { - std::swap(value, other.value); - return *this; - } - bool operator==(int other) const { return value == other; } -}; - -TEST_CASE("CircularFifo can be default constructed") { CircularFifo f; } - -TEST_CASE("Newly constructed fifo has the right size") { - size_t size = 17; - CircularFifo f(size); - CHECK(f.numFreeSlots() == size); - CHECK(f.numFilledSlots() == 0); -} - -TEST_CASE("Can fit size number of objects") { - size_t size = 8; - size_t numPushedItems = 0; - CircularFifo f(size); - for (size_t i = 0; i < size; ++i) { - MoveOnlyInt a; - bool popped = f.try_pop_free(a); - CHECK(popped); - if (popped) { - a.value = i; - bool pushed = f.try_push_value(std::move(a)); - CHECK(pushed); - if (pushed) - numPushedItems++; - } - } - CHECK(f.numFreeSlots() == 0); - CHECK(f.numFilledSlots() == size); - CHECK(numPushedItems == size); -} - -TEST_CASE("Push move only type") { - CircularFifo f; - f.push_value(5); -} - -TEST_CASE("Push pop") { - CircularFifo f; - f.push_value(MoveOnlyInt(1)); - - auto a = f.pop_value(); - CHECK(a == 1); -} - -TEST_CASE("Pop free and then push") { - CircularFifo f; - - auto a = f.pop_free(); - a.value = 5; - f.push_value(std::move(a)); // Explicit move since we can't copy - auto b = f.pop_value(); - - CHECK(a == 0); // Moved from value - CHECK(b == 5); // Original value -} - -TEST_CASE("Skip the first value") { - CircularFifo f; - - for (int i = 0; i != 10; ++i) { - auto a = f.pop_free(); - a.value = i + 1; - f.push_value(std::move(a)); // Explicit move since we can't copy - } - - auto b = f.pop_value(); - CHECK(b == 1); - f.next(); - auto c = f.pop_value(); - CHECK(c == 3); -} - -TEST_CASE("Use in place and move to free") { - size_t size = 18; - CircularFifo f(size); - - //Push 10 values to the fifo - for (int i = 0; i != 10; ++i) { - auto a = f.pop_free(); - a.value = i + 1; - f.push_value(std::move(a)); // Explicit move since we can't copy - } - - auto b = f.frontPtr(); - CHECK(*b == 1); - CHECK(f.numFilledSlots() == 10); - CHECK(f.numFreeSlots() == size-10); - f.next(); - auto c = f.frontPtr(); - CHECK(*c == 2); - CHECK(f.numFilledSlots() == 9); - CHECK(f.numFreeSlots() == size-9); -} + #include + + #include "aare/CircularFifo.hpp" + + using aare::CircularFifo; + + // Only for testing. To make sure we can avoid copy constructor + // and copy assignment + + struct MoveOnlyInt { + int value{}; + + MoveOnlyInt() = default; + MoveOnlyInt(int i) : value(i){}; + MoveOnlyInt(const MoveOnlyInt &) = delete; + MoveOnlyInt &operator=(const MoveOnlyInt &) = delete; + MoveOnlyInt(MoveOnlyInt &&other) { std::swap(value, other.value); } + MoveOnlyInt &operator=(MoveOnlyInt &&other) { + std::swap(value, other.value); + return *this; + } + bool operator==(int other) const { return value == other; } + }; + + TEST_CASE("CircularFifo can be default constructed") { CircularFifo f; } + + TEST_CASE("Newly constructed fifo has the right size") { + size_t size = 17; + CircularFifo f(size); + CHECK(f.numFreeSlots() == size); + CHECK(f.numFilledSlots() == 0); + } + + TEST_CASE("Can fit size number of objects") { + size_t size = 8; + size_t numPushedItems = 0; + CircularFifo f(size); + for (size_t i = 0; i < size; ++i) { + MoveOnlyInt a; + bool popped = f.try_pop_free(a); + CHECK(popped); + if (popped) { + a.value = i; + bool pushed = f.try_push_value(std::move(a)); + CHECK(pushed); + if (pushed) + numPushedItems++; + } + } + CHECK(f.numFreeSlots() == 0); + CHECK(f.numFilledSlots() == size); + CHECK(numPushedItems == size); + } + + TEST_CASE("Push move only type") { + CircularFifo f; + f.push_value(5); + } + + TEST_CASE("Push pop") { + CircularFifo f; + f.push_value(MoveOnlyInt(1)); + + auto a = f.pop_value(); + CHECK(a == 1); + } + + TEST_CASE("Pop free and then push") { + CircularFifo f; + + auto a = f.pop_free(); + a.value = 5; + f.push_value(std::move(a)); // Explicit move since we can't copy + auto b = f.pop_value(); + + CHECK(a == 0); // Moved from value + CHECK(b == 5); // Original value + } + + TEST_CASE("Skip the first value") { + CircularFifo f; + + for (int i = 0; i != 10; ++i) { + auto a = f.pop_free(); + a.value = i + 1; + f.push_value(std::move(a)); // Explicit move since we can't copy + } + + auto b = f.pop_value(); + CHECK(b == 1); + f.next(); + auto c = f.pop_value(); + CHECK(c == 3); + } + + TEST_CASE("Use in place and move to free") { + size_t size = 18; + CircularFifo f(size); + + //Push 10 values to the fifo + for (int i = 0; i != 10; ++i) { + auto a = f.pop_free(); + a.value = i + 1; + f.push_value(std::move(a)); // Explicit move since we can't copy + } + + auto b = f.frontPtr(); + CHECK(*b == 1); + CHECK(f.numFilledSlots() == 10); + CHECK(f.numFreeSlots() == size-10); + f.next(); + auto c = f.frontPtr(); + CHECK(*c == 2); + CHECK(f.numFilledSlots() == 9); + CHECK(f.numFreeSlots() == size-9); + } diff --git a/core/test/NDView.test.cpp b/core/test/NDView.test.cpp index 9ea375f1..f03229d4 100644 --- a/core/test/NDView.test.cpp +++ b/core/test/NDView.test.cpp @@ -175,4 +175,20 @@ TEST_CASE("Retrieve shape"){ REQUIRE(data.shape()[0] == 3); REQUIRE(data.shape()[1] == 4); +} + +TEST_CASE("compare two views"){ + std::vector vec1; + for (int i = 0; i != 12; ++i) { + vec1.push_back(i); + } + NDView view1(vec1.data(), Shape<2>{3,4}); + + std::vector vec2; + for (int i = 0; i != 12; ++i) { + vec2.push_back(i); + } + NDView view2(vec2.data(), Shape<2>{3,4}); + + REQUIRE(view1 == view2); } \ No newline at end of file diff --git a/core/test/ProducerConsumerQueue.test.cpp b/core/test/ProducerConsumerQueue.test.cpp index 03bba0c0..993a374a 100644 --- a/core/test/ProducerConsumerQueue.test.cpp +++ b/core/test/ProducerConsumerQueue.test.cpp @@ -1,49 +1,49 @@ -#include -#include "aare/ProducerConsumerQueue.hpp" + #include + #include "aare/ProducerConsumerQueue.hpp" -// using arve::SimpleQueue; -TEST_CASE("push pop"){ + // using arve::SimpleQueue; + TEST_CASE("push pop"){ - folly::ProducerConsumerQueue q(5); - int a = 3; - int b = 8; - CHECK(q.sizeGuess() == 0); - CHECK(q.write(a)); - CHECK(q.sizeGuess() == 1); - CHECK(q.write(b)); - CHECK(q.sizeGuess() == 2); - int c = 0; + folly::ProducerConsumerQueue q(5); + int a = 3; + int b = 8; + CHECK(q.sizeGuess() == 0); + CHECK(q.write(a)); + CHECK(q.sizeGuess() == 1); + CHECK(q.write(b)); + CHECK(q.sizeGuess() == 2); + int c = 0; - CHECK(q.read(c)); - CHECK(c == 3); - CHECK(q.sizeGuess() == 1); - CHECK(q.read(c)); - CHECK(c == 8); - CHECK(q.sizeGuess() == 0); -} + CHECK(q.read(c)); + CHECK(c == 3); + CHECK(q.sizeGuess() == 1); + CHECK(q.read(c)); + CHECK(c == 8); + CHECK(q.sizeGuess() == 0); + } -TEST_CASE("Cannot push to a full queue"){ - folly::ProducerConsumerQueue q(3); - int a = 3; - int b = 4; - int c = 0; - CHECK(q.write(a)); - CHECK(q.write(b)); - CHECK_FALSE(q.write(a)); + TEST_CASE("Cannot push to a full queue"){ + folly::ProducerConsumerQueue q(3); + int a = 3; + int b = 4; + int c = 0; + CHECK(q.write(a)); + CHECK(q.write(b)); + CHECK_FALSE(q.write(a)); - //values are still ok - CHECK(q.read(c)); - CHECK(c == 3); - CHECK(q.read(c)); - CHECK(c == 4); -} + //values are still ok + CHECK(q.read(c)); + CHECK(c == 3); + CHECK(q.read(c)); + CHECK(c == 4); + } -TEST_CASE("Cannot pop from an empty queue"){ - folly::ProducerConsumerQueue q(2); - int a=0; - CHECK_FALSE(q.read(a)); -} + TEST_CASE("Cannot pop from an empty queue"){ + folly::ProducerConsumerQueue q(2); + int a=0; + CHECK_FALSE(q.read(a)); + } -// TEST_CASE("fail"){ -// CHECK(false); -// } \ No newline at end of file + // TEST_CASE("fail"){ + // CHECK(false); + // } diff --git a/data/jungfrau/jungfrau_single_0.npy b/data/jungfrau/jungfrau_single_0.npy new file mode 100644 index 00000000..ef14d628 Binary files /dev/null and b/data/jungfrau/jungfrau_single_0.npy differ diff --git a/data/jungfrau/read_frame.py b/data/jungfrau/read_frame.py index c031e577..ee5ceafc 100644 --- a/data/jungfrau/read_frame.py +++ b/data/jungfrau/read_frame.py @@ -24,7 +24,7 @@ # Read three frames from a jungfrau file with a single interface rows = 512 cols = 1024 -frames = 3 +frames = 10 data = np.zeros((frames,rows,cols), dtype = np.uint16) header = np.zeros(frames, dtype = header_dt) @@ -32,17 +32,18 @@ file_name = 'jungfrau_single_d0_f{}_0.raw'.format(file_id) print("Reading file:", file_name) with open(file_name) as f: - for i in range(frames if file_id != 3 else 1): - header[i] = np.fromfile(f, dtype=header_dt, count = 1) - data[i] = np.fromfile(f, dtype=np.uint16,count = rows*cols).reshape(rows,cols) + for i in range(3 if file_id != 3 else 1): + header[i+file_id*3] = np.fromfile(f, dtype=header_dt, count = 1) + data[i+file_id*3] = np.fromfile(f, dtype=np.uint16,count = rows*cols).reshape(rows,cols) - for i in range(frames if file_id != 3 else 1 ): - print("frame:",i) - print(data[i][0,0],data[i][0,1],data[i][1,0],data[i][rows-1,cols-1]) - print("") + # for i in range(frames if file_id != 3 else 1 ): + # print("frame:",i) + # print(header[i][0,0],data[i][0,1],data[i][1,0],data[i][rows-1,cols-1]) + # print("") +print(header[1]["Frame Number"]) #fig, ax = plt.subplots() #im = ax.imshow(data[0]) #im.set_clim(2000,4000) diff --git a/data/scripts/read_first_frame_number.py b/data/scripts/read_first_frame_number.py new file mode 100644 index 00000000..02b19d24 --- /dev/null +++ b/data/scripts/read_first_frame_number.py @@ -0,0 +1,29 @@ +import numpy as np +from pathlib import Path + +header_dt = np.dtype( + [ + ("Frame Number", "u8"), + ("SubFrame Number/ExpLength", "u4"), + ("Packet Number", "u4"), + ("Bunch ID", "u8"), + ("Timestamp", "u8"), + ("Module Id", "u2"), + ("Row", "u2"), + ("Column", "u2"), + ("Reserved", "u2"), + ("Debug", "u4"), + ("Round Robin Number", "u2"), + ("Detector Type", "u1"), + ("Header Version", "u1"), + ("Packets caught mask", "8u8") + ] +) + + + +with open("data/eiger/eiger_500k_16bit_d0_f0_0.raw", "rb") as f: + for i in range(3): + frame_number = np.fromfile(f, dtype=header_dt, count=1)["Frame Number"][0] + print(frame_number) + f.seek(262144,1) diff --git a/data/read_multiport.py b/data/scripts/read_multiport.py similarity index 100% rename from data/read_multiport.py rename to data/scripts/read_multiport.py diff --git a/file_io/CMakeLists.txt b/file_io/CMakeLists.txt index 031d01b2..80884745 100644 --- a/file_io/CMakeLists.txt +++ b/file_io/CMakeLists.txt @@ -32,7 +32,8 @@ endif() if(AARE_TESTS) set(TestSources - ${CMAKE_CURRENT_SOURCE_DIR}/src/NumpyHelpers.test.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test/NumpyHelpers.test.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test/RawFile.test.cpp ) target_sources(tests PRIVATE ${TestSources} ) target_link_libraries(tests PRIVATE core file_io) diff --git a/file_io/include/aare/NumpyFile.hpp b/file_io/include/aare/NumpyFile.hpp index 94e71208..f4cb06ca 100644 --- a/file_io/include/aare/NumpyFile.hpp +++ b/file_io/include/aare/NumpyFile.hpp @@ -20,9 +20,9 @@ class NumpyFile : public FileInterface { void seek(size_t frame_number) override { this->current_frame = frame_number; } size_t tell() override { return this->current_frame; } size_t total_frames() const override { return header.shape[0]; } - ssize_t rows()const override { return header.shape[1]; } - ssize_t cols()const override { return header.shape[2]; } - ssize_t bitdepth()const override { return header.dtype.itemsize; } + ssize_t rows() const override { return header.shape[1]; } + ssize_t cols() const override { return header.shape[2]; } + ssize_t bitdepth() const override { return header.dtype.itemsize; } NumpyFile(std::filesystem::path fname); header_t header{}; diff --git a/file_io/include/aare/SubFile.hpp b/file_io/include/aare/SubFile.hpp index 2f8ad04f..d8080d5b 100644 --- a/file_io/include/aare/SubFile.hpp +++ b/file_io/include/aare/SubFile.hpp @@ -2,8 +2,8 @@ #include "aare/defs.hpp" #include #include -#include #include +#include class SubFile { protected: @@ -19,20 +19,21 @@ class SubFile { std::map, pfunc> read_impl_map = { {{DetectorType::Moench, 16}, &SubFile::read_impl_reorder}, {{DetectorType::Jungfrau, 16}, &SubFile::read_impl_normal}, - {{DetectorType::ChipTestBoard,16}, &SubFile::read_impl_normal}, - {{DetectorType::Mythen3, 32}, &SubFile::read_impl_normal} - }; + {{DetectorType::ChipTestBoard, 16}, &SubFile::read_impl_normal}, + {{DetectorType::Mythen3, 32}, &SubFile::read_impl_normal}, + {{DetectorType::Eiger, 32}, &SubFile::read_impl_normal}, + {{DetectorType::Eiger, 16}, &SubFile::read_impl_normal} + }; public: // pointer to a read_impl function. pointer will be set to the appropriate read_impl function in the constructor pfunc read_impl = nullptr; size_t read_impl_normal(std::byte *buffer); - template size_t read_impl_flip(std::byte *buffer); - template size_t read_impl_reorder(std::byte *buffer); - + template size_t read_impl_flip(std::byte *buffer); + template size_t read_impl_reorder(std::byte *buffer); - SubFile(std::filesystem::path fname,DetectorType detector, ssize_t rows, ssize_t cols, uint16_t bitdepth); + SubFile(std::filesystem::path fname, DetectorType detector, ssize_t rows, ssize_t cols, uint16_t bitdepth); size_t get_part(std::byte *buffer, int frame_number); size_t frame_number(int frame_index); @@ -40,5 +41,4 @@ class SubFile { // TODO: define the inlines as variables and assign them in constructor inline size_t bytes_per_part() { return (m_bitdepth / 8) * m_rows * m_cols; } inline size_t pixels_per_part() { return m_rows * m_cols; } - }; diff --git a/file_io/src/File.cpp b/file_io/src/File.cpp index e449bfeb..f5b4adbc 100644 --- a/file_io/src/File.cpp +++ b/file_io/src/File.cpp @@ -10,7 +10,7 @@ File::File(std::filesystem::path fname, std::string mode) { } Frame File::read() { return file_impl->read(); } -size_t File::total_frames() const { return file_impl->m_total_frames; } +size_t File::total_frames() const { return file_impl->total_frames(); } std::vector File::read(size_t n_frames) { return file_impl->read(n_frames); } void File::read_into(std::byte *image_buf) { file_impl->read_into(image_buf); } void File::read_into(std::byte *image_buf, size_t n_frames) { file_impl->read_into(image_buf, n_frames); } diff --git a/file_io/src/FileFactory.cpp b/file_io/src/FileFactory.cpp index 491875e0..7912c1d9 100644 --- a/file_io/src/FileFactory.cpp +++ b/file_io/src/FileFactory.cpp @@ -13,16 +13,16 @@ FileFactory *FileFactory::get_factory(std::filesystem::path fpath) { } if (fpath.extension() == ".raw" || fpath.extension() == ".json"){ - aare::logger::info("Loading",fpath.extension(),"file"); + aare::logger::debug("Loading",fpath.extension(),"file"); return new RawFileFactory(fpath); } if (fpath.extension() == ".raw" || fpath.extension() == ".json"){ - aare::logger::info("Loading",fpath.extension(),"file"); + aare::logger::debug("Loading",fpath.extension(),"file"); return new RawFileFactory(fpath); } // check if extension is numpy else if (fpath.extension() == ".npy") { - aare::logger::info("Loading numpy file"); + aare::logger::debug("Loading numpy file"); return new NumpyFileFactory(fpath); } diff --git a/file_io/src/NumpyFileFactory.cpp b/file_io/src/NumpyFileFactory.cpp index 987a0886..3e46c10b 100644 --- a/file_io/src/NumpyFileFactory.cpp +++ b/file_io/src/NumpyFileFactory.cpp @@ -1,10 +1,8 @@ #include "aare/NumpyFileFactory.hpp" #include "aare/NumpyHelpers.hpp" -NumpyFileFactory::NumpyFileFactory(std::filesystem::path fpath) { - this->m_fpath = fpath; -} +NumpyFileFactory::NumpyFileFactory(std::filesystem::path fpath) { this->m_fpath = fpath; } void NumpyFileFactory::parse_metadata(FileInterface *_file) { - auto file = dynamic_cast(_file); + auto file = dynamic_cast(_file); // open ifsteam to file f = std::ifstream(file->m_fname, std::ios::binary); // check if file exists @@ -46,7 +44,7 @@ void NumpyFileFactory::parse_metadata(FileInterface *_file) { // parse header std::vector keys{"descr", "fortran_order", "shape"}; - std::cout << "original header: " << '"' << header << '"' << std::endl; + aare::logger::debug("original header: \"header\""); auto dict_map = parse_dict(header, keys); if (dict_map.size() == 0) @@ -72,11 +70,8 @@ void NumpyFileFactory::parse_metadata(FileInterface *_file) { file->header = {dtype, fortran_order, shape}; } - NumpyFile* NumpyFileFactory::load_file() { - NumpyFile* file = new NumpyFile(this->m_fpath); +NumpyFile *NumpyFileFactory::load_file() { + NumpyFile *file = new NumpyFile(this->m_fpath); parse_metadata(file); - std::cout << "parsed header: " << file->header.to_string() << std::endl; return file; }; - - diff --git a/file_io/src/RawFileFactory.cpp b/file_io/src/RawFileFactory.cpp index bb704639..cd625a22 100644 --- a/file_io/src/RawFileFactory.cpp +++ b/file_io/src/RawFileFactory.cpp @@ -87,7 +87,6 @@ void RawFileFactory::parse_json_metadata(RawFile *file) { json j; ifs >> j; double v = j["Version"]; - std::cout << "Version: " << v << std::endl; file->version = fmt::format("{:.1f}", v); file->m_type = StringTo(j["Detector Type"].get()); file->timing_mode = StringTo(j["Timing Mode"].get()); diff --git a/file_io/src/SubFile.cpp b/file_io/src/SubFile.cpp index 915d9f3c..cc7ac890 100644 --- a/file_io/src/SubFile.cpp +++ b/file_io/src/SubFile.cpp @@ -10,7 +10,8 @@ SubFile::SubFile(std::filesystem::path fname, DetectorType detector, ssize_t row this->m_bitdepth = bitdepth; this->n_frames = std::filesystem::file_size(fname) / (sizeof(sls_detector_header) + rows * cols * bitdepth / 8); if (read_impl_map.find({detector, bitdepth}) == read_impl_map.end()) { - throw std::runtime_error(LOCATION + "Unsupported detector/bitdepth combination"); + auto error_msg = LOCATION + "No read_impl function found for detector: " + toString(detector) + " and bitdepth: " + std::to_string(bitdepth); + throw std::runtime_error(error_msg); } this->read_impl = read_impl_map.at({detector, bitdepth}); } @@ -88,7 +89,7 @@ size_t SubFile::frame_number(int frame_index) { FILE *fp = fopen(this->m_fname.c_str(), "r"); if (!fp) throw std::runtime_error(fmt::format("Could not open: {} for reading", m_fname.c_str())); - + fseek(fp, (sizeof(sls_detector_header) + bytes_per_part()) * frame_index, SEEK_SET); size_t rc = fread(reinterpret_cast(&h), sizeof(h), 1, fp); fclose(fp); if (rc != 1) diff --git a/file_io/src/NumpyHelpers.test.cpp b/file_io/test/NumpyHelpers.test.cpp similarity index 100% rename from file_io/src/NumpyHelpers.test.cpp rename to file_io/test/NumpyHelpers.test.cpp diff --git a/file_io/test/RawFile.test.cpp b/file_io/test/RawFile.test.cpp new file mode 100644 index 00000000..dfbcc44a --- /dev/null +++ b/file_io/test/RawFile.test.cpp @@ -0,0 +1,81 @@ +#include "aare/File.hpp" +#include "aare/utils/logger.hpp" +#include +#include + +#include "test_config.hpp" + + +TEST_CASE("Read number of frames from a jungfrau raw file") { + + auto fpath = test_data_path() / "jungfrau" / "jungfrau_single_master_0.json"; + REQUIRE(std::filesystem::exists(fpath)); + + File f(fpath, "r"); + REQUIRE(f.total_frames() == 10); +} + +TEST_CASE("Read frame numbers from a jungfrau raw file") { + auto fpath = test_data_path() / "jungfrau" / "jungfrau_single_master_0.json"; + REQUIRE(std::filesystem::exists(fpath)); + + File f(fpath, "r"); + + // we know this file has 10 frames with frame numbers 1 to 10 + // f0 1,2,3 + // f1 4,5,6 + // f2 7,8,9 + // f3 10 + for (size_t i = 0; i < 10; i++) { + CHECK(f.frame_number(i) == i + 1); + } +} + +TEST_CASE("Read data from a jungfrau 500k single port raw file") { + auto fpath = test_data_path() / "jungfrau" / "jungfrau_single_master_0.json"; + REQUIRE(std::filesystem::exists(fpath)); + + File f(fpath, "r"); + + // we know this file has 10 frames with pixel 0,0 being: 2123, 2051, 2109, 2117, 2089, 2095, 2072, 2126, 2097, 2102 + std::vector pixel_0_0 = {2123, 2051, 2109, 2117, 2089, 2095, 2072, 2126, 2097, 2102}; + for (size_t i = 0; i < 10; i++) { + auto frame = f.read(); + CHECK(frame.rows() == 512); + CHECK(frame.cols() == 1024); + CHECK(frame.view()(0, 0) == pixel_0_0[i]); + } +} + +TEST_CASE("Read frame numbers from a raw file") { + auto fpath = test_data_path() / "eiger" / "eiger_500k_16bit_master_0.json"; + REQUIRE(std::filesystem::exists(fpath)); + + // we know this file has 3 frames with frame numbers 14, 15, 16 + std::vector frame_numbers = {14, 15, 16}; + + File f(fpath, "r"); + for (size_t i = 0; i < 3; i++) { + CHECK(f.frame_number(i) == frame_numbers[i]); + } +} + +TEST_CASE("Compare reading from a numpy file with a raw file") { + auto fpath_raw = test_data_path() / "jungfrau" / "jungfrau_single_master_0.json"; + REQUIRE(std::filesystem::exists(fpath_raw)); + + auto fpath_npy = test_data_path() / "jungfrau" / "jungfrau_single_0.npy"; + REQUIRE(std::filesystem::exists(fpath_npy)); + + File raw(fpath_raw, "r"); + File npy(fpath_npy, "r"); + + CHECK(raw.total_frames() == 10); + CHECK(npy.total_frames() == 10); + + for (size_t i = 0; i < 10; ++i) { + auto raw_frame = raw.read(); + auto npy_frame = npy.read(); + CHECK(raw_frame.view() == npy_frame.view()); + } +} \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 543f07df..5ea4be91 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -32,7 +32,7 @@ target_sources(tests PRIVATE ${TestSources} ) #Work around to remove, this is not the way to do it =) # target_include_directories(tests PRIVATE ${CMAKE_SOURCE_DIR}/include/common) -target_link_libraries(tests PRIVATE core aare_compiler_flags) +target_link_libraries(tests PRIVATE core aare_compiler_flags utils) catch_discover_tests(tests # WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/data diff --git a/utils/include/aare/utils/logger.hpp b/utils/include/aare/utils/logger.hpp index 1ed5bbc7..4587f2cb 100644 --- a/utils/include/aare/utils/logger.hpp +++ b/utils/include/aare/utils/logger.hpp @@ -37,7 +37,7 @@ class Logger { std::streambuf *error_buf = std::cerr.rdbuf(); std::ostream *standard_output; std::ostream *error_output; - LOGGING_LEVEL VERBOSITY_LEVEL = LOGGING_LEVEL::DEBUG; + LOGGING_LEVEL VERBOSITY_LEVEL = LOGGING_LEVEL::INFO; std::ofstream out_file;