mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-04-23 15:00:02 +02:00
added parallel and container3
This commit is contained in:
parent
4f712fcd70
commit
d66df844e5
157
slsDetectorSoftware/src/Container3.h
Normal file
157
slsDetectorSoftware/src/Container3.h
Normal file
@ -0,0 +1,157 @@
|
||||
#pragma once
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
#include <numeric>
|
||||
|
||||
namespace sls{
|
||||
|
||||
template <typename T> class Container3 {
|
||||
std::array<size_t, 3> shape_{0, 0, 0};
|
||||
T *data_{nullptr};
|
||||
|
||||
public:
|
||||
Container3(){};
|
||||
|
||||
Container3(std::array<size_t, 3> shape)
|
||||
: Container3(shape[0], shape[1], shape[2]) {}
|
||||
|
||||
Container3(std::array<size_t, 3> shape, T value)
|
||||
: Container3(shape[0], shape[1], shape[2], value) {}
|
||||
|
||||
Container3(size_t x, size_t y, size_t z)
|
||||
: shape_{x, y, z}, data_(new T[size()]{}) {}
|
||||
|
||||
Container3(size_t x, size_t y, size_t z, const T &value)
|
||||
: shape_{x, y, z}, data_(new T[size()]) {
|
||||
std::fill_n(data_, size(), value);
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
Container3(const Container3 &other) {
|
||||
shape_ = other.shape_;
|
||||
data_ = new T[size()];
|
||||
std::copy(other.data_, other.data_ + size(), data_);
|
||||
}
|
||||
|
||||
// Move constructor
|
||||
Container3(Container3 &&other) {
|
||||
shape_ = other.shape_;
|
||||
other.shape_ = {0, 0, 0};
|
||||
data_ = other.data_;
|
||||
other.data_ = nullptr;
|
||||
}
|
||||
|
||||
// Copy assignment
|
||||
Container3 &operator=(const Container3 &other) {
|
||||
if (this != &other) {
|
||||
Container3<T> tmp(other);
|
||||
std::swap(shape_, tmp.shape_);
|
||||
std::swap(data_, tmp.data_);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Move assignment
|
||||
Container3 &operator=(Container3 &&other) {
|
||||
if (this != &other) {
|
||||
shape_ = other.shape_;
|
||||
other.shape_ = {0, 0, 0};
|
||||
delete[] data_;
|
||||
data_ = other.data_;
|
||||
other.data_ = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~Container3() { delete[] data_; }
|
||||
|
||||
size_t size() const noexcept {
|
||||
return std::accumulate(std::begin(shape_), std::end(shape_), 1,
|
||||
std::multiplies<size_t>());
|
||||
}
|
||||
size_t size(size_t i) const noexcept { return shape_[i]; }
|
||||
|
||||
std::array<size_t, 3> shape() const noexcept { return shape_; }
|
||||
|
||||
T *data() noexcept { return data_; }
|
||||
const T *data() const noexcept { return data_; }
|
||||
|
||||
bool is_valid_index(size_t x, size_t y, size_t z) const noexcept {
|
||||
return x < shape_[0] && y < shape_[1] && z < shape_[2];
|
||||
}
|
||||
|
||||
// Will truncate if other is larger in any dimension
|
||||
// In the future move object out of other, rename function
|
||||
void copy_data(const Container3 &other) {
|
||||
for (size_t i = 0; i < std::min(size(0), other.size(0)); ++i) {
|
||||
for (size_t j = 0; j < std::min(size(1), other.size(1)); ++j) {
|
||||
for (size_t k = 0; k < std::min(size(2), other.size(2)); ++k) {
|
||||
(*this)(i, j, k) = other(i, j, k);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void move_data(Container3 &other) {
|
||||
for (size_t i = 0; i < std::min(size(0), other.size(0)); ++i) {
|
||||
for (size_t j = 0; j < std::min(size(1), other.size(1)); ++j) {
|
||||
for (size_t k = 0; k < std::min(size(2), other.size(2)); ++k) {
|
||||
(*this)(i, j, k) = std::move(other(i, j, k));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void resize(size_t x, size_t y, size_t z) {
|
||||
Container3<T> tmp(x, y, z);
|
||||
tmp.move_data(*this);
|
||||
*this = std::move(tmp);
|
||||
}
|
||||
|
||||
T &operator()(size_t x, size_t y, size_t z) noexcept {
|
||||
return data_[element_offset(x, y, z)];
|
||||
}
|
||||
const T &operator()(size_t x, size_t y, size_t z) const noexcept {
|
||||
return data_[element_offset(x, y, z)];
|
||||
}
|
||||
|
||||
// throws on out of bounds access
|
||||
const T &at(size_t x, size_t y, size_t z) const {
|
||||
if (!is_valid_index(x, y, z))
|
||||
throw std::runtime_error("Index error");
|
||||
return data_[element_offset(x, y, z)];
|
||||
}
|
||||
|
||||
T &at(size_t x, size_t y, size_t z) {
|
||||
return const_cast<T &>(
|
||||
static_cast<const Container3 &>(*this).at(x, y, z));
|
||||
}
|
||||
|
||||
T &operator[](size_t i) { return data_[i]; }
|
||||
const T &operator[](size_t i) const { return data_[i]; }
|
||||
|
||||
T *begin() { return data_; }
|
||||
|
||||
T *end() { return data_ + size(); }
|
||||
|
||||
void clear(){
|
||||
*this = Container3<T>();
|
||||
}
|
||||
|
||||
// reference to position, grow if needed, prefer resize and .at()
|
||||
T &at_can_grow(size_t x, size_t y, size_t z) {
|
||||
if (!is_valid_index(x, y, z)) {
|
||||
resize(std::max(x + 1, size(0)), std::max(y + 1, size(1)),
|
||||
std::max(z + 1, size(2)));
|
||||
}
|
||||
return data_[element_offset(x, y, z)];
|
||||
}
|
||||
|
||||
private:
|
||||
size_t element_offset(size_t x, size_t y, size_t z) const noexcept {
|
||||
return x * shape_[1] * shape_[2] + y * shape_[2] + z;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace sls
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "Container3.h"
|
||||
#include "Result.h"
|
||||
#include "SharedMemory.h"
|
||||
#include "logger.h"
|
||||
@ -22,7 +22,7 @@ class detectorData;
|
||||
#include <future>
|
||||
#include <numeric>
|
||||
|
||||
namespace sls{
|
||||
namespace sls {
|
||||
|
||||
class Module;
|
||||
class Receiver;
|
||||
@ -75,7 +75,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
* @param update true to update last user pid, date etc
|
||||
*/
|
||||
explicit DetectorImpl(int detector_id = 0, bool verify = true,
|
||||
bool update = true);
|
||||
bool update = true);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
@ -88,8 +88,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
std::vector<int> positions,
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (positions.empty() ||
|
||||
(positions.size() == 1 && positions[0] == -1)) {
|
||||
positions.resize(detectors.size());
|
||||
@ -116,8 +116,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
std::vector<int> positions,
|
||||
typename NonDeduced<CT>::type... Args) const {
|
||||
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (positions.empty() ||
|
||||
(positions.size() == 1 && positions[0] == -1)) {
|
||||
positions.resize(detectors.size());
|
||||
@ -144,8 +144,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
std::vector<int> positions,
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (positions.empty() ||
|
||||
(positions.size() == 1 && positions[0] == -1)) {
|
||||
positions.resize(detectors.size());
|
||||
@ -169,8 +169,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
std::vector<int> positions,
|
||||
typename NonDeduced<CT>::type... Args) const {
|
||||
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (positions.empty() ||
|
||||
(positions.size() == 1 && positions[0] == -1)) {
|
||||
positions.resize(detectors.size());
|
||||
@ -189,467 +189,101 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename RT, typename... CT>
|
||||
sls::Result<RT> Parallel1(RT (sls::Receiver::*somefunc)(CT...),
|
||||
std::vector<int> dPositions,
|
||||
std::vector<int> rxPositions,
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
std::vector<int> dPositions,
|
||||
std::vector<int> rxPositions,
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
|
||||
if (receivers.size() == 0)
|
||||
throw sls::RuntimeError("No receivers added");
|
||||
if (dPositions.empty() ||
|
||||
(dPositions.size() == 1 && dPositions[0] == -1)) {
|
||||
dPositions.resize(receivers.size());
|
||||
std::iota(begin(dPositions), end(dPositions), 0);
|
||||
}
|
||||
if (rxPositions.empty() ||
|
||||
(rxPositions.size() == 1 && rxPositions[0] == -1)) {
|
||||
rxPositions.resize(receivers[0].size());
|
||||
std::iota(begin(rxPositions), end(rxPositions), 0);
|
||||
}
|
||||
std::vector<std::future<RT>> futures;
|
||||
futures.reserve(dPositions.size() * rxPositions.size());
|
||||
for (size_t i : dPositions) {
|
||||
if (i >= receivers.size())
|
||||
throw sls::RuntimeError("Detector out of range");
|
||||
// each entry
|
||||
for (size_t j : rxPositions) {
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
receivers[i][j].get(), Args...));
|
||||
}
|
||||
}
|
||||
sls::Result<RT> result;
|
||||
result.reserve(dPositions.size() * rxPositions.size());
|
||||
for (auto &i : futures) {
|
||||
result.push_back(i.get());
|
||||
}
|
||||
return result;
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename RT, typename... CT>
|
||||
sls::Result<RT> Parallel1(RT (sls::Receiver::*somefunc)(CT...) const,
|
||||
std::vector<int> dPositions,
|
||||
std::vector<int> rxPositions,
|
||||
typename NonDeduced<CT>::type... Args) const {
|
||||
std::vector<int> dPositions,
|
||||
std::vector<int> rxPositions,
|
||||
typename NonDeduced<CT>::type... Args) const {
|
||||
|
||||
if (receivers.size() == 0)
|
||||
throw sls::RuntimeError("No receivers added");
|
||||
if (dPositions.empty() ||
|
||||
(dPositions.size() == 1 && dPositions[0] == -1)) {
|
||||
dPositions.resize(receivers.size());
|
||||
std::iota(begin(dPositions), end(dPositions), 0);
|
||||
}
|
||||
if (rxPositions.empty() ||
|
||||
(rxPositions.size() == 1 && rxPositions[0] == -1)) {
|
||||
rxPositions.resize(receivers[0].size());
|
||||
std::iota(begin(rxPositions), end(rxPositions), 0);
|
||||
}
|
||||
std::vector<std::future<RT>> futures;
|
||||
futures.reserve(dPositions.size() * rxPositions.size());
|
||||
for (size_t i : dPositions) {
|
||||
if (i >= receivers.size())
|
||||
throw sls::RuntimeError("Detector out of range");
|
||||
// each entry
|
||||
for (size_t j : rxPositions) {
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
receivers[i][j].get(), Args...));
|
||||
}
|
||||
}
|
||||
sls::Result<RT> result;
|
||||
result.reserve(dPositions.size() * rxPositions.size());
|
||||
for (auto &i : futures) {
|
||||
result.push_back(i.get());
|
||||
}
|
||||
return result;
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename... CT>
|
||||
void Parallel1(void (sls::Receiver::*somefunc)(CT...),
|
||||
std::vector<int> dPositions,
|
||||
std::vector<int> rxPositions,
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
|
||||
if (receivers.size() == 0)
|
||||
throw sls::RuntimeError("No receivers added");
|
||||
if (dPositions.empty() ||
|
||||
(dPositions.size() == 1 && dPositions[0] == -1)) {
|
||||
dPositions.resize(receivers.size());
|
||||
std::iota(begin(dPositions), end(dPositions), 0);
|
||||
}
|
||||
if (rxPositions.empty() ||
|
||||
(rxPositions.size() == 1 && rxPositions[0] == -1)) {
|
||||
rxPositions.resize(receivers[0].size());
|
||||
std::iota(begin(rxPositions), end(rxPositions), 0);
|
||||
}
|
||||
std::vector<std::future<void>> futures;
|
||||
futures.reserve(dPositions.size() * rxPositions.size());
|
||||
for (size_t i : dPositions) {
|
||||
if (i >= receivers.size())
|
||||
throw sls::RuntimeError("Detector out of range");
|
||||
// each entry
|
||||
for (size_t j : rxPositions) {
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
receivers[i][j].get(), Args...));
|
||||
}
|
||||
}
|
||||
for (auto &i : futures) {
|
||||
i.get();
|
||||
}
|
||||
}
|
||||
std::vector<int> dPositions, std::vector<int> rxPositions,
|
||||
typename NonDeduced<CT>::type... Args) {}
|
||||
|
||||
template <typename... CT>
|
||||
void Parallel1(void (sls::Receiver::*somefunc)(CT...) const,
|
||||
std::vector<int> dPositions,
|
||||
std::vector<int> rxPositions,
|
||||
typename NonDeduced<CT>::type... Args) const {
|
||||
|
||||
if (receivers.size() == 0)
|
||||
throw sls::RuntimeError("No receivers added");
|
||||
if (dPositions.empty() ||
|
||||
(dPositions.size() == 1 && dPositions[0] == -1)) {
|
||||
dPositions.resize(receivers.size());
|
||||
std::iota(begin(dPositions), end(dPositions), 0);
|
||||
}
|
||||
if (rxPositions.empty() ||
|
||||
(rxPositions.size() == 1 && rxPositions[0] == -1)) {
|
||||
rxPositions.resize(receivers[0].size());
|
||||
std::iota(begin(rxPositions), end(rxPositions), 0);
|
||||
}
|
||||
std::vector<std::future<void>> futures;
|
||||
futures.reserve(dPositions.size() * rxPositions.size());
|
||||
for (size_t i : dPositions) {
|
||||
if (i >= receivers.size())
|
||||
throw sls::RuntimeError("Detector out of range");
|
||||
// each entry
|
||||
for (size_t j : rxPositions) {
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
receivers[i][j].get(), Args...));
|
||||
}
|
||||
}
|
||||
for (auto &i : futures) {
|
||||
i.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
std::vector<int> dPositions, std::vector<int> rxPositions,
|
||||
typename NonDeduced<CT>::type... Args) const {}
|
||||
|
||||
template <typename RT, typename... CT>
|
||||
sls::Result<RT> Parallel2(RT (sls::Receiver::*somefunc)(CT...),
|
||||
std::vector<int> dPositions,
|
||||
std::vector<int> rxPositions,
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
std::vector<int> dPositions,
|
||||
std::vector<int> rxPositions,
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
|
||||
if (receivers2.size() == 0)
|
||||
throw sls::RuntimeError("No receivers2 added");
|
||||
if (dPositions.empty() ||
|
||||
(dPositions.size() == 1 && dPositions[0] == -1)) {
|
||||
dPositions.resize(receivers2.size());
|
||||
std::iota(begin(dPositions), end(dPositions), 0);
|
||||
}
|
||||
if (rxPositions.empty() ||
|
||||
(rxPositions.size() == 1 && rxPositions[0] == -1)) {
|
||||
rxPositions.resize(receivers2[0].size());
|
||||
std::iota(begin(rxPositions), end(rxPositions), 0);
|
||||
}
|
||||
std::vector<std::future<RT>> futures;
|
||||
futures.reserve(dPositions.size() * rxPositions.size());
|
||||
for (size_t i : dPositions) {
|
||||
if (i >= receivers2.size())
|
||||
throw sls::RuntimeError("Detector out of range");
|
||||
// each entry
|
||||
for (size_t j : rxPositions) {
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
receivers2[i][j].get(), Args...));
|
||||
}
|
||||
}
|
||||
sls::Result<RT> result;
|
||||
result.reserve(dPositions.size() * rxPositions.size());
|
||||
for (auto &i : futures) {
|
||||
result.push_back(i.get());
|
||||
}
|
||||
return result;
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename RT, typename... CT>
|
||||
sls::Result<RT> Parallel2(RT (sls::Receiver::*somefunc)(CT...) const,
|
||||
std::vector<int> dPositions,
|
||||
std::vector<int> rxPositions,
|
||||
typename NonDeduced<CT>::type... Args) const {
|
||||
std::vector<int> dPositions,
|
||||
std::vector<int> rxPositions,
|
||||
typename NonDeduced<CT>::type... Args) const {
|
||||
|
||||
if (receivers2.size() == 0)
|
||||
throw sls::RuntimeError("No receivers2 added");
|
||||
if (dPositions.empty() ||
|
||||
(dPositions.size() == 1 && dPositions[0] == -1)) {
|
||||
dPositions.resize(receivers2.size());
|
||||
std::iota(begin(dPositions), end(dPositions), 0);
|
||||
}
|
||||
if (rxPositions.empty() ||
|
||||
(rxPositions.size() == 1 && rxPositions[0] == -1)) {
|
||||
rxPositions.resize(receivers2[0].size());
|
||||
std::iota(begin(rxPositions), end(rxPositions), 0);
|
||||
}
|
||||
std::vector<std::future<RT>> futures;
|
||||
futures.reserve(dPositions.size() * rxPositions.size());
|
||||
for (size_t i : dPositions) {
|
||||
if (i >= receivers2.size())
|
||||
throw sls::RuntimeError("Detector out of range");
|
||||
// each entry
|
||||
for (size_t j : rxPositions) {
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
receivers2[i][j].get(), Args...));
|
||||
}
|
||||
}
|
||||
sls::Result<RT> result;
|
||||
result.reserve(dPositions.size() * rxPositions.size());
|
||||
for (auto &i : futures) {
|
||||
result.push_back(i.get());
|
||||
}
|
||||
return result;
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename... CT>
|
||||
void Parallel2(void (sls::Receiver::*somefunc)(CT...),
|
||||
std::vector<int> dPositions,
|
||||
std::vector<int> rxPositions,
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
|
||||
if (receivers2.size() == 0)
|
||||
throw sls::RuntimeError("No receivers2 added");
|
||||
if (dPositions.empty() ||
|
||||
(dPositions.size() == 1 && dPositions[0] == -1)) {
|
||||
dPositions.resize(receivers2.size());
|
||||
std::iota(begin(dPositions), end(dPositions), 0);
|
||||
}
|
||||
if (rxPositions.empty() ||
|
||||
(rxPositions.size() == 1 && rxPositions[0] == -1)) {
|
||||
rxPositions.resize(receivers2[0].size());
|
||||
std::iota(begin(rxPositions), end(rxPositions), 0);
|
||||
}
|
||||
std::vector<std::future<void>> futures;
|
||||
futures.reserve(dPositions.size() * rxPositions.size());
|
||||
for (size_t i : dPositions) {
|
||||
if (i >= receivers2.size())
|
||||
throw sls::RuntimeError("Detector out of range");
|
||||
// each entry
|
||||
for (size_t j : rxPositions) {
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
receivers2[i][j].get(), Args...));
|
||||
}
|
||||
}
|
||||
for (auto &i : futures) {
|
||||
i.get();
|
||||
}
|
||||
}
|
||||
std::vector<int> dPositions, std::vector<int> rxPositions,
|
||||
typename NonDeduced<CT>::type... Args) {}
|
||||
|
||||
template <typename... CT>
|
||||
void Parallel2(void (sls::Receiver::*somefunc)(CT...) const,
|
||||
std::vector<int> dPositions,
|
||||
std::vector<int> rxPositions,
|
||||
typename NonDeduced<CT>::type... Args) const {
|
||||
|
||||
if (receivers2.size() == 0)
|
||||
throw sls::RuntimeError("No receivers2 added");
|
||||
if (dPositions.empty() ||
|
||||
(dPositions.size() == 1 && dPositions[0] == -1)) {
|
||||
dPositions.resize(receivers2.size());
|
||||
std::iota(begin(dPositions), end(dPositions), 0);
|
||||
}
|
||||
if (rxPositions.empty() ||
|
||||
(rxPositions.size() == 1 && rxPositions[0] == -1)) {
|
||||
rxPositions.resize(receivers2[0].size());
|
||||
std::iota(begin(rxPositions), end(rxPositions), 0);
|
||||
}
|
||||
std::vector<std::future<void>> futures;
|
||||
futures.reserve(dPositions.size() * rxPositions.size());
|
||||
for (size_t i : dPositions) {
|
||||
if (i >= receivers2.size())
|
||||
throw sls::RuntimeError("Detector out of range");
|
||||
// each entry
|
||||
for (size_t j : rxPositions) {
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
receivers2[i][j].get(), Args...));
|
||||
}
|
||||
}
|
||||
for (auto &i : futures) {
|
||||
i.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
std::vector<int> dPositions, std::vector<int> rxPositions,
|
||||
typename NonDeduced<CT>::type... Args) const {}
|
||||
|
||||
// for all , but dont complain if receiver2 doesnt exist
|
||||
template <typename RT, typename... CT>
|
||||
sls::Result<RT> Parallel3(RT (sls::Receiver::*somefunc)(CT...),
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
|
||||
if (receivers.size() == 0)
|
||||
throw sls::RuntimeError("No receivers added");
|
||||
std::vector<int> dPositions;
|
||||
dPositions.resize(receivers.size());
|
||||
std::iota(begin(dPositions), end(dPositions), 0);
|
||||
std::vector<int> rxPositions;
|
||||
rxPositions.resize(receivers[0].size());
|
||||
std::iota(begin(rxPositions), end(rxPositions), 0);
|
||||
// multiply by 2 if receivers2 exists
|
||||
size_t futureSize = dPositions.size() * rxPositions.size() *
|
||||
(receivers2.size() > 0 ? 2 : 1);
|
||||
std::vector<std::future<RT>> futures;
|
||||
futures.reserve(futureSize);
|
||||
for (size_t i : dPositions) {
|
||||
// each entry
|
||||
for (size_t j : rxPositions) {
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
receivers[i][j].get(), Args...));
|
||||
if (receivers2.size()) {
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
receivers2[i][j].get(), Args...));
|
||||
}
|
||||
}
|
||||
}
|
||||
sls::Result<RT> result;
|
||||
result.reserve(futureSize);
|
||||
for (auto &i : futures) {
|
||||
result.push_back(i.get());
|
||||
}
|
||||
return result;
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename RT, typename... CT>
|
||||
sls::Result<RT> Parallel3(RT (sls::Receiver::*somefunc)(CT...) const,
|
||||
typename NonDeduced<CT>::type... Args) const {
|
||||
typename NonDeduced<CT>::type... Args) const {
|
||||
|
||||
if (receivers.size() == 0)
|
||||
throw sls::RuntimeError("No receivers added");
|
||||
std::vector<int> dPositions;
|
||||
dPositions.resize(receivers.size());
|
||||
std::iota(begin(dPositions), end(dPositions), 0);
|
||||
std::vector<int> rxPositions;
|
||||
rxPositions.resize(receivers[0].size());
|
||||
std::iota(begin(rxPositions), end(rxPositions), 0);
|
||||
// multiply by 2 if receivers2 exists
|
||||
size_t futureSize = dPositions.size() * rxPositions.size() *
|
||||
(receivers2.size() > 0 ? 2 : 1);
|
||||
std::vector<std::future<RT>> futures;
|
||||
futures.reserve(futureSize);
|
||||
for (size_t i : dPositions) {
|
||||
// each entry
|
||||
for (size_t j : rxPositions) {
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
receivers[i][j].get(), Args...));
|
||||
if (receivers2.size()) {
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
receivers2[i][j].get(), Args...));
|
||||
}
|
||||
}
|
||||
}
|
||||
sls::Result<RT> result;
|
||||
result.reserve(futureSize);
|
||||
for (auto &i : futures) {
|
||||
result.push_back(i.get());
|
||||
}
|
||||
return result;
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename... CT>
|
||||
void Parallel3(void (sls::Receiver::*somefunc)(CT...),
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
|
||||
if (receivers.size() == 0)
|
||||
throw sls::RuntimeError("No receivers added");
|
||||
std::vector<int> dPositions;
|
||||
dPositions.resize(receivers.size());
|
||||
std::iota(begin(dPositions), end(dPositions), 0);
|
||||
std::vector<int> rxPositions;
|
||||
rxPositions.resize(receivers[0].size());
|
||||
std::iota(begin(rxPositions), end(rxPositions), 0);
|
||||
// multiply by 2 if receivers2 exists
|
||||
size_t futureSize = dPositions.size() * rxPositions.size() *
|
||||
(receivers2.size() > 0 ? 2 : 1);
|
||||
std::vector<std::future<void>> futures;
|
||||
futures.reserve(futureSize);
|
||||
for (size_t i : dPositions) {
|
||||
// each entry
|
||||
for (size_t j : rxPositions) {
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
receivers[i][j].get(), Args...));
|
||||
if (receivers2.size()) {
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
receivers2[i][j].get(), Args...));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto &i : futures) {
|
||||
i.get();
|
||||
}
|
||||
}
|
||||
typename NonDeduced<CT>::type... Args) {}
|
||||
|
||||
template <typename... CT>
|
||||
void Parallel3(void (sls::Receiver::*somefunc)(CT...) const,
|
||||
typename NonDeduced<CT>::type... Args) const {
|
||||
|
||||
if (receivers.size() == 0)
|
||||
throw sls::RuntimeError("No receivers added");
|
||||
std::vector<int> dPositions;
|
||||
dPositions.resize(receivers.size());
|
||||
std::iota(begin(dPositions), end(dPositions), 0);
|
||||
std::vector<int> rxPositions;
|
||||
rxPositions.resize(receivers[0].size());
|
||||
std::iota(begin(rxPositions), end(rxPositions), 0);
|
||||
// multiply by 2 if receivers2 exists
|
||||
size_t futureSize = dPositions.size() * rxPositions.size() *
|
||||
(receivers2.size() > 0 ? 2 : 1);
|
||||
std::vector<std::future<void>> futures;
|
||||
futures.reserve(futureSize);
|
||||
for (size_t i : dPositions) {
|
||||
// each entry
|
||||
for (size_t j : rxPositions) {
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
receivers[i][j].get(), Args...));
|
||||
if (receivers2.size()) {
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
receivers2[i][j].get(), Args...));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto &i : futures) {
|
||||
i.get();
|
||||
}
|
||||
}
|
||||
|
||||
typename NonDeduced<CT>::type... Args) const {}
|
||||
|
||||
/** set acquiring flag in shared memory */
|
||||
void setAcquiringFlag(bool flag);
|
||||
void setAcquiringFlag(bool flag);
|
||||
|
||||
/** return detector shared memory ID */
|
||||
int getDetectorId() const;
|
||||
|
||||
/** Free specific shared memory from the command line without creating object */
|
||||
/** Free specific shared memory from the command line without creating
|
||||
* object */
|
||||
static void freeSharedMemory(int detectorId, int moduleId = -1);
|
||||
|
||||
/** Free all modules from current multi Id shared memory and delete members */
|
||||
void freeSharedMemory();
|
||||
/** Free all modules from current multi Id shared memory and delete members
|
||||
*/
|
||||
void freeSharedMemory();
|
||||
|
||||
/** Get user details of shared memory */
|
||||
std::string getUserDetails();
|
||||
std::string getUserDetails();
|
||||
|
||||
bool getInitialChecks() const;
|
||||
|
||||
@ -664,29 +298,29 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
*/
|
||||
void setVirtualDetectorServers(const int numdet, const int port);
|
||||
|
||||
void setHostname(const std::vector<std::string> &name);
|
||||
void setHostname(const std::vector<std::string> &name);
|
||||
void setHostname(const std::vector<std::string> &name,
|
||||
const std::vector<int> &port);
|
||||
const std::vector<int> &port);
|
||||
|
||||
int getNumberofReceiversPerModule() const;
|
||||
void initReceiver(const int udpInterface);
|
||||
bool isReceiverInitialized(const int udpInterface);
|
||||
void removeReceivers(const int udpInterface);
|
||||
void configureReceiver(const int udpInterface, Positions pos,
|
||||
const std::string &hostname);
|
||||
void configureReceiver(const int udpInterface, int module_id,
|
||||
const std::string &hostname, const int port);
|
||||
void configureReceiver(const int udpInterface, Positions pos,
|
||||
const std::string &hostname);
|
||||
void configureReceiver(const int udpInterface, int module_id,
|
||||
const std::string &hostname, const int port);
|
||||
|
||||
/** Gets the total number of detectors */
|
||||
int size() const;
|
||||
|
||||
slsDetectorDefs::xy getNumberOfDetectors() const;
|
||||
slsDetectorDefs::xy getNumberOfDetectors() const;
|
||||
|
||||
slsDetectorDefs::xy getNumberOfChannels() const;
|
||||
slsDetectorDefs::xy getNumberOfChannels() const;
|
||||
|
||||
/** Must be set before setting hostname
|
||||
* Sets maximum number of channels of all sls detectors */
|
||||
void setNumberOfChannels(const slsDetectorDefs::xy c);
|
||||
void setNumberOfChannels(const slsDetectorDefs::xy c);
|
||||
|
||||
/** [Eiger][Jungfrau] */
|
||||
bool getGapPixelsinCallback() const;
|
||||
@ -729,7 +363,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
* index, loops for measurements, calls required call backs.
|
||||
* @returns OK or FAIL depending on if it already started
|
||||
*/
|
||||
int acquire();
|
||||
int acquire();
|
||||
|
||||
/**
|
||||
* Combines data from all readouts and gives it to the gui
|
||||
@ -741,7 +375,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
* Convert raw file
|
||||
* [Jungfrau][Ctb] from pof file
|
||||
* [Mythen3][Gotthard2] from rbf file
|
||||
* @param fname name of pof/rbf file
|
||||
* @param fname name of pof/rbf file
|
||||
* @param fpgasrc pointer in memory to read programming file to
|
||||
* @returns file size
|
||||
*/
|
||||
@ -808,8 +442,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
* @param nPixelsy number of pixels in Y axis (updated)
|
||||
* @returns total data bytes for updated image
|
||||
*/
|
||||
int InsertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr,
|
||||
int &nPixelsx, int &nPixelsy);
|
||||
int InsertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr,
|
||||
int &nPixelsx, int &nPixelsy);
|
||||
|
||||
void printProgress(double progress);
|
||||
|
||||
@ -843,10 +477,13 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
std::vector<std::unique_ptr<sls::Module>> detectors;
|
||||
|
||||
/** pointers to the Receiver structures, each row for a module */
|
||||
std::vector<std::vector<std::unique_ptr<sls::Receiver>>> receivers;
|
||||
// std::vector<std::vector<std::unique_ptr<sls::Receiver>>> receivers;
|
||||
/** for the second udp port [Eiger][Jungfrau] */
|
||||
std::vector<std::vector<std::unique_ptr<sls::Receiver>>> receivers2;
|
||||
|
||||
sls::Container3<std::unique_ptr<sls::Receiver>> receivers;
|
||||
|
||||
// sls::Container3<Receiver> receivers;
|
||||
|
||||
/** data streaming (down stream) enabled in client (zmq sckets created) */
|
||||
bool client_downstream{false};
|
||||
@ -881,4 +518,4 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
void *pCallbackArg{nullptr};
|
||||
};
|
||||
|
||||
}//namespace sls
|
||||
} // namespace sls
|
53
slsDetectorSoftware/src/MaskGenerator.h
Normal file
53
slsDetectorSoftware/src/MaskGenerator.h
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
#include "Container3.h"
|
||||
#include <initializer_list>
|
||||
#include <vector>
|
||||
|
||||
namespace sls{
|
||||
|
||||
class MaskGenerator {
|
||||
enum class OperationMode { ALL, ROW, SINGLE };
|
||||
|
||||
OperationMode mode_{OperationMode::ALL};
|
||||
std::vector<size_t> idx0;
|
||||
size_t x_{0};
|
||||
size_t y_{0};
|
||||
size_t z_{0};
|
||||
|
||||
public:
|
||||
MaskGenerator(){};
|
||||
explicit MaskGenerator(size_t i) : mode_(OperationMode::SINGLE), x_(i) {}
|
||||
MaskGenerator(size_t i, size_t j)
|
||||
: mode_(OperationMode::SINGLE), x_(i), y_(j) {}
|
||||
MaskGenerator(size_t i, size_t j, size_t k)
|
||||
: mode_(OperationMode::SINGLE), x_(i), y_(j), z_(k) {}
|
||||
|
||||
explicit MaskGenerator(const std::vector<size_t> vec)
|
||||
: mode_(OperationMode::ROW), idx0(vec) {}
|
||||
|
||||
template <typename T> Container3<bool> mask(const Container3<T>& cont) {
|
||||
return mask(cont.shape());
|
||||
}
|
||||
Container3<bool> mask(std::array<size_t, 3> shape) {
|
||||
Container3<bool> m(shape);
|
||||
|
||||
switch (mode_) {
|
||||
case OperationMode::ALL:
|
||||
for (auto &item : m)
|
||||
item = true;
|
||||
break;
|
||||
case OperationMode::ROW:
|
||||
for (auto i : idx0) {
|
||||
m(i, 0, 0) = true;
|
||||
}
|
||||
break;
|
||||
case OperationMode::SINGLE:
|
||||
m(x_, y_, z_) = true;
|
||||
break;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
Container3<bool> mask() { return {}; }
|
||||
};
|
||||
|
||||
} // namespace sls
|
81
slsDetectorSoftware/src/Parallel.h
Normal file
81
slsDetectorSoftware/src/Parallel.h
Normal file
@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
#include "Container3.h"
|
||||
#include "Result.h"
|
||||
#include <future>
|
||||
#include <vector>
|
||||
|
||||
/*
|
||||
Can't use std::forward<CT>(Args)...) in parallel call since it would
|
||||
end up moving temporary objects into the first called function
|
||||
leaving the other ones with moved from args.
|
||||
*/
|
||||
|
||||
namespace experimental{
|
||||
|
||||
template <class CT> struct NonDeduced { using type = CT; };
|
||||
|
||||
template <typename RT, typename Class, typename... CT>
|
||||
sls::Result<RT>
|
||||
Parallel(RT (Class::*func)(CT...) const, const Container3<Class> &objects,
|
||||
const Container3<bool> &mask, typename NonDeduced<CT>::type... Args) {
|
||||
std::vector<std::future<RT>> futures;
|
||||
for (size_t i = 0; i < objects.size(); ++i) {
|
||||
if (mask[i])
|
||||
futures.push_back(
|
||||
std::async(std::launch::async, func, &objects[i], Args...));
|
||||
}
|
||||
sls::Result<RT> result;
|
||||
for (auto &f : futures) {
|
||||
result.push_back(f.get());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename RT, typename Class, typename... CT>
|
||||
sls::Result<RT>
|
||||
Parallel(RT (Class::*func)(CT...), const Container3<Class> &objects,
|
||||
const Container3<bool> &mask, typename NonDeduced<CT>::type... Args) {
|
||||
std::vector<std::future<RT>> futures;
|
||||
for (size_t i = 0; i < objects.size(); ++i) {
|
||||
if (mask[i])
|
||||
futures.push_back(
|
||||
std::async(std::launch::async, func, &objects[i], Args...));
|
||||
}
|
||||
sls::Result<RT> result;
|
||||
for (auto &f : futures) {
|
||||
result.push_back(f.get());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Class, typename... CT>
|
||||
void Parallel(void (Class::*func)(CT...) const,
|
||||
const Container3<Class> &objects, const Container3<bool> &mask,
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
std::vector<std::future<void>> futures;
|
||||
for (size_t i = 0; i < objects.size(); ++i) {
|
||||
if (mask[i])
|
||||
futures.push_back(
|
||||
std::async(std::launch::async, func, &objects[i], Args...));
|
||||
}
|
||||
for (auto &f : futures) {
|
||||
f.get();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Class, typename... CT>
|
||||
void Parallel(void (Class::*func)(CT...), const Container3<Class> &objects,
|
||||
const Container3<bool> &mask,
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
|
||||
std::vector<std::future<void>> futures;
|
||||
for (size_t i = 0; i < objects.size(); ++i) {
|
||||
if (mask[i])
|
||||
futures.push_back(
|
||||
std::async(std::launch::async, func, &objects[i], Args...));
|
||||
}
|
||||
for (auto &f : futures)
|
||||
f.get();
|
||||
}
|
||||
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
#include "SharedMemory.h"
|
||||
#include "logger.h"
|
||||
#include "sls_detector_defs.h"
|
||||
#include "network_utils.h"
|
||||
#include "sls_detector_defs.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
@ -11,45 +11,52 @@
|
||||
namespace sls {
|
||||
struct sharedReceiver {
|
||||
|
||||
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/
|
||||
int shmversion;
|
||||
char hostname[MAX_STR_LENGTH];
|
||||
int tcpPort;
|
||||
/** END OF FIXED PATTERN -----------------------------------------------*/
|
||||
|
||||
int stoppedFlag;
|
||||
int zmqPort;
|
||||
sls::IpAddr zmqIp;
|
||||
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/
|
||||
int shmversion;
|
||||
char hostname[MAX_STR_LENGTH];
|
||||
int tcpPort;
|
||||
/** END OF FIXED PATTERN -----------------------------------------------*/
|
||||
|
||||
int stoppedFlag;
|
||||
int zmqPort;
|
||||
sls::IpAddr zmqIp;
|
||||
};
|
||||
|
||||
class Receiver : public virtual slsDetectorDefs {
|
||||
public:
|
||||
const int receiverId{0};
|
||||
const int interfaceId{0};
|
||||
const int moduleId{0};
|
||||
std::string indexString;
|
||||
mutable sls::SharedMemory<sharedReceiver> shm{0, 0, 0, 0};
|
||||
|
||||
public:
|
||||
static size_t getNumReceivers();
|
||||
|
||||
|
||||
// create shm
|
||||
explicit Receiver(int detector_id, int module_id, int interface_id,
|
||||
int receiver_id, int tcp_port = 0, std::string hostname = "",
|
||||
int zmq_port = 0);
|
||||
int receiver_id, int tcp_port = 0,
|
||||
std::string hostname = "", int zmq_port = 0);
|
||||
// open shm
|
||||
explicit Receiver(int detector_id, int module_id, int interface_id,
|
||||
int receiver_id, bool verify);
|
||||
int receiver_id, bool verify);
|
||||
|
||||
virtual ~Receiver();
|
||||
|
||||
void createIndexString();
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* Configuration *
|
||||
* *
|
||||
* ************************************************/
|
||||
* *
|
||||
* Configuration *
|
||||
* *
|
||||
* ************************************************/
|
||||
/**
|
||||
* Free shared memory and delete shared memory structure
|
||||
* occupied by the sharedReceiver structure
|
||||
* Is only safe to call if one deletes the Receiver object afterward
|
||||
* and frees multi shared memory/updates
|
||||
* thisMultiDetector->numberOfReceivers
|
||||
*/
|
||||
* Free shared memory and delete shared memory structure
|
||||
* occupied by the sharedReceiver structure
|
||||
* Is only safe to call if one deletes the Receiver object afterward
|
||||
* and frees multi shared memory/updates
|
||||
* thisMultiDetector->numberOfReceivers
|
||||
*/
|
||||
void freeSharedMemory();
|
||||
std::string getHostname() const;
|
||||
void setHostname(const std::string &hostname);
|
||||
@ -60,10 +67,10 @@ class Receiver : public virtual slsDetectorDefs {
|
||||
int64_t getSoftwareVersion() const;
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* Acquisition *
|
||||
* *
|
||||
* ************************************************/
|
||||
* *
|
||||
* Acquisition *
|
||||
* *
|
||||
* ************************************************/
|
||||
void start();
|
||||
void stop();
|
||||
slsDetectorDefs::runStatus getStatus() const;
|
||||
@ -75,10 +82,10 @@ class Receiver : public virtual slsDetectorDefs {
|
||||
uint64_t getCurrentFrameIndex() const;
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* Network Configuration (Detector<->Receiver) *
|
||||
* *
|
||||
* ************************************************/
|
||||
* *
|
||||
* Network Configuration (Detector<->Receiver) *
|
||||
* *
|
||||
* ************************************************/
|
||||
sls::MacAddr setUDPIP(const sls::IpAddr ip);
|
||||
void setUDPPort(const int udpport);
|
||||
int64_t getUDPSocketBufferSize() const;
|
||||
@ -86,10 +93,10 @@ class Receiver : public virtual slsDetectorDefs {
|
||||
int64_t getRealUDPSocketBufferSize() const;
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* ZMQ Streaming Parameters (Receiver<->Client)*
|
||||
* *
|
||||
* ************************************************/
|
||||
* *
|
||||
* ZMQ Streaming Parameters (Receiver<->Client)*
|
||||
* *
|
||||
* ************************************************/
|
||||
bool getZmq() const;
|
||||
void setZmq(const bool enable);
|
||||
int getZmqFrequency() const;
|
||||
@ -97,7 +104,7 @@ class Receiver : public virtual slsDetectorDefs {
|
||||
void setZmqFrequency(const int freq);
|
||||
int getZmqTimer() const;
|
||||
void setZmqTimer(const int time_in_ms = 200);
|
||||
int getZmqPort() const;
|
||||
int getZmqPort() const;
|
||||
void setZmqPort(int port);
|
||||
sls::IpAddr getZmqIP() const;
|
||||
void setZmqIP(const sls::IpAddr ip);
|
||||
@ -106,17 +113,15 @@ class Receiver : public virtual slsDetectorDefs {
|
||||
sls::IpAddr getClientZmqIP() const;
|
||||
void setClientZmqIP(const sls::IpAddr ip);
|
||||
|
||||
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* Receiver Parameters *
|
||||
* *
|
||||
* ************************************************/
|
||||
* *
|
||||
* Receiver Parameters *
|
||||
* *
|
||||
* ************************************************/
|
||||
bool getLock() const;
|
||||
void setLock(const bool lock);
|
||||
sls::IpAddr getLastClientIP() const;
|
||||
void exitServer();
|
||||
void exitServer();
|
||||
|
||||
bool getDeactivatedPaddingMode() const;
|
||||
void setDeactivatedPaddingMode(const bool padding);
|
||||
@ -132,10 +137,10 @@ class Receiver : public virtual slsDetectorDefs {
|
||||
void setSilentMode(const bool value);
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* File *
|
||||
* *
|
||||
* ************************************************/
|
||||
* *
|
||||
* File *
|
||||
* *
|
||||
* ************************************************/
|
||||
std::string getFilePath() const;
|
||||
void setFilePath(const std::string &path);
|
||||
std::string getFileName() const;
|
||||
@ -156,10 +161,10 @@ class Receiver : public virtual slsDetectorDefs {
|
||||
void setFileOverWrite(const bool value);
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* Detector Parameters *
|
||||
* *
|
||||
* ************************************************/
|
||||
* *
|
||||
* Detector Parameters *
|
||||
* *
|
||||
* ************************************************/
|
||||
void setNumberOfFrames(const int64_t value);
|
||||
void setNumberOfTriggers(const int64_t value);
|
||||
void setNumberOfBursts(const int64_t value);
|
||||
@ -181,7 +186,7 @@ class Receiver : public virtual slsDetectorDefs {
|
||||
void clearROI();
|
||||
std::vector<int> getDbitList() const;
|
||||
/** digital data bits enable (CTB only) */
|
||||
void setDbitList(const std::vector<int>& list);
|
||||
void setDbitList(const std::vector<int> &list);
|
||||
int getDbitOffset() const;
|
||||
/** Set digital data offset in bytes (CTB only) */
|
||||
void setDbitOffset(const int value);
|
||||
@ -190,22 +195,22 @@ class Receiver : public virtual slsDetectorDefs {
|
||||
void setCounterMask(const uint32_t mask);
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* Json *
|
||||
* *
|
||||
* ************************************************/
|
||||
* *
|
||||
* Json *
|
||||
* *
|
||||
* ************************************************/
|
||||
|
||||
std::map<std::string, std::string> getAdditionalJsonHeader() const;
|
||||
/** empty vector deletes entire additional json header */
|
||||
void setAdditionalJsonHeader(const std::map<std::string, std::string> &jsonHeader);
|
||||
void setAdditionalJsonHeader(
|
||||
const std::map<std::string, std::string> &jsonHeader);
|
||||
std::string getAdditionalJsonParameter(const std::string &key) const;
|
||||
/** Sets the value for the additional json header parameter key if found,
|
||||
/** Sets the value for the additional json header parameter key if found,
|
||||
else append it. If value empty, then deletes parameter */
|
||||
void setAdditionalJsonParameter(const std::string &key, const std::string &value);
|
||||
void setAdditionalJsonParameter(const std::string &key,
|
||||
const std::string &value);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
private:
|
||||
void sendToReceiver(int fnum, const void *args, size_t args_size,
|
||||
void *retval, size_t retval_size);
|
||||
|
||||
@ -230,11 +235,9 @@ class Receiver : public virtual slsDetectorDefs {
|
||||
template <typename Ret>
|
||||
void sendToReceiver(int fnum, std::nullptr_t, Ret &retval) const;
|
||||
|
||||
template <typename Ret>
|
||||
Ret sendToReceiver(int fnum);
|
||||
template <typename Ret> Ret sendToReceiver(int fnum);
|
||||
|
||||
template <typename Ret>
|
||||
Ret sendToReceiver(int fnum) const;
|
||||
template <typename Ret> Ret sendToReceiver(int fnum) const;
|
||||
|
||||
template <typename Ret, typename Arg>
|
||||
Ret sendToReceiver(int fnum, const Arg &args);
|
||||
@ -243,11 +246,6 @@ class Receiver : public virtual slsDetectorDefs {
|
||||
Ret sendToReceiver(int fnum, const Arg &args) const;
|
||||
|
||||
void checkVersionCompatibility();
|
||||
const int receiverId{0};
|
||||
const int interfaceId{0};
|
||||
const int moduleId{0};
|
||||
std::string indexString;
|
||||
mutable sls::SharedMemory<sharedReceiver> shm{0, 0, 0, 0};
|
||||
};
|
||||
|
||||
} // sls
|
||||
} // namespace sls
|
@ -13,6 +13,9 @@ target_sources(tests PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-CmdProxy-global.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-Result.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-CmdParser.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-Container3.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-MaskGenerator.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-Receiver.cpp
|
||||
)
|
||||
|
||||
target_include_directories(tests PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../src>")
|
@ -144,10 +144,10 @@ TEST_CASE("rx_printconfig", "[.cmd][.rx][.new]") {
|
||||
|
||||
/* Receiver Config */
|
||||
|
||||
TEST_CASE("rx_hostname", "[.cmd][.rx][.new]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
auto prev_val = det.getRxHostname();
|
||||
// TEST_CASE("rx_hostname", "[.cmd][.rx][.new]") {
|
||||
// Detector det;
|
||||
// CmdProxy proxy(&det);
|
||||
// auto prev_val = det.getRxHostname();
|
||||
|
||||
// Cannot set rx_hostname (will reset parameters in rxr and no shm variables to update)
|
||||
// {
|
||||
@ -168,37 +168,37 @@ TEST_CASE("rx_hostname", "[.cmd][.rx][.new]") {
|
||||
// for (int i = 0; i != det.size(); ++i) {
|
||||
// det.setRxHostname(prev_val[i], {i});
|
||||
// }
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_hostname", {}, 0, GET, oss);
|
||||
REQUIRE(oss.str() == "rx_hostname " + prev_val[0] + "\n");
|
||||
}
|
||||
}
|
||||
// {
|
||||
// std::ostringstream oss;
|
||||
// proxy.Call("rx_hostname", {}, 0, GET, oss);
|
||||
// REQUIRE(oss.str() == "rx_hostname " + prev_val[0] + "\n");
|
||||
// }
|
||||
// }
|
||||
|
||||
TEST_CASE("rx_tcpport", "[.cmd][.rx][.new]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
auto prev_val = det.getRxPort();
|
||||
// TEST_CASE("rx_tcpport", "[.cmd][.rx][.new]") {
|
||||
// Detector det;
|
||||
// CmdProxy proxy(&det);
|
||||
// auto prev_val = det.getRxPort();
|
||||
|
||||
int port = 3500;
|
||||
proxy.Call("rx_tcpport", {std::to_string(port)}, -1, PUT);
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_tcpport", {}, i, GET, oss);
|
||||
REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n');
|
||||
}
|
||||
REQUIRE_THROWS(proxy.Call("rx_tcpport", {"15"}, -1, PUT));
|
||||
port = 5754;
|
||||
proxy.Call("rx_tcpport", {std::to_string(port)}, -1, PUT);
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_tcpport", {}, i, GET, oss);
|
||||
REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n');
|
||||
}
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setRxPort(prev_val[i], i);
|
||||
}
|
||||
}
|
||||
// int port = 3500;
|
||||
// proxy.Call("rx_tcpport", {std::to_string(port)}, -1, PUT);
|
||||
// for (int i = 0; i != det.size(); ++i) {
|
||||
// std::ostringstream oss;
|
||||
// proxy.Call("rx_tcpport", {}, i, GET, oss);
|
||||
// REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n');
|
||||
// }
|
||||
// REQUIRE_THROWS(proxy.Call("rx_tcpport", {"15"}, -1, PUT));
|
||||
// port = 5754;
|
||||
// proxy.Call("rx_tcpport", {std::to_string(port)}, -1, PUT);
|
||||
// for (int i = 0; i != det.size(); ++i) {
|
||||
// std::ostringstream oss;
|
||||
// proxy.Call("rx_tcpport", {}, i, GET, oss);
|
||||
// REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n');
|
||||
// }
|
||||
// for (int i = 0; i != det.size(); ++i) {
|
||||
// det.setRxPort(prev_val[i], i);
|
||||
// }
|
||||
// }
|
||||
|
||||
TEST_CASE("rx_fifodepth", "[.cmd][.rx][.new]") {
|
||||
Detector det;
|
||||
|
330
slsDetectorSoftware/tests/test-Container3.cpp
Normal file
330
slsDetectorSoftware/tests/test-Container3.cpp
Normal file
@ -0,0 +1,330 @@
|
||||
|
||||
#include "catch.hpp"
|
||||
#include "Container3.h"
|
||||
using sls::Container3;
|
||||
|
||||
TEST_CASE("Default construction gives container of size 0") {
|
||||
Container3<int> c;
|
||||
CHECK(c.size() == 0);
|
||||
CHECK(c.size(0) == 0);
|
||||
CHECK(c.size(1) == 0);
|
||||
CHECK(c.size(2) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Construct container with size") {
|
||||
|
||||
Container3<int> c(3, 4, 5);
|
||||
CHECK(c.size() == 3 * 4 * 5);
|
||||
CHECK(c.size(0) == 3);
|
||||
CHECK(c.size(1) == 4);
|
||||
CHECK(c.size(2) == 5);
|
||||
}
|
||||
|
||||
TEST_CASE("Constructor with default value") {
|
||||
constexpr int val = 7;
|
||||
Container3<int> c({1, 1, 5}, val);
|
||||
for (size_t i = 0; i < c.size(); ++i) {
|
||||
CHECK(c[i] == val);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Container3 can be iterated with range for") {
|
||||
constexpr int val = 7;
|
||||
Container3<int> c({1, 1, 5}, val);
|
||||
for (const auto& item : c) {
|
||||
CHECK(item == val);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"() gives access to an element for both const and non const objects") {
|
||||
Container3<int> c{1, 1, 1};
|
||||
CHECK(c(0, 0, 0) == 0);
|
||||
const Container3<int> c2{1, 1, 1};
|
||||
CHECK(c2(0, 0, 0) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("() can be used to modify object") {
|
||||
Container3<int> c{1, 1, 1};
|
||||
c(0, 0, 0) = 7;
|
||||
CHECK(c(0, 0, 0) == 7);
|
||||
}
|
||||
|
||||
TEST_CASE("at() can be used to modify object") {
|
||||
Container3<int> c{1, 1, 1};
|
||||
c.at(0, 0, 0) = 7;
|
||||
CHECK(c(0, 0, 0) == 7);
|
||||
}
|
||||
|
||||
TEST_CASE("at throws outsize range for both const and non const objects") {
|
||||
Container3<int> c{1, 1, 1};
|
||||
const Container3<double> c2{1, 1, 1};
|
||||
|
||||
CHECK_THROWS(c.at(5, 5, 5));
|
||||
CHECK_THROWS(c2.at(5, 5, 5));
|
||||
}
|
||||
|
||||
TEST_CASE("Set values") {
|
||||
Container3<int> c(2, 3, 4);
|
||||
size_t count = 0;
|
||||
for (size_t i = 0; i < c.size(0); ++i) {
|
||||
for (size_t j = 0; j < c.size(1); ++j) {
|
||||
for (size_t k = 0; k < c.size(2); ++k) {
|
||||
c(i, j, k) = count;
|
||||
CHECK(c(i, j, k) == count);
|
||||
CHECK(c[count] == count);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Check if index is valid") {
|
||||
Container3<int> c(2, 3, 4);
|
||||
|
||||
CHECK(c.is_valid_index(1,1,1));
|
||||
CHECK(c.is_valid_index(1,2,3));
|
||||
CHECK(c.is_valid_index(1,2,3));
|
||||
|
||||
CHECK_FALSE(c.is_valid_index(1,7,1));
|
||||
CHECK_FALSE(c.is_valid_index(1,1,4));
|
||||
CHECK_FALSE(c.is_valid_index(3,1,1));
|
||||
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Copy data from one container to another") {
|
||||
Container3<int> c(2, 1, 2);
|
||||
for (size_t i = 0; i < c.size(); ++i) {
|
||||
c[i] = i;
|
||||
}
|
||||
Container3<int> c2(3, 3, 3);
|
||||
c2.copy_data(c);
|
||||
|
||||
for (size_t i = 0; i < c.size(0); ++i) {
|
||||
for (size_t j = 0; j < c.size(1); ++j) {
|
||||
for (size_t k = 0; k < c.size(2); ++k) {
|
||||
CHECK(c2(i, j, k) == c(i, j, k));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Copy assignment copies values") {
|
||||
Container3<int> c(2, 3, 4);
|
||||
size_t count = 0;
|
||||
for (size_t i = 0; i < c.size(0); ++i) {
|
||||
for (size_t j = 0; j < c.size(1); ++j) {
|
||||
for (size_t k = 0; k < c.size(2); ++k) {
|
||||
c(i, j, k) = count;
|
||||
CHECK(c(i, j, k) == count);
|
||||
CHECK(c[count] == count);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Container3<int> c2;
|
||||
|
||||
c2 = c;
|
||||
count = 0;
|
||||
for (size_t i = 0; i < c.size(0); ++i) {
|
||||
for (size_t j = 0; j < c.size(1); ++j) {
|
||||
for (size_t k = 0; k < c.size(2); ++k) {
|
||||
c2(i, j, k) = count;
|
||||
CHECK(c(i, j, k) == count);
|
||||
CHECK(c[count] == count);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Copy constructor copies values") {
|
||||
Container3<int> c(18, 23, 4);
|
||||
size_t count = 0;
|
||||
for (size_t i = 0; i < c.size(0); ++i) {
|
||||
for (size_t j = 0; j < c.size(1); ++j) {
|
||||
for (size_t k = 0; k < c.size(2); ++k) {
|
||||
c(i, j, k) = count;
|
||||
CHECK(c(i, j, k) == count);
|
||||
CHECK(c[count] == count);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Container3<int> c2 = c;
|
||||
|
||||
count = 0;
|
||||
for (size_t i = 0; i < c.size(0); ++i) {
|
||||
|
||||
for (size_t j = 0; j < c.size(1); ++j) {
|
||||
for (size_t k = 0; k < c.size(2); ++k) {
|
||||
c2(i, j, k) = count;
|
||||
CHECK(c(i, j, k) == count);
|
||||
CHECK(c[count] == count);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Copy assignment create disjoint objects") {
|
||||
Container3<int> c(2, 3, 4);
|
||||
Container3<int> c2;
|
||||
c2 = c;
|
||||
c2(1, 1, 1) = 72;
|
||||
CHECK(c2(1, 1, 1) == 72);
|
||||
CHECK(c(1, 1, 1) != 72);
|
||||
}
|
||||
|
||||
TEST_CASE("Move constructor") {
|
||||
Container3<int> c(2, 3, 4);
|
||||
|
||||
// explicit move only for testing
|
||||
Container3<int> c2(std::move(c));
|
||||
|
||||
// Moved from object is in an ok state
|
||||
CHECK(c.data() == nullptr);
|
||||
for (size_t i = 0; i < 3; ++i) {
|
||||
CHECK(c.size(i) == 0);
|
||||
}
|
||||
|
||||
// new object has the correct size and owns some data
|
||||
CHECK(c2.data() != nullptr);
|
||||
CHECK(c2.size(0) == 2);
|
||||
CHECK(c2.size(1) == 3);
|
||||
CHECK(c2.size(2) == 4);
|
||||
}
|
||||
|
||||
TEST_CASE("Move assignment ") {
|
||||
Container3<int> c(2, 3, 4);
|
||||
|
||||
Container3<int> c2(5, 5, 5);
|
||||
|
||||
c2 = std::move(c);
|
||||
// Moved from object is in an ok state
|
||||
CHECK(c.data() == nullptr);
|
||||
for (size_t i = 0; i < 3; ++i) {
|
||||
CHECK(c.size(i) == 0);
|
||||
}
|
||||
|
||||
// new object has the correct size and owns some data
|
||||
CHECK(c2.data() != nullptr);
|
||||
CHECK(c2.size(0) == 2);
|
||||
CHECK(c2.size(1) == 3);
|
||||
CHECK(c2.size(2) == 4);
|
||||
}
|
||||
|
||||
TEST_CASE("Resize to a larger size") {
|
||||
Container3<int> c(2, 3, 4);
|
||||
|
||||
// Assign values
|
||||
auto shape = c.shape();
|
||||
CHECK(shape == std::array<size_t, 3>{2,3,4});
|
||||
|
||||
size_t count = 0;
|
||||
for (size_t i = 0; i < shape[0]; ++i) {
|
||||
for (size_t j = 0; j < shape[1]; ++j) {
|
||||
for (size_t k = 0; k < shape[2]; ++k) {
|
||||
c(i, j, k) = count;
|
||||
CHECK(c(i, j, k) == count);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c.resize(3, 4, 5);
|
||||
CHECK(c.shape() == std::array<size_t, 3>{3,4,5});
|
||||
|
||||
// Values should remain the same in the old region
|
||||
count = 0;
|
||||
for (size_t i = 0; i < shape[0]; ++i) {
|
||||
for (size_t j = 0; j < shape[1]; ++j) {
|
||||
for (size_t k = 0; k < shape[2]; ++k) {
|
||||
CHECK(c(i, j, k) == count);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Default constructed values outsize
|
||||
|
||||
CHECK(c(2, 2, 2) == 0);
|
||||
CHECK(c(2, 3, 2) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Inserting values outside range with a empty receiver") {
|
||||
Container3<int> c;
|
||||
c.at_can_grow(0, 0, 0) = 5;
|
||||
|
||||
CHECK(c(0, 0, 0) == 5);
|
||||
CHECK(c.size() == 1);
|
||||
CHECK(c.size(0) == 1);
|
||||
CHECK(c.size(1) == 1);
|
||||
CHECK(c.size(2) == 1);
|
||||
|
||||
c.at_can_grow(0, 0, 1) = 6;
|
||||
CHECK(c.size() == 2);
|
||||
CHECK(c.size(0) == 1);
|
||||
CHECK(c.size(1) == 1);
|
||||
CHECK(c.size(2) == 2);
|
||||
}
|
||||
|
||||
TEST_CASE("Inserting a value outside of the current size") {
|
||||
Container3<int> c{1, 2, 3};
|
||||
for (size_t i = 0; i < c.size(); ++i) {
|
||||
c[i] = i;
|
||||
}
|
||||
|
||||
Container3<int> copy;
|
||||
copy = c;
|
||||
|
||||
c.at_can_grow(2, 2, 2) = 7;
|
||||
|
||||
CHECK(c.size(0) == 3);
|
||||
CHECK(c.size(1) == 3);
|
||||
CHECK(c.size(2) == 3);
|
||||
|
||||
for (size_t i = 0; i < copy.size(0); ++i) {
|
||||
for (size_t j = 0; j < copy.size(0); ++j) {
|
||||
for (size_t k = 0; k < copy.size(0); ++k) {
|
||||
CHECK(copy(i, j, k) == c(i, j, k));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Clear sets size to zero and clears memory"){
|
||||
Container3<int> c(5,5,5);
|
||||
CHECK(c.shape() == std::array<size_t, 3>{5,5,5});
|
||||
|
||||
c.clear();
|
||||
CHECK(c.shape() == std::array<size_t, 3>{0,0,0});
|
||||
CHECK(c.size() == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Put unique pointer in Container3"){
|
||||
Container3<std::unique_ptr<int>> c(3,1,1);
|
||||
c(0,0,0) = std::unique_ptr<int>(new int);
|
||||
|
||||
CHECK(c(0,0,0) != nullptr);
|
||||
CHECK(c(1,0,0) == nullptr);
|
||||
CHECK(c(2,0,0) == nullptr);
|
||||
|
||||
*c(0,0,0) = 5;
|
||||
CHECK(*c(0,0,0) == 5);
|
||||
}
|
||||
|
||||
TEST_CASE("Resize with unique ptr"){
|
||||
Container3<std::unique_ptr<int>> c(2,1,1);
|
||||
c(1,0,0) = std::unique_ptr<int>(new int);
|
||||
*c(1,0,0) = 7;
|
||||
|
||||
c.resize(3,1,1);
|
||||
CHECK(c.size() == 3);
|
||||
CHECK(*c(1,0,0) == 7);
|
||||
|
||||
|
||||
}
|
84
slsDetectorSoftware/tests/test-MaskGenerator.cpp
Normal file
84
slsDetectorSoftware/tests/test-MaskGenerator.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
#include "catch.hpp"
|
||||
#include "MaskGenerator.h"
|
||||
|
||||
using sls::MaskGenerator;
|
||||
using sls::Container3;
|
||||
|
||||
TEST_CASE("Default construction gives an mask of size 0") {
|
||||
auto m = MaskGenerator().mask();
|
||||
CHECK(m.shape() == std::array<size_t, 3>{0, 0, 0});
|
||||
CHECK(m.size() == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Default behaviour with shape is all true and same shape") {
|
||||
Container3<int> c{1, 2, 3};
|
||||
auto m = MaskGenerator().mask(c.shape());
|
||||
|
||||
CHECK(m.shape() == std::array<size_t, 3>{1, 2, 3});
|
||||
for (auto &i : m)
|
||||
CHECK(i == true);
|
||||
}
|
||||
|
||||
TEST_CASE("With std::vector we give back the first index and 0, 0") {
|
||||
|
||||
Container3<int> rec{14, 1, 3};
|
||||
|
||||
auto m = MaskGenerator(std::vector<size_t>{0, 3, 5}).mask(rec.shape());
|
||||
CHECK(m.shape() == std::array<size_t, 3>{14, 1, 3});
|
||||
|
||||
CHECK(m(0, 0, 0) == true);
|
||||
CHECK(m(3, 0, 0) == true);
|
||||
CHECK(m(5, 0, 0) == true);
|
||||
|
||||
std::vector<size_t> positions(rec.size(0));
|
||||
std::iota(begin(positions), end(positions), 0);
|
||||
positions.erase(std::remove(positions.begin(), positions.end(), 0),
|
||||
positions.end());
|
||||
positions.erase(std::remove(positions.begin(), positions.end(), 3),
|
||||
positions.end());
|
||||
positions.erase(std::remove(positions.begin(), positions.end(), 5),
|
||||
positions.end());
|
||||
|
||||
for (auto i : positions) {
|
||||
for (size_t j = 0; j < rec.size(1); ++j) {
|
||||
for (size_t k = 0; k < rec.size(2); ++k) {
|
||||
REQUIRE(m(i, j, k) == false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("With single number we get that detector x,0,0") {
|
||||
Container3<int> rec{2, 2, 1};
|
||||
auto m = MaskGenerator(1).mask(rec);
|
||||
CHECK(m(1, 0, 0) == true);
|
||||
CHECK(m(1, 1, 0) == false);
|
||||
CHECK(m(0, 1, 0) == false);
|
||||
CHECK(m(0, 0, 0) == false);
|
||||
}
|
||||
|
||||
TEST_CASE("With two numbers we get x,y,0") {
|
||||
Container3<int> rec{2, 2, 1};
|
||||
auto m = MaskGenerator(1, 1).mask(rec);
|
||||
CHECK(m(1, 1, 0) == true);
|
||||
CHECK(m(1, 0, 0) == false);
|
||||
CHECK(m(0, 1, 0) == false);
|
||||
CHECK(m(0, 0, 0) == false);
|
||||
}
|
||||
|
||||
TEST_CASE("With three numbers we get x,y,z") {
|
||||
Container3<int> rec{9, 7, 5};
|
||||
auto m = MaskGenerator(3, 4, 1).mask(rec);
|
||||
REQUIRE(m.shape() == rec.shape());
|
||||
REQUIRE(m(3, 4, 1) == true);
|
||||
|
||||
for (size_t i = 0; i < rec.size(0); ++i) {
|
||||
for (size_t j = 0; j < rec.size(1); ++j) {
|
||||
for (size_t k = 0; k < rec.size(2); ++k) {
|
||||
if (!(i == 3 && j == 4 && k == 1)) {
|
||||
REQUIRE(m(i, j, k) == false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
10
slsDetectorSoftware/tests/test-Receiver.cpp
Normal file
10
slsDetectorSoftware/tests/test-Receiver.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
#include "catch.hpp"
|
||||
#include "Container3.h"
|
||||
#include "Receiver.h"
|
||||
|
||||
using sls::Receiver;
|
||||
|
||||
// TEST_CASE("Receiver can be default constructed"){
|
||||
|
||||
|
||||
// }
|
Loading…
x
Reference in New Issue
Block a user