Falcon
Loading...
Searching...
No Matches
timeseriesdata.hpp
1// ---------------------------------------------------------------------
2// This file is part of falcon-core.
3//
4// Copyright (C) 2021-present Neuro-Electronics Research Flanders
5//
6// Falcon-server is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10//
11// Falcon-server is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with falcon-core. If not, see <http://www.gnu.org/licenses/>.
18// ---------------------------------------------------------------------
19
20#pragma once
21
22#include <algorithm>
23#include <cmath>
24#include <string>
25#include <vector>
26
27#include "columnsdata/columnsdata.hpp"
28#include "idata.hpp"
29
30namespace nsTimeSeries {
31
32struct Parameters : nsColumn::Parameters {
33 Parameters(size_t nchan = 0, size_t nsamp = 0, double rate = 1.0)
34 : nsColumn::Parameters(generate_labels(nchan), nsamp), sample_rate(rate) {}
35
36 Parameters(const std::vector<std::string>& labels, size_t nsamp = 0, double rate = 1.0)
37 : nsColumn::Parameters(labels, nsamp), sample_rate(rate) {}
38
39 double sample_rate;
40};
41
42template <typename T>
43using Base = ColumnsType<T>;
44
45template <typename T>
46class Data : public IData<Data<T>, Base<T>> {
47 using BaseClass = IData<Data<T>, Base<T>>;
48
49 public:
50 typedef stride_iter<T*> column_iterator;
51 typedef T* sample_iterator;
52
62 Data(const std::vector<std::string>& labels, size_t nsamples, double sample_rate)
63 : BaseClass(labels, nsamples) {
64 if (sample_rate <= 0) {
65 throw std::runtime_error(
66 "Time Series Data::Data - sample rate "
67 "needs to be larger than 0.");
68 }
69
70 sample_rate_ = sample_rate;
71 timestamps_.resize(nsamples);
72 }
73
84 Data(size_t ncolumns, size_t nsamples, double sample_rate)
85 : Data(generate_labels(ncolumns), ncolumns, nsamples, sample_rate) {}
86
93 Data(const Parameters& parameters)
94 : Data(parameters.labels, parameters.nsamples, parameters.sample_rate) {}
95
96 static const std::string static_datatype() {
97 return "time series [" + get_type_string<T>() + "]";
98 }
99 static const std::string static_dataname() { return "data"; }
100
105 void ClearData() override {
106 BaseClass::ClearData();
107 std::fill(timestamps_.begin(), timestamps_.end(), 0);
108 }
109
110 Parameters parameters() const {
111 return Parameters(this->labels_, this->nsamples_, sample_rate_);
112 }
113
114 double sample_rate() const { return sample_rate_; }
115
122 uint64_t sample_timestamp(size_t sample = 0) const { return timestamps_[sample]; }
123
128 const std::vector<uint64_t>& sample_timestamps() const { return timestamps_; }
129 std::vector<uint64_t>& sample_timestamps() { return timestamps_; }
130
136 void set_sample_timestamp(size_t sample, uint64_t t) {
137 if (sample >= this->nsamples_) {
138 throw std::out_of_range(". Sample index " + std::to_string(sample) +
139 " out of range. Max index is " +
140 std::to_string(this->nsamples_ - 1));
141 } else {
142 timestamps_[sample] = t;
143 }
144 }
145
150 void set_sample_timestamps(const std::vector<uint64_t>& t) {
151 if (t.size() != this->nsamples_) {
152 throw std::length_error(
153 ". the timestamps vector to set should have the same size as "
154 "the number of samples (" +
155 std::to_string(this->nsamples_) + " samples)");
156 }
157 timestamps_ = t;
158 }
159
168 void SerializeFlatBuffer(flexbuffers::Builder& flex_builder) override {
169 BaseClass::SerializeFlatBuffer(flex_builder);
170 flex_builder.TypedVector("timestamps", [&] {
171 for (auto samples : timestamps_) flex_builder.Add(samples);
172 });
173 }
174
184 void SerializeBinary(std::ostream& stream, Serialization::Format format =
185 Serialization::Format::FULL) const override {
186 BaseClass::SerializeBinary(stream, format);
187
188 if (format == Serialization::Format::FULL || format == Serialization::Format::COMPACT) {
189 stream.write(reinterpret_cast<const char*>(timestamps_.data()),
190 timestamps_.size() * sizeof(uint64_t));
191 }
192 }
193
194 std::string_view serialized_type_name() const override {
195 if constexpr (std::is_same_v<T, double>) {
196 return "TimeSeriesType<double>";
197 } else if constexpr (std::is_same_v<T, float>) {
198 return "TimeSeriesType<float>";
199 } else if constexpr (std::is_same_v<T, uint8_t>) {
200 return "TimeSeriesType<uint8_t>";
201 } else {
202 return "TimeSeriesType<Unknown>";
203 }
204 }
205
214 void SerializeYAML(YAML::Node& node,
215 Serialization::Format format = Serialization::Format::FULL) const override {
216 BaseClass::SerializeYAML(node, format);
217
218 if (format == Serialization::Format::FULL || format == Serialization::Format::COMPACT) {
219 node["timestamps"] = timestamps_;
220 }
221 }
222
230 void YAMLDescription(YAML::Node& node, Serialization::Format format =
231 Serialization::Format::FULL) const override {
232 BaseClass::YAMLDescription(node, format);
233
234 if (format == Serialization::Format::FULL) {
235 node.push_back("timestamps uint64 (" + std::to_string(this->nsamples()) + ")");
236 }
237
238 if (format == Serialization::Format::COMPACT) {
239 node.push_back("timestamps uint64 (1)");
240 }
241 }
242
243 protected:
244 double sample_rate_;
245 std::vector<uint64_t> timestamps_;
246};
247
248using Capabilities = nsColumn::Capabilities;
249} // namespace nsTimeSeries
250
251template <typename T>
252using TimeSeriesType = DefineType<nsTimeSeries::Data<T>, ColumnsType<T>, false,
253 nsTimeSeries::Capabilities, nsTimeSeries::Parameters>;
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
void set_sample_timestamps(const std::vector< uint64_t > &t)
set_sample_timestamps - set all timestamps for all sample
Definition timeseriesdata.hpp:150
void SerializeYAML(YAML::Node &node, Serialization::Format format=Serialization::Format::FULL) const override
SerializeYAML - This datatype add as a yaml node the timestamps.
Definition timeseriesdata.hpp:214
void set_sample_timestamp(size_t sample, uint64_t t)
set_sample_timestamp - set one timestamp for a given sample number
Definition timeseriesdata.hpp:136
void ClearData() override
ClearData - clear the timestamps and the data (done in the columndatatype::Data).
Definition timeseriesdata.hpp:105
Data(const std::vector< std::string > &labels, size_t nsamples, double sample_rate)
Data constructor with the label of the columns, the number of samples and the sample rate.
Definition timeseriesdata.hpp:62
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 timestamp format.
Definition timeseriesdata.hpp:230
void SerializeBinary(std::ostream &stream, Serialization::Format format=Serialization::Format::FULL) const override
SerializeBinary - This datatype add in the binary stream the timestamps.
Definition timeseriesdata.hpp:184
uint64_t sample_timestamp(size_t sample=0) const
sample_timestamp - give the timestamp corresponding to a sample number
Definition timeseriesdata.hpp:122
Data(size_t ncolumns, size_t nsamples, double sample_rate)
Data constructor with only the number of columns, the number of samples and the sample rate.
Definition timeseriesdata.hpp:84
const std::vector< uint64_t > & sample_timestamps() const
sample_timestamps - give all the timestamps in the packet
Definition timeseriesdata.hpp:128
void SerializeFlatBuffer(flexbuffers::Builder &flex_builder) override
FlatbufferDescription - This datatype add in the flexbuffer stream the timestamps and the type name.
Definition timeseriesdata.hpp:168
Data(const Parameters &parameters)
Data constructor based on the parameters object.
Definition timeseriesdata.hpp:93
Definition columnsdata.hpp:41
Definition timeseriesdata.hpp:32