2022-09-27 15:20:45 +00:00
|
|
|
/* #define DEBUGTRACE_ENABLED */
|
2022-10-10 17:17:38 +00:00
|
|
|
#include "lasp_daqdata.h"
|
2022-10-20 15:12:34 +00:00
|
|
|
#include "debugtrace.hpp"
|
2022-10-04 07:27:27 +00:00
|
|
|
#include "lasp_mathtypes.h"
|
2022-10-20 15:12:34 +00:00
|
|
|
#include <armadillo>
|
2022-06-13 19:30:02 +00:00
|
|
|
#include <cassert>
|
2022-10-10 17:17:38 +00:00
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
using std::cerr;
|
|
|
|
using std::cout;
|
|
|
|
using std::endl;
|
|
|
|
using rte = std::runtime_error;
|
|
|
|
|
|
|
|
static_assert(sizeof(byte_t) == 1, "Invalid char size");
|
2022-06-13 19:30:02 +00:00
|
|
|
|
|
|
|
DEBUGTRACE_VARIABLES;
|
|
|
|
|
2022-10-10 17:17:38 +00:00
|
|
|
/// Constructors and destructors
|
|
|
|
DaqData::DaqData(const us nframes, const us nchannels,
|
2022-06-13 19:30:02 +00:00
|
|
|
const DataTypeDescriptor::DataType dtype)
|
2022-10-10 17:17:38 +00:00
|
|
|
|
|
|
|
: nframes(nframes), nchannels(nchannels), dtype(dtype),
|
2022-10-04 07:27:27 +00:00
|
|
|
dtype_descr(dtype_map.at(dtype)), sw(dtype_descr.sw) {
|
2022-06-13 19:30:02 +00:00
|
|
|
|
2022-10-10 17:17:38 +00:00
|
|
|
DEBUGTRACE_ENTER;
|
|
|
|
DEBUGTRACE_PRINT(sw);
|
|
|
|
|
2022-10-11 12:50:44 +00:00
|
|
|
assert(sw > 0 && sw <= 8);
|
2023-06-18 19:05:47 +00:00
|
|
|
_data = reinterpret_cast<byte_t *>(
|
|
|
|
new double[(sw * nchannels * nframes) / sizeof(double) + 1]);
|
|
|
|
|
2022-10-10 17:17:38 +00:00
|
|
|
if (!_data) {
|
|
|
|
throw rte("Could not allocate memory for DaqData!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DaqData::DaqData(const DaqData &o) : DaqData(o.nframes, o.nchannels, o.dtype) {
|
|
|
|
|
|
|
|
DEBUGTRACE_ENTER;
|
|
|
|
memcpy(_data, o._data, sw * nchannels * nframes);
|
2022-06-13 19:30:02 +00:00
|
|
|
}
|
|
|
|
|
2022-10-20 15:12:34 +00:00
|
|
|
DaqData::DaqData(DaqData &&o)
|
|
|
|
: nframes(o.nframes), nchannels(o.nchannels), dtype(o.dtype),
|
|
|
|
dtype_descr(std::move(o.dtype_descr)), sw(o.sw) {
|
2022-10-10 17:17:38 +00:00
|
|
|
|
2022-10-20 15:12:34 +00:00
|
|
|
/// Steal from other one
|
|
|
|
|
|
|
|
DEBUGTRACE_ENTER;
|
|
|
|
_data = o._data;
|
|
|
|
/// Nullptrs do not get deleted
|
|
|
|
o._data = nullptr;
|
|
|
|
}
|
2022-10-10 17:17:38 +00:00
|
|
|
|
|
|
|
DaqData::~DaqData() {
|
|
|
|
DEBUGTRACE_ENTER;
|
|
|
|
if (_data)
|
2023-06-18 19:05:47 +00:00
|
|
|
delete[](reinterpret_cast<double *>(_data));
|
2022-10-10 17:17:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DaqData::copyInFromRaw(const std::vector<byte_t *> &ptrs) {
|
|
|
|
DEBUGTRACE_ENTER;
|
2022-06-13 19:30:02 +00:00
|
|
|
us ch = 0;
|
|
|
|
assert(ptrs.size() == nchannels);
|
2022-10-20 15:12:34 +00:00
|
|
|
for (auto &ptr : ptrs) {
|
|
|
|
copyInFromRaw(ch, ptr);
|
2022-06-13 19:30:02 +00:00
|
|
|
ch++;
|
|
|
|
}
|
|
|
|
}
|
2022-10-20 15:12:34 +00:00
|
|
|
void DaqData::copyInFromRaw(const us channel, const byte_t *ptr) {
|
|
|
|
DEBUGTRACE_ENTER;
|
|
|
|
assert(ptr);
|
|
|
|
memcpy(&_data[sw * channel * nframes], ptr, sw * nframes);
|
|
|
|
}
|
2022-06-13 19:30:02 +00:00
|
|
|
|
2022-10-10 17:17:38 +00:00
|
|
|
void DaqData::copyToRaw(const us channel, byte_t *ptr) {
|
|
|
|
/* std::copy(raw_ptr(0, channel), raw_ptr(nframes, channel), ptr); */
|
2022-10-20 15:12:34 +00:00
|
|
|
assert(channel < nchannels);
|
2022-10-12 13:02:42 +00:00
|
|
|
assert(ptr);
|
2022-10-20 15:12:34 +00:00
|
|
|
memcpy(ptr, raw_ptr(0, channel), sw * nframes);
|
2022-06-13 19:30:02 +00:00
|
|
|
}
|
2022-10-04 07:27:27 +00:00
|
|
|
|
2022-10-10 17:17:38 +00:00
|
|
|
template <typename T>
|
|
|
|
d DaqData::toFloat(const us frame, const us channel) const {
|
2022-10-12 13:02:42 +00:00
|
|
|
/* DEBUGTRACE_ENTER; */
|
2022-10-10 17:17:38 +00:00
|
|
|
if constexpr (std::is_integral<T>::value) {
|
|
|
|
return static_cast<d>(value<T>(frame, channel)) /
|
2022-10-20 15:12:34 +00:00
|
|
|
std::numeric_limits<T>::max();
|
2022-10-04 07:27:27 +00:00
|
|
|
} else {
|
2022-10-10 17:17:38 +00:00
|
|
|
return static_cast<d>(value<T>(frame, channel));
|
2022-10-04 07:27:27 +00:00
|
|
|
}
|
|
|
|
}
|
2022-10-10 17:17:38 +00:00
|
|
|
|
|
|
|
template <typename T> vd DaqData::toFloat(const us channel) const {
|
|
|
|
DEBUGTRACE_ENTER;
|
|
|
|
#if LASP_DEBUG == 1
|
2022-10-20 15:12:34 +00:00
|
|
|
check_type<T>();
|
2022-10-10 17:17:38 +00:00
|
|
|
#endif
|
2022-10-04 07:27:27 +00:00
|
|
|
vd res(nframes);
|
|
|
|
for (us i = 0; i < nframes; i++) {
|
2022-10-10 17:17:38 +00:00
|
|
|
res(i) = toFloat<T>(i, channel);
|
2022-10-04 07:27:27 +00:00
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
2022-10-10 17:17:38 +00:00
|
|
|
template <typename T> dmat DaqData::toFloat() const {
|
|
|
|
|
|
|
|
DEBUGTRACE_ENTER;
|
|
|
|
#if LASP_DEBUG == 1
|
2022-10-20 15:12:34 +00:00
|
|
|
check_type<T>();
|
2022-10-10 17:17:38 +00:00
|
|
|
#endif
|
2022-10-04 07:27:27 +00:00
|
|
|
dmat res(nframes, nchannels);
|
2022-10-10 17:17:38 +00:00
|
|
|
|
|
|
|
for (us i = 0; i < nframes; i++) {
|
|
|
|
for (us j = 0; j < nchannels; j++) {
|
|
|
|
res(i, j) = toFloat<T>(i, j);
|
2022-10-04 07:27:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2022-10-10 17:17:38 +00:00
|
|
|
d DaqData::toFloat(const us frame, const us channel) const {
|
|
|
|
DEBUGTRACE_ENTER;
|
|
|
|
using DataType = DataTypeDescriptor::DataType;
|
|
|
|
switch (dtype) {
|
|
|
|
case (DataType::dtype_int8):
|
|
|
|
return toFloat<int8_t>(frame, channel);
|
|
|
|
break;
|
|
|
|
case (DataType::dtype_int16):
|
|
|
|
return toFloat<int16_t>(frame, channel);
|
|
|
|
break;
|
|
|
|
case (DataType::dtype_int32):
|
|
|
|
return toFloat<int32_t>(frame, channel);
|
|
|
|
break;
|
|
|
|
case (DataType::dtype_fl32):
|
|
|
|
return toFloat<float>(frame, channel);
|
|
|
|
break;
|
|
|
|
case (DataType::dtype_fl64):
|
|
|
|
return toFloat<double>(frame, channel);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw std::runtime_error("BUG");
|
|
|
|
} // End of switch
|
|
|
|
|
|
|
|
// Never arrives her
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-10-04 07:27:27 +00:00
|
|
|
vd DaqData::toFloat(const us channel_no) const {
|
2022-10-10 17:17:38 +00:00
|
|
|
DEBUGTRACE_ENTER;
|
2022-10-04 07:27:27 +00:00
|
|
|
using DataType = DataTypeDescriptor::DataType;
|
2022-10-20 15:12:34 +00:00
|
|
|
/* cerr << (int)dtype << endl; */
|
2022-10-04 07:27:27 +00:00
|
|
|
switch (dtype) {
|
|
|
|
case (DataType::dtype_int8): {
|
2022-10-10 17:17:38 +00:00
|
|
|
return toFloat<int8_t>(channel_no);
|
2022-10-04 07:27:27 +00:00
|
|
|
} break;
|
|
|
|
case (DataType::dtype_int16): {
|
2022-10-10 17:17:38 +00:00
|
|
|
return toFloat<int16_t>(channel_no);
|
2022-10-04 07:27:27 +00:00
|
|
|
} break;
|
|
|
|
case (DataType::dtype_int32): {
|
2022-10-10 17:17:38 +00:00
|
|
|
return toFloat<int32_t>(channel_no);
|
2022-10-04 07:27:27 +00:00
|
|
|
} break;
|
|
|
|
case (DataType::dtype_fl32): {
|
2022-10-10 17:17:38 +00:00
|
|
|
return toFloat<float>(channel_no);
|
2022-10-04 07:27:27 +00:00
|
|
|
} break;
|
|
|
|
case (DataType::dtype_fl64): {
|
2022-10-10 17:17:38 +00:00
|
|
|
return toFloat<double>(channel_no);
|
2022-10-04 07:27:27 +00:00
|
|
|
} break;
|
|
|
|
default:
|
|
|
|
throw std::runtime_error("BUG");
|
|
|
|
} // End of switch
|
2022-10-10 17:17:38 +00:00
|
|
|
|
|
|
|
// Never arrives here
|
|
|
|
return vd();
|
2022-10-04 07:27:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
dmat DaqData::toFloat() const {
|
2022-10-10 17:17:38 +00:00
|
|
|
|
|
|
|
DEBUGTRACE_ENTER;
|
|
|
|
/* DEBUGTRACE_PRINT(nframes); */
|
|
|
|
/* DEBUGTRACE_PRINT(nchannels); */
|
|
|
|
|
2022-10-04 07:27:27 +00:00
|
|
|
using DataType = DataTypeDescriptor::DataType;
|
2022-10-10 17:17:38 +00:00
|
|
|
|
|
|
|
/* cerr << "DataType: " << (int) dtype << endl; */
|
|
|
|
|
2022-10-04 07:27:27 +00:00
|
|
|
switch (dtype) {
|
2022-10-10 17:17:38 +00:00
|
|
|
case (DataType::dtype_int8):
|
|
|
|
return toFloat<int8_t>();
|
|
|
|
break;
|
|
|
|
case (DataType::dtype_int16):
|
2022-10-11 12:50:44 +00:00
|
|
|
DEBUGTRACE_PRINT("Dtype = int16");
|
2022-10-10 17:17:38 +00:00
|
|
|
return toFloat<int16_t>();
|
|
|
|
break;
|
|
|
|
case (DataType::dtype_int32):
|
|
|
|
return toFloat<int32_t>();
|
|
|
|
break;
|
|
|
|
case (DataType::dtype_fl32):
|
2022-10-11 12:50:44 +00:00
|
|
|
DEBUGTRACE_PRINT("Dtype = float32");
|
2022-10-10 17:17:38 +00:00
|
|
|
return toFloat<float>();
|
|
|
|
break;
|
|
|
|
case (DataType::dtype_fl64):
|
2022-10-11 12:50:44 +00:00
|
|
|
DEBUGTRACE_PRINT("Dtype = float64");
|
2022-10-10 17:17:38 +00:00
|
|
|
return toFloat<double>();
|
|
|
|
break;
|
2022-10-04 07:27:27 +00:00
|
|
|
default:
|
|
|
|
throw std::runtime_error("BUG");
|
|
|
|
} // End of switch
|
2022-10-10 17:17:38 +00:00
|
|
|
|
|
|
|
// Never reached
|
|
|
|
return dmat();
|
|
|
|
}
|
|
|
|
|
2022-10-20 15:12:34 +00:00
|
|
|
template <typename T>
|
|
|
|
void DaqData::fromFloat(const us frame, const us channel, const d val) {
|
|
|
|
DEBUGTRACE_ENTER;
|
|
|
|
#if LASP_DEBUG == 1
|
|
|
|
check_type<T>();
|
|
|
|
#endif
|
|
|
|
if constexpr (std::is_integral<T>::value) {
|
|
|
|
value<T>(frame, channel) =
|
|
|
|
static_cast<T>(val * std::numeric_limits<T>::max());
|
|
|
|
} else {
|
|
|
|
value<T>(frame, channel) = static_cast<T>(val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DaqData::fromFloat(const us frame, const us channel, const d val) {
|
|
|
|
|
|
|
|
using DataType = DataTypeDescriptor::DataType;
|
|
|
|
|
|
|
|
switch (dtype) {
|
|
|
|
case (DataType::dtype_int8):
|
|
|
|
return fromFloat<int8_t>(frame, channel, val);
|
|
|
|
break;
|
|
|
|
case (DataType::dtype_int16):
|
|
|
|
return fromFloat<int16_t>(frame, channel, val);
|
|
|
|
break;
|
|
|
|
case (DataType::dtype_int32):
|
|
|
|
return fromFloat<int32_t>(frame, channel, val);
|
|
|
|
break;
|
|
|
|
case (DataType::dtype_fl32):
|
|
|
|
return fromFloat<float>(frame, channel, val);
|
|
|
|
break;
|
|
|
|
case (DataType::dtype_fl64):
|
|
|
|
return fromFloat<float>(frame, channel, val);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw std::runtime_error("BUG");
|
|
|
|
} // End of switch
|
|
|
|
}
|
|
|
|
void DaqData::fromFloat(const us channel, const vd &vals) {
|
|
|
|
if (vals.size() != nframes) {
|
|
|
|
throw rte("Invalid number of frames in channel data");
|
|
|
|
}
|
|
|
|
using DataType = DataTypeDescriptor::DataType;
|
|
|
|
switch (dtype) {
|
|
|
|
case (DataType::dtype_int8):
|
|
|
|
for (us frame = 0; frame < nframes; frame++) {
|
|
|
|
fromFloat<int8_t>(frame, channel, vals(frame));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case (DataType::dtype_int16):
|
|
|
|
for (us frame = 0; frame < nframes; frame++) {
|
|
|
|
fromFloat<int16_t>(frame, channel, vals(frame));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case (DataType::dtype_int32):
|
|
|
|
for (us frame = 0; frame < nframes; frame++) {
|
|
|
|
fromFloat<int32_t>(frame, channel, vals(frame));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case (DataType::dtype_fl32):
|
|
|
|
for (us frame = 0; frame < nframes; frame++) {
|
|
|
|
fromFloat<float>(frame, channel, vals(frame));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case (DataType::dtype_fl64):
|
|
|
|
for (us frame = 0; frame < nframes; frame++) {
|
|
|
|
fromFloat<double>(frame, channel, vals(frame));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw std::runtime_error("BUG");
|
|
|
|
} // End of switch
|
|
|
|
}
|
|
|
|
|
2022-10-10 17:17:38 +00:00
|
|
|
void DaqData::print() const {
|
|
|
|
cout << "Number of frames: " << nframes << endl;
|
|
|
|
cout << "Number of channels: " << nchannels << endl;
|
|
|
|
cout << "DataType: " << dtype_map.at(dtype).name << endl;
|
2022-10-20 15:12:34 +00:00
|
|
|
cout << "First sample of first channel (as float)" << toFloat(0, 0) << endl;
|
|
|
|
cout << "Last sample of first channel (as float)" << toFloat(nframes - 1, 0)
|
|
|
|
<< endl;
|
|
|
|
cout << "Last sample of last channel (as float)"
|
|
|
|
<< toFloat(nframes - 1, nchannels - 1) << endl;
|
2022-10-11 12:50:44 +00:00
|
|
|
dmat data = toFloat();
|
|
|
|
vrd max = arma::max(data, 0);
|
|
|
|
vrd min = arma::min(data, 0);
|
|
|
|
cout << "Maximum value in buf: " << max << endl;
|
|
|
|
cout << "Minumum value in buf: " << min << endl;
|
2022-10-04 07:27:27 +00:00
|
|
|
}
|