fix ci and add formatting (#48)

* add dependency

* dont run blocking zmq example and add formatting

* format files
This commit is contained in:
Bechir Braham
2024-04-03 13:47:52 +02:00
committed by GitHub
parent 23c855acbc
commit 31a20d4f6c
34 changed files with 438 additions and 522 deletions

View File

@ -45,7 +45,7 @@ jobs:
pwd pwd
export PROJECT_ROOT_DIR="." export PROJECT_ROOT_DIR="."
ls build/examples/*_example ls build/examples/*_example
find build/examples -name "*_example" | xargs -I {} -n 1 -t bash -c {} find build/examples -name "*_example" -not -name "zmq_example" | xargs -I {} -n 1 -t bash -c {}

19
.github/workflows/format.yml vendored Normal file
View File

@ -0,0 +1,19 @@
name: test-formatting
on:
push:
jobs:
test-formatting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: check if files are formatted
# find all examples in build/examples and run them
run: |
pwd
find -name "*.cpp" -not -path "./build/*" | xargs -I {} -n 1 -P 10 clang-format {} -Werror --dry-run -style='file:.clang-format'

View File

@ -7,3 +7,4 @@ dependencies:
- pybind11 - pybind11
- nlohmann_json - nlohmann_json
- catch2 - catch2
- zeromq

View File

@ -4,7 +4,6 @@
namespace aare { namespace aare {
DType::DType(const std::type_info &t) { DType::DType(const std::type_info &t) {
if (t == typeid(int8_t)) if (t == typeid(int8_t))
m_type = TypeIndex::INT8; m_type = TypeIndex::INT8;
@ -29,11 +28,10 @@ DType::DType(const std::type_info &t) {
else if (t == typeid(double)) else if (t == typeid(double))
m_type = TypeIndex::DOUBLE; m_type = TypeIndex::DOUBLE;
else else
throw std::runtime_error( throw std::runtime_error("Could not construct data type. Type not supported.");
"Could not construct data type. Type not supported.");
} }
uint8_t DType::bitdepth()const { uint8_t DType::bitdepth() const {
switch (m_type) { switch (m_type) {
case TypeIndex::INT8: case TypeIndex::INT8:
case TypeIndex::UINT8: case TypeIndex::UINT8:
@ -54,12 +52,11 @@ uint8_t DType::bitdepth()const {
case TypeIndex::ERROR: case TypeIndex::ERROR:
return 0; return 0;
default: default:
throw std::runtime_error(LOCATION+"Could not get bitdepth. Type not supported."); throw std::runtime_error(LOCATION + "Could not get bitdepth. Type not supported.");
} }
} }
DType::DType(DType::TypeIndex ti):m_type(ti){} DType::DType(DType::TypeIndex ti) : m_type(ti) {}
DType::DType(std::string_view sv) { DType::DType(std::string_view sv) {
@ -99,8 +96,7 @@ DType::DType(std::string_view sv) {
else if (sv == "f8") else if (sv == "f8")
m_type = TypeIndex::DOUBLE; m_type = TypeIndex::DOUBLE;
else else
throw std::runtime_error( throw std::runtime_error("Could not construct data type. Type no supported.");
"Could not construct data type. Type no supported.");
} }
std::string DType::str() const { std::string DType::str() const {
@ -138,18 +134,10 @@ std::string DType::str() const {
return {}; return {};
} }
bool DType::operator==(const DType &other) const noexcept { bool DType::operator==(const DType &other) const noexcept { return m_type == other.m_type; }
return m_type == other.m_type; bool DType::operator!=(const DType &other) const noexcept { return !(*this == other); }
}
bool DType::operator!=(const DType &other) const noexcept {
return !(*this == other);
}
bool DType::operator==(const std::type_info &t) const { bool DType::operator==(const std::type_info &t) const { return DType(t) == *this; }
return DType(t) == *this; bool DType::operator!=(const std::type_info &t) const { return DType(t) != *this; }
}
bool DType::operator!=(const std::type_info &t) const {
return DType(t) != *this;
}
} // namespace pl } // namespace aare

View File

@ -1,31 +1,27 @@
#include "aare/Frame.hpp" #include "aare/Frame.hpp"
#include "aare/utils/logger.hpp" #include "aare/utils/logger.hpp"
#include <iostream>
#include <cassert> #include <cassert>
#include <iostream>
namespace aare { namespace aare {
Frame::Frame(std::byte* bytes, ssize_t rows, ssize_t cols, ssize_t bitdepth): Frame::Frame(std::byte *bytes, ssize_t rows, ssize_t cols, ssize_t bitdepth)
m_rows(rows), m_cols(cols), m_bitdepth(bitdepth) { : m_rows(rows), m_cols(cols), m_bitdepth(bitdepth) {
m_data = new std::byte[rows*cols*bitdepth/8]; m_data = new std::byte[rows * cols * bitdepth / 8];
std::memcpy(m_data, bytes, rows*cols*bitdepth/8); std::memcpy(m_data, bytes, rows * cols * bitdepth / 8);
}
Frame::Frame(ssize_t rows, ssize_t cols, ssize_t bitdepth):
m_rows(rows), m_cols(cols), m_bitdepth(bitdepth) {
m_data = new std::byte[rows*cols*bitdepth/8];
std::memset(m_data, 0, rows*cols*bitdepth/8);
}
std::byte* Frame::get(int row, int col) {
if (row < 0 || row >= m_rows || col < 0 || col >= m_cols) {
std::cerr << "Invalid row or column index" << std::endl;
return 0;
}
return m_data+(row*m_cols + col)*(m_bitdepth/8);
} }
Frame::Frame(ssize_t rows, ssize_t cols, ssize_t bitdepth) : m_rows(rows), m_cols(cols), m_bitdepth(bitdepth) {
m_data = new std::byte[rows * cols * bitdepth / 8];
std::memset(m_data, 0, rows * cols * bitdepth / 8);
}
std::byte *Frame::get(int row, int col) {
if (row < 0 || row >= m_rows || col < 0 || col >= m_cols) {
std::cerr << "Invalid row or column index" << std::endl;
return 0;
}
return m_data + (row * m_cols + col) * (m_bitdepth / 8);
}
} // namespace aare } // namespace aare

View File

@ -1,24 +1,23 @@
#include "aare/ZmqSocket.hpp" #include "aare/ZmqSocket.hpp"
#include <zmq.h>
#include <fmt/core.h> #include <fmt/core.h>
#include <zmq.h>
namespace aare{ namespace aare {
ZmqSocket::ZmqSocket(const std::string &endpoint) : m_endpoint(endpoint) {
ZmqSocket::ZmqSocket(const std::string& endpoint):m_endpoint(endpoint){
memset(m_header_buffer, 0, m_max_header_size); memset(m_header_buffer, 0, m_max_header_size);
} }
void ZmqSocket::connect(){ void ZmqSocket::connect() {
m_context = zmq_ctx_new(); m_context = zmq_ctx_new();
m_socket = zmq_socket(m_context, ZMQ_SUB); m_socket = zmq_socket(m_context, ZMQ_SUB);
fmt::print("Setting ZMQ_RCVHWM to {}\n", m_zmq_hwm); fmt::print("Setting ZMQ_RCVHWM to {}\n", m_zmq_hwm);
int rc = zmq_setsockopt(m_socket, ZMQ_RCVHWM, &m_zmq_hwm, sizeof(m_zmq_hwm)); //should be set before connect int rc = zmq_setsockopt(m_socket, ZMQ_RCVHWM, &m_zmq_hwm, sizeof(m_zmq_hwm)); // should be set before connect
if (rc) if (rc)
throw std::runtime_error(fmt::format("Could not set ZMQ_RCVHWM: {}", strerror(errno))); throw std::runtime_error(fmt::format("Could not set ZMQ_RCVHWM: {}", strerror(errno)));
int bufsize = 1024*1024*m_zmq_hwm; int bufsize = 1024 * 1024 * m_zmq_hwm;
fmt::print("Setting ZMQ_RCVBUF to: {} MB\n", bufsize/(1024*1024)); fmt::print("Setting ZMQ_RCVBUF to: {} MB\n", bufsize / (1024 * 1024));
rc = zmq_setsockopt(m_socket, ZMQ_RCVBUF, &bufsize, sizeof(bufsize)); rc = zmq_setsockopt(m_socket, ZMQ_RCVBUF, &bufsize, sizeof(bufsize));
if (rc) if (rc)
throw std::runtime_error(fmt::format("Could not set ZMQ_RCVBUF: {}", strerror(errno))); throw std::runtime_error(fmt::format("Could not set ZMQ_RCVBUF: {}", strerror(errno)));
@ -34,53 +33,49 @@ void ZmqSocket::disconnect() {
m_context = nullptr; m_context = nullptr;
} }
ZmqSocket::~ZmqSocket(){ ZmqSocket::~ZmqSocket() {
if (m_socket) if (m_socket)
disconnect(); disconnect();
delete[] m_header_buffer; delete[] m_header_buffer;
} }
void ZmqSocket::set_zmq_hwm(int hwm){ void ZmqSocket::set_zmq_hwm(int hwm) { m_zmq_hwm = hwm; }
m_zmq_hwm = hwm;
}
void ZmqSocket::set_timeout_ms(int n){ void ZmqSocket::set_timeout_ms(int n) { m_timeout_ms = n; }
m_timeout_ms = n;
}
int ZmqSocket::receive(zmqHeader &header, std::byte *data){ int ZmqSocket::receive(zmqHeader &header, std::byte *data) {
//receive header // receive header
int header_bytes_received = zmq_recv(m_socket, m_header_buffer, m_max_header_size, 0); int header_bytes_received = zmq_recv(m_socket, m_header_buffer, m_max_header_size, 0);
m_header_buffer[header_bytes_received] = '\0'; //make sure we zero terminate m_header_buffer[header_bytes_received] = '\0'; // make sure we zero terminate
if (header_bytes_received < 0){ if (header_bytes_received < 0) {
fmt::print("Error receiving header: {}\n", strerror(errno)); fmt::print("Error receiving header: {}\n", strerror(errno));
return -1; return -1;
} }
fmt::print("Bytes: {}, Header: {}\n", header_bytes_received, m_header_buffer); fmt::print("Bytes: {}, Header: {}\n", header_bytes_received, m_header_buffer);
//decode header // decode header
if (!decode_header(header)){ if (!decode_header(header)) {
fmt::print("Error decoding header\n"); fmt::print("Error decoding header\n");
return -1; return -1;
} }
//do we have a multipart message (data following header)? // do we have a multipart message (data following header)?
int more; int more;
size_t more_size = sizeof(more); size_t more_size = sizeof(more);
zmq_getsockopt(m_socket, ZMQ_RCVMORE, &more, &more_size); zmq_getsockopt(m_socket, ZMQ_RCVMORE, &more, &more_size);
if (!more) { if (!more) {
return 0; //no data following header return 0; // no data following header
}else{ } else {
int data_bytes_received = zmq_recv(m_socket, data, 1024*1024*2, 0); //TODO! configurable size!!!! int data_bytes_received = zmq_recv(m_socket, data, 1024 * 1024 * 2, 0); // TODO! configurable size!!!!
if (data_bytes_received == -1) if (data_bytes_received == -1)
throw std::runtime_error("Got half of a multipart msg!!!"); throw std::runtime_error("Got half of a multipart msg!!!");
} }
return 1; return 1;
} }
bool ZmqSocket::decode_header(zmqHeader &h){ bool ZmqSocket::decode_header(zmqHeader &h) {
//TODO: implement // TODO: implement
return true; return true;
} }

View File

@ -1,116 +1,116 @@
#include <catch2/catch_all.hpp> #include <catch2/catch_all.hpp>
#include "aare/CircularFifo.hpp" #include "aare/CircularFifo.hpp"
using aare::CircularFifo; using aare::CircularFifo;
// Only for testing. To make sure we can avoid copy constructor // Only for testing. To make sure we can avoid copy constructor
// and copy assignment // and copy assignment
struct MoveOnlyInt { struct MoveOnlyInt {
int value{}; int value{};
MoveOnlyInt() = default; MoveOnlyInt() = default;
MoveOnlyInt(int i) : value(i){}; MoveOnlyInt(int i) : value(i){};
MoveOnlyInt(const MoveOnlyInt &) = delete; MoveOnlyInt(const MoveOnlyInt &) = delete;
MoveOnlyInt &operator=(const MoveOnlyInt &) = delete; MoveOnlyInt &operator=(const MoveOnlyInt &) = delete;
MoveOnlyInt(MoveOnlyInt &&other) { std::swap(value, other.value); } MoveOnlyInt(MoveOnlyInt &&other) { std::swap(value, other.value); }
MoveOnlyInt &operator=(MoveOnlyInt &&other) { MoveOnlyInt &operator=(MoveOnlyInt &&other) {
std::swap(value, other.value); std::swap(value, other.value);
return *this; return *this;
} }
bool operator==(int other) const { return value == other; } bool operator==(int other) const { return value == other; }
}; };
TEST_CASE("CircularFifo can be default constructed") { CircularFifo<MoveOnlyInt> f; } TEST_CASE("CircularFifo can be default constructed") { CircularFifo<MoveOnlyInt> f; }
TEST_CASE("Newly constructed fifo has the right size") { TEST_CASE("Newly constructed fifo has the right size") {
size_t size = 17; size_t size = 17;
CircularFifo<MoveOnlyInt> f(size); CircularFifo<MoveOnlyInt> f(size);
CHECK(f.numFreeSlots() == size); CHECK(f.numFreeSlots() == size);
CHECK(f.numFilledSlots() == 0); CHECK(f.numFilledSlots() == 0);
} }
TEST_CASE("Can fit size number of objects") { TEST_CASE("Can fit size number of objects") {
size_t size = 8; size_t size = 8;
size_t numPushedItems = 0; size_t numPushedItems = 0;
CircularFifo<MoveOnlyInt> f(size); CircularFifo<MoveOnlyInt> f(size);
for (size_t i = 0; i < size; ++i) { for (size_t i = 0; i < size; ++i) {
MoveOnlyInt a; MoveOnlyInt a;
bool popped = f.try_pop_free(a); bool popped = f.try_pop_free(a);
CHECK(popped); CHECK(popped);
if (popped) { if (popped) {
a.value = i; a.value = i;
bool pushed = f.try_push_value(std::move(a)); bool pushed = f.try_push_value(std::move(a));
CHECK(pushed); CHECK(pushed);
if (pushed) if (pushed)
numPushedItems++; numPushedItems++;
} }
} }
CHECK(f.numFreeSlots() == 0); CHECK(f.numFreeSlots() == 0);
CHECK(f.numFilledSlots() == size); CHECK(f.numFilledSlots() == size);
CHECK(numPushedItems == size); CHECK(numPushedItems == size);
} }
TEST_CASE("Push move only type") { TEST_CASE("Push move only type") {
CircularFifo<MoveOnlyInt> f; CircularFifo<MoveOnlyInt> f;
f.push_value(5); f.push_value(5);
} }
TEST_CASE("Push pop") { TEST_CASE("Push pop") {
CircularFifo<MoveOnlyInt> f; CircularFifo<MoveOnlyInt> f;
f.push_value(MoveOnlyInt(1)); f.push_value(MoveOnlyInt(1));
auto a = f.pop_value(); auto a = f.pop_value();
CHECK(a == 1); CHECK(a == 1);
} }
TEST_CASE("Pop free and then push") { TEST_CASE("Pop free and then push") {
CircularFifo<MoveOnlyInt> f; CircularFifo<MoveOnlyInt> f;
auto a = f.pop_free(); auto a = f.pop_free();
a.value = 5; a.value = 5;
f.push_value(std::move(a)); // Explicit move since we can't copy f.push_value(std::move(a)); // Explicit move since we can't copy
auto b = f.pop_value(); auto b = f.pop_value();
CHECK(a == 0); // Moved from value CHECK(a == 0); // Moved from value
CHECK(b == 5); // Original value CHECK(b == 5); // Original value
} }
TEST_CASE("Skip the first value") { TEST_CASE("Skip the first value") {
CircularFifo<MoveOnlyInt> f; CircularFifo<MoveOnlyInt> f;
for (int i = 0; i != 10; ++i) { for (int i = 0; i != 10; ++i) {
auto a = f.pop_free(); auto a = f.pop_free();
a.value = i + 1; a.value = i + 1;
f.push_value(std::move(a)); // Explicit move since we can't copy f.push_value(std::move(a)); // Explicit move since we can't copy
} }
auto b = f.pop_value(); auto b = f.pop_value();
CHECK(b == 1); CHECK(b == 1);
f.next(); f.next();
auto c = f.pop_value(); auto c = f.pop_value();
CHECK(c == 3); CHECK(c == 3);
} }
TEST_CASE("Use in place and move to free") { TEST_CASE("Use in place and move to free") {
size_t size = 18; size_t size = 18;
CircularFifo<MoveOnlyInt> f(size); CircularFifo<MoveOnlyInt> f(size);
//Push 10 values to the fifo // Push 10 values to the fifo
for (int i = 0; i != 10; ++i) { for (int i = 0; i != 10; ++i) {
auto a = f.pop_free(); auto a = f.pop_free();
a.value = i + 1; a.value = i + 1;
f.push_value(std::move(a)); // Explicit move since we can't copy f.push_value(std::move(a)); // Explicit move since we can't copy
} }
auto b = f.frontPtr(); auto b = f.frontPtr();
CHECK(*b == 1); CHECK(*b == 1);
CHECK(f.numFilledSlots() == 10); CHECK(f.numFilledSlots() == 10);
CHECK(f.numFreeSlots() == size-10); CHECK(f.numFreeSlots() == size - 10);
f.next(); f.next();
auto c = f.frontPtr(); auto c = f.frontPtr();
CHECK(*c == 2); CHECK(*c == 2);
CHECK(f.numFilledSlots() == 9); CHECK(f.numFilledSlots() == 9);
CHECK(f.numFreeSlots() == size-9); CHECK(f.numFreeSlots() == size - 9);
} }

View File

@ -6,15 +6,13 @@
using aare::DType; using aare::DType;
using aare::endian; using aare::endian;
TEST_CASE("Construct from typeid") { TEST_CASE("Construct from typeid") {
REQUIRE(DType(typeid(int)) == typeid(int)); REQUIRE(DType(typeid(int)) == typeid(int));
REQUIRE(DType(typeid(int)) != typeid(double)); REQUIRE(DType(typeid(int)) != typeid(double));
} }
TEST_CASE("Construct from string") { TEST_CASE("Construct from string") {
if (endian::native == endian::little){ if (endian::native == endian::little) {
REQUIRE(DType("<i1") == typeid(int8_t)); REQUIRE(DType("<i1") == typeid(int8_t));
REQUIRE(DType("<u1") == typeid(uint8_t)); REQUIRE(DType("<u1") == typeid(uint8_t));
REQUIRE(DType("<i2") == typeid(int16_t)); REQUIRE(DType("<i2") == typeid(int16_t));
@ -30,7 +28,7 @@ TEST_CASE("Construct from string") {
REQUIRE(DType("f8") == typeid(double)); REQUIRE(DType("f8") == typeid(double));
} }
if (endian::native == endian::big){ if (endian::native == endian::big) {
REQUIRE(DType(">i1") == typeid(int8_t)); REQUIRE(DType(">i1") == typeid(int8_t));
REQUIRE(DType(">u1") == typeid(uint8_t)); REQUIRE(DType(">u1") == typeid(uint8_t));
REQUIRE(DType(">i2") == typeid(int16_t)); REQUIRE(DType(">i2") == typeid(int16_t));
@ -45,14 +43,12 @@ TEST_CASE("Construct from string") {
REQUIRE(DType("f4") == typeid(float)); REQUIRE(DType("f4") == typeid(float));
REQUIRE(DType("f8") == typeid(double)); REQUIRE(DType("f8") == typeid(double));
} }
} }
TEST_CASE("Construct from string with endianess"){ TEST_CASE("Construct from string with endianess") {
//TODO! handle big endian system in test! // TODO! handle big endian system in test!
REQUIRE(DType("<i4") == typeid(int32_t)); REQUIRE(DType("<i4") == typeid(int32_t));
REQUIRE_THROWS(DType(">i4") == typeid(int32_t)); REQUIRE_THROWS(DType(">i4") == typeid(int32_t));
} }
TEST_CASE("Convert to string") { REQUIRE(DType(typeid(int)).str() == "<i4"); } TEST_CASE("Convert to string") { REQUIRE(DType(typeid(int)).str() == "<i4"); }

View File

@ -3,7 +3,7 @@
using aare::Frame; using aare::Frame;
TEST_CASE("Construct a frame"){ TEST_CASE("Construct a frame") {
ssize_t rows = 10; ssize_t rows = 10;
ssize_t cols = 10; ssize_t cols = 10;
ssize_t bitdepth = 8; ssize_t bitdepth = 8;
@ -13,20 +13,19 @@ TEST_CASE("Construct a frame"){
REQUIRE(frame.rows() == rows); REQUIRE(frame.rows() == rows);
REQUIRE(frame.cols() == cols); REQUIRE(frame.cols() == cols);
REQUIRE(frame.bitdepth() == bitdepth); REQUIRE(frame.bitdepth() == bitdepth);
REQUIRE(frame.size() == rows*cols*bitdepth/8); REQUIRE(frame.size() == rows * cols * bitdepth / 8);
// data should be initialized to 0 // data should be initialized to 0
for (int i = 0; i < rows; i++){ for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++){ for (int j = 0; j < cols; j++) {
uint8_t *data = (uint8_t*)frame.get(i, j); uint8_t *data = (uint8_t *)frame.get(i, j);
REQUIRE(data != nullptr); REQUIRE(data != nullptr);
REQUIRE(*data == 0); REQUIRE(*data == 0);
} }
} }
} }
TEST_CASE("Set a value in a 8 bit frame"){ TEST_CASE("Set a value in a 8 bit frame") {
ssize_t rows = 10; ssize_t rows = 10;
ssize_t cols = 10; ssize_t cols = 10;
ssize_t bitdepth = 8; ssize_t bitdepth = 8;
@ -37,13 +36,12 @@ TEST_CASE("Set a value in a 8 bit frame"){
uint8_t value = 255; uint8_t value = 255;
frame.set(5, 7, value); frame.set(5, 7, value);
// only the value we did set should be non-zero // only the value we did set should be non-zero
for (int i = 0; i < rows; i++){ for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++){ for (int j = 0; j < cols; j++) {
uint8_t *data = (uint8_t*)frame.get(i, j); uint8_t *data = (uint8_t *)frame.get(i, j);
REQUIRE(data != nullptr); REQUIRE(data != nullptr);
if (i == 5 && j == 7){ if (i == 5 && j == 7) {
REQUIRE(*data == value); REQUIRE(*data == value);
} else { } else {
REQUIRE(*data == 0); REQUIRE(*data == 0);
@ -52,7 +50,7 @@ TEST_CASE("Set a value in a 8 bit frame"){
} }
} }
TEST_CASE("Set a value in a 64 bit frame"){ TEST_CASE("Set a value in a 64 bit frame") {
ssize_t rows = 10; ssize_t rows = 10;
ssize_t cols = 10; ssize_t cols = 10;
ssize_t bitdepth = 64; ssize_t bitdepth = 64;
@ -63,13 +61,12 @@ TEST_CASE("Set a value in a 64 bit frame"){
uint64_t value = 255; uint64_t value = 255;
frame.set(5, 7, value); frame.set(5, 7, value);
// only the value we did set should be non-zero // only the value we did set should be non-zero
for (int i = 0; i < rows; i++){ for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++){ for (int j = 0; j < cols; j++) {
uint64_t *data = (uint64_t*)frame.get(i, j); uint64_t *data = (uint64_t *)frame.get(i, j);
REQUIRE(data != nullptr); REQUIRE(data != nullptr);
if (i == 5 && j == 7){ if (i == 5 && j == 7) {
REQUIRE(*data == value); REQUIRE(*data == value);
} else { } else {
REQUIRE(*data == 0); REQUIRE(*data == 0);
@ -78,28 +75,27 @@ TEST_CASE("Set a value in a 64 bit frame"){
} }
} }
TEST_CASE("Move construct a frame") {
TEST_CASE("Move construct a frame"){
ssize_t rows = 10; ssize_t rows = 10;
ssize_t cols = 10; ssize_t cols = 10;
ssize_t bitdepth = 8; ssize_t bitdepth = 8;
Frame frame(rows, cols, bitdepth); Frame frame(rows, cols, bitdepth);
std::byte* data = frame.data(); std::byte *data = frame.data();
Frame frame2(std::move(frame)); Frame frame2(std::move(frame));
//state of the moved from object // state of the moved from object
REQUIRE(frame.rows() == 0); REQUIRE(frame.rows() == 0);
REQUIRE(frame.cols() == 0); REQUIRE(frame.cols() == 0);
REQUIRE(frame.bitdepth() == 0); REQUIRE(frame.bitdepth() == 0);
REQUIRE(frame.size() == 0); REQUIRE(frame.size() == 0);
REQUIRE(frame.data() == nullptr); REQUIRE(frame.data() == nullptr);
//state of the moved to object // state of the moved to object
REQUIRE(frame2.rows() == rows); REQUIRE(frame2.rows() == rows);
REQUIRE(frame2.cols() == cols); REQUIRE(frame2.cols() == cols);
REQUIRE(frame2.bitdepth() == bitdepth); REQUIRE(frame2.bitdepth() == bitdepth);
REQUIRE(frame2.size() == rows*cols*bitdepth/8); REQUIRE(frame2.size() == rows * cols * bitdepth / 8);
REQUIRE(frame2.data() == data); REQUIRE(frame2.data() == data);
} }

View File

@ -1,67 +1,58 @@
#include <catch2/catch_test_macros.hpp>
#include "aare/NDArray.hpp" #include "aare/NDArray.hpp"
#include <array> #include <array>
#include <catch2/catch_test_macros.hpp>
using aare::NDArray; using aare::NDArray;
using aare::NDView; using aare::NDView;
using aare::Shape; using aare::Shape;
TEST_CASE("Initial size is zero if no size is specified") {
TEST_CASE("Initial size is zero if no size is specified")
{
NDArray<double> a; NDArray<double> a;
REQUIRE(a.size() == 0); REQUIRE(a.size() == 0);
REQUIRE(a.shape() == Shape<2>{0,0}); REQUIRE(a.shape() == Shape<2>{0, 0});
} }
TEST_CASE("Construct from a DataSpan") {
std::vector<int> some_data(9, 42);
NDView<int, 2> view(some_data.data(), Shape<2>{3, 3});
TEST_CASE("Construct from a DataSpan"){ NDArray<int, 2> image(view);
std::vector<int> some_data(9,42);
NDView<int, 2> view(some_data.data(), Shape<2>{3,3});
NDArray<int,2> image(view);
REQUIRE(image.shape() == view.shape()); REQUIRE(image.shape() == view.shape());
REQUIRE(image.size() == view.size()); REQUIRE(image.size() == view.size());
REQUIRE(image.data() != view.data()); REQUIRE(image.data() != view.data());
for (int i = 0; i<image.size(); ++i){ for (int i = 0; i < image.size(); ++i) {
REQUIRE(image(i) == view(i)); REQUIRE(image(i) == view(i));
} }
//Changing the image doesn't change the view // Changing the image doesn't change the view
image = 43; image = 43;
for (int i = 0; i<image.size(); ++i){ for (int i = 0; i < image.size(); ++i) {
REQUIRE(image(i) != view(i)); REQUIRE(image(i) != view(i));
} }
} }
TEST_CASE("1D image"){ TEST_CASE("1D image") {
std::array<ssize_t, 1>shape{{20}}; std::array<ssize_t, 1> shape{{20}};
NDArray<short,1>img(shape,3); NDArray<short, 1> img(shape, 3);
REQUIRE(img.size()==20); REQUIRE(img.size() == 20);
REQUIRE(img(5)==3); REQUIRE(img(5) == 3);
} }
TEST_CASE("Accessing a const object"){ TEST_CASE("Accessing a const object") {
const NDArray<double, 3> img({3,4,5}, 0); const NDArray<double, 3> img({3, 4, 5}, 0);
REQUIRE(img(1,1,1)==0); REQUIRE(img(1, 1, 1) == 0);
REQUIRE(img.size() == 3*4*5); REQUIRE(img.size() == 3 * 4 * 5);
REQUIRE(img.shape() == Shape<3>{3,4,5}); REQUIRE(img.shape() == Shape<3>{3, 4, 5});
REQUIRE(img.shape(0) == 3); REQUIRE(img.shape(0) == 3);
REQUIRE(img.shape(1) == 4); REQUIRE(img.shape(1) == 4);
REQUIRE(img.shape(2) == 5); REQUIRE(img.shape(2) == 5);
} }
TEST_CASE("Indexing of a 2D image") TEST_CASE("Indexing of a 2D image") {
{ std::array<ssize_t, 2> shape{{3, 7}};
std::array<ssize_t, 2>shape{{ 3, 7 }}; NDArray<long> img(shape, 5);
NDArray<long> img( shape, 5 );
for (int i = 0; i != img.size(); ++i) { for (int i = 0; i != img.size(); ++i) {
REQUIRE(img(i) == 5); REQUIRE(img(i) == 5);
} }
@ -74,14 +65,13 @@ TEST_CASE("Indexing of a 2D image")
REQUIRE(img(1, 0) == 7); REQUIRE(img(1, 0) == 7);
} }
TEST_CASE("Indexing of a 3D image") TEST_CASE("Indexing of a 3D image") {
{ NDArray<float, 3> img{{{3, 4, 2}}, 5.0f};
NDArray<float, 3> img{ {{ 3, 4, 2 }}, 5.0f };
for (int i = 0; i != img.size(); ++i) { for (int i = 0; i != img.size(); ++i) {
REQUIRE(img(i) == 5.0f); REQUIRE(img(i) == 5.0f);
} }
//Double check general properties // Double check general properties
REQUIRE(img.size() == 3 * 4 * 2); REQUIRE(img.size() == 3 * 4 * 2);
for (int i = 0; i != img.size(); ++i) { for (int i = 0; i != img.size(); ++i) {
@ -94,21 +84,19 @@ TEST_CASE("Indexing of a 3D image")
REQUIRE(img(2, 3, 1) == 23); REQUIRE(img(2, 3, 1) == 23);
} }
TEST_CASE("Divide double by int"){ TEST_CASE("Divide double by int") {
NDArray<double,1> a{{5}, 5}; NDArray<double, 1> a{{5}, 5};
NDArray<int,1> b{{5},5}; NDArray<int, 1> b{{5}, 5};
a /=b; a /= b;
for (auto it : a){ for (auto it : a) {
REQUIRE(it == 1.0); REQUIRE(it == 1.0);
} }
} }
TEST_CASE("Elementwise multiplication of 3D image") TEST_CASE("Elementwise multiplication of 3D image") {
{ std::array<ssize_t, 3> shape{3, 4, 2};
std::array<ssize_t, 3>shape{3, 4, 2}; NDArray<double, 3> a{shape};
NDArray<double, 3> a{ shape }; NDArray<double, 3> b{shape};
NDArray<double, 3> b{ shape };
for (int i = 0; i != a.size(); ++i) { for (int i = 0; i != a.size(); ++i) {
a(i) = i; a(i) = i;
b(i) = i; b(i) = i;
@ -121,55 +109,51 @@ TEST_CASE("Elementwise multiplication of 3D image")
REQUIRE(c(2, 3, 1) == 23 * 23); REQUIRE(c(2, 3, 1) == 23 * 23);
} }
TEST_CASE("Compare two images") TEST_CASE("Compare two images") {
{
NDArray<int> a; NDArray<int> a;
NDArray<int> b; NDArray<int> b;
CHECK(a == b); CHECK(a == b);
a = NDArray<int>{ { 5, 10 }, 0 }; a = NDArray<int>{{5, 10}, 0};
CHECK(a != b); CHECK(a != b);
b = NDArray<int>{ { 5, 10 }, 0 }; b = NDArray<int>{{5, 10}, 0};
CHECK(a == b); CHECK(a == b);
b(3, 3) = 7; b(3, 3) = 7;
CHECK(a != b); CHECK(a != b);
} }
TEST_CASE("Size and shape matches") TEST_CASE("Size and shape matches") {
{
ssize_t w = 15; ssize_t w = 15;
ssize_t h = 75; ssize_t h = 75;
std::array<ssize_t, 2> shape{ w, h }; std::array<ssize_t, 2> shape{w, h};
NDArray<double> a{ shape }; NDArray<double> a{shape};
REQUIRE(a.size() == w * h); REQUIRE(a.size() == w * h);
REQUIRE(a.shape() == shape); REQUIRE(a.shape() == shape);
} }
TEST_CASE("Initial value matches for all elements") TEST_CASE("Initial value matches for all elements") {
{
double v = 4.35; double v = 4.35;
NDArray<double> a{ { 5, 5 }, v }; NDArray<double> a{{5, 5}, v};
for (int i = 0; i < a.size(); ++i) { for (int i = 0; i < a.size(); ++i) {
REQUIRE(a(i) == v); REQUIRE(a(i) == v);
} }
} }
TEST_CASE("Data layout of 3D image, fast index last"){ TEST_CASE("Data layout of 3D image, fast index last") {
NDArray<int,3> a{{3,3,3}, 0}; NDArray<int, 3> a{{3, 3, 3}, 0};
REQUIRE(a.size()== 27); REQUIRE(a.size() == 27);
int* ptr = a.data(); int *ptr = a.data();
for (int i = 0; i<9; ++i){
*ptr++ = 10+i;
REQUIRE(a(0,0,i) == 10+i);
REQUIRE(a(i) == 10+i);
for (int i = 0; i < 9; ++i) {
*ptr++ = 10 + i;
REQUIRE(a(0, 0, i) == 10 + i);
REQUIRE(a(i) == 10 + i);
} }
} }
TEST_CASE("Bitwise and on data"){ TEST_CASE("Bitwise and on data") {
NDArray<uint16_t, 1> a({3}, 0); NDArray<uint16_t, 1> a({3}, 0);
uint16_t mask = 0x3FF; uint16_t mask = 0x3FF;
@ -182,7 +166,6 @@ TEST_CASE("Bitwise and on data"){
REQUIRE(a(0) == 300); REQUIRE(a(0) == 300);
REQUIRE(a(1) == 300); REQUIRE(a(1) == 300);
REQUIRE(a(2) == 384); REQUIRE(a(2) == 384);
} }
// TEST_CASE("Benchmarks") // TEST_CASE("Benchmarks")
@ -220,182 +203,173 @@ TEST_CASE("Bitwise and on data"){
// } // }
// } // }
TEST_CASE("Elementwise operatios on images") TEST_CASE("Elementwise operatios on images") {
{ std::array<ssize_t, 2> shape{5, 5};
std::array<ssize_t, 2> shape{ 5, 5 };
double a_val = 3.0; double a_val = 3.0;
double b_val = 8.0; double b_val = 8.0;
SECTION("Add two images") SECTION("Add two images") {
{
NDArray<double> A(shape, a_val); NDArray<double> A(shape, a_val);
NDArray<double> B(shape, b_val); NDArray<double> B(shape, b_val);
auto C = A + B; auto C = A + B;
//Value of C matches // Value of C matches
for (int i = 0; i < C.size(); ++i) { for (int i = 0; i < C.size(); ++i) {
REQUIRE(C(i) == a_val + b_val); REQUIRE(C(i) == a_val + b_val);
} }
//Value of A is not changed // Value of A is not changed
for (int i = 0; i < A.size(); ++i) { for (int i = 0; i < A.size(); ++i) {
REQUIRE(A(i) == a_val); REQUIRE(A(i) == a_val);
} }
//Value of B is not changed // Value of B is not changed
for (int i = 0; i < B.size(); ++i) { for (int i = 0; i < B.size(); ++i) {
REQUIRE(B(i) == b_val); REQUIRE(B(i) == b_val);
} }
//A, B and C referes to different data // A, B and C referes to different data
REQUIRE(A.data() != B.data()); REQUIRE(A.data() != B.data());
REQUIRE(B.data() != C.data()); REQUIRE(B.data() != C.data());
} }
SECTION("Subtract two images") SECTION("Subtract two images") {
{
NDArray<double> A(shape, a_val); NDArray<double> A(shape, a_val);
NDArray<double> B(shape, b_val); NDArray<double> B(shape, b_val);
auto C = A - B; auto C = A - B;
//Value of C matches // Value of C matches
for (int i = 0; i < C.size(); ++i) { for (int i = 0; i < C.size(); ++i) {
REQUIRE(C(i) == a_val - b_val); REQUIRE(C(i) == a_val - b_val);
} }
//Value of A is not changed // Value of A is not changed
for (int i = 0; i < A.size(); ++i) { for (int i = 0; i < A.size(); ++i) {
REQUIRE(A(i) == a_val); REQUIRE(A(i) == a_val);
} }
//Value of B is not changed // Value of B is not changed
for (int i = 0; i < B.size(); ++i) { for (int i = 0; i < B.size(); ++i) {
REQUIRE(B(i) == b_val); REQUIRE(B(i) == b_val);
} }
//A, B and C referes to different data // A, B and C referes to different data
REQUIRE(A.data() != B.data()); REQUIRE(A.data() != B.data());
REQUIRE(B.data() != C.data()); REQUIRE(B.data() != C.data());
} }
SECTION("Multiply two images") SECTION("Multiply two images") {
{
NDArray<double> A(shape, a_val); NDArray<double> A(shape, a_val);
NDArray<double> B(shape, b_val); NDArray<double> B(shape, b_val);
auto C = A * B; auto C = A * B;
//Value of C matches // Value of C matches
for (int i = 0; i < C.size(); ++i) { for (int i = 0; i < C.size(); ++i) {
REQUIRE(C(i) == a_val * b_val); REQUIRE(C(i) == a_val * b_val);
} }
//Value of A is not changed // Value of A is not changed
for (int i = 0; i < A.size(); ++i) { for (int i = 0; i < A.size(); ++i) {
REQUIRE(A(i) == a_val); REQUIRE(A(i) == a_val);
} }
//Value of B is not changed // Value of B is not changed
for (int i = 0; i < B.size(); ++i) { for (int i = 0; i < B.size(); ++i) {
REQUIRE(B(i) == b_val); REQUIRE(B(i) == b_val);
} }
//A, B and C referes to different data // A, B and C referes to different data
REQUIRE(A.data() != B.data()); REQUIRE(A.data() != B.data());
REQUIRE(B.data() != C.data()); REQUIRE(B.data() != C.data());
} }
SECTION("Divide two images") SECTION("Divide two images") {
{
NDArray<double> A(shape, a_val); NDArray<double> A(shape, a_val);
NDArray<double> B(shape, b_val); NDArray<double> B(shape, b_val);
auto C = A / B; auto C = A / B;
//Value of C matches // Value of C matches
for (int i = 0; i < C.size(); ++i) { for (int i = 0; i < C.size(); ++i) {
REQUIRE(C(i) == a_val / b_val); REQUIRE(C(i) == a_val / b_val);
} }
//Value of A is not changed // Value of A is not changed
for (int i = 0; i < A.size(); ++i) { for (int i = 0; i < A.size(); ++i) {
REQUIRE(A(i) == a_val); REQUIRE(A(i) == a_val);
} }
//Value of B is not changed // Value of B is not changed
for (int i = 0; i < B.size(); ++i) { for (int i = 0; i < B.size(); ++i) {
REQUIRE(B(i) == b_val); REQUIRE(B(i) == b_val);
} }
//A, B and C referes to different data // A, B and C referes to different data
REQUIRE(A.data() != B.data()); REQUIRE(A.data() != B.data());
REQUIRE(B.data() != C.data()); REQUIRE(B.data() != C.data());
} }
SECTION("subtract scalar") SECTION("subtract scalar") {
{
NDArray<double> A(shape, a_val); NDArray<double> A(shape, a_val);
NDArray<double> B(shape, b_val); NDArray<double> B(shape, b_val);
double v = 1.0; double v = 1.0;
auto C = A - v; auto C = A - v;
REQUIRE(C.data() != A.data()); REQUIRE(C.data() != A.data());
//Value of C matches // Value of C matches
for (int i = 0; i < C.size(); ++i) { for (int i = 0; i < C.size(); ++i) {
REQUIRE(C(i) == a_val - v); REQUIRE(C(i) == a_val - v);
} }
//Value of A is not changed // Value of A is not changed
for (int i = 0; i < A.size(); ++i) { for (int i = 0; i < A.size(); ++i) {
REQUIRE(A(i) == a_val); REQUIRE(A(i) == a_val);
} }
} }
SECTION("add scalar") SECTION("add scalar") {
{
NDArray<double> A(shape, a_val); NDArray<double> A(shape, a_val);
NDArray<double> B(shape, b_val); NDArray<double> B(shape, b_val);
double v = 1.0; double v = 1.0;
auto C = A + v; auto C = A + v;
REQUIRE(C.data() != A.data()); REQUIRE(C.data() != A.data());
//Value of C matches // Value of C matches
for (int i = 0; i < C.size(); ++i) { for (int i = 0; i < C.size(); ++i) {
REQUIRE(C(i) == a_val + v); REQUIRE(C(i) == a_val + v);
} }
//Value of A is not changed // Value of A is not changed
for (int i = 0; i < A.size(); ++i) { for (int i = 0; i < A.size(); ++i) {
REQUIRE(A(i) == a_val); REQUIRE(A(i) == a_val);
} }
} }
SECTION("divide with scalar") SECTION("divide with scalar") {
{
NDArray<double> A(shape, a_val); NDArray<double> A(shape, a_val);
NDArray<double> B(shape, b_val); NDArray<double> B(shape, b_val);
double v = 3.7; double v = 3.7;
auto C = A / v; auto C = A / v;
REQUIRE(C.data() != A.data()); REQUIRE(C.data() != A.data());
//Value of C matches // Value of C matches
for (int i = 0; i < C.size(); ++i) { for (int i = 0; i < C.size(); ++i) {
REQUIRE(C(i) == a_val / v); REQUIRE(C(i) == a_val / v);
} }
//Value of A is not changed // Value of A is not changed
for (int i = 0; i < A.size(); ++i) { for (int i = 0; i < A.size(); ++i) {
REQUIRE(A(i) == a_val); REQUIRE(A(i) == a_val);
} }
} }
SECTION("multiply with scalar") SECTION("multiply with scalar") {
{
NDArray<double> A(shape, a_val); NDArray<double> A(shape, a_val);
NDArray<double> B(shape, b_val); NDArray<double> B(shape, b_val);
double v = 3.7; double v = 3.7;
auto C = A / v; auto C = A / v;
REQUIRE(C.data() != A.data()); REQUIRE(C.data() != A.data());
//Value of C matches // Value of C matches
for (int i = 0; i < C.size(); ++i) { for (int i = 0; i < C.size(); ++i) {
REQUIRE(C(i) == a_val / v); REQUIRE(C(i) == a_val / v);
} }
//Value of A is not changed // Value of A is not changed
for (int i = 0; i < A.size(); ++i) { for (int i = 0; i < A.size(); ++i) {
REQUIRE(A(i) == a_val); REQUIRE(A(i) == a_val);
} }

View File

@ -105,12 +105,12 @@ TEST_CASE("Multiply and divide with single value") {
} }
} }
TEST_CASE("elementwise assign"){ TEST_CASE("elementwise assign") {
std::vector<int> vec(25); std::vector<int> vec(25);
NDView<int, 2> data(vec.data(), Shape<2>{5,5}); NDView<int, 2> data(vec.data(), Shape<2>{5, 5});
data = 3; data = 3;
for (auto it : data){ for (auto it : data) {
REQUIRE(it == 3); REQUIRE(it == 3);
} }
} }
@ -131,7 +131,7 @@ TEST_CASE("iterators") {
for (auto ptr = data.begin(); ptr != data.end(); ++ptr) { for (auto ptr = data.begin(); ptr != data.end(); ++ptr) {
*ptr += 1; *ptr += 1;
} }
for (auto& item : data){ for (auto &item : data) {
++item; ++item;
} }
@ -142,54 +142,52 @@ TEST_CASE("iterators") {
} }
} }
TEST_CASE("shape from vector") {
TEST_CASE("shape from vector"){
std::vector<int> vec; std::vector<int> vec;
for (int i = 0; i != 12; ++i) { for (int i = 0; i != 12; ++i) {
vec.push_back(i); vec.push_back(i);
} }
std::vector<ssize_t> shape{3,4}; std::vector<ssize_t> shape{3, 4};
NDView<int,2> data(vec.data(), shape); NDView<int, 2> data(vec.data(), shape);
} }
TEST_CASE("divide with another span"){ TEST_CASE("divide with another span") {
std::vector<int> vec0{9,12,3}; std::vector<int> vec0{9, 12, 3};
std::vector<int> vec1{3,2,1}; std::vector<int> vec1{3, 2, 1};
std::vector<int> result{3,6,3}; std::vector<int> result{3, 6, 3};
NDView<int, 1> data0(vec0.data(), Shape<1>{static_cast<ssize_t>(vec0.size())}); NDView<int, 1> data0(vec0.data(), Shape<1>{static_cast<ssize_t>(vec0.size())});
NDView<int, 1> data1(vec1.data(), Shape<1>{static_cast<ssize_t>(vec1.size())}); NDView<int, 1> data1(vec1.data(), Shape<1>{static_cast<ssize_t>(vec1.size())});
data0 /= data1; data0 /= data1;
for(size_t i =0; i!=vec0.size(); ++i){ for (size_t i = 0; i != vec0.size(); ++i) {
REQUIRE(data0[i] == result[i] ); REQUIRE(data0[i] == result[i]);
} }
} }
TEST_CASE("Retrieve shape"){ TEST_CASE("Retrieve shape") {
std::vector<int> vec; std::vector<int> vec;
for (int i = 0; i != 12; ++i) { for (int i = 0; i != 12; ++i) {
vec.push_back(i); vec.push_back(i);
} }
NDView<int,2> data(vec.data(), Shape<2>{3,4}); NDView<int, 2> data(vec.data(), Shape<2>{3, 4});
REQUIRE(data.shape()[0] == 3); REQUIRE(data.shape()[0] == 3);
REQUIRE(data.shape()[1] == 4); REQUIRE(data.shape()[1] == 4);
} }
TEST_CASE("compare two views"){ TEST_CASE("compare two views") {
std::vector<int> vec1; std::vector<int> vec1;
for (int i = 0; i != 12; ++i) { for (int i = 0; i != 12; ++i) {
vec1.push_back(i); vec1.push_back(i);
} }
NDView<int,2> view1(vec1.data(), Shape<2>{3,4}); NDView<int, 2> view1(vec1.data(), Shape<2>{3, 4});
std::vector<int> vec2; std::vector<int> vec2;
for (int i = 0; i != 12; ++i) { for (int i = 0; i != 12; ++i) {
vec2.push_back(i); vec2.push_back(i);
} }
NDView<int,2> view2(vec2.data(), Shape<2>{3,4}); NDView<int, 2> view2(vec2.data(), Shape<2>{3, 4});
REQUIRE(view1 == view2); REQUIRE(view1 == view2);
} }

View File

@ -1,49 +1,49 @@
#include <catch2/catch_all.hpp> #include "aare/ProducerConsumerQueue.hpp"
#include "aare/ProducerConsumerQueue.hpp" #include <catch2/catch_all.hpp>
// using arve::SimpleQueue; // using arve::SimpleQueue;
TEST_CASE("push pop"){ TEST_CASE("push pop") {
folly::ProducerConsumerQueue<int> q(5); folly::ProducerConsumerQueue<int> q(5);
int a = 3; int a = 3;
int b = 8; int b = 8;
CHECK(q.sizeGuess() == 0); CHECK(q.sizeGuess() == 0);
CHECK(q.write(a)); CHECK(q.write(a));
CHECK(q.sizeGuess() == 1); CHECK(q.sizeGuess() == 1);
CHECK(q.write(b)); CHECK(q.write(b));
CHECK(q.sizeGuess() == 2); CHECK(q.sizeGuess() == 2);
int c = 0; int c = 0;
CHECK(q.read(c)); CHECK(q.read(c));
CHECK(c == 3); CHECK(c == 3);
CHECK(q.sizeGuess() == 1); CHECK(q.sizeGuess() == 1);
CHECK(q.read(c)); CHECK(q.read(c));
CHECK(c == 8); CHECK(c == 8);
CHECK(q.sizeGuess() == 0); CHECK(q.sizeGuess() == 0);
} }
TEST_CASE("Cannot push to a full queue"){ TEST_CASE("Cannot push to a full queue") {
folly::ProducerConsumerQueue<int> q(3); folly::ProducerConsumerQueue<int> q(3);
int a = 3; int a = 3;
int b = 4; int b = 4;
int c = 0; int c = 0;
CHECK(q.write(a)); CHECK(q.write(a));
CHECK(q.write(b)); CHECK(q.write(b));
CHECK_FALSE(q.write(a)); CHECK_FALSE(q.write(a));
//values are still ok // values are still ok
CHECK(q.read(c)); CHECK(q.read(c));
CHECK(c == 3); CHECK(c == 3);
CHECK(q.read(c)); CHECK(q.read(c));
CHECK(c == 4); CHECK(c == 4);
} }
TEST_CASE("Cannot pop from an empty queue"){ TEST_CASE("Cannot pop from an empty queue") {
folly::ProducerConsumerQueue<int> q(2); folly::ProducerConsumerQueue<int> q(2);
int a=0; int a = 0;
CHECK_FALSE(q.read(a)); CHECK_FALSE(q.read(a));
} }
// TEST_CASE("fail"){ // TEST_CASE("fail"){
// CHECK(false); // CHECK(false);
// } // }

View File

@ -1,8 +1,8 @@
#include "aare/defs.hpp"
#include <catch2/catch_test_macros.hpp> #include <catch2/catch_test_macros.hpp>
#include <string> #include <string>
#include "aare/defs.hpp" TEST_CASE("Enum to string conversion") {
TEST_CASE("Enum to string conversion"){ // By the way I don't think the enum string conversions should be in the defs.hpp file
//By the way I don't think the enum string conversions should be in the defs.hpp file // but let's use this to show a test
//but let's use this to show a test
REQUIRE(toString(aare::DetectorType::Jungfrau) == "Jungfrau"); REQUIRE(toString(aare::DetectorType::Jungfrau) == "Jungfrau");
} }

View File

@ -1,12 +1,11 @@
#include <aare/NDView.hpp>
#include <aare/Frame.hpp> #include <aare/Frame.hpp>
#include <aare/NDView.hpp> #include <aare/NDView.hpp>
#include <catch2/catch_test_macros.hpp> #include <catch2/catch_test_macros.hpp>
#include <cstdint> #include <cstdint>
using aare::Frame; using aare::Frame;
using aare::NDView;
using aare::NDArray; using aare::NDArray;
using aare::NDView;
TEST_CASE("Frame") { TEST_CASE("Frame") {
auto data = new uint16_t[100]; auto data = new uint16_t[100];

View File

@ -8,7 +8,7 @@
using aare::File; using aare::File;
using aare::Frame; using aare::Frame;
void test(File& f, int frame_number) { void test(File &f, int frame_number) {
std::cout << "frame number: " << frame_number << std::endl; std::cout << "frame number: " << frame_number << std::endl;
Frame frame = f.iread(frame_number); Frame frame = f.iread(frame_number);
std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl; std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl;

View File

@ -1,6 +1,6 @@
#include "aare/utils/logger.hpp" #include "aare/utils/logger.hpp"
#include <iostream>
#include <fstream> #include <fstream>
#include <iostream>
int main() { int main() {
aare::logger::debug(LOCATION, "hello", 1, "world", std::vector<long>{1, 2, 3, 4, 5}); aare::logger::debug(LOCATION, "hello", 1, "world", std::vector<long>{1, 2, 3, 4, 5});
@ -9,15 +9,12 @@ int main() {
aare::logger::debug(LOCATION, "NOTHING SHOULD BE PRINTED"); aare::logger::debug(LOCATION, "NOTHING SHOULD BE PRINTED");
aare::logger::info(LOCATION, "info printed"); aare::logger::info(LOCATION, "info printed");
// writing to file // writing to file
std::ofstream textfile; std::ofstream textfile;
textfile.open("Test.txt"); textfile.open("Test.txt");
aare::logger::set_streams(textfile.rdbuf()); aare::logger::set_streams(textfile.rdbuf());
aare::logger::info(LOCATION, "info printed to file"); aare::logger::info(LOCATION, "info printed to file");
// writing with a local logger instance // writing with a local logger instance
aare::logger::Logger logger; aare::logger::Logger logger;
logger.set_verbosity(aare::logger::WARNING); logger.set_verbosity(aare::logger::WARNING);
@ -27,7 +24,6 @@ int main() {
aare::logger::info(LOCATION, "info printed in file ##"); aare::logger::info(LOCATION, "info printed in file ##");
textfile.close(); textfile.close();
// setting file output by path // setting file output by path
// user doesn't have to close file // user doesn't have to close file
aare::logger::set_output_file("Test2.txt"); aare::logger::set_output_file("Test2.txt");

View File

@ -2,7 +2,6 @@
#include "aare/File.hpp" #include "aare/File.hpp"
#include "aare/utils/logger.hpp" #include "aare/utils/logger.hpp"
#include <iostream> #include <iostream>
#include <iostream>
#define AARE_ROOT_DIR_VAR "PROJECT_ROOT_DIR" #define AARE_ROOT_DIR_VAR "PROJECT_ROOT_DIR"

View File

@ -7,7 +7,7 @@
using aare::File; using aare::File;
using aare::Frame; using aare::Frame;
void test(File& f, int frame_number) { void test(File &f, int frame_number) {
std::cout << "frame number: " << frame_number << std::endl; std::cout << "frame number: " << frame_number << std::endl;
Frame frame = f.iread(frame_number); Frame frame = f.iread(frame_number);
std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl; std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl;
@ -22,7 +22,7 @@ int main() {
std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "numpy" / "test_numpy_file.npy"); std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "numpy" / "test_numpy_file.npy");
std::cout << fpath << std::endl; std::cout << fpath << std::endl;
File file(fpath,"r"); File file(fpath, "r");
test(file, 0); test(file, 0);
test(file, 2); test(file, 2);
test(file, 24); test(file, 24);

View File

@ -9,23 +9,19 @@ using aare::File;
using aare::FileConfig; using aare::FileConfig;
using aare::Frame; using aare::Frame;
int main() { int main() {
auto path = std::filesystem::path("/tmp/test.npy"); auto path = std::filesystem::path("/tmp/test.npy");
auto dtype = aare::DType(typeid(uint32_t)); auto dtype = aare::DType(typeid(uint32_t));
FileConfig cfg = {path, dtype, 100, 100}; FileConfig cfg = {path, dtype, 100, 100};
File npy(path, "w",cfg); File npy(path, "w", cfg);
Frame f(100, 100, dtype.bitdepth()); Frame f(100, 100, dtype.bitdepth());
for (int i = 0; i < 10000; i++) { for (int i = 0; i < 10000; i++) {
f.set<uint32_t>(i/100, i%100,i); f.set<uint32_t>(i / 100, i % 100, i);
} }
npy.write(f); npy.write(f);
f.set<uint32_t>(0,0,77); f.set<uint32_t>(0, 0, 77);
npy.write(f); npy.write(f);
npy.write(f); npy.write(f);
return 0; return 0;
} }

View File

@ -1,14 +1,14 @@
// Your First C++ Program // Your First C++ Program
#include "aare/File.hpp" #include "aare/File.hpp"
#include <iostream>
#include "aare/utils/logger.hpp" #include "aare/utils/logger.hpp"
#include <iostream>
#define AARE_ROOT_DIR_VAR "PROJECT_ROOT_DIR" #define AARE_ROOT_DIR_VAR "PROJECT_ROOT_DIR"
using aare::File; using aare::File;
using aare::Frame; using aare::Frame;
void test(File& f, int frame_number) { void test(File &f, int frame_number) {
std::cout << "frame number: " << frame_number << std::endl; std::cout << "frame number: " << frame_number << std::endl;
Frame frame = f.iread(frame_number); Frame frame = f.iread(frame_number);
std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl; std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl;
@ -21,7 +21,8 @@ int main() {
if (PROJECT_ROOT_DIR.empty()) { if (PROJECT_ROOT_DIR.empty()) {
throw std::runtime_error("environment variable PROJECT_ROOT_DIR is not set"); throw std::runtime_error("environment variable PROJECT_ROOT_DIR is not set");
} }
std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" /"moench"/ "moench04_noise_200V_sto_both_100us_no_light_thresh_900_master_0.raw"); std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "moench" /
"moench04_noise_200V_sto_both_100us_no_light_thresh_900_master_0.raw");
File file(fpath, "r"); File file(fpath, "r");
test(file, 0); test(file, 0);
test(file, 2); test(file, 2);

View File

@ -1,18 +1,15 @@
#include <string>
#include <fmt/core.h>
#include "aare/ZmqSocket.hpp" #include "aare/ZmqSocket.hpp"
#include <fmt/core.h>
#include <string>
int main() {
int main(){
std::string endpoint = "tcp://localhost:5555"; std::string endpoint = "tcp://localhost:5555";
aare::ZmqSocket socket(endpoint); aare::ZmqSocket socket(endpoint);
socket.connect(); socket.connect();
char* data = new char[1024*1024*10]; char *data = new char[1024 * 1024 * 10];
aare::zmqHeader header; aare::zmqHeader header;
while(true){ while (true) {
int rc = socket.receive(header, reinterpret_cast<std::byte*>(data)); int rc = socket.receive(header, reinterpret_cast<std::byte *>(data));
} }
delete[] data; delete[] data;
return 0; return 0;

View File

@ -8,7 +8,7 @@ File::File(std::filesystem::path fname, std::string mode, FileConfig cfg) {
file_impl = FileFactory::load_file(fname, mode, cfg); file_impl = FileFactory::load_file(fname, mode, cfg);
} }
void File::write(Frame& frame) { file_impl->write(frame); } void File::write(Frame &frame) { file_impl->write(frame); }
Frame File::read() { return file_impl->read(); } Frame File::read() { return file_impl->read(); }
size_t File::total_frames() const { return file_impl->total_frames(); } size_t File::total_frames() const { return file_impl->total_frames(); }
std::vector<Frame> File::read(size_t n_frames) { return file_impl->read(n_frames); } std::vector<Frame> File::read(size_t n_frames) { return file_impl->read(n_frames); }
@ -33,4 +33,4 @@ File::File(File &&other) {
// write move assignment operator // write move assignment operator
} } // namespace aare

View File

@ -1,20 +1,19 @@
#include "aare/FileFactory.hpp" #include "aare/FileFactory.hpp"
#include "aare/FileInterface.hpp" #include "aare/FileInterface.hpp"
#include "aare/RawFileFactory.hpp"
#include "aare/NumpyFileFactory.hpp" #include "aare/NumpyFileFactory.hpp"
#include "aare/utils/logger.hpp" #include "aare/RawFileFactory.hpp"
#include "aare/utils/logger.hpp" #include "aare/utils/logger.hpp"
#include <iostream> #include <iostream>
namespace aare { namespace aare {
FileFactory *FileFactory::get_factory(std::filesystem::path fpath) { FileFactory *FileFactory::get_factory(std::filesystem::path fpath) {
if (fpath.extension() == ".raw" || fpath.extension() == ".json"){ if (fpath.extension() == ".raw" || fpath.extension() == ".json") {
aare::logger::debug("Loading",fpath.extension(),"file"); aare::logger::debug("Loading", fpath.extension(), "file");
return new RawFileFactory(fpath); return new RawFileFactory(fpath);
} }
if (fpath.extension() == ".raw" || fpath.extension() == ".json"){ if (fpath.extension() == ".raw" || fpath.extension() == ".json") {
aare::logger::debug("Loading",fpath.extension(),"file"); aare::logger::debug("Loading", fpath.extension(), "file");
return new RawFileFactory(fpath); return new RawFileFactory(fpath);
} }
// check if extension is numpy // check if extension is numpy
@ -27,5 +26,3 @@ FileFactory *FileFactory::get_factory(std::filesystem::path fpath) {
} }
} // namespace aare } // namespace aare

View File

@ -1,10 +1,10 @@
#include "aare/NumpyFile.hpp" #include "aare/NumpyFile.hpp"
namespace aare{ namespace aare {
NumpyFile::NumpyFile(const std::filesystem::path& fname) { NumpyFile::NumpyFile(const std::filesystem::path &fname) {
//TODO! add opts to constructor // TODO! add opts to constructor
m_fname = fname; m_fname = fname;
fp = fopen(m_fname.c_str(), "rb"); fp = fopen(m_fname.c_str(), "rb");
if (!fp) { if (!fp) {
@ -26,8 +26,7 @@ NumpyFile::NumpyFile(FileConfig config, header_t header) {
throw std::runtime_error(fmt::format("Could not open: {} for reading", m_fname.c_str())); throw std::runtime_error(fmt::format("Could not open: {} for reading", m_fname.c_str()));
} }
initial_header_len = initial_header_len = aare::NumpyHelpers::write_header(std::filesystem::path(m_fname.c_str()), header);
aare::NumpyHelpers::write_header(std::filesystem::path(m_fname.c_str()), header);
} }
void NumpyFile::write(Frame &frame) { void NumpyFile::write(Frame &frame) {
@ -41,8 +40,6 @@ void NumpyFile::write(Frame &frame) {
fwrite(frame.data(), frame.size(), 1, fp); fwrite(frame.data(), frame.size(), 1, fp);
} }
Frame NumpyFile::get_frame(size_t frame_number) { Frame NumpyFile::get_frame(size_t frame_number) {
Frame frame(m_header.shape[1], m_header.shape[2], m_header.dtype.bitdepth()); Frame frame(m_header.shape[1], m_header.shape[2], m_header.dtype.bitdepth());
get_frame_into(frame_number, frame.data()); get_frame_into(frame_number, frame.data());
@ -97,17 +94,14 @@ NumpyFile::~NumpyFile() {
std::string header_str = ss.str(); std::string header_str = ss.str();
// write header // write header
fwrite(header_str.c_str(), header_str.size(), 1, fp); fwrite(header_str.c_str(), header_str.size(), 1, fp);
} }
if (fp != nullptr) { if (fp != nullptr) {
fclose(fp); fclose(fp);
} }
} }
void NumpyFile::load_metadata(){ void NumpyFile::load_metadata() {
// read magic number // read magic number
std::array<char, 6> tmp{}; std::array<char, 6> tmp{};
@ -120,8 +114,8 @@ void NumpyFile::load_metadata(){
} }
// read version // read version
fread(reinterpret_cast<char *>(&major_ver_), sizeof(major_ver_), 1,fp); fread(reinterpret_cast<char *>(&major_ver_), sizeof(major_ver_), 1, fp);
fread(reinterpret_cast<char *>(&minor_ver_), sizeof(minor_ver_), 1,fp); fread(reinterpret_cast<char *>(&minor_ver_), sizeof(minor_ver_), 1, fp);
if (major_ver_ == 1) { if (major_ver_ == 1) {
header_len_size = 2; header_len_size = 2;
@ -132,7 +126,7 @@ void NumpyFile::load_metadata(){
} }
// read header length // read header length
fread(reinterpret_cast<char *>(&header_len), header_len_size,1, fp); fread(reinterpret_cast<char *>(&header_len), header_len_size, 1, fp);
header_size = aare::NumpyHelpers::magic_string_length + 2 + header_len_size + header_len; header_size = aare::NumpyHelpers::magic_string_length + 2 + header_len_size + header_len;
if (header_size % 16 != 0) { if (header_size % 16 != 0) {
fmt::print("Warning: header length is not a multiple of 16\n"); fmt::print("Warning: header length is not a multiple of 16\n");
@ -140,8 +134,7 @@ void NumpyFile::load_metadata(){
// read header // read header
std::string header(header_len, '\0'); std::string header(header_len, '\0');
fread(header.data(), header_len,1,fp); fread(header.data(), header_len, 1, fp);
// parse header // parse header
std::vector<std::string> keys{"descr", "fortran_order", "shape"}; std::vector<std::string> keys{"descr", "fortran_order", "shape"};
@ -171,5 +164,4 @@ void NumpyFile::load_metadata(){
m_header = {dtype, fortran_order, shape}; m_header = {dtype, fortran_order, shape};
} }
} // namespace aare } // namespace aare

View File

@ -5,7 +5,6 @@ namespace aare {
NumpyFileFactory::NumpyFileFactory(std::filesystem::path fpath) { this->m_fpath = fpath; } NumpyFileFactory::NumpyFileFactory(std::filesystem::path fpath) { this->m_fpath = fpath; }
NumpyFile *NumpyFileFactory::load_file_read() { NumpyFile *NumpyFileFactory::load_file_read() {
NumpyFile *file = new NumpyFile(this->m_fpath); NumpyFile *file = new NumpyFile(this->m_fpath);
return file; return file;
@ -14,8 +13,6 @@ NumpyFile *NumpyFileFactory::load_file_read() {
NumpyFile *NumpyFileFactory::load_file_write(FileConfig config) { NumpyFile *NumpyFileFactory::load_file_write(FileConfig config) {
NumpyFile *file = new NumpyFile(config, {config.dtype, false, {config.rows, config.cols}}); NumpyFile *file = new NumpyFile(config, {config.dtype, false, {config.rows, config.cols}});
return file; return file;
}; };

View File

@ -187,7 +187,7 @@ template <typename T> inline std::string write_tuple(const std::vector<T> &v) {
// ss << v[i] << delimiter; // ss << v[i] << delimiter;
// } // }
// ss << v.back(); // ss << v.back();
std::copy(v.begin(), v.end()-1, std::ostream_iterator<T>(ss, ", ")); std::copy(v.begin(), v.end() - 1, std::ostream_iterator<T>(ss, ", "));
ss << v.back(); ss << v.back();
ss << ")"; ss << ")";
} }
@ -214,7 +214,6 @@ size_t write_header(std::filesystem::path fname, const header_t &header) {
return write_header(out, header); return write_header(out, header);
} }
size_t write_header(std::ostream &out, const header_t &header) { size_t write_header(std::ostream &out, const header_t &header) {
std::string header_dict = write_header_dict(header.dtype.str(), header.fortran_order, header.shape); std::string header_dict = write_header_dict(header.dtype.str(), header.fortran_order, header.shape);

View File

@ -1,7 +1,7 @@
#include "aare/RawFile.hpp" #include "aare/RawFile.hpp"
#include "aare/utils/logger.hpp" #include "aare/utils/logger.hpp"
namespace aare{ namespace aare {
Frame RawFile::get_frame(size_t frame_number) { Frame RawFile::get_frame(size_t frame_number) {
auto f = Frame(this->m_rows, this->m_cols, this->m_bitdepth); auto f = Frame(this->m_rows, this->m_cols, this->m_bitdepth);
@ -62,8 +62,6 @@ void RawFile::read_into(std::byte *image_buf, size_t n_frames) {
} }
} }
size_t RawFile::frame_number(size_t frame_index) { size_t RawFile::frame_number(size_t frame_index) {
if (frame_index > this->m_total_frames) { if (frame_index > this->m_total_frames) {
throw std::runtime_error(LOCATION + "Frame number out of range"); throw std::runtime_error(LOCATION + "Frame number out of range");

View File

@ -65,7 +65,7 @@ void RawFileFactory::parse_raw_metadata(RawFile *file) {
} else if (key == "Pixels") { } else if (key == "Pixels") {
// Total number of pixels cannot be found yet looking at // Total number of pixels cannot be found yet looking at
// submodule // submodule
pos = value.find(','); pos = value.find(',');
file->subfile_cols = std::stoi(value.substr(1, pos)); file->subfile_cols = std::stoi(value.substr(1, pos));
file->subfile_rows = std::stoi(value.substr(pos + 1)); file->subfile_rows = std::stoi(value.substr(pos + 1));
} else if (key == "Total Frames") { } else if (key == "Total Frames") {
@ -77,7 +77,7 @@ void RawFileFactory::parse_raw_metadata(RawFile *file) {
} else if (key == "Max Frames Per File") { } else if (key == "Max Frames Per File") {
file->max_frames_per_file = std::stoi(value); file->max_frames_per_file = std::stoi(value);
} else if (key == "Geometry") { } else if (key == "Geometry") {
pos = value.find(','); pos = value.find(',');
file->geometry = {std::stoi(value.substr(1, pos)), std::stoi(value.substr(pos + 1))}; file->geometry = {std::stoi(value.substr(1, pos)), std::stoi(value.substr(pos + 1))};
} }
} }
@ -114,8 +114,8 @@ void RawFileFactory::open_subfiles(FileInterface *_file) {
for (size_t i = 0; i != file->n_subfiles; ++i) { for (size_t i = 0; i != file->n_subfiles; ++i) {
auto v = std::vector<SubFile *>(file->n_subfile_parts); auto v = std::vector<SubFile *>(file->n_subfile_parts);
for (size_t j = 0; j != file->n_subfile_parts; ++j) { for (size_t j = 0; j != file->n_subfile_parts; ++j) {
v[j] = v[j] = new SubFile(file->data_fname(i, j), file->m_type, file->subfile_rows, file->subfile_cols,
new SubFile(file->data_fname(i, j), file->m_type, file->subfile_rows, file->subfile_cols, file->bitdepth()); file->bitdepth());
} }
file->subfiles.push_back(v); file->subfiles.push_back(v);
} }
@ -147,7 +147,6 @@ sls_detector_header RawFileFactory::read_header(const std::filesystem::path &fna
return h; return h;
} }
void RawFileFactory::find_geometry(FileInterface *_file) { void RawFileFactory::find_geometry(FileInterface *_file) {
auto file = dynamic_cast<RawFile *>(_file); auto file = dynamic_cast<RawFile *>(_file);
uint16_t r{}; uint16_t r{};

View File

@ -12,7 +12,8 @@ SubFile::SubFile(std::filesystem::path fname, DetectorType detector, ssize_t row
this->m_bitdepth = bitdepth; this->m_bitdepth = bitdepth;
this->n_frames = std::filesystem::file_size(fname) / (sizeof(sls_detector_header) + rows * cols * bitdepth / 8); 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()) { if (read_impl_map.find({detector, bitdepth}) == read_impl_map.end()) {
auto error_msg = LOCATION + "No read_impl function found for detector: " + toString(detector) + " and bitdepth: " + std::to_string(bitdepth); 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); throw std::runtime_error(error_msg);
} }
this->read_impl = read_impl_map.at({detector, bitdepth}); this->read_impl = read_impl_map.at({detector, bitdepth});

View File

@ -10,4 +10,4 @@ bool is_master_file(std::filesystem::path fpath) {
return false; return false;
} }
}// namespace aare } // namespace aare

View File

@ -1,53 +1,50 @@
#include <catch2/catch_test_macros.hpp>
#include "aare/NumpyFile.hpp" #include "aare/NumpyFile.hpp"
#include "aare/NDArray.hpp" #include "aare/NDArray.hpp"
#include <catch2/catch_test_macros.hpp>
#include "test_config.hpp" #include "test_config.hpp"
using aare::NumpyFile;
using aare::DType; using aare::DType;
TEST_CASE("Read a 1D numpy file with int32 data type"){ using aare::NumpyFile;
TEST_CASE("Read a 1D numpy file with int32 data type") {
auto fpath = test_data_path() / "numpy" / "test_1d_int32.npy"; auto fpath = test_data_path() / "numpy" / "test_1d_int32.npy";
REQUIRE(std::filesystem::exists(fpath)); REQUIRE(std::filesystem::exists(fpath));
NumpyFile f(fpath); NumpyFile f(fpath);
//we know the file contains 10 elements of np.int32 containing values 0-9 // we know the file contains 10 elements of np.int32 containing values 0-9
REQUIRE(f.dtype() == DType::INT32); REQUIRE(f.dtype() == DType::INT32);
REQUIRE(f.shape() == std::vector<size_t>{10}); REQUIRE(f.shape() == std::vector<size_t>{10});
//use the load function to read the full file into a NDArray // use the load function to read the full file into a NDArray
auto data = f.load<int32_t,1>(); auto data = f.load<int32_t, 1>();
for(size_t i = 0; i < 10; i++){ for (size_t i = 0; i < 10; i++) {
REQUIRE(data(i) == i); REQUIRE(data(i) == i);
} }
} }
TEST_CASE("Read a 3D numpy file with np.double data type"){ TEST_CASE("Read a 3D numpy file with np.double data type") {
auto fpath = test_data_path() / "numpy" / "test_3d_double.npy"; auto fpath = test_data_path() / "numpy" / "test_3d_double.npy";
REQUIRE(std::filesystem::exists(fpath)); REQUIRE(std::filesystem::exists(fpath));
NumpyFile f(fpath); NumpyFile f(fpath);
//we know the file contains 10 elements of np.int32 containing values 0-9 // we know the file contains 10 elements of np.int32 containing values 0-9
REQUIRE(f.dtype() == DType::DOUBLE); REQUIRE(f.dtype() == DType::DOUBLE);
REQUIRE(f.shape() == std::vector<size_t>{3,2,5}); REQUIRE(f.shape() == std::vector<size_t>{3, 2, 5});
//use the load function to read the full file into a NDArray
//numpy code to generate the array
// arr2[0,0,0] = 1.0
// arr2[0,0,1] = 2.0
// arr2[0,1,0] = 72.0
// arr2[2,0,4] = 63.0
auto data = f.load<double,3>();
REQUIRE(data(0,0,0) == 1.0);
REQUIRE(data(0,0,1) == 2.0);
REQUIRE(data(0,1,0) == 72.0);
REQUIRE(data(2,0,4) == 63.0);
// use the load function to read the full file into a NDArray
// numpy code to generate the array
// arr2[0,0,0] = 1.0
// arr2[0,0,1] = 2.0
// arr2[0,1,0] = 72.0
// arr2[2,0,4] = 63.0
auto data = f.load<double, 3>();
REQUIRE(data(0, 0, 0) == 1.0);
REQUIRE(data(0, 0, 1) == 2.0);
REQUIRE(data(0, 1, 0) == 72.0);
REQUIRE(data(2, 0, 4) == 63.0);
} }

View File

@ -1,9 +1,9 @@
#include <catch2/catch_test_macros.hpp>
#include "aare/NumpyHelpers.hpp" //Is this really a public header? #include "aare/NumpyHelpers.hpp" //Is this really a public header?
#include <catch2/catch_test_macros.hpp>
using namespace aare::NumpyHelpers; using namespace aare::NumpyHelpers;
TEST_CASE("is_digits with a few standard cases"){ TEST_CASE("is_digits with a few standard cases") {
REQUIRE(is_digits("")); REQUIRE(is_digits(""));
REQUIRE(is_digits("123")); REQUIRE(is_digits("123"));
REQUIRE(is_digits("0")); REQUIRE(is_digits("0"));
@ -13,17 +13,15 @@ TEST_CASE("is_digits with a few standard cases"){
REQUIRE_FALSE(is_digits("abcdef")); REQUIRE_FALSE(is_digits("abcdef"));
} }
TEST_CASE("Check for quotes and return stripped string"){ TEST_CASE("Check for quotes and return stripped string") {
REQUIRE(parse_str("'hej'") == "hej"); REQUIRE(parse_str("'hej'") == "hej");
REQUIRE(parse_str("'hej hej'") == "hej hej"); REQUIRE(parse_str("'hej hej'") == "hej hej");
REQUIRE(parse_str("''") == ""); REQUIRE(parse_str("''") == "");
} }
TEST_CASE("parsing a string without quotes throws"){ TEST_CASE("parsing a string without quotes throws") { REQUIRE_THROWS(parse_str("hej")); }
REQUIRE_THROWS(parse_str("hej"));
}
TEST_CASE("trim whitespace"){ TEST_CASE("trim whitespace") {
REQUIRE(trim(" hej ") == "hej"); REQUIRE(trim(" hej ") == "hej");
REQUIRE(trim("hej") == "hej"); REQUIRE(trim("hej") == "hej");
REQUIRE(trim(" hej") == "hej"); REQUIRE(trim(" hej") == "hej");
@ -32,7 +30,7 @@ TEST_CASE("trim whitespace"){
REQUIRE(trim(" \thej hej ") == "hej hej"); REQUIRE(trim(" \thej hej ") == "hej hej");
} }
TEST_CASE("parse data type descriptions"){ TEST_CASE("parse data type descriptions") {
REQUIRE(parse_descr("<i1") == aare::DType::INT8); REQUIRE(parse_descr("<i1") == aare::DType::INT8);
REQUIRE(parse_descr("<i2") == aare::DType::INT16); REQUIRE(parse_descr("<i2") == aare::DType::INT16);
REQUIRE(parse_descr("<i4") == aare::DType::INT32); REQUIRE(parse_descr("<i4") == aare::DType::INT32);
@ -47,14 +45,14 @@ TEST_CASE("parse data type descriptions"){
REQUIRE(parse_descr("<f8") == aare::DType::DOUBLE); REQUIRE(parse_descr("<f8") == aare::DType::DOUBLE);
} }
TEST_CASE("is element in array"){ TEST_CASE("is element in array") {
REQUIRE(in_array(1, std::array<int, 3>{1,2,3})); REQUIRE(in_array(1, std::array<int, 3>{1, 2, 3}));
REQUIRE_FALSE(in_array(4, std::array<int, 3>{1,2,3})); REQUIRE_FALSE(in_array(4, std::array<int, 3>{1, 2, 3}));
REQUIRE(in_array(1, std::array<int, 1>{1})); REQUIRE(in_array(1, std::array<int, 1>{1}));
REQUIRE_FALSE(in_array(1, std::array<int, 0>{})); REQUIRE_FALSE(in_array(1, std::array<int, 0>{}));
} }
TEST_CASE("Parse numpy dict"){ TEST_CASE("Parse numpy dict") {
std::string in = "{'descr': '<f4', 'fortran_order': False, 'shape': (3, 4)}"; std::string in = "{'descr': '<f4', 'fortran_order': False, 'shape': (3, 4)}";
std::vector<std::string> keys{"descr", "fortran_order", "shape"}; std::vector<std::string> keys{"descr", "fortran_order", "shape"};
auto map = parse_dict(in, keys); auto map = parse_dict(in, keys);

View File

@ -4,41 +4,28 @@
#include <pybind11/stl.h> #include <pybind11/stl.h>
#include <string> #include <string>
#include "aare/defs.hpp"
#include "aare/Frame.hpp"
#include "aare/FileHandler.hpp" #include "aare/FileHandler.hpp"
#include "aare/Frame.hpp"
#include "aare/defs.hpp"
namespace py = pybind11; namespace py = pybind11;
PYBIND11_MODULE(_aare, m) { PYBIND11_MODULE(_aare, m) {
// helps to convert from std::string to std::filesystem::path // helps to convert from std::string to std::filesystem::path
py::class_<std::filesystem::path>(m, "Path") py::class_<std::filesystem::path>(m, "Path").def(py::init<std::string>());
.def(py::init<std::string>()); py::implicitly_convertible<std::string, std::filesystem::path>();
py::implicitly_convertible<std::string, std::filesystem::path>();
//TODO: find a solution to avoid code duplication and include other detectors // TODO: find a solution to avoid code duplication and include other detectors
py::class_<FileHandler>(m, "_FileHandler") py::class_<FileHandler>(m, "_FileHandler")
.def(py::init<std::filesystem::path>()) .def(py::init<std::filesystem::path>())
.def("get_frame", &FileHandler::get_frame); .def("get_frame", &FileHandler::get_frame);
py::enum_<DetectorType>(m, "DetectorType"); py::enum_<DetectorType>(m, "DetectorType");
py::class_<Frame>(m, "_Frame") py::class_<Frame>(m, "_Frame")
.def(py::init<std::byte*, ssize_t, ssize_t,ssize_t>()) .def(py::init<std::byte *, ssize_t, ssize_t, ssize_t>())
.def("get", &Frame::get) .def("get", &Frame::get)
.def_property_readonly("rows", &Frame::rows) .def_property_readonly("rows", &Frame::rows)
.def_property_readonly("cols", &Frame::cols) .def_property_readonly("cols", &Frame::cols)
.def_property_readonly("bitdepth", &Frame::bitdepth); .def_property_readonly("bitdepth", &Frame::bitdepth);
} }

View File

@ -9,6 +9,6 @@ void set_streams(std::streambuf *out, std::streambuf *err) { internal::logger_in
void set_streams(std::streambuf *out) { internal::logger_instance.set_streams(out); } void set_streams(std::streambuf *out) { internal::logger_instance.set_streams(out); }
void set_verbosity(LOGGING_LEVEL level) { internal::logger_instance.set_verbosity(level); } void set_verbosity(LOGGING_LEVEL level) { internal::logger_instance.set_verbosity(level); }
Logger &get_logger_instance() { return internal::logger_instance; } Logger &get_logger_instance() { return internal::logger_instance; }
void set_output_file(std::string filename){ internal::logger_instance.set_output_file(filename); } void set_output_file(std::string filename) { internal::logger_instance.set_output_file(filename); }
} // namespace logger } // namespace logger
} // namespace aare } // namespace aare