mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-07 10:30:41 +02:00
Fixed container (#19)
* added FixedCapacityContainer * added empty to FixedCapacityContainer * removed commented out section * added FixedCapacityContainer to public headers
This commit is contained in:
parent
0e0e7ea81f
commit
2a1c89f712
@ -6,12 +6,14 @@
|
||||
#include "logger.h"
|
||||
#include "sls_detector_defs.h"
|
||||
#include "network_utils.h"
|
||||
#include "FixedCapacityContainer.h"
|
||||
class ClientInterface;
|
||||
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
|
||||
class multiSlsDetector;
|
||||
class ServerInterface;
|
||||
class MySocketTCP;
|
||||
@ -62,11 +64,8 @@ struct sharedSlsDetector {
|
||||
/** path of the trimbits/settings files */
|
||||
char settingsDir[MAX_STR_LENGTH];
|
||||
|
||||
/** number of energies at which the detector has been trimmed */
|
||||
int nTrimEn;
|
||||
|
||||
/** list of the energies at which the detector has been trimmed */
|
||||
int trimEnergies[MAX_TRIMEN];
|
||||
sls::FixedCapacityContainer<int, MAX_TRIMEN> trimEnergies;
|
||||
|
||||
/** number of channels per chip */
|
||||
int nChans;
|
||||
|
@ -300,10 +300,6 @@ void slsDetector::initializeDetectorStructure(detectorType type) {
|
||||
shm()->controlPort = DEFAULT_PORTNO;
|
||||
shm()->stopPort = DEFAULT_PORTNO + 1;
|
||||
sls::strcpy_safe(shm()->settingsDir, getenv("HOME"));
|
||||
shm()->nTrimEn = 0;
|
||||
for (int &trimEnergie : shm()->trimEnergies) {
|
||||
trimEnergie = 0;
|
||||
}
|
||||
shm()->nROI = 0;
|
||||
memset(shm()->roiLimits, 0, MAX_ROIS * sizeof(ROI));
|
||||
shm()->adcEnableMask = BIT32_MASK;
|
||||
@ -1166,14 +1162,14 @@ int slsDetector::setThresholdEnergyAndSettings(int e_eV,
|
||||
((isettings != GET_SETTINGS) ? isettings : shm()->currentSettings);
|
||||
|
||||
// verify e_eV exists in trimEneregies[]
|
||||
if ((shm()->nTrimEn == 0) || (e_eV < shm()->trimEnergies[0]) ||
|
||||
(e_eV > shm()->trimEnergies[shm()->nTrimEn - 1])) {
|
||||
if (shm()->trimEnergies.empty() || (e_eV < shm()->trimEnergies.front()) ||
|
||||
(e_eV > shm()->trimEnergies.back())) {
|
||||
throw RuntimeError("This energy " + std::to_string(e_eV) +
|
||||
" not defined for this module!");
|
||||
}
|
||||
|
||||
bool interpolate =
|
||||
std::all_of(shm()->trimEnergies, shm()->trimEnergies + shm()->nTrimEn,
|
||||
std::all_of(shm()->trimEnergies.begin(), shm()->trimEnergies.end(),
|
||||
[e_eV](const int &e) { return e != e_eV; });
|
||||
|
||||
sls_detector_module myMod{shm()->myDetectorType};
|
||||
@ -1185,7 +1181,7 @@ int slsDetector::setThresholdEnergyAndSettings(int e_eV,
|
||||
} else {
|
||||
// find the trim values
|
||||
int trim1 = -1, trim2 = -1;
|
||||
for (int i = 0; i < shm()->nTrimEn; ++i) {
|
||||
for (size_t i = 0; i < shm()->trimEnergies.size(); ++i) {
|
||||
if (e_eV < shm()->trimEnergies[i]) {
|
||||
trim2 = shm()->trimEnergies[i];
|
||||
trim1 = shm()->trimEnergies[i - 1];
|
||||
@ -2908,14 +2904,13 @@ int slsDetector::setTrimEn(std::vector<int> energies) {
|
||||
<< "\n";
|
||||
throw RuntimeError(os.str());
|
||||
}
|
||||
std::copy(begin(energies), end(energies), shm()->trimEnergies);
|
||||
shm()->nTrimEn = energies.size();
|
||||
return shm()->nTrimEn;
|
||||
shm()->trimEnergies = energies;
|
||||
return shm()->trimEnergies.size();
|
||||
}
|
||||
|
||||
std::vector<int> slsDetector::getTrimEn() {
|
||||
return std::vector<int>(shm()->trimEnergies,
|
||||
shm()->trimEnergies + shm()->nTrimEn);
|
||||
return std::vector<int>(shm()->trimEnergies.begin(),
|
||||
shm()->trimEnergies.end());
|
||||
}
|
||||
|
||||
int slsDetector::pulsePixel(int n, int x, int y) {
|
||||
|
@ -32,6 +32,7 @@ set(PUBLICHEADERS
|
||||
include/ServerSocket.h
|
||||
include/ServerInterface.h
|
||||
include/network_utils.h
|
||||
include/FixedCapacityContainer.h
|
||||
)
|
||||
|
||||
add_library(slsSupportLib SHARED
|
||||
|
172
slsSupportLib/include/FixedCapacityContainer.h
Normal file
172
slsSupportLib/include/FixedCapacityContainer.h
Normal file
@ -0,0 +1,172 @@
|
||||
|
||||
#pragma once
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
namespace sls {
|
||||
template <typename T, size_t Capacity> class FixedCapacityContainer {
|
||||
public:
|
||||
FixedCapacityContainer() = default;
|
||||
explicit FixedCapacityContainer(std::initializer_list<T> l);
|
||||
explicit FixedCapacityContainer(const std::vector<T> &v);
|
||||
|
||||
FixedCapacityContainer &operator=(const std::vector<T> &other);
|
||||
|
||||
bool operator==(const std::vector<T> &other) const;
|
||||
bool operator!=(const std::vector<T> &other) const;
|
||||
|
||||
template <size_t OtherCapacity>
|
||||
bool
|
||||
operator==(const FixedCapacityContainer<T, OtherCapacity> &other) const;
|
||||
|
||||
template <size_t OtherCapacity>
|
||||
bool
|
||||
operator!=(const FixedCapacityContainer<T, OtherCapacity> &other) const;
|
||||
|
||||
T &operator[](size_t i) { return data_[i]; }
|
||||
const T &operator[](size_t i) const { return data_[i]; }
|
||||
|
||||
size_t size() const { return size_; }
|
||||
bool empty() const{ return size_ == 0;}
|
||||
size_t capacity() const { return Capacity; }
|
||||
|
||||
void push_back(const T &value);
|
||||
void resize(size_t new_size);
|
||||
void erase(T *ptr);
|
||||
T &front() { return data_.front(); }
|
||||
T &back() { return data_[size_ - 1]; }
|
||||
const T &front() const { return data_.front(); }
|
||||
const T &back() const { return data_[size_ - 1]; }
|
||||
|
||||
// iterators
|
||||
T *begin() { return &data_[0]; }
|
||||
T *end() { return &data_[size_]; }
|
||||
const T *cbegin() const { return &data_[0]; }
|
||||
const T *cend() const { return &data_[size_]; }
|
||||
|
||||
private:
|
||||
size_t size_{0};
|
||||
std::array<T, Capacity> data_;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Member functions */
|
||||
template <typename T, size_t Capacity>
|
||||
FixedCapacityContainer<T, Capacity>::FixedCapacityContainer(
|
||||
std::initializer_list<T> l) {
|
||||
size_ = l.size();
|
||||
std::copy(l.begin(), l.end(), data_.begin());
|
||||
}
|
||||
|
||||
template <typename T, size_t Capacity>
|
||||
FixedCapacityContainer<T, Capacity>::FixedCapacityContainer(
|
||||
const std::vector<T> &v) {
|
||||
size_ = v.size();
|
||||
std::copy(v.begin(), v.end(), data_.begin());
|
||||
}
|
||||
|
||||
template <typename T, size_t Capacity>
|
||||
void FixedCapacityContainer<T, Capacity>::push_back(const T &value) {
|
||||
if (size_ == Capacity) {
|
||||
throw std::runtime_error("Container is full");
|
||||
} else {
|
||||
data_[size_] = value;
|
||||
++size_;
|
||||
}
|
||||
}
|
||||
template <typename T, size_t Capacity>
|
||||
void FixedCapacityContainer<T, Capacity>::resize(size_t new_size) {
|
||||
if (new_size > Capacity) {
|
||||
throw std::runtime_error("Cannot resize beyond capacity");
|
||||
} else {
|
||||
size_ = new_size;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, size_t Capacity>
|
||||
FixedCapacityContainer<T, Capacity> &FixedCapacityContainer<T, Capacity>::
|
||||
operator=(const std::vector<T> &other) {
|
||||
std::copy(other.begin(), other.end(), data_.begin());
|
||||
size_ = other.size();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, size_t Capacity>
|
||||
bool FixedCapacityContainer<T, Capacity>::
|
||||
operator==(const std::vector<T> &other) const {
|
||||
if (size_ != other.size()) {
|
||||
return false;
|
||||
} else {
|
||||
for (size_t i = 0; i != size_; ++i) {
|
||||
if (data_[i] != other[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T, size_t Capacity>
|
||||
bool FixedCapacityContainer<T, Capacity>::
|
||||
operator!=(const std::vector<T> &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
template <typename T, size_t Capacity>
|
||||
template <size_t OtherCapacity>
|
||||
bool FixedCapacityContainer<T, Capacity>::
|
||||
operator==(const FixedCapacityContainer<T, OtherCapacity> &other) const {
|
||||
if (size_ != other.size()) {
|
||||
return false;
|
||||
} else {
|
||||
for (size_t i = 0; i != size_; ++i) {
|
||||
if (data_[i] != other[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T, size_t Capacity>
|
||||
template <size_t OtherCapacity>
|
||||
bool FixedCapacityContainer<T, Capacity>::
|
||||
operator!=(const FixedCapacityContainer<T, OtherCapacity> &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
template <typename T, size_t Capacity>
|
||||
void FixedCapacityContainer<T, Capacity>::erase(T *ptr) {
|
||||
if (ptr >= begin() && ptr < end()) {
|
||||
size_ = static_cast<size_t>(ptr - begin());
|
||||
} else {
|
||||
throw std::runtime_error("tried to erase with a ptr outside obj");
|
||||
}
|
||||
}
|
||||
|
||||
/* Free function concerning FixedCapacityContainer */
|
||||
|
||||
template <typename T, size_t Capacity>
|
||||
T *begin(FixedCapacityContainer<T, Capacity> &container) {
|
||||
return container.begin();
|
||||
}
|
||||
|
||||
template <typename T, size_t Capacity>
|
||||
T *end(FixedCapacityContainer<T, Capacity> &container) {
|
||||
return container.end();
|
||||
}
|
||||
|
||||
template <typename T, size_t Capacity>
|
||||
bool operator==(const std::vector<T> &vec,
|
||||
const FixedCapacityContainer<T, Capacity> &fixed_container) {
|
||||
return fixed_container == vec;
|
||||
}
|
||||
|
||||
template <typename T, size_t Capacity>
|
||||
bool operator!=(const std::vector<T> &vec,
|
||||
const FixedCapacityContainer<T, Capacity> &fixed_container) {
|
||||
return fixed_container != vec;
|
||||
}
|
||||
|
||||
} // namespace sls
|
@ -7,4 +7,5 @@ target_sources(tests PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-Timer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-sls_detector_defs.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-Sockets.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test-FixedCapacityContainer.cpp
|
||||
)
|
205
slsSupportLib/tests/test-FixedCapacityContainer.cpp
Normal file
205
slsSupportLib/tests/test-FixedCapacityContainer.cpp
Normal file
@ -0,0 +1,205 @@
|
||||
#include "FixedCapacityContainer.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
using sls::FixedCapacityContainer;
|
||||
|
||||
SCENARIO("FixedCapacityContainers can be sized and resized", "[support]") {
|
||||
|
||||
GIVEN("A default constructed container") {
|
||||
constexpr size_t n_elem = 5;
|
||||
FixedCapacityContainer<int, n_elem> vec;
|
||||
|
||||
REQUIRE(vec.empty());
|
||||
REQUIRE(vec.size() == 0);
|
||||
REQUIRE(vec.capacity() == n_elem);
|
||||
REQUIRE(sizeof(vec) == sizeof(int) * n_elem + sizeof(size_t));
|
||||
|
||||
WHEN("an item is pushed back") {
|
||||
vec.push_back(42);
|
||||
|
||||
THEN("the element is stored and the size increases but the "
|
||||
"capacity remains fixed") {
|
||||
REQUIRE(vec[0] == 42);
|
||||
REQUIRE(vec.size() == 1);
|
||||
REQUIRE_FALSE(vec.empty());
|
||||
REQUIRE(vec.capacity() == 5);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We try to push back more elements than the capcity") {
|
||||
for (size_t i = 0; i != vec.capacity(); ++i)
|
||||
vec.push_back(static_cast<int>(i));
|
||||
THEN("It throws") { REQUIRE_THROWS(vec.push_back(92)); }
|
||||
}
|
||||
|
||||
WHEN("a vector is assigned to the fixed container") {
|
||||
std::vector<int> standard_vector{1, 2, 8, 0};
|
||||
vec = standard_vector;
|
||||
THEN("their values and size match") {
|
||||
REQUIRE(vec.size() == standard_vector.size());
|
||||
for (size_t i = 0; i != vec.size(); ++i) {
|
||||
REQUIRE(vec[i] == standard_vector[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("A FixedCapacityContainer constructed form a std::initializer list") {
|
||||
FixedCapacityContainer<int, 10> vec{23, 52, 11};
|
||||
REQUIRE(vec.size() == 3);
|
||||
REQUIRE(vec.capacity() == 10);
|
||||
REQUIRE(vec[0] == 23);
|
||||
REQUIRE(vec[1] == 52);
|
||||
REQUIRE(vec[2] == 11);
|
||||
|
||||
WHEN("The container is resized to a smaller size") {
|
||||
vec.resize(2);
|
||||
THEN("The size changes but not the values or capacity") {
|
||||
REQUIRE(vec.size() == 2);
|
||||
REQUIRE(vec[0] == 23);
|
||||
REQUIRE(vec[1] == 52);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("The container is resized to a larger size") {
|
||||
vec.resize(7);
|
||||
THEN("The size changes but not the values") {
|
||||
REQUIRE(vec.size() == 7);
|
||||
REQUIRE(vec[0] == 23);
|
||||
REQUIRE(vec[1] == 52);
|
||||
REQUIRE(vec[2] == 11);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We try to resize beyond the capacity") {
|
||||
THEN("it throws") { CHECK_THROWS(vec.resize(25)); }
|
||||
}
|
||||
WHEN("We call front and back"){
|
||||
THEN("They return referenced to the first and last element"){
|
||||
REQUIRE(vec.front() == 23);
|
||||
REQUIRE(&vec.front() == &vec[0]);
|
||||
REQUIRE(vec.back() == 11);
|
||||
REQUIRE(&vec.back() == &vec[2]);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("An std::vector of size 3") {
|
||||
std::vector<int> standard_vector{5, 2, 1};
|
||||
WHEN("we construct a fixed capacity container from it") {
|
||||
FixedCapacityContainer<int, 5> vec(standard_vector);
|
||||
THEN("size and data matches") {
|
||||
REQUIRE(vec.size() == 3);
|
||||
REQUIRE(vec[0] == 5);
|
||||
REQUIRE(vec[1] == 2);
|
||||
REQUIRE(vec[2] == 1);
|
||||
}
|
||||
THEN("we can compare the vector and fixed container") {
|
||||
REQUIRE(vec == standard_vector);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SCENARIO("Comparison of FixedCapacityContainers", "[support]") {
|
||||
GIVEN("Two containers containers that are equal at the start") {
|
||||
FixedCapacityContainer<int, 5> a{0, 1, 2};
|
||||
FixedCapacityContainer<int, 5> b{0, 1, 2};
|
||||
REQUIRE(a == b);
|
||||
REQUIRE_FALSE(a != b);
|
||||
|
||||
WHEN("We push back one element") {
|
||||
a.push_back(4);
|
||||
THEN("they are not equal anymore") { REQUIRE(a != b); }
|
||||
}
|
||||
WHEN("Compared to a FixedCapacityContainer with different capacity") {
|
||||
FixedCapacityContainer<int, 8> c{0, 1, 2};
|
||||
THEN("The comparison still holds") {
|
||||
REQUIRE(a == c);
|
||||
REQUIRE_FALSE(a != c);
|
||||
}
|
||||
}
|
||||
WHEN("we make a copy of one container") {
|
||||
auto c = a;
|
||||
THEN("The comparison holds") {
|
||||
REQUIRE(c == a);
|
||||
REQUIRE(&c != &a);
|
||||
REQUIRE(&a[0] != &c[0]);
|
||||
}
|
||||
}
|
||||
WHEN("Compared to an std::vector") {
|
||||
std::vector<int> standard_vector{0, 1, 2};
|
||||
THEN("The comparison also holds for both orderings") {
|
||||
REQUIRE(a == standard_vector);
|
||||
REQUIRE(standard_vector == a);
|
||||
REQUIRE_FALSE(a != standard_vector);
|
||||
REQUIRE_FALSE(standard_vector != a);
|
||||
|
||||
standard_vector.push_back(3);
|
||||
REQUIRE(a != standard_vector);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SCENARIO("Sorting, removing and other manipulation of a container", "[support]") {
|
||||
GIVEN("An unsorted container") {
|
||||
FixedCapacityContainer<int, 5> a{14, 12, 90, 12};
|
||||
WHEN("We sort it") {
|
||||
std::sort(a.begin(), a.end());
|
||||
THEN("Elements appear sorted") {
|
||||
REQUIRE(a[0] == 12);
|
||||
REQUIRE(a[1] == 12);
|
||||
REQUIRE(a[2] == 14);
|
||||
REQUIRE(a[3] == 90);
|
||||
}
|
||||
}
|
||||
WHEN("Sorting is done using free function for begin and end") {
|
||||
std::sort(begin(a), end(a));
|
||||
THEN("it also works") {
|
||||
REQUIRE(a[0] == 12);
|
||||
REQUIRE(a[1] == 12);
|
||||
REQUIRE(a[2] == 14);
|
||||
REQUIRE(a[3] == 90);
|
||||
}
|
||||
}
|
||||
WHEN("Erasing elements of a certain value") {
|
||||
a.erase(std::remove(begin(a), end(a), 12));
|
||||
THEN("all elements of that value are removed") {
|
||||
REQUIRE(a.size() == 2);
|
||||
REQUIRE(a[0] == 14);
|
||||
REQUIRE(a[1] == 90);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SCENARIO("Assigning containers to each other", "[support]") {
|
||||
GIVEN("Two containers") {
|
||||
FixedCapacityContainer<int, 3> a{1, 2, 3};
|
||||
FixedCapacityContainer<int, 3> b{4, 5, 6};
|
||||
WHEN("a is assigned to b") {
|
||||
a = b;
|
||||
THEN("A deep copy is made and both containers are equal") {
|
||||
REQUIRE(a == b);
|
||||
REQUIRE(&a != &b);
|
||||
REQUIRE(&a[0] != &b[0]);
|
||||
REQUIRE(a[0] == 4);
|
||||
REQUIRE(a[1] == 5);
|
||||
REQUIRE(a[2] == 6);
|
||||
}
|
||||
}
|
||||
WHEN("A new object is create from an old one") {
|
||||
FixedCapacityContainer<int, 3> c(a);
|
||||
THEN("A deep copy is also made") {
|
||||
REQUIRE(c == a);
|
||||
REQUIRE(&c != &a);
|
||||
REQUIRE(&c[0] != &a[0]);
|
||||
REQUIRE(c[0] == 1);
|
||||
REQUIRE(c[1] == 2);
|
||||
REQUIRE(c[2] == 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user