22#include "utilities/general.hpp"
23#include "utilities/iterators.hpp"
24#include "utilities/string.hpp"
26typedef Range<size_t> SampleRange;
28inline std::vector<std::string> generate_labels(
size_t nchannels) {
29 std::vector<std::string> labels;
30 for (
size_t i = 0; i < nchannels; i++) {
31 labels.push_back(std::to_string(i));
39using ParentType = AnyType;
42 Parameters(
const std::vector<std::string>& labels,
size_t nsamp = 0)
43 : ncolumns(labels.size()), nsamples(nsamp), labels(labels) {}
47 std::vector<std::string> labels;
60 Data(
const std::vector<std::string>& labels,
size_t nsamples) {
61 if (labels.size() == 0 || nsamples == 0) {
62 throw std::runtime_error(
63 "Column Data::Initialize - number of "
64 "columns/samples needs to be larger than 0.");
67 ncolumns_ = labels.size();
69 data_.resize(ncolumns_ * nsamples_);
78 static const std::string static_datatype() {
return "columnar [" + get_type_string<T>() +
"]"; }
79 static const std::string static_dataname() {
return "data"; }
84 void ClearData()
override { std::fill(data_.begin(), data_.end(), 0); }
88 size_t ncolumns()
const {
return ncolumns_; }
89 size_t nsamples()
const {
return nsamples_; }
90 std::vector<std::string> labels()
const {
return labels_; }
99 if (
data.size() != this->nsamples_) {
100 throw std::length_error(
101 ". the data vector to set should have the "
102 "same size as the number of columns (" +
103 std::to_string(ncolumns_) +
" columns)");
115 if (
data.size() != this->nsamples_) {
116 throw std::length_error(
117 ". the data vector to set should have the "
118 "same size as the number of samples (" +
119 std::to_string(nsamples_) +
" samples)");
130 if (
data.size() != ncolumns_) {
131 throw std::length_error(
132 ". the data vector to set should have the same size as the "
133 "number of column in the dataset (" +
134 std::to_string(ncolumns_) +
" columns)");
147 if (sample >= nsamples_) {
148 throw std::out_of_range(
". Sample index " + std::to_string(sample) +
149 " out of range. Max index is " + std::to_string(nsamples_ - 1));
151 if (column >= ncolumns_) {
152 throw std::out_of_range(
". Channel index " + std::to_string(sample) +
153 " out of range. Max index is " + std::to_string(ncolumns_ - 1));
155 data_[flat_index(sample, column)] =
data;
166 auto index = extract_index_from_column(column);
176 std::vector<T>&
data() {
return data_; }
177 const std::vector<T>&
data()
const {
return data_; }
187 return data_[flat_index(sample, column)];
198 return data_[flat_index(sample, extract_index_from_column(column))];
203 T& operator()(
size_t sample,
size_t column = 0) {
return data_[flat_index(sample, column)]; }
204 const T& operator()(
size_t sample,
size_t column = 0)
const {
205 return data_[flat_index(sample, column)];
210 T& operator()(
size_t sample, std::string column) {
211 auto index = extract_index_from_column(column);
212 return data_[flat_index(sample, index)];
214 const T& operator()(
size_t sample, std::string column)
const {
215 auto index = extract_index_from_column(column);
216 return data_[flat_index(sample, index)];
221 T& operator()(
size_t index) {
return data_[index]; }
222 const T& operator()(
size_t index)
const {
return data_[index]; }
238 const T*
begin_sample(
size_t sample)
const {
return &data_[flat_index(sample)]; }
248 return stride_iter<T*>(&data_[column], ncolumns_);
265 auto index = extract_index_from_column(column);
283 Serialization::Format::FULL)
const override {
284 BaseClass::SerializeBinary(stream, format);
285 if (format == Serialization::Format::FULL) {
286 stream.write(
reinterpret_cast<const char*
>(data_.data()), data_.size() *
sizeof(T));
289 if (format == Serialization::Format::COMPACT) {
290 uint32_t nsamples_out =
static_cast<uint32_t
>(nsamples_);
291 uint32_t ncolumns_out =
static_cast<uint32_t
>(ncolumns_);
292 stream.write(
reinterpret_cast<const char*
>(&nsamples_out),
sizeof(uint32_t));
293 stream.write(
reinterpret_cast<const char*
>(&ncolumns_out),
sizeof(uint32_t));
295 for (
size_t k = 0; k < nsamples_; ++k) {
296 stream.write(
reinterpret_cast<const char*
>(&data_[flat_index(k)]),
297 sizeof(T) * ncolumns_);
309 BaseClass::SerializeFlatBuffer(flex_builder);
311 flex_builder.TypedVector(
"labels", [&] {
312 for (
const auto& label : labels_) flex_builder.Add(label);
315 flex_builder.TypedVector(
"data", [&] {
316 for (
auto samples : data_) flex_builder.Add(samples);
319 flex_builder.UInt(
"ncolumns", ncolumns());
320 flex_builder.UInt(
"nsamples", nsamples());
329 Serialization::Format format = Serialization::Format::FULL)
const override {
330 BaseClass::SerializeYAML(node, format);
331 if (format == Serialization::Format::FULL || format == Serialization::Format::COMPACT) {
332 node[
"signal"] = data_;
343 Serialization::Format::FULL)
const override {
344 BaseClass::YAMLDescription(node, format);
345 if (format == Serialization::Format::FULL) {
346 node.push_back(
"signal " + get_type_string<T>() +
" (" +
347 std::to_string(nsColumn::Data<T>::nsamples()) +
"," +
348 std::to_string(nsColumn::Data<T>::ncolumns()) +
")");
351 if (format == Serialization::Format::COMPACT) {
352 node.push_back(
"signal " + get_type_string<T>() +
" (" +
353 std::to_string(nsColumn::Data<T>::ncolumns()) +
")");
365 T
sum_column(std::string column,
bool absolute =
false)
const {
366 auto index = extract_index_from_column(column);
381 [](T a, T b) {
return a + std::abs(b); });
396 return sum_column(column, absolute) / ncolumns_;
408 return sum_column(column, absolute) / ncolumns_;
422 [](T a, T b) {
return a + std::abs(b); });
436 return sum_sample(sample, absolute) / ncolumns_;
440 size_t extract_index_from_column(std::string column)
const {
441 auto it = std::find(labels_.begin(), labels_.end(), column);
444 if (it == labels_.end()) {
445 throw std::runtime_error(
". The column " + column +
" does not exist in this dataset.");
448 return it - labels_.begin();
452 inline size_t flat_index(
size_t sample,
size_t channel)
const {
453 return channel + sample * ncolumns_;
455 inline size_t flat_index(
size_t sample)
const {
return sample * ncolumns_; }
461 std::vector<std::string> labels_;
462 std::vector<T> data_;
467 Capabilities(ChannelRange column_range,
468 SampleRange sample_range = SampleRange(1, std::numeric_limits<uint32_t>::max()))
469 : column_range_(column_range), sample_range_(sample_range), labels_({}) {}
471 Capabilities(std::vector<std::string> labels,
472 SampleRange sample_range = SampleRange(1, std::numeric_limits<uint32_t>::max()))
473 : column_range_(ChannelRange(labels.size())),
474 sample_range_(sample_range),
477 ChannelRange column_range()
const {
return column_range_; }
478 SampleRange sample_range()
const {
return sample_range_; }
481 void Validate(
const Data<T>& prototype) {
482 if (!sample_range_.inrange(prototype.nsamples())) {
483 throw std::runtime_error(
"Number of samples cannot be zero and needs to be in range " +
484 sample_range_.to_string());
487 if (!column_range_.inrange(prototype.ncolumns())) {
488 throw std::runtime_error(
"Number of columns cannot be zero and needs to be in range " +
489 column_range_.to_string());
492 auto cl = prototype.labels();
493 for (
auto label : labels_) {
494 if (std::find(cl.begin(), cl.end(), label) == cl.end()) {
495 throw std::runtime_error(
"Expected column: " + label +
496 " is not part of the column dataset given in input.");
502 ChannelRange column_range_;
503 SampleRange sample_range_;
504 std::vector<std::string> labels_;
Convenient template class to define data types.
Definition idata.hpp:75
Base class of all data object classes.
Definition idata.hpp:95
Definition columnsdata.hpp:465
Definition columnsdata.hpp:51
T * end_sample(size_t sample)
end_sample iterator at the end of a sample index
Definition columnsdata.hpp:236
void YAMLDescription(YAML::Node &node, Serialization::Format format=Serialization::Format::FULL) const override
YAMLDescription - this datatype add to the metadata describing the data format the signal,...
Definition columnsdata.hpp:342
const T & data_sample(size_t sample, size_t column=0) const
data_sample - return the data for one sample index and one column index
Definition columnsdata.hpp:186
void set_data_column(std::string column, const std::vector< T > &data)
set_data_column set all samples for one column based on the name of the column
Definition columnsdata.hpp:98
T sum_sample(size_t sample, bool absolute=false) const
sum_sample - compute the (absolute) sum of all column data for the same sample index
Definition columnsdata.hpp:419
const T & data_sample(size_t sample, std::string column) const
data_sample - return the data for one sample index and one column label
Definition columnsdata.hpp:197
T * begin_sample(size_t sample)
begin_sample iterator at the start of a sample index
Definition columnsdata.hpp:230
void SerializeBinary(std::ostream &stream, Serialization::Format format=Serialization::Format::FULL) const override
SerializeBinary - add to the binary stream the data [columnxsample].
Definition columnsdata.hpp:282
void SerializeYAML(YAML::Node &node, Serialization::Format format=Serialization::Format::FULL) const override
SerializeYAML - add to the yaml node the data [columnxsample].
Definition columnsdata.hpp:328
T mean_sample(size_t sample, bool absolute=false) const
mean_sample - compute the mean of the (absolute) sum of all column data for the same sample index
Definition columnsdata.hpp:435
stride_iter< T * > end_column(size_t column)
end_column - iterator at the end of the column based on the location in the dataset
Definition columnsdata.hpp:256
void set_data_sample(size_t sample, size_t column, T data)
set_data_sample set one data for one column index and one sample index
Definition columnsdata.hpp:146
void set_data_sample(size_t sample, std::string column, T data)
set_data_sample set one data for one column label and one sample index
Definition columnsdata.hpp:165
void ClearData() override
ClearData - clear the data.
Definition columnsdata.hpp:84
T mean_column(size_t column, bool absolute=false) const
mean_column - compute the mean of the (absolute) sum of all samples in the same column
Definition columnsdata.hpp:407
void set_data_sample(size_t sample, const std::vector< T > &data)
set_data_sample set column data for one sample
Definition columnsdata.hpp:129
stride_iter< T * > begin_column(std::string column)
begin_column - iterator at the start of the column based on name of the column
Definition columnsdata.hpp:264
void set_data_column(size_t column, const std::vector< T > &data)
set_data_column set all samples for one column based on the column index
Definition columnsdata.hpp:114
Data(const std::vector< std::string > &labels, size_t nsamples)
Data constructor with the labels for each column and the number of samples.
Definition columnsdata.hpp:60
stride_iter< T * > begin_column(size_t column)
begin_column iterator at the start of the column based on the location in the dataset
Definition columnsdata.hpp:247
T sum_column(std::string column, bool absolute=false) const
sum_column - compute the (absolute) sum of all samples in the same column
Definition columnsdata.hpp:365
Data(const Parameters ¶meters)
Data constructor from the parameters object.
Definition columnsdata.hpp:76
T mean_column(std::string column, bool absolute=false) const
mean_column - compute the mean of the (absolute) sum of all samples in the same column
Definition columnsdata.hpp:395
std::vector< T > & data()
data - return full data with this format [c1s1, c1s2.., c1sn, c2s1, c2s2 ..., cns1,...
Definition columnsdata.hpp:176
T sum_column(size_t column, bool absolute=false) const
sum_column - compute the (absolute) sum of all samples in the same column
Definition columnsdata.hpp:378
stride_iter< T * > end_column(std::string column)
end_column - iterator at the end of the column based on name of the column
Definition columnsdata.hpp:274
void SerializeFlatBuffer(flexbuffers::Builder &flex_builder) override
SerializeFlatBuffer - add to the flexbuffer the data labeled [label0:nsamples, label1:nsamples....
Definition columnsdata.hpp:308
Definition columnsdata.hpp:41