aqnwb 0.1.0
Loading...
Searching...
No Matches
ReadIO.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <any>
4#include <cstdint>
5#include <iostream>
6#include <memory>
7#include <string>
8#include <typeindex>
9#include <vector>
10
11#include <boost/multi_array.hpp> // TODO move this and function def to the cpp file
12
13#include "BaseIO.hpp"
14#include "Types.hpp"
15
18
23namespace AQNWB::IO
24{
25
30{
31public:
39 std::any data;
44 std::vector<SizeType> shape;
45
64 std::type_index typeIndex = typeid(void);
65
68
72 DataBlockGeneric() = default;
73
77 DataBlockGeneric(const std::any& inData,
78 const std::vector<SizeType>& inShape,
79 const std::type_index& inTypeIndex,
81 : data(inData)
82 , shape(inShape)
83 , typeIndex(inTypeIndex)
85 {
86 }
87
99 {
100 try {
101 switch (baseDataType.type) {
103 return std::any_cast<std::vector<uint8_t>>(data);
105 return std::any_cast<std::vector<uint16_t>>(data);
107 return std::any_cast<std::vector<uint32_t>>(data);
109 return std::any_cast<std::vector<uint64_t>>(data);
111 return std::any_cast<std::vector<int8_t>>(data);
113 return std::any_cast<std::vector<int16_t>>(data);
115 return std::any_cast<std::vector<int32_t>>(data);
117 return std::any_cast<std::vector<int64_t>>(data);
119 return std::any_cast<std::vector<float>>(data);
121 return std::any_cast<std::vector<double>>(data);
123 return std::any_cast<std::vector<std::string>>(data);
124 default:
125 return std::monostate {};
126 }
127 } catch (const std::bad_any_cast&) {
128 // If the actual type stored in `data` does not match the expected type
129 // based on `baseDataType`, a `std::bad_any_cast` exception will be
130 // thrown. In this case, we catch the exception and return
131 // `std::monostate` to indicate that the conversion failed.
132 return std::monostate {};
133 }
134 }
135};
136
142template<typename DTYPE>
144{
145public:
149 std::vector<DTYPE> data;
154 std::vector<SizeType> shape;
159 const std::type_index typeIndex = typeid(DTYPE);
160
164 DataBlock(const std::vector<DTYPE>& inData,
165 const std::vector<SizeType>& inShape)
166 : data(inData)
167 , shape(inShape)
168 {
169 }
170
179 template<std::size_t NDIMS>
180 inline boost::const_multi_array_ref<DTYPE, NDIMS> as_multi_array() const
181 {
182 if (shape.size() != NDIMS) {
183 throw std::invalid_argument(
184 "Shape size does not match the number of dimensions.");
185 }
186
187 // Calculate the total number of elements expected
188 SizeType expected_size = 1;
189 for (SizeType dim : shape) {
190 expected_size *= dim;
191 }
192
193 if (data.size() != expected_size) {
194 throw std::invalid_argument("Data size does not match the shape.");
195 }
196
197 // Convert the shape vector to a boost::array
198 boost::array<std::size_t, NDIMS> boost_shape;
199 std::copy(shape.begin(), shape.end(), boost_shape.begin());
200
201 // Construct and return the boost::const_multi_array_ref
202 return boost::const_multi_array_ref<DTYPE, NDIMS>(data.data(), boost_shape);
203 }
204
216 const DataBlockGeneric& genericData)
217 {
218 auto result = DataBlock<DTYPE>(
219 std::any_cast<std::vector<DTYPE>>(genericData.data), genericData.shape);
220 return result;
221 }
222
234 {
236 }
237}; // class DataBlock
238
241template<StorageObjectType T>
242struct isAllowedStorageObjectType : std::false_type
243{
244};
245
248template<>
249struct isAllowedStorageObjectType<StorageObjectType::Dataset> : std::true_type
250{
251};
252
255template<>
256struct isAllowedStorageObjectType<StorageObjectType::Attribute> : std::true_type
257{
258};
259
268template<StorageObjectType OTYPE, typename VTYPE = std::any>
270{
271 // Embedded traits for compile time checking of allowed OTYPE for the class
272 // and methods
273private:
282 template<StorageObjectType U>
284 : std::integral_constant<bool, (U == StorageObjectType::Dataset)>
285 {
286 };
287
295 "StorageObjectType not allowed for ReadDataWrapper");
296
297 // Actual definition of the class
298public:
305 ReadDataWrapper(const std::shared_ptr<IO::BaseIO> io, const std::string& path)
306 : m_io(io)
307 , m_path(path)
308 {
309 }
310
315 inline StorageObjectType getStorageObjectType() const { return OTYPE; }
316
321 template<typename T>
322 static constexpr bool isType()
323 {
324 return std::is_same_v<VTYPE, T>;
325 }
326
331
336
340 virtual ~ReadDataWrapper() {}
341
346 inline std::string getPath() const { return m_path; }
347
352 inline std::shared_ptr<IO::BaseIO> getIO() const { return m_io; }
353
358 inline std::vector<SizeType> getShape() const
359 {
360 return m_io->getStorageObjectShape(m_path);
361 }
362
367 inline SizeType getNumDimensions() const { return this->getShape().size(); }
368
373 inline bool exists() const
374 {
375 switch (OTYPE) {
376 case StorageObjectType::Dataset: {
377 return m_io->objectExists(m_path);
378 }
379 case StorageObjectType::Attribute: {
380 return m_io->attributeExists(m_path);
381 }
382 default: {
383 throw std::runtime_error("Unsupported StorageObjectType");
384 }
385 }
386 }
387
396 {
397 switch (OTYPE) {
398 case StorageObjectType::Dataset: {
399 return m_io->readDataset(m_path);
400 }
401 case StorageObjectType::Attribute: {
402 return m_io->readAttribute(m_path);
403 }
404 default: {
405 throw std::runtime_error("Unsupported StorageObjectType");
406 }
407 }
408 }
409
424 template<StorageObjectType U = OTYPE,
425 typename std::enable_if<isDataset<U>::value, int>::type = 0>
427 const std::vector<SizeType>& start,
428 const std::vector<SizeType>& count = {},
429 const std::vector<SizeType>& stride = {},
430 const std::vector<SizeType>& block = {}) const
431 {
432 // The function is only enabled for datasets so we don't need to check
433 // for attributes here.
434 return m_io->readDataset(m_path, start, count, stride, block);
435 }
436
451 template<typename T = VTYPE>
453 {
455 }
456
480 template<typename T = VTYPE,
481 StorageObjectType U = OTYPE,
482 typename std::enable_if<isDataset<U>::value, int>::type = 0>
483 inline DataBlock<VTYPE> values(const std::vector<SizeType>& start,
484 const std::vector<SizeType>& count = {},
485 const std::vector<SizeType>& stride = {},
486 const std::vector<SizeType>& block = {}) const
487 {
488 // The function is only enabled for datasets so we don't need to check
489 // for attributes here.
491 this->valuesGeneric(start, count, stride, block));
492 }
493
494protected:
498 const std::shared_ptr<IO::BaseIO> m_io;
502 std::string m_path;
503}; // ReadDataWrapper
504
505} // namespace AQNWB::IO
AQNWB::Types::StorageObjectType StorageObjectType
Definition BaseIO.hpp:21
AQNWB::Types::SizeType SizeType
Definition Channel.hpp:8
Represents a base data type.
Definition BaseIO.hpp:43
@ T_I32
Signed 32-bit integer.
Definition BaseIO.hpp:56
@ T_I64
Signed 64-bit integer.
Definition BaseIO.hpp:57
@ T_I8
Signed 8-bit integer.
Definition BaseIO.hpp:54
@ T_U32
Unsigned 32-bit integer.
Definition BaseIO.hpp:52
@ T_U64
Unsigned 64-bit integer.
Definition BaseIO.hpp:53
@ T_U8
Unsigned 8-bit integer.
Definition BaseIO.hpp:50
@ T_F32
32-bit floating point
Definition BaseIO.hpp:58
@ T_STR
String.
Definition BaseIO.hpp:60
@ T_F64
64-bit floating point
Definition BaseIO.hpp:59
@ T_U16
Unsigned 16-bit integer.
Definition BaseIO.hpp:51
@ T_I16
Signed 16-bit integer.
Definition BaseIO.hpp:55
std::variant< std::monostate, std::vector< uint8_t >, std::vector< uint16_t >, std::vector< uint32_t >, std::vector< uint64_t >, std::vector< int8_t >, std::vector< int16_t >, std::vector< int32_t >, std::vector< int64_t >, std::vector< float >, std::vector< double >, std::vector< std::string > > BaseDataVectorVariant
Definition BaseIO.hpp:96
static BaseDataType fromTypeId(const std::type_index &typeIndex)
Get the BaseDataType from a std::type_index.
Definition BaseIO.hpp:117
Generic structure to hold type-erased data and shape.
Definition ReadIO.hpp:30
std::vector< SizeType > shape
The 1D vector with the n-dimensional shape of the data. Set to empty in case of scalar data.
Definition ReadIO.hpp:44
IO::BaseDataType baseDataType
The base data type for the data block.
Definition ReadIO.hpp:67
DataBlockGeneric()=default
Default constructor.
std::any data
Definition ReadIO.hpp:39
BaseDataType::BaseDataVectorVariant as_variant() const
Cast the data to an std::variant for convenient access.
Definition ReadIO.hpp:98
std::type_index typeIndex
Type index of the values stored in the data vector.
Definition ReadIO.hpp:64
DataBlockGeneric(const std::any &inData, const std::vector< SizeType > &inShape, const std::type_index &inTypeIndex, const IO::BaseDataType baseDataType)
Parameterized constructor.
Definition ReadIO.hpp:77
Structure to hold data and shape for a typed data vector.
Definition ReadIO.hpp:144
DataBlock(const std::vector< DTYPE > &inData, const std::vector< SizeType > &inShape)
Definition ReadIO.hpp:164
static DataBlock< DTYPE > fromGeneric(const DataBlockGeneric &genericData)
Factory method to create an DataBlock from a DataBlockGeneric.
Definition ReadIO.hpp:215
boost::const_multi_array_ref< DTYPE, NDIMS > as_multi_array() const
Transform the data to a boost multi-dimensional array for convenient access.
Definition ReadIO.hpp:180
const std::type_index typeIndex
Type index of the values stored in the data vector. Here this is fixed to typeid(DTYPE)
Definition ReadIO.hpp:159
std::vector< DTYPE > data
Definition ReadIO.hpp:149
BaseDataType getBaseDataType() const
Get the BaseDataType for the data.
Definition ReadIO.hpp:233
std::vector< SizeType > shape
The 1D vector with the n-dimensional shape of the data. Set to empty in case of scalar data.
Definition ReadIO.hpp:154
static constexpr bool isType()
Function to check at compile-time whether the object is of a particular VTYPE, e.g....
Definition ReadIO.hpp:322
SizeType getNumDimensions() const
Get the number of dimensions of the data object.
Definition ReadIO.hpp:367
ReadDataWrapper & operator=(const ReadDataWrapper &)=delete
Deleted copy assignment operator to prevent copying.
std::string m_path
Path to the dataset or attribute to read.
Definition ReadIO.hpp:502
DataBlockGeneric valuesGeneric(const std::vector< SizeType > &start, const std::vector< SizeType > &count={}, const std::vector< SizeType > &stride={}, const std::vector< SizeType > &block={}) const
Reads a dataset and determines the data type.
Definition ReadIO.hpp:426
const std::shared_ptr< IO::BaseIO > m_io
Pointer to the I/O object to use for reading.
Definition ReadIO.hpp:498
DataBlock< VTYPE > values() const
Reads an attribute with a specified data type.
Definition ReadIO.hpp:452
DataBlockGeneric valuesGeneric() const
Reads a dataset and determines the data type.
Definition ReadIO.hpp:395
virtual ~ReadDataWrapper()
Destructor.
Definition ReadIO.hpp:340
std::shared_ptr< IO::BaseIO > getIO() const
Get a shared pointer to the IO object.
Definition ReadIO.hpp:352
bool exists() const
Check that the object exists.
Definition ReadIO.hpp:373
ReadDataWrapper(const std::shared_ptr< IO::BaseIO > io, const std::string &path)
Default constructor.
Definition ReadIO.hpp:305
std::string getPath() const
Gets the path of the registered type.
Definition ReadIO.hpp:346
DataBlock< VTYPE > values(const std::vector< SizeType > &start, const std::vector< SizeType > &count={}, const std::vector< SizeType > &stride={}, const std::vector< SizeType > &block={}) const
Reads an dataset with a specified data type.
Definition ReadIO.hpp:483
ReadDataWrapper(const ReadDataWrapper &)=delete
Deleted copy constructor to prevent construction-copying.
StorageObjectType getStorageObjectType() const
Function to return the AQNWB::Types::StorageObjectType OTYPE of the instance.
Definition ReadIO.hpp:315
std::vector< SizeType > getShape() const
Get the shape of the data object.
Definition ReadIO.hpp:358
StorageObjectType
Types of object used in the NWB schema.
Definition Types.hpp:53
size_t SizeType
Alias for the size type used in the project.
Definition Types.hpp:76
Definition BaseIO.hpp:31
Internal embedded Trait to Check the OTYPE Enum Value at compile time.
Definition ReadIO.hpp:285
Definition ReadIO.hpp:243