mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-04-20 05:40:03 +02:00
underlying container of ClusterVcetor is now a std::vector
This commit is contained in:
parent
9de84a7f87
commit
a12e43b176
@ -29,6 +29,7 @@ class ClusterVector; // Forward declaration
|
|||||||
* @tparam CoordType data type of the x and y coordinates of the cluster
|
* @tparam CoordType data type of the x and y coordinates of the cluster
|
||||||
* (normally int16_t)
|
* (normally int16_t)
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
template <typename T, uint8_t ClusterSizeX, uint8_t ClusterSizeY,
|
template <typename T, uint8_t ClusterSizeX, uint8_t ClusterSizeY,
|
||||||
typename CoordType>
|
typename CoordType>
|
||||||
class ClusterVector<Cluster<T, ClusterSizeX, ClusterSizeY, CoordType>> {
|
class ClusterVector<Cluster<T, ClusterSizeX, ClusterSizeY, CoordType>> {
|
||||||
@ -37,7 +38,7 @@ class ClusterVector<Cluster<T, ClusterSizeX, ClusterSizeY, CoordType>> {
|
|||||||
size_t m_size{0};
|
size_t m_size{0};
|
||||||
size_t m_capacity;
|
size_t m_capacity;
|
||||||
uint64_t m_frame_number{0}; // TODO! Check frame number size and type
|
uint64_t m_frame_number{0}; // TODO! Check frame number size and type
|
||||||
/*
|
/**
|
||||||
Format string used in the python bindings to create a numpy
|
Format string used in the python bindings to create a numpy
|
||||||
array from the buffer
|
array from the buffer
|
||||||
= - native byte order
|
= - native byte order
|
||||||
@ -59,7 +60,7 @@ class ClusterVector<Cluster<T, ClusterSizeX, ClusterSizeY, CoordType>> {
|
|||||||
*/
|
*/
|
||||||
ClusterVector(size_t capacity = 1024, uint64_t frame_number = 0)
|
ClusterVector(size_t capacity = 1024, uint64_t frame_number = 0)
|
||||||
: m_capacity(capacity), m_frame_number(frame_number) {
|
: m_capacity(capacity), m_frame_number(frame_number) {
|
||||||
allocate_buffer(capacity);
|
allocate_buffer(m_capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ClusterVector() { delete[] m_data; }
|
~ClusterVector() { delete[] m_data; }
|
||||||
@ -230,7 +231,7 @@ class ClusterVector<Cluster<T, ClusterSizeX, ClusterSizeY, CoordType>> {
|
|||||||
return m_fmt_base;
|
return m_fmt_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the frame number of the clusters. 0 is used to indicate
|
* @brief Return the frame number of the clusters. 0 is used to indicate
|
||||||
* that the clusters come from many frames
|
* that the clusters come from many frames
|
||||||
*/
|
*/
|
||||||
@ -240,7 +241,7 @@ class ClusterVector<Cluster<T, ClusterSizeX, ClusterSizeY, CoordType>> {
|
|||||||
m_frame_number = frame_number;
|
m_frame_number = frame_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Resize the vector to contain new_size clusters. If new_size is
|
* @brief Resize the vector to contain new_size clusters. If new_size is
|
||||||
* greater than the current capacity, a new buffer is allocated. If the size
|
* greater than the current capacity, a new buffer is allocated. If the size
|
||||||
* is smaller no memory is freed, size is just updated.
|
* is smaller no memory is freed, size is just updated.
|
||||||
@ -265,5 +266,124 @@ class ClusterVector<Cluster<T, ClusterSizeX, ClusterSizeY, CoordType>> {
|
|||||||
m_capacity = new_capacity;
|
m_capacity = new_capacity;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ClusterVector is a container for clusters of various sizes. It
|
||||||
|
* uses a contiguous memory buffer to store the clusters. It is templated on
|
||||||
|
* the data type and the coordinate type of the clusters.
|
||||||
|
* @note push_back can invalidate pointers to elements in the container
|
||||||
|
* @warning ClusterVector is currently move only to catch unintended copies,
|
||||||
|
* but this might change since there are probably use cases where copying is
|
||||||
|
* needed.
|
||||||
|
* @tparam T data type of the pixels in the cluster
|
||||||
|
* @tparam CoordType data type of the x and y coordinates of the cluster
|
||||||
|
* (normally int16_t)
|
||||||
|
*/
|
||||||
|
template <typename T, uint8_t ClusterSizeX, uint8_t ClusterSizeY,
|
||||||
|
typename CoordType>
|
||||||
|
class ClusterVector<Cluster<T, ClusterSizeX, ClusterSizeY, CoordType>> {
|
||||||
|
|
||||||
|
std::vector<Cluster<T, ClusterSizeX, ClusterSizeY, CoordType>> m_data{};
|
||||||
|
uint64_t m_frame_number{0}; // TODO! Check frame number size and type
|
||||||
|
|
||||||
|
public:
|
||||||
|
using value_type = T;
|
||||||
|
using ClusterType = Cluster<T, ClusterSizeX, ClusterSizeY, CoordType>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct a new ClusterVector object
|
||||||
|
* @param capacity initial capacity of the buffer in number of clusters
|
||||||
|
* @param frame_number frame number of the clusters. Default is 0, which is
|
||||||
|
* also used to indicate that the clusters come from many frames
|
||||||
|
*/
|
||||||
|
ClusterVector(size_t capacity = 1024, uint64_t frame_number = 0)
|
||||||
|
: m_frame_number(frame_number) {
|
||||||
|
m_data.reserve(capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move constructor
|
||||||
|
ClusterVector(ClusterVector &&other) noexcept
|
||||||
|
: m_data(other.m_data), m_frame_number(other.m_frame_number) {
|
||||||
|
other.m_data.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move assignment operator
|
||||||
|
ClusterVector &operator=(ClusterVector &&other) noexcept {
|
||||||
|
if (this != &other) {
|
||||||
|
m_data = other.m_data;
|
||||||
|
m_frame_number = other.m_frame_number;
|
||||||
|
other.m_data.clear();
|
||||||
|
other.m_frame_number = 0;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reserve space for at least capacity clusters
|
||||||
|
* @param capacity number of clusters to reserve space for
|
||||||
|
* @note If capacity is less than the current capacity, the function does
|
||||||
|
* nothing.
|
||||||
|
*/
|
||||||
|
void reserve(size_t capacity) { m_data.reserve(capacity); }
|
||||||
|
|
||||||
|
void resize(size_t size) { m_data.resize(size); }
|
||||||
|
|
||||||
|
void push_back(const ClusterType &cluster) { m_data.push_back(cluster); }
|
||||||
|
|
||||||
|
ClusterVector &operator+=(const ClusterVector &other) {
|
||||||
|
m_data.insert(m_data.end(), other.begin(), other.end());
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return the number of clusters in the vector
|
||||||
|
*/
|
||||||
|
size_t size() const { return m_data.size(); }
|
||||||
|
|
||||||
|
uint8_t cluster_size_x() const { return ClusterSizeX; }
|
||||||
|
|
||||||
|
uint8_t cluster_size_y() const { return ClusterSizeY; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return the capacity of the buffer in number of clusters. This is
|
||||||
|
* the number of clusters that can be stored in the current buffer without
|
||||||
|
* reallocation.
|
||||||
|
*/
|
||||||
|
size_t capacity() const { return m_data.capacity(); }
|
||||||
|
|
||||||
|
const auto begin() const { return m_data.begin(); }
|
||||||
|
|
||||||
|
const auto end() const { return m_data.end(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return the size in bytes of a single cluster
|
||||||
|
*/
|
||||||
|
size_t item_size() const {
|
||||||
|
return 2 * sizeof(CoordType) + ClusterSizeX * ClusterSizeY * sizeof(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClusterType *data() { return m_data.data(); }
|
||||||
|
ClusterType const *data() const { return m_data.data(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return a reference to the i-th cluster casted to type V
|
||||||
|
* @tparam V type of the cluster
|
||||||
|
*/
|
||||||
|
ClusterType &at(size_t i) { return m_data[i]; }
|
||||||
|
|
||||||
|
const ClusterType &at(size_t i) const { return m_data[i]; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return the frame number of the clusters. 0 is used to indicate
|
||||||
|
* that the clusters come from many frames
|
||||||
|
*/
|
||||||
|
uint64_t frame_number() const { return m_frame_number; }
|
||||||
|
|
||||||
|
void set_frame_number(uint64_t frame_number) {
|
||||||
|
m_frame_number = frame_number;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace aare
|
} // namespace aare
|
@ -58,7 +58,8 @@ void define_cluster(py::module &m, const std::string &typestr) {
|
|||||||
[](ClusterType &c, py::array_t<Type> arr) {
|
[](ClusterType &c, py::array_t<Type> arr) {
|
||||||
py::buffer_info buf_info = arr.request();
|
py::buffer_info buf_info = arr.request();
|
||||||
Type *ptr = static_cast<Type *>(buf_info.ptr);
|
Type *ptr = static_cast<Type *>(buf_info.ptr);
|
||||||
std::copy(ptr, ptr + ClusterSizeX * ClusterSizeY, c.data);
|
std::copy(ptr, ptr + ClusterSizeX * ClusterSizeY,
|
||||||
|
c.data); // TODO dont iterate over centers!!!
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,14 +69,15 @@ void define_cluster_vector(py::module &m, const std::string &typestr) {
|
|||||||
|
|
||||||
py::class_<ClusterVector<ClusterType>>(m, class_name.c_str(),
|
py::class_<ClusterVector<ClusterType>>(m, class_name.c_str(),
|
||||||
py::buffer_protocol())
|
py::buffer_protocol())
|
||||||
|
|
||||||
.def(py::init()) // TODO change!!!
|
.def(py::init()) // TODO change!!!
|
||||||
/*
|
/*
|
||||||
.def("push_back",
|
.def("push_back",
|
||||||
[](ClusterVector<ClusterType> &self, ClusterType &cl) {
|
[](ClusterVector<ClusterType> &self, ClusterType &cl) {
|
||||||
// auto view = make_view_2d(data);
|
// auto view = make_view_2d(data);
|
||||||
self.push_back(cl);
|
self.push_back(cl);
|
||||||
})
|
})
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
.def(
|
.def(
|
||||||
"push_back",
|
"push_back",
|
||||||
@ -92,15 +94,11 @@ void define_cluster_vector(py::module &m, const std::string &typestr) {
|
|||||||
})
|
})
|
||||||
*/
|
*/
|
||||||
//.def("push_back", &ClusterVector<ClusterType>::push_back) //TODO
|
//.def("push_back", &ClusterVector<ClusterType>::push_back) //TODO
|
||||||
//implement push_back
|
// implement push_back
|
||||||
.def_property_readonly("size", &ClusterVector<ClusterType>::size)
|
.def_property_readonly("size", &ClusterVector<ClusterType>::size)
|
||||||
.def("item_size", &ClusterVector<ClusterType>::item_size)
|
.def("item_size", &ClusterVector<ClusterType>::item_size)
|
||||||
.def_property_readonly("fmt",
|
.def_property_readonly("fmt",
|
||||||
[typestr](ClusterVector<ClusterType> &self) {
|
[typestr]() { return fmt_format<ClusterType>; })
|
||||||
return fmt::format(
|
|
||||||
self.fmt_base(), self.cluster_size_x(),
|
|
||||||
self.cluster_size_y(), typestr);
|
|
||||||
})
|
|
||||||
/*
|
/*
|
||||||
.def("sum",
|
.def("sum",
|
||||||
[](ClusterVector<ClusterType> &self) {
|
[](ClusterVector<ClusterType> &self) {
|
||||||
@ -124,13 +122,11 @@ void define_cluster_vector(py::module &m, const std::string &typestr) {
|
|||||||
.def_buffer(
|
.def_buffer(
|
||||||
[typestr](ClusterVector<ClusterType> &self) -> py::buffer_info {
|
[typestr](ClusterVector<ClusterType> &self) -> py::buffer_info {
|
||||||
return py::buffer_info(
|
return py::buffer_info(
|
||||||
self.data(), /* Pointer to buffer */
|
self.data(), /* Pointer to buffer */
|
||||||
self.item_size(), /* Size of one scalar */
|
self.item_size(), /* Size of one scalar */
|
||||||
fmt::format(self.fmt_base(), self.cluster_size_x(),
|
fmt_format<ClusterType>, /* Format descriptor */
|
||||||
self.cluster_size_y(),
|
1, /* Number of dimensions */
|
||||||
typestr), /* Format descriptor */
|
{self.size()}, /* Buffer dimensions */
|
||||||
1, /* Number of dimensions */
|
|
||||||
{self.size()}, /* Buffer dimensions */
|
|
||||||
{self.item_size()} /* Strides (in bytes) for each index */
|
{self.item_size()} /* Strides (in bytes) for each index */
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "aare/NDView.hpp"
|
#include "aare/NDView.hpp"
|
||||||
|
|
||||||
namespace py = pybind11;
|
namespace py = pybind11;
|
||||||
|
using namespace aare;
|
||||||
|
|
||||||
// Pass image data back to python as a numpy array
|
// Pass image data back to python as a numpy array
|
||||||
template <typename T, int64_t Ndim>
|
template <typename T, int64_t Ndim>
|
||||||
@ -64,4 +65,22 @@ template <class T, int Flags> auto make_view_2d(py::array_t<T, Flags> &arr) {
|
|||||||
}
|
}
|
||||||
template <class T, int Flags> auto make_view_1d(py::array_t<T, Flags> &arr) {
|
template <class T, int Flags> auto make_view_1d(py::array_t<T, Flags> &arr) {
|
||||||
return aare::NDView<T, 1>(arr.mutable_data(), get_shape_1d<T, Flags>(arr));
|
return aare::NDView<T, 1>(arr.mutable_data(), get_shape_1d<T, Flags>(arr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename ClusterType> struct fmt_format_trait; // forward declaration
|
||||||
|
|
||||||
|
template <typename T, uint8_t ClusterSizeX, uint8_t ClusterSizeY,
|
||||||
|
typename CoordType>
|
||||||
|
struct fmt_format_trait<Cluster<T, ClusterSizeX, ClusterSizeY, CoordType>> {
|
||||||
|
|
||||||
|
static std::string value() {
|
||||||
|
return fmt::format("T{{{}:x;{}:y;{}:data;}}",
|
||||||
|
py::format_descriptor<CoordType>::format(),
|
||||||
|
py::format_descriptor<CoordType>::format(),
|
||||||
|
fmt::format("{}{}", ClusterSizeX * ClusterSizeY,
|
||||||
|
py::format_descriptor<T>::format()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename ClusterType>
|
||||||
|
auto fmt_format = fmt_format_trait<ClusterType>::value();
|
@ -25,10 +25,7 @@ TEST_CASE("ClusterVector 2x2 int32_t capacity 4, push back then read",
|
|||||||
REQUIRE(cv.size() == 1);
|
REQUIRE(cv.size() == 1);
|
||||||
REQUIRE(cv.capacity() == 4);
|
REQUIRE(cv.capacity() == 4);
|
||||||
|
|
||||||
// Read the cluster back out using copy. TODO! Can we improve the API?
|
auto c2 = cv.at(0);
|
||||||
Cluster<int32_t, 2, 2> c2;
|
|
||||||
std::byte *ptr = cv.element_ptr(0);
|
|
||||||
std::copy(ptr, ptr + cv.item_size(), reinterpret_cast<std::byte *>(&c2));
|
|
||||||
|
|
||||||
// Check that the data is the same
|
// Check that the data is the same
|
||||||
REQUIRE(c1.x == c2.x);
|
REQUIRE(c1.x == c2.x);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user